cortico-world-hands 0.1.5 → 0.1.7
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 +129 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -670,6 +670,43 @@ var Hands = class {
|
|
|
670
670
|
const ms = milliseconds(opts.ms, 900);
|
|
671
671
|
return this.perform({ kind: "drag", x1: a, y1: b, x2: c, y2: d, ms });
|
|
672
672
|
}
|
|
673
|
+
/** 长期记忆:存/改一条事实。 */
|
|
674
|
+
async memorySave(key, value, tags) {
|
|
675
|
+
const cfg = this.cfg();
|
|
676
|
+
const credential = this.readToken();
|
|
677
|
+
const t = credential ? `&t=${encodeURIComponent(credential)}` : "";
|
|
678
|
+
const tg = tags ? `&tags=${encodeURIComponent(tags)}` : "";
|
|
679
|
+
const path = `/hand/memory?key=${encodeURIComponent(key)}&value=${encodeURIComponent(value)}${tg}${t}`;
|
|
680
|
+
const res = await get(this.port(cfg.handPort), path, ACTION_TIMEOUT_MS);
|
|
681
|
+
let body = {};
|
|
682
|
+
try {
|
|
683
|
+
body = JSON.parse(res.body.toString("utf8"));
|
|
684
|
+
} catch {
|
|
685
|
+
}
|
|
686
|
+
return { ok: res.status === 200 && body.ok !== false, detail: flat(body.detail || body.error || "", 80) };
|
|
687
|
+
}
|
|
688
|
+
/** 长期记忆:按关键词回想(不传就全列)。 */
|
|
689
|
+
async memorySearch(query) {
|
|
690
|
+
const cfg = this.cfg();
|
|
691
|
+
const credential = this.readToken();
|
|
692
|
+
const t = credential ? `&t=${encodeURIComponent(credential)}` : "";
|
|
693
|
+
const q = query ? `?q=${encodeURIComponent(query)}${t}` : t ? `?${t.slice(1)}` : "";
|
|
694
|
+
const res = await get(this.port(cfg.handPort), `/hand/memories${q}`, ACTION_TIMEOUT_MS);
|
|
695
|
+
try {
|
|
696
|
+
const body = JSON.parse(res.body.toString("utf8"));
|
|
697
|
+
return Array.isArray(body.memories) ? body.memories : [];
|
|
698
|
+
} catch {
|
|
699
|
+
return [];
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
/** 长期记忆:忘掉一条。 */
|
|
703
|
+
async memoryForget(key) {
|
|
704
|
+
const cfg = this.cfg();
|
|
705
|
+
const credential = this.readToken();
|
|
706
|
+
const t = credential ? `&t=${encodeURIComponent(credential)}` : "";
|
|
707
|
+
const res = await get(this.port(cfg.handPort), `/hand/memory/forget?key=${encodeURIComponent(key)}${t}`, ACTION_TIMEOUT_MS);
|
|
708
|
+
return res.status === 200;
|
|
709
|
+
}
|
|
673
710
|
/** 留言板:写一条。 */
|
|
674
711
|
async noteAdd(text, kind) {
|
|
675
712
|
const cfg = this.cfg();
|
|
@@ -698,6 +735,15 @@ var Hands = class {
|
|
|
698
735
|
return [];
|
|
699
736
|
}
|
|
700
737
|
}
|
|
738
|
+
/** 留言板:未完成的待办条数(状态灯里显示)。 */
|
|
739
|
+
async notePending() {
|
|
740
|
+
try {
|
|
741
|
+
const notes = await this.noteList();
|
|
742
|
+
return notes.filter((n) => !n.done).length;
|
|
743
|
+
} catch {
|
|
744
|
+
return 0;
|
|
745
|
+
}
|
|
746
|
+
}
|
|
701
747
|
/** 留言板:划掉一条。 */
|
|
702
748
|
async noteDone(id) {
|
|
703
749
|
const cfg = this.cfg();
|
|
@@ -741,6 +787,7 @@ var Hands = class {
|
|
|
741
787
|
if (!state.ok) throw new HandError(`\u624B\u73B0\u5728\u52A8\u4E0D\u4E86\uFF1A${state.detail}`);
|
|
742
788
|
const where = await this.screenGuard();
|
|
743
789
|
await this.throttle();
|
|
790
|
+
this.lookCache = null;
|
|
744
791
|
const described = describeCommand(command);
|
|
745
792
|
const cfg = this.cfg();
|
|
746
793
|
if (cfg.dryRun) {
|
|
@@ -764,7 +811,18 @@ var Hands = class {
|
|
|
764
811
|
}
|
|
765
812
|
}
|
|
766
813
|
/** 看一眼屏幕。detail: both(画面加文字,默认)、screen(只要画面)、text(只要文字)。 */
|
|
814
|
+
lookCache = null;
|
|
767
815
|
async look(detail = "both") {
|
|
816
|
+
const now = Date.now();
|
|
817
|
+
if (this.lookCache && this.lookCache.detail === detail && now - this.lookCache.at < 1200) {
|
|
818
|
+
this.looks += 1;
|
|
819
|
+
return this.lookCache.report;
|
|
820
|
+
}
|
|
821
|
+
const report = await this.lookFresh(detail);
|
|
822
|
+
this.lookCache = { at: Date.now(), detail, report };
|
|
823
|
+
return report;
|
|
824
|
+
}
|
|
825
|
+
async lookFresh(detail = "both") {
|
|
768
826
|
const cfg = this.cfg();
|
|
769
827
|
const health = await this.eyes.health();
|
|
770
828
|
if (!health?.ok) {
|
|
@@ -952,6 +1010,42 @@ var HANDS_TOOL_DECLS = [
|
|
|
952
1010
|
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",
|
|
953
1011
|
parameters: { type: "object", properties: {}, required: [] }
|
|
954
1012
|
},
|
|
1013
|
+
{
|
|
1014
|
+
name: "memory_save",
|
|
1015
|
+
tags: ["act"],
|
|
1016
|
+
description: "\u5F80\u957F\u671F\u8BB0\u5FC6\u91CC\u5B58\u4E00\u6761\u4E8B\u5B9E\uFF1A\u4E3B\u4EBA\u7684\u540D\u5B57/\u79F0\u547C\u3001\u559C\u597D\u5FCC\u8BB3\u3001\u4F5C\u606F\u4E60\u60EF\u3001\u6B63\u5728\u505A\u7684\u4E8B\u3001\u7EA6\u5B9A\u3001\u91CD\u8981\u65E5\u5B50\u3001\u4F60\u7B54\u5E94\u8FC7\u7684\u4E8B\u3002key \u7528\u7B80\u77ED\u4E3B\u9898\uFF08\u5982\u300C\u4E3B\u4EBA\u79F0\u547C\u300D\u300C\u5496\u5561\u504F\u597D\u300D\u300C\u5468\u672B\u5B89\u6392\u300D\uFF09\uFF0Cvalue \u5199\u6E05\u695A\uFF1B\u540C\u4E00\u4E2A key \u4F1A\u8986\u76D6\u3002",
|
|
1017
|
+
parameters: {
|
|
1018
|
+
type: "object",
|
|
1019
|
+
properties: {
|
|
1020
|
+
key: { type: "string", description: "\u7B80\u77ED\u4E3B\u9898\uFF0C\u6BD4\u5982\u300C\u4E3B\u4EBA\u7684\u732B\u300D\u300C\u751F\u65E5\u300D\u300C\u4E0D\u559C\u6B22\u300D" },
|
|
1021
|
+
value: { type: "string", description: "\u8BB0\u7684\u5177\u4F53\u5185\u5BB9\uFF0C\u4E00\u53E5\u8BDD\u8BF4\u6E05\u3002" },
|
|
1022
|
+
tags: { type: "string", description: "\u53EF\u9009\u6807\u7B7E\uFF0C\u9017\u53F7\u5206\u9694\u3002" }
|
|
1023
|
+
},
|
|
1024
|
+
required: ["key", "value"]
|
|
1025
|
+
}
|
|
1026
|
+
},
|
|
1027
|
+
{
|
|
1028
|
+
name: "memory_search",
|
|
1029
|
+
tags: ["read"],
|
|
1030
|
+
description: "\u56DE\u60F3\u957F\u671F\u8BB0\u5FC6\uFF1A\u6309\u5173\u952E\u8BCD\u67E5\uFF08\u4E0D\u4F20\u5173\u952E\u8BCD\u5C31\u5168\u90E8\u5217\u51FA\uFF09\u3002\u804A\u5929\u91CC\u6D89\u53CA\u4E3B\u4EBA\u7684\u504F\u597D\u3001\u7EA6\u5B9A\u3001\u4EE5\u524D\u8BF4\u8FC7\u7684\u4E8B\u65F6\u5148\u67E5\u4E00\u4E0B\uFF0C\u522B\u51ED\u611F\u89C9\u3002",
|
|
1031
|
+
parameters: {
|
|
1032
|
+
type: "object",
|
|
1033
|
+
properties: {
|
|
1034
|
+
query: { type: "string", description: "\u5173\u952E\u8BCD\uFF0C\u6BD4\u5982\u300C\u5496\u5561\u300D\u300C\u751F\u65E5\u300D\uFF1B\u7559\u7A7A\u770B\u5168\u90E8\u3002" }
|
|
1035
|
+
},
|
|
1036
|
+
required: []
|
|
1037
|
+
}
|
|
1038
|
+
},
|
|
1039
|
+
{
|
|
1040
|
+
name: "memory_forget",
|
|
1041
|
+
tags: ["act"],
|
|
1042
|
+
description: "\u5FD8\u6389\u4E00\u6761\u957F\u671F\u8BB0\u5FC6\uFF08\u8BB0\u9519\u4E86\u3001\u8FC7\u65F6\u4E86\u3001\u4E3B\u4EBA\u8BF4\u522B\u8BB0\u4E86\uFF09\u3002",
|
|
1043
|
+
parameters: {
|
|
1044
|
+
type: "object",
|
|
1045
|
+
properties: { key: { type: "string", description: "\u8981\u5FD8\u6389\u7684\u4E3B\u9898 key\u3002" } },
|
|
1046
|
+
required: ["key"]
|
|
1047
|
+
}
|
|
1048
|
+
},
|
|
955
1049
|
{
|
|
956
1050
|
name: "note_add",
|
|
957
1051
|
tags: ["act"],
|
|
@@ -1078,7 +1172,13 @@ var HandsWorld = class {
|
|
|
1078
1172
|
case "hand_key":
|
|
1079
1173
|
return await this.key(args);
|
|
1080
1174
|
case "hand_status":
|
|
1081
|
-
return this.statusText();
|
|
1175
|
+
return await this.statusText();
|
|
1176
|
+
case "memory_save":
|
|
1177
|
+
return await this.memorySave(args);
|
|
1178
|
+
case "memory_search":
|
|
1179
|
+
return await this.memorySearch(args);
|
|
1180
|
+
case "memory_forget":
|
|
1181
|
+
return await this.memoryForget(args);
|
|
1082
1182
|
case "note_add":
|
|
1083
1183
|
return await this.noteAdd(args);
|
|
1084
1184
|
case "note_list":
|
|
@@ -1115,6 +1215,28 @@ var HandsWorld = class {
|
|
|
1115
1215
|
return { text: report.text, ...blobs.length ? { blobs } : {} };
|
|
1116
1216
|
}
|
|
1117
1217
|
/** 给文字就先在屏幕上找,找到唯一一处才点;给坐标就直接点。 */
|
|
1218
|
+
async memorySave(args) {
|
|
1219
|
+
const key = typeof args.key === "string" ? args.key.trim() : "";
|
|
1220
|
+
const value = typeof args.value === "string" ? args.value.trim() : "";
|
|
1221
|
+
if (!key || !value) return failed("\u8981 key \u548C value\u3002");
|
|
1222
|
+
const tags = typeof args.tags === "string" ? args.tags : void 0;
|
|
1223
|
+
const r = await this.hands.memorySave(key, value, tags);
|
|
1224
|
+
return r.ok ? `\u8BB0\u7262\u4E86\uFF1A\u300C${key}\u300D\u2192 ${value}` : failed(`\u6CA1\u8BB0\u4F4F\uFF1A${r.detail || "\u624B\u6CA1\u54CD\u5E94"}`);
|
|
1225
|
+
}
|
|
1226
|
+
async memorySearch(args) {
|
|
1227
|
+
const query = typeof args.query === "string" ? args.query.trim() : "";
|
|
1228
|
+
const rows = await this.hands.memorySearch(query);
|
|
1229
|
+
if (rows.length === 0) return query ? `\u8BB0\u5FC6\u91CC\u6CA1\u6709\u548C\u300C${query}\u300D\u76F8\u5173\u7684\u3002` : "\u957F\u671F\u8BB0\u5FC6\u8FD8\u662F\u7A7A\u7684\u3002";
|
|
1230
|
+
const lines = rows.slice(0, 30).map((r) => `- ${r.key}\uFF1A${r.value}${r.ts ? `\uFF08${r.ts}\uFF09` : ""}`).join("\n");
|
|
1231
|
+
return `\u60F3\u8D77 ${rows.length} \u6761\uFF1A
|
|
1232
|
+
${lines}`;
|
|
1233
|
+
}
|
|
1234
|
+
async memoryForget(args) {
|
|
1235
|
+
const key = typeof args.key === "string" ? args.key.trim() : "";
|
|
1236
|
+
if (!key) return failed("\u8981\u5FD8\u6389\u54EA\u4E2A key\uFF1F");
|
|
1237
|
+
const ok = await this.hands.memoryForget(key);
|
|
1238
|
+
return ok ? `\u5FD8\u4E86\u300C${key}\u300D\u3002` : failed(`\u6CA1\u627E\u5230\u300C${key}\u300D\u8FD9\u6761\u8BB0\u5FC6\u3002`);
|
|
1239
|
+
}
|
|
1118
1240
|
async noteAdd(args) {
|
|
1119
1241
|
const text = typeof args.text === "string" ? args.text.trim() : "";
|
|
1120
1242
|
if (!text) return failed("\u8981\u5199\u4EC0\u4E48\uFF1F\u7ED9 text\u3002");
|
|
@@ -1230,7 +1352,7 @@ ${list}`);
|
|
|
1230
1352
|
this.note(receipt);
|
|
1231
1353
|
return receipt.text;
|
|
1232
1354
|
}
|
|
1233
|
-
statusText() {
|
|
1355
|
+
async statusText() {
|
|
1234
1356
|
const cfg = this.opts.cfg;
|
|
1235
1357
|
const state = this.hands.state();
|
|
1236
1358
|
const stats = this.hands.stats();
|
|
@@ -1241,6 +1363,11 @@ ${list}`);
|
|
|
1241
1363
|
`\u8FD9\u4E00\u5206\u949F\uFF1A${stats.inWindow}\uFF0F${Math.max(1, Math.round(cfg.maxActionsPerMinute) || 30)} \u4E0B\uFF1B\u7D2F\u8BA1\u52A8\u8FC7 ${stats.acts} \u6B21\u3001\u770B\u8FC7 ${stats.looks} \u6B21`
|
|
1242
1364
|
];
|
|
1243
1365
|
if (this.pausedUntil > Date.now()) lines.push(`\u53EB\u505C\u4E2D\uFF1A\u8FD8\u6709 ${Math.ceil((this.pausedUntil - Date.now()) / 1e3)} \u79D2`);
|
|
1366
|
+
try {
|
|
1367
|
+
const pending = await this.hands.notePending();
|
|
1368
|
+
if (pending > 0) lines.push(`\u7559\u8A00\u677F\uFF1A\u8FD8\u6709 ${pending} \u6761\u6CA1\u5212\u6389`);
|
|
1369
|
+
} catch {
|
|
1370
|
+
}
|
|
1244
1371
|
if (this.recent.length) lines.push(`\u6700\u8FD1\uFF1A
|
|
1245
1372
|
${this.recent.map((r) => `- ${r}`).join("\n")}`);
|
|
1246
1373
|
return lines.join("\n");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cortico-world-hands",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
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",
|