cortico-world-hands 0.1.6 → 0.1.8
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 +294 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -15,7 +15,13 @@ var HANDS_DEFAULTS = {
|
|
|
15
15
|
maxTextLength: 200,
|
|
16
16
|
lookAttach: true,
|
|
17
17
|
lookMaxWidth: 720,
|
|
18
|
-
lookQuality: 60
|
|
18
|
+
lookQuality: 60,
|
|
19
|
+
honchoEnabled: false,
|
|
20
|
+
honchoApiKey: "",
|
|
21
|
+
honchoBaseUrl: "https://api.honcho.dev",
|
|
22
|
+
honchoWorkspace: "dsh",
|
|
23
|
+
honchoPeerId: "\u4E3B\u4EBA",
|
|
24
|
+
honchoSessionId: "yixin"
|
|
19
25
|
};
|
|
20
26
|
var KEY_CODES = {
|
|
21
27
|
back: 4,
|
|
@@ -37,6 +43,54 @@ var KEY_CODES = {
|
|
|
37
43
|
menu: 82
|
|
38
44
|
};
|
|
39
45
|
var K = `worlds.${HANDS_ID}`;
|
|
46
|
+
var HK = `worlds.${HANDS_ID}`;
|
|
47
|
+
var HANDS_HONCHO_GROUP = {
|
|
48
|
+
id: `world:${HANDS_ID}:honcho`,
|
|
49
|
+
owner: `world:${HANDS_ID}`,
|
|
50
|
+
schema: {
|
|
51
|
+
type: "object",
|
|
52
|
+
title: "Honcho \u8BB0\u5FC6",
|
|
53
|
+
description: "\u628A\u684C\u5BA0\u7684\u957F\u671F\u8BB0\u5FC6\u540C\u6B65\u5230 Honcho\uFF08plastic-labs \u7684\u8BB0\u5FC6\u670D\u52A1\uFF09\uFF0C\u56DE\u60F3\u65F6\u628A\u4E91\u7AEF\u7ED3\u8BBA\u4E00\u8D77\u5E26\u56DE\u6765\u3002\u4E0D\u586B key \u5C31\u53EA\u7528\u672C\u5730 memory.jsonl\u3002",
|
|
54
|
+
properties: {
|
|
55
|
+
[`${HK}.honchoEnabled`]: {
|
|
56
|
+
type: "boolean",
|
|
57
|
+
title: "\u542F\u7528 Honcho \u8BB0\u5FC6",
|
|
58
|
+
description: "\u6253\u5F00\u540E memory_save \u4F1A\u540C\u65F6\u5199\u672C\u5730\u4E0E Honcho\uFF0Cmemory_search \u4F1A\u5408\u5E76\u4E91\u7AEF\u7ED3\u679C\u3002",
|
|
59
|
+
"x-hot": true
|
|
60
|
+
},
|
|
61
|
+
[`${HK}.honchoApiKey`]: {
|
|
62
|
+
type: "string",
|
|
63
|
+
title: "API Key",
|
|
64
|
+
description: "\u5728 app.honcho.dev \u7533\u8BF7\u3002\u53EA\u586B\u8FD9\u4E00\u9879\u5373\u53EF\uFF0C\u5176\u4F59\u4FDD\u6301\u9ED8\u8BA4\u3002",
|
|
65
|
+
"x-hot": true
|
|
66
|
+
},
|
|
67
|
+
[`${HK}.honchoBaseUrl`]: {
|
|
68
|
+
type: "string",
|
|
69
|
+
title: "\u670D\u52A1\u5730\u5740",
|
|
70
|
+
description: "\u9ED8\u8BA4 https://api.honcho.dev\uFF1B\u81EA\u5EFA\u5B9E\u4F8B\u586B\u81EA\u5DF1\u7684\u5730\u5740\u3002",
|
|
71
|
+
"x-hot": false
|
|
72
|
+
},
|
|
73
|
+
[`${HK}.honchoWorkspace`]: {
|
|
74
|
+
type: "string",
|
|
75
|
+
title: "\u5DE5\u4F5C\u533A",
|
|
76
|
+
description: "\u8BB0\u5FC6\u7684\u9694\u79BB\u8FB9\u754C\u3002\u60F3\u548C\u5176\u4ED6\u7AEF\uFF08claude-honcho \u7B49\uFF09\u5171\u4EAB\u8BB0\u5FC6\u5C31\u586B\u540C\u4E00\u4E2A workspace\u3002",
|
|
77
|
+
"x-hot": false
|
|
78
|
+
},
|
|
79
|
+
[`${HK}.honchoPeerId`]: {
|
|
80
|
+
type: "string",
|
|
81
|
+
title: "\u5173\u4E8E\u8C01",
|
|
82
|
+
description: "\u8BB0\u5FC6\u5F52\u5C5E\u7684 peer\uFF0C\u9ED8\u8BA4\u300C\u4E3B\u4EBA\u300D\u3002",
|
|
83
|
+
"x-hot": false
|
|
84
|
+
},
|
|
85
|
+
[`${HK}.honchoSessionId`]: {
|
|
86
|
+
type: "string",
|
|
87
|
+
title: "\u4F1A\u8BDD\u540D",
|
|
88
|
+
description: "Honcho \u91CC\u7684\u4F1A\u8BDD\u6807\u8BC6\uFF0C\u9ED8\u8BA4 yixin\u3002",
|
|
89
|
+
"x-hot": false
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
};
|
|
40
94
|
var HANDS_CONFIG_GROUP = {
|
|
41
95
|
id: `world:${HANDS_ID}`,
|
|
42
96
|
owner: `world:${HANDS_ID}`,
|
|
@@ -161,6 +215,98 @@ var HANDS_LOOK_CONFIG_GROUP = {
|
|
|
161
215
|
// src/world.ts
|
|
162
216
|
import { fileURLToPath } from "node:url";
|
|
163
217
|
|
|
218
|
+
// src/honcho.ts
|
|
219
|
+
var TIMEOUT_MS = 12e3;
|
|
220
|
+
var Honcho = class {
|
|
221
|
+
cfg;
|
|
222
|
+
peerReady = false;
|
|
223
|
+
sessionReady = false;
|
|
224
|
+
constructor(cfg) {
|
|
225
|
+
this.cfg = cfg;
|
|
226
|
+
}
|
|
227
|
+
get configured() {
|
|
228
|
+
return this.cfg.enabled && this.cfg.apiKey.trim().length > 0;
|
|
229
|
+
}
|
|
230
|
+
base() {
|
|
231
|
+
return this.cfg.baseUrl.replace(/\/+$/, "");
|
|
232
|
+
}
|
|
233
|
+
async call(path, body) {
|
|
234
|
+
const url = `${this.base()}/v3/workspaces/${encodeURIComponent(this.cfg.workspace)}${path}`;
|
|
235
|
+
const controller = new AbortController();
|
|
236
|
+
const timer = setTimeout(() => controller.abort(), TIMEOUT_MS);
|
|
237
|
+
try {
|
|
238
|
+
const res = await fetch(url, {
|
|
239
|
+
method: "POST",
|
|
240
|
+
headers: {
|
|
241
|
+
"content-type": "application/json",
|
|
242
|
+
authorization: `Bearer ${this.cfg.apiKey.trim()}`
|
|
243
|
+
},
|
|
244
|
+
body: JSON.stringify(body),
|
|
245
|
+
signal: controller.signal
|
|
246
|
+
});
|
|
247
|
+
const text = await res.text();
|
|
248
|
+
if (!res.ok) throw new Error(`honcho ${res.status}: ${text.slice(0, 160)}`);
|
|
249
|
+
return text ? JSON.parse(text) : {};
|
|
250
|
+
} finally {
|
|
251
|
+
clearTimeout(timer);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
async ensurePeer() {
|
|
255
|
+
if (this.peerReady) return;
|
|
256
|
+
await this.call("/peers", { id: this.cfg.peerId });
|
|
257
|
+
this.peerReady = true;
|
|
258
|
+
}
|
|
259
|
+
async ensureSession() {
|
|
260
|
+
if (this.sessionReady) return;
|
|
261
|
+
await this.ensurePeer();
|
|
262
|
+
await this.call("/sessions", { id: this.cfg.sessionId, peers: [this.cfg.peerId] });
|
|
263
|
+
this.sessionReady = true;
|
|
264
|
+
}
|
|
265
|
+
/** 把一条事实写进 Honcho 的会话里(后台 Deriver 会据此归纳结论)。 */
|
|
266
|
+
async remember(sentence) {
|
|
267
|
+
if (!this.configured) return;
|
|
268
|
+
await this.ensureSession();
|
|
269
|
+
await this.call(`/sessions/${encodeURIComponent(this.cfg.sessionId)}/messages`, {
|
|
270
|
+
messages: [{ peer_id: this.cfg.peerId, content: sentence }]
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
/** 在 Honcho 里搜相关记忆(原始消息 + 归纳结论)。 */
|
|
274
|
+
async search(query, limit = 8) {
|
|
275
|
+
if (!this.configured) return [];
|
|
276
|
+
await this.ensurePeer();
|
|
277
|
+
const raw = await this.call(`/peers/${encodeURIComponent(this.cfg.peerId)}/search`, {
|
|
278
|
+
query,
|
|
279
|
+
limit
|
|
280
|
+
});
|
|
281
|
+
const hits = [];
|
|
282
|
+
const push = (item, source) => {
|
|
283
|
+
if (typeof item === "string") {
|
|
284
|
+
hits.push({ text: item, source });
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
if (!item || typeof item !== "object") return;
|
|
288
|
+
const row = item;
|
|
289
|
+
const text = [row.content, row.text, row.conclusion, row.observation].find((v) => typeof v === "string" && v.trim().length > 0);
|
|
290
|
+
if (text) hits.push({ text: text.trim(), source: String(row.session_id || row.type || source) });
|
|
291
|
+
};
|
|
292
|
+
const list = Array.isArray(raw) ? raw : raw.results || raw.messages || raw.conclusions || [];
|
|
293
|
+
for (const item of list) push(item, "\u7ED3\u8BBA");
|
|
294
|
+
return hits.slice(0, limit);
|
|
295
|
+
}
|
|
296
|
+
/** 让 Honcho 用自己的推理回答一个关于主人的问题(慢,但更“懂”)。 */
|
|
297
|
+
async ask(question) {
|
|
298
|
+
if (!this.configured) return "";
|
|
299
|
+
await this.ensurePeer();
|
|
300
|
+
const raw = await this.call(`/peers/${encodeURIComponent(this.cfg.peerId)}/chat`, {
|
|
301
|
+
query: question
|
|
302
|
+
});
|
|
303
|
+
const answer = [raw.content, raw.answer, raw.text, raw.reply].find(
|
|
304
|
+
(v) => typeof v === "string" && v.trim().length > 0
|
|
305
|
+
);
|
|
306
|
+
return answer ? answer.trim() : "";
|
|
307
|
+
}
|
|
308
|
+
};
|
|
309
|
+
|
|
164
310
|
// src/hands.ts
|
|
165
311
|
import { execFile } from "node:child_process";
|
|
166
312
|
import { readFileSync } from "node:fs";
|
|
@@ -670,6 +816,43 @@ var Hands = class {
|
|
|
670
816
|
const ms = milliseconds(opts.ms, 900);
|
|
671
817
|
return this.perform({ kind: "drag", x1: a, y1: b, x2: c, y2: d, ms });
|
|
672
818
|
}
|
|
819
|
+
/** 长期记忆:存/改一条事实。 */
|
|
820
|
+
async memorySave(key, value, tags) {
|
|
821
|
+
const cfg = this.cfg();
|
|
822
|
+
const credential = this.readToken();
|
|
823
|
+
const t = credential ? `&t=${encodeURIComponent(credential)}` : "";
|
|
824
|
+
const tg = tags ? `&tags=${encodeURIComponent(tags)}` : "";
|
|
825
|
+
const path = `/hand/memory?key=${encodeURIComponent(key)}&value=${encodeURIComponent(value)}${tg}${t}`;
|
|
826
|
+
const res = await get(this.port(cfg.handPort), path, ACTION_TIMEOUT_MS);
|
|
827
|
+
let body = {};
|
|
828
|
+
try {
|
|
829
|
+
body = JSON.parse(res.body.toString("utf8"));
|
|
830
|
+
} catch {
|
|
831
|
+
}
|
|
832
|
+
return { ok: res.status === 200 && body.ok !== false, detail: flat(body.detail || body.error || "", 80) };
|
|
833
|
+
}
|
|
834
|
+
/** 长期记忆:按关键词回想(不传就全列)。 */
|
|
835
|
+
async memorySearch(query) {
|
|
836
|
+
const cfg = this.cfg();
|
|
837
|
+
const credential = this.readToken();
|
|
838
|
+
const t = credential ? `&t=${encodeURIComponent(credential)}` : "";
|
|
839
|
+
const q = query ? `?q=${encodeURIComponent(query)}${t}` : t ? `?${t.slice(1)}` : "";
|
|
840
|
+
const res = await get(this.port(cfg.handPort), `/hand/memories${q}`, ACTION_TIMEOUT_MS);
|
|
841
|
+
try {
|
|
842
|
+
const body = JSON.parse(res.body.toString("utf8"));
|
|
843
|
+
return Array.isArray(body.memories) ? body.memories : [];
|
|
844
|
+
} catch {
|
|
845
|
+
return [];
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
/** 长期记忆:忘掉一条。 */
|
|
849
|
+
async memoryForget(key) {
|
|
850
|
+
const cfg = this.cfg();
|
|
851
|
+
const credential = this.readToken();
|
|
852
|
+
const t = credential ? `&t=${encodeURIComponent(credential)}` : "";
|
|
853
|
+
const res = await get(this.port(cfg.handPort), `/hand/memory/forget?key=${encodeURIComponent(key)}${t}`, ACTION_TIMEOUT_MS);
|
|
854
|
+
return res.status === 200;
|
|
855
|
+
}
|
|
673
856
|
/** 留言板:写一条。 */
|
|
674
857
|
async noteAdd(text, kind) {
|
|
675
858
|
const cfg = this.cfg();
|
|
@@ -973,6 +1156,42 @@ var HANDS_TOOL_DECLS = [
|
|
|
973
1156
|
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",
|
|
974
1157
|
parameters: { type: "object", properties: {}, required: [] }
|
|
975
1158
|
},
|
|
1159
|
+
{
|
|
1160
|
+
name: "memory_save",
|
|
1161
|
+
tags: ["act"],
|
|
1162
|
+
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",
|
|
1163
|
+
parameters: {
|
|
1164
|
+
type: "object",
|
|
1165
|
+
properties: {
|
|
1166
|
+
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" },
|
|
1167
|
+
value: { type: "string", description: "\u8BB0\u7684\u5177\u4F53\u5185\u5BB9\uFF0C\u4E00\u53E5\u8BDD\u8BF4\u6E05\u3002" },
|
|
1168
|
+
tags: { type: "string", description: "\u53EF\u9009\u6807\u7B7E\uFF0C\u9017\u53F7\u5206\u9694\u3002" }
|
|
1169
|
+
},
|
|
1170
|
+
required: ["key", "value"]
|
|
1171
|
+
}
|
|
1172
|
+
},
|
|
1173
|
+
{
|
|
1174
|
+
name: "memory_search",
|
|
1175
|
+
tags: ["read"],
|
|
1176
|
+
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",
|
|
1177
|
+
parameters: {
|
|
1178
|
+
type: "object",
|
|
1179
|
+
properties: {
|
|
1180
|
+
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" }
|
|
1181
|
+
},
|
|
1182
|
+
required: []
|
|
1183
|
+
}
|
|
1184
|
+
},
|
|
1185
|
+
{
|
|
1186
|
+
name: "memory_forget",
|
|
1187
|
+
tags: ["act"],
|
|
1188
|
+
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",
|
|
1189
|
+
parameters: {
|
|
1190
|
+
type: "object",
|
|
1191
|
+
properties: { key: { type: "string", description: "\u8981\u5FD8\u6389\u7684\u4E3B\u9898 key\u3002" } },
|
|
1192
|
+
required: ["key"]
|
|
1193
|
+
}
|
|
1194
|
+
},
|
|
976
1195
|
{
|
|
977
1196
|
name: "note_add",
|
|
978
1197
|
tags: ["act"],
|
|
@@ -1039,6 +1258,7 @@ var HandsWorld = class {
|
|
|
1039
1258
|
hands;
|
|
1040
1259
|
pausedUntil = 0;
|
|
1041
1260
|
recent = [];
|
|
1261
|
+
honchoClient = null;
|
|
1042
1262
|
opts;
|
|
1043
1263
|
constructor(opts) {
|
|
1044
1264
|
this.opts = opts;
|
|
@@ -1100,6 +1320,12 @@ var HandsWorld = class {
|
|
|
1100
1320
|
return await this.key(args);
|
|
1101
1321
|
case "hand_status":
|
|
1102
1322
|
return await this.statusText();
|
|
1323
|
+
case "memory_save":
|
|
1324
|
+
return await this.memorySave(args);
|
|
1325
|
+
case "memory_search":
|
|
1326
|
+
return await this.memorySearch(args);
|
|
1327
|
+
case "memory_forget":
|
|
1328
|
+
return await this.memoryForget(args);
|
|
1103
1329
|
case "note_add":
|
|
1104
1330
|
return await this.noteAdd(args);
|
|
1105
1331
|
case "note_list":
|
|
@@ -1136,6 +1362,72 @@ var HandsWorld = class {
|
|
|
1136
1362
|
return { text: report.text, ...blobs.length ? { blobs } : {} };
|
|
1137
1363
|
}
|
|
1138
1364
|
/** 给文字就先在屏幕上找,找到唯一一处才点;给坐标就直接点。 */
|
|
1365
|
+
honcho() {
|
|
1366
|
+
if (!this.honchoClient) {
|
|
1367
|
+
this.honchoClient = new Honcho({
|
|
1368
|
+
enabled: Boolean(this.opts.cfg.honchoEnabled),
|
|
1369
|
+
apiKey: this.opts.cfg.honchoApiKey || "",
|
|
1370
|
+
baseUrl: this.opts.cfg.honchoBaseUrl || "https://api.honcho.dev",
|
|
1371
|
+
workspace: this.opts.cfg.honchoWorkspace || "dsh",
|
|
1372
|
+
peerId: this.opts.cfg.honchoPeerId || "\u4E3B\u4EBA",
|
|
1373
|
+
sessionId: this.opts.cfg.honchoSessionId || "yixin"
|
|
1374
|
+
});
|
|
1375
|
+
}
|
|
1376
|
+
return this.honchoClient;
|
|
1377
|
+
}
|
|
1378
|
+
async memorySave(args) {
|
|
1379
|
+
const key = typeof args.key === "string" ? args.key.trim() : "";
|
|
1380
|
+
const value = typeof args.value === "string" ? args.value.trim() : "";
|
|
1381
|
+
if (!key || !value) return failed("\u8981 key \u548C value\u3002");
|
|
1382
|
+
const tags = typeof args.tags === "string" ? args.tags : void 0;
|
|
1383
|
+
const r = await this.hands.memorySave(key, value, tags);
|
|
1384
|
+
if (!r.ok) return failed(`\u6CA1\u8BB0\u4F4F\uFF1A${r.detail || "\u624B\u6CA1\u54CD\u5E94"}`);
|
|
1385
|
+
let cloud = "";
|
|
1386
|
+
const honcho = this.honcho();
|
|
1387
|
+
if (honcho.configured) {
|
|
1388
|
+
try {
|
|
1389
|
+
await honcho.remember(`\u5173\u4E8E\u300C${key}\u300D\uFF1A${value}`);
|
|
1390
|
+
cloud = "\uFF08\u5DF2\u540C\u6B65 Honcho\uFF09";
|
|
1391
|
+
} catch (err) {
|
|
1392
|
+
cloud = `\uFF08Honcho \u540C\u6B65\u5931\u8D25\uFF1A${err.message.slice(0, 60)}\uFF09`;
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
return `\u8BB0\u7262\u4E86\uFF1A\u300C${key}\u300D\u2192 ${value}${cloud}`;
|
|
1396
|
+
}
|
|
1397
|
+
async memorySearch(args) {
|
|
1398
|
+
const query = typeof args.query === "string" ? args.query.trim() : "";
|
|
1399
|
+
const rows = await this.hands.memorySearch(query);
|
|
1400
|
+
const lines = rows.slice(0, 30).map((r) => `- ${r.key}\uFF1A${r.value}${r.ts ? `\uFF08${r.ts}\uFF09` : ""}`);
|
|
1401
|
+
let cloudHits = [];
|
|
1402
|
+
let cloudNote = "";
|
|
1403
|
+
const honcho = this.honcho();
|
|
1404
|
+
if (honcho.configured && query) {
|
|
1405
|
+
try {
|
|
1406
|
+
const hits = await honcho.search(query);
|
|
1407
|
+
cloudHits = hits.map((h) => `- ${h.text}`);
|
|
1408
|
+
if (cloudHits.length > 0) cloudNote = `
|
|
1409
|
+
|
|
1410
|
+
Honcho \u8865\u5145 ${cloudHits.length} \u6761\uFF1A`;
|
|
1411
|
+
} catch (err) {
|
|
1412
|
+
cloudNote = `
|
|
1413
|
+
|
|
1414
|
+
\uFF08Honcho \u67E5\u8BE2\u5931\u8D25\uFF1A${err.message.slice(0, 60)}\uFF09`;
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
if (lines.length === 0 && cloudHits.length === 0) {
|
|
1418
|
+
return query ? `\u8BB0\u5FC6\u91CC\u6CA1\u6709\u548C\u300C${query}\u300D\u76F8\u5173\u7684\u3002` : "\u957F\u671F\u8BB0\u5FC6\u8FD8\u662F\u7A7A\u7684\u3002";
|
|
1419
|
+
}
|
|
1420
|
+
const local = lines.length > 0 ? `\u60F3\u8D77 ${rows.length} \u6761\uFF1A
|
|
1421
|
+
${lines.join("\n")}` : "\u672C\u5730\u8BB0\u5FC6\u6CA1\u6709\u76F4\u63A5\u547D\u4E2D\u3002";
|
|
1422
|
+
return local + cloudNote + (cloudHits.length > 0 ? `
|
|
1423
|
+
${cloudHits.join("\n")}` : "");
|
|
1424
|
+
}
|
|
1425
|
+
async memoryForget(args) {
|
|
1426
|
+
const key = typeof args.key === "string" ? args.key.trim() : "";
|
|
1427
|
+
if (!key) return failed("\u8981\u5FD8\u6389\u54EA\u4E2A key\uFF1F");
|
|
1428
|
+
const ok = await this.hands.memoryForget(key);
|
|
1429
|
+
return ok ? `\u5FD8\u4E86\u300C${key}\u300D\u3002` : failed(`\u6CA1\u627E\u5230\u300C${key}\u300D\u8FD9\u6761\u8BB0\u5FC6\u3002`);
|
|
1430
|
+
}
|
|
1139
1431
|
async noteAdd(args) {
|
|
1140
1432
|
const text = typeof args.text === "string" ? args.text.trim() : "";
|
|
1141
1433
|
if (!text) return failed("\u8981\u5199\u4EC0\u4E48\uFF1F\u7ED9 text\u3002");
|
|
@@ -1313,7 +1605,7 @@ ${this.recent.map((r) => `- ${r}`).join("\n")}`);
|
|
|
1313
1605
|
{ label: zh ? "\u52A8\u8FC7" : "actions", value: stats.acts, tone: "plain" },
|
|
1314
1606
|
{ label: zh ? "\u770B\u8FC7" : "looks", value: stats.looks, tone: "plain" }
|
|
1315
1607
|
],
|
|
1316
|
-
config: [HANDS_CONFIG_GROUP, HANDS_LOOK_CONFIG_GROUP],
|
|
1608
|
+
config: [HANDS_CONFIG_GROUP, HANDS_LOOK_CONFIG_GROUP, HANDS_HONCHO_GROUP],
|
|
1317
1609
|
promptDocs: [
|
|
1318
1610
|
{
|
|
1319
1611
|
key: `worlds.${HANDS_ID}.envPrompt`,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cortico-world-hands",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
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",
|