cortico-world-hands 0.1.8 → 0.2.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.
Files changed (2) hide show
  1. package/dist/index.js +48 -7
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -20,7 +20,7 @@ var HANDS_DEFAULTS = {
20
20
  honchoApiKey: "",
21
21
  honchoBaseUrl: "https://api.honcho.dev",
22
22
  honchoWorkspace: "dsh",
23
- honchoPeerId: "\u4E3B\u4EBA",
23
+ honchoPeerId: "morse",
24
24
  honchoSessionId: "yixin"
25
25
  };
26
26
  var KEY_CODES = {
@@ -79,7 +79,7 @@ var HANDS_HONCHO_GROUP = {
79
79
  [`${HK}.honchoPeerId`]: {
80
80
  type: "string",
81
81
  title: "\u5173\u4E8E\u8C01",
82
- description: "\u8BB0\u5FC6\u5F52\u5C5E\u7684 peer\uFF0C\u9ED8\u8BA4\u300C\u4E3B\u4EBA\u300D\u3002",
82
+ description: "\u8BB0\u5FC6\u5F52\u5C5E\u7684 peer\uFF0C\u53EA\u80FD\u7528\u5B57\u6BCD/\u6570\u5B57/\u4E0B\u5212\u7EBF/\u8FDE\u5B57\u7B26\uFF08\u9ED8\u8BA4 morse\uFF0C\u4E2D\u6587\u4F1A\u88AB\u6362\u6210 morse\uFF09\u3002",
83
83
  "x-hot": false
84
84
  },
85
85
  [`${HK}.honchoSessionId`]: {
@@ -227,6 +227,11 @@ var Honcho = class {
227
227
  get configured() {
228
228
  return this.cfg.enabled && this.cfg.apiKey.trim().length > 0;
229
229
  }
230
+ /** Honcho 只接受 ^[a-zA-Z0-9_-]+$ 的 peer id,中文名要退化成 morse 这类。 */
231
+ safePeer() {
232
+ const raw = (this.cfg.peerId || "").trim();
233
+ return /^[a-zA-Z0-9_-]+$/.test(raw) ? raw : "morse";
234
+ }
230
235
  base() {
231
236
  return this.cfg.baseUrl.replace(/\/+$/, "");
232
237
  }
@@ -253,13 +258,13 @@ var Honcho = class {
253
258
  }
254
259
  async ensurePeer() {
255
260
  if (this.peerReady) return;
256
- await this.call("/peers", { id: this.cfg.peerId });
261
+ await this.call("/peers", { id: this.safePeer() });
257
262
  this.peerReady = true;
258
263
  }
259
264
  async ensureSession() {
260
265
  if (this.sessionReady) return;
261
266
  await this.ensurePeer();
262
- await this.call("/sessions", { id: this.cfg.sessionId, peers: [this.cfg.peerId] });
267
+ await this.call("/sessions", { id: this.cfg.sessionId });
263
268
  this.sessionReady = true;
264
269
  }
265
270
  /** 把一条事实写进 Honcho 的会话里(后台 Deriver 会据此归纳结论)。 */
@@ -267,14 +272,14 @@ var Honcho = class {
267
272
  if (!this.configured) return;
268
273
  await this.ensureSession();
269
274
  await this.call(`/sessions/${encodeURIComponent(this.cfg.sessionId)}/messages`, {
270
- messages: [{ peer_id: this.cfg.peerId, content: sentence }]
275
+ messages: [{ peer_id: this.safePeer(), content: sentence }]
271
276
  });
272
277
  }
273
278
  /** 在 Honcho 里搜相关记忆(原始消息 + 归纳结论)。 */
274
279
  async search(query, limit = 8) {
275
280
  if (!this.configured) return [];
276
281
  await this.ensurePeer();
277
- const raw = await this.call(`/peers/${encodeURIComponent(this.cfg.peerId)}/search`, {
282
+ const raw = await this.call(`/peers/${encodeURIComponent(this.safePeer())}/search`, {
278
283
  query,
279
284
  limit
280
285
  });
@@ -297,7 +302,7 @@ var Honcho = class {
297
302
  async ask(question) {
298
303
  if (!this.configured) return "";
299
304
  await this.ensurePeer();
300
- const raw = await this.call(`/peers/${encodeURIComponent(this.cfg.peerId)}/chat`, {
305
+ const raw = await this.call(`/peers/${encodeURIComponent(this.safePeer())}/chat`, {
301
306
  query: question
302
307
  });
303
308
  const answer = [raw.content, raw.answer, raw.text, raw.reply].find(
@@ -816,6 +821,20 @@ var Hands = class {
816
821
  const ms = milliseconds(opts.ms, 900);
817
822
  return this.perform({ kind: "drag", x1: a, y1: b, x2: c, y2: d, ms });
818
823
  }
824
+ /** 口令通过后解锁(并可打开)懿心的受保护页面。 */
825
+ async unlockPages(page, minutes = 5) {
826
+ const cfg = this.cfg();
827
+ const credential = this.readToken();
828
+ const t = credential ? `&t=${encodeURIComponent(credential)}` : "";
829
+ const path = `/hand/unlock?page=${encodeURIComponent(page)}&minutes=${minutes}${t}`;
830
+ const res = await get(this.port(cfg.handPort), path, ACTION_TIMEOUT_MS);
831
+ let body = {};
832
+ try {
833
+ body = JSON.parse(res.body.toString("utf8"));
834
+ } catch {
835
+ }
836
+ return { ok: res.status === 200 && body.ok !== false, detail: flat(body.detail || body.error || "", 60) };
837
+ }
819
838
  /** 长期记忆:存/改一条事实。 */
820
839
  async memorySave(key, value, tags) {
821
840
  const cfg = this.cfg();
@@ -1156,6 +1175,19 @@ var HANDS_TOOL_DECLS = [
1156
1175
  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",
1157
1176
  parameters: { type: "object", properties: {}, required: [] }
1158
1177
  },
1178
+ {
1179
+ name: "unlock_pages",
1180
+ tags: ["act"],
1181
+ description: "\u6253\u5F00\u61FF\u5FC3\u91CC\u88AB\u9501\u4F4F\u7684\u9875\u9762\uFF08\u7559\u8A00\u677F / \u8BB0\u5FC6\u5E93 / \u4EBA\u683C / \u603B\u63A7\u5236\u53F0\uFF09\u3002\u53EA\u6709\u5728\u4E3B\u4EBA\u8BF4\u51FA\u7EA6\u5B9A\u53E3\u4EE4\u3001\u5E76\u4E14\u660E\u786E\u8981\u4F60\u6253\u5F00\u65F6\u624D\u80FD\u8C03\u7528\u3002",
1182
+ parameters: {
1183
+ type: "object",
1184
+ properties: {
1185
+ page: { type: "string", enum: ["notes", "memory", "persona", "console"], description: "\u8981\u6253\u5F00\u7684\u9875\u9762\u3002" },
1186
+ minutes: { type: "integer", description: "\u89E3\u9501\u4FDD\u6301\u591A\u5C11\u5206\u949F\uFF0C\u9ED8\u8BA4 5\u3002" }
1187
+ },
1188
+ required: ["page"]
1189
+ }
1190
+ },
1159
1191
  {
1160
1192
  name: "memory_save",
1161
1193
  tags: ["act"],
@@ -1320,6 +1352,8 @@ var HandsWorld = class {
1320
1352
  return await this.key(args);
1321
1353
  case "hand_status":
1322
1354
  return await this.statusText();
1355
+ case "unlock_pages":
1356
+ return await this.unlockPages(args);
1323
1357
  case "memory_save":
1324
1358
  return await this.memorySave(args);
1325
1359
  case "memory_search":
@@ -1375,6 +1409,13 @@ var HandsWorld = class {
1375
1409
  }
1376
1410
  return this.honchoClient;
1377
1411
  }
1412
+ async unlockPages(args) {
1413
+ const page = typeof args.page === "string" ? args.page.trim().toLowerCase() : "";
1414
+ if (!["notes", "memory", "persona", "console"].includes(page)) return failed("page \u53EA\u80FD\u662F notes / memory / persona / console\u3002");
1415
+ const minutes = typeof args.minutes === "number" ? Math.round(args.minutes) : 5;
1416
+ const r = await this.hands.unlockPages(page, Math.max(1, Math.min(60, minutes)));
1417
+ return r.ok ? `\u6253\u5F00\u4E86\uFF08${page}\uFF09\uFF0C\u4FDD\u6301 ${minutes} \u5206\u949F\u3002` : failed(`\u6CA1\u6253\u5F00\uFF1A${r.detail || "\u624B\u6CA1\u54CD\u5E94"}`);
1418
+ }
1378
1419
  async memorySave(args) {
1379
1420
  const key = typeof args.key === "string" ? args.key.trim() : "";
1380
1421
  const value = typeof args.value === "string" ? args.value.trim() : "";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cortico-world-hands",
3
- "version": "0.1.8",
3
+ "version": "0.2.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",