@downcity/plugins 1.0.145 → 1.0.148

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 (108) hide show
  1. package/bin/asr/Plugin.js +8 -8
  2. package/bin/asr/Plugin.js.map +1 -1
  3. package/bin/auth/types/AuthPlugin.js +3 -3
  4. package/bin/auth/types/AuthPlugin.js.map +1 -1
  5. package/bin/chat/PROMPT.direct.d.ts +1 -1
  6. package/bin/chat/PROMPT.direct.d.ts.map +1 -1
  7. package/bin/chat/PROMPT.direct.js +1 -1
  8. package/bin/chat/PROMPT.direct.js.map +1 -1
  9. package/bin/chat/channels/feishu/PROMPT.direct.d.ts +1 -1
  10. package/bin/chat/channels/feishu/PROMPT.direct.d.ts.map +1 -1
  11. package/bin/chat/channels/feishu/PROMPT.direct.js +1 -1
  12. package/bin/chat/channels/feishu/PROMPT.direct.js.map +1 -1
  13. package/bin/chat/channels/qq/PROMPT.direct.d.ts +1 -1
  14. package/bin/chat/channels/qq/PROMPT.direct.d.ts.map +1 -1
  15. package/bin/chat/channels/qq/PROMPT.direct.js +1 -1
  16. package/bin/chat/channels/qq/PROMPT.direct.js.map +1 -1
  17. package/bin/chat/runtime/ChatAuthorizationRuntime.js +5 -5
  18. package/bin/chat/runtime/ChatAuthorizationRuntime.js.map +1 -1
  19. package/bin/chat/runtime/ChatPluginActionRegistry.js +61 -61
  20. package/bin/chat/runtime/ChatPluginActionRegistry.js.map +1 -1
  21. package/bin/chat/runtime/ChatSessionContextComposer.d.ts +2 -2
  22. package/bin/chat/runtime/ChatSessionContextComposer.d.ts.map +1 -1
  23. package/bin/chat/runtime/ChatSessionTypes.d.ts +1 -1
  24. package/bin/chat/runtime/ChatSessionTypes.d.ts.map +1 -1
  25. package/bin/contact/Action.js +48 -48
  26. package/bin/contact/Action.js.map +1 -1
  27. package/bin/contact/PROMPT.d.ts +1 -1
  28. package/bin/contact/PROMPT.d.ts.map +1 -1
  29. package/bin/contact/PROMPT.js +1 -1
  30. package/bin/contact/PROMPT.js.map +1 -1
  31. package/bin/contact/runtime/ChatRuntime.js.map +1 -1
  32. package/bin/image/ImagePlugin.js +21 -21
  33. package/bin/image/ImagePlugin.js.map +1 -1
  34. package/bin/memory/Action.js +2 -2
  35. package/bin/memory/Action.js.map +1 -1
  36. package/bin/memory/MemoryPlugin.js +50 -50
  37. package/bin/memory/MemoryPlugin.js.map +1 -1
  38. package/bin/skill/PROMPT.d.ts +1 -1
  39. package/bin/skill/PROMPT.d.ts.map +1 -1
  40. package/bin/skill/PROMPT.js +1 -1
  41. package/bin/skill/PROMPT.js.map +1 -1
  42. package/bin/skill/Plugin.js +23 -23
  43. package/bin/skill/Plugin.js.map +1 -1
  44. package/bin/task/Action.js +1 -1
  45. package/bin/task/Action.js.map +1 -1
  46. package/bin/task/PROMPT.d.ts +1 -1
  47. package/bin/task/PROMPT.d.ts.map +1 -1
  48. package/bin/task/PROMPT.js +1 -1
  49. package/bin/task/PROMPT.js.map +1 -1
  50. package/bin/task/runtime/Runner.js +2 -2
  51. package/bin/task/runtime/Runner.js.map +1 -1
  52. package/bin/task/runtime/TaskPluginActionRegistry.js +73 -73
  53. package/bin/task/runtime/TaskPluginActionRegistry.js.map +1 -1
  54. package/bin/task/runtime/TaskRunnerProgress.js +1 -1
  55. package/bin/task/runtime/TaskRunnerProgress.js.map +1 -1
  56. package/bin/task/runtime/TaskRunnerScript.js +3 -3
  57. package/bin/task/runtime/TaskRunnerScript.js.map +1 -1
  58. package/bin/task/runtime/TaskRunnerSession.js +3 -3
  59. package/bin/task/runtime/TaskRunnerSession.js.map +1 -1
  60. package/bin/tts/Plugin.js +7 -7
  61. package/bin/tts/Plugin.js.map +1 -1
  62. package/bin/web/PROMPT.d.ts +1 -1
  63. package/bin/web/PROMPT.d.ts.map +1 -1
  64. package/bin/web/PROMPT.js +1 -1
  65. package/bin/web/PROMPT.js.map +1 -1
  66. package/bin/web/Plugin.js +8 -8
  67. package/bin/web/Plugin.js.map +1 -1
  68. package/bin/workboard/Plugin.js +2 -2
  69. package/bin/workboard/Plugin.js.map +1 -1
  70. package/bin/workboard/runtime/Normalizer.js +1 -1
  71. package/bin/workboard/runtime/Normalizer.js.map +1 -1
  72. package/package.json +3 -3
  73. package/src/asr/Plugin.ts +8 -8
  74. package/src/auth/types/AuthPlugin.ts +3 -3
  75. package/src/chat/PROMPT.direct.ts +1 -1
  76. package/src/chat/PROMPT.direct.ts.txt +32 -32
  77. package/src/chat/channels/feishu/PROMPT.direct.ts +1 -1
  78. package/src/chat/channels/feishu/PROMPT.direct.ts.txt +2 -2
  79. package/src/chat/channels/qq/PROMPT.direct.ts +1 -1
  80. package/src/chat/channels/qq/PROMPT.direct.ts.txt +11 -9
  81. package/src/chat/runtime/ChatAuthorizationRuntime.ts +5 -5
  82. package/src/chat/runtime/ChatPluginActionRegistry.ts +61 -61
  83. package/src/chat/runtime/ChatSessionContextComposer.ts +2 -2
  84. package/src/chat/runtime/ChatSessionTypes.ts +1 -1
  85. package/src/contact/Action.ts +48 -48
  86. package/src/contact/PROMPT.ts +1 -1
  87. package/src/contact/PROMPT.ts.txt +22 -22
  88. package/src/contact/runtime/ChatRuntime.ts +2 -2
  89. package/src/image/ImagePlugin.ts +21 -21
  90. package/src/memory/Action.ts +2 -2
  91. package/src/memory/MemoryPlugin.ts +50 -50
  92. package/src/skill/PROMPT.ts +1 -1
  93. package/src/skill/PROMPT.ts.txt +5 -6
  94. package/src/skill/Plugin.ts +23 -23
  95. package/src/task/Action.ts +1 -1
  96. package/src/task/PROMPT.ts +1 -1
  97. package/src/task/PROMPT.ts.txt +159 -159
  98. package/src/task/runtime/Runner.ts +2 -2
  99. package/src/task/runtime/TaskPluginActionRegistry.ts +73 -73
  100. package/src/task/runtime/TaskRunnerProgress.ts +1 -1
  101. package/src/task/runtime/TaskRunnerScript.ts +3 -3
  102. package/src/task/runtime/TaskRunnerSession.ts +3 -3
  103. package/src/tts/Plugin.ts +7 -7
  104. package/src/web/PROMPT.ts +1 -1
  105. package/src/web/PROMPT.ts.txt +31 -31
  106. package/src/web/Plugin.ts +8 -8
  107. package/src/workboard/Plugin.ts +2 -2
  108. package/src/workboard/runtime/Normalizer.ts +1 -1
@@ -97,21 +97,21 @@ export type ContactActionHandlers = {
97
97
  export function createContactActions(handlers: ContactActionHandlers): PluginActions {
98
98
  return {
99
99
  link: createAction({
100
- description: "生成一次性 contact link code,供其他 agent approve",
100
+ description: "Create a one-time contact link code for another agent to approve.",
101
101
  input_schema: {
102
102
  zod: z.object({ ttlSeconds: z.number().optional() }),
103
103
  json_schema: {
104
104
  type: "object",
105
105
  properties: {
106
- ttlSeconds: { type: "number", description: "link 过期秒数,默认 600" },
106
+ ttlSeconds: { type: "number", description: "Link expiration in seconds, defaulting to 600." },
107
107
  },
108
108
  },
109
109
  },
110
- examples: [{ title: "生成默认 link", payload: {} }],
110
+ examples: [{ title: "Create default link", payload: {} }],
111
111
  command: {
112
- description: "生成一次性 contact link code,交给另一个 agent approve",
112
+ description: "Create a one-time contact link code for another agent to approve.",
113
113
  configure(command) {
114
- command.option("--ttl-seconds <seconds>", "link 过期秒数,默认 600", Number);
114
+ command.option("--ttl-seconds <seconds>", "Link expiration in seconds, defaulting to 600.", Number);
115
115
  },
116
116
  mapInput({ opts }) {
117
117
  const payload: JsonObject = {};
@@ -128,7 +128,7 @@ export function createContactActions(handlers: ContactActionHandlers): PluginAct
128
128
  }),
129
129
  }),
130
130
  approve: createAction({
131
- description: "使用 contact link code 建立点对点联系。",
131
+ description: "Use a contact link code to establish a peer-to-peer contact.",
132
132
  input_schema: {
133
133
  zod: z.object({
134
134
  code: z.string(),
@@ -139,7 +139,7 @@ export function createContactActions(handlers: ContactActionHandlers): PluginAct
139
139
  required: ["code"],
140
140
  properties: {
141
141
  code: { type: "string", description: "link code" },
142
- name: { type: "string", description: "本地 contact 别名" },
142
+ name: { type: "string", description: "Local contact alias." },
143
143
  },
144
144
  },
145
145
  },
@@ -147,11 +147,11 @@ export function createContactActions(handlers: ContactActionHandlers): PluginAct
147
147
  { title: "approve link", payload: { code: "abc123", name: "alice" } },
148
148
  ],
149
149
  command: {
150
- description: "使用 contact link code 建立点对点联系",
150
+ description: "Use a contact link code to establish a peer-to-peer contact.",
151
151
  configure(command) {
152
152
  command
153
153
  .argument("<code>")
154
- .option("--name <alias>", "本地 contact 别名");
154
+ .option("--name <alias>", "Local contact alias.");
155
155
  },
156
156
  mapInput({ args, opts }) {
157
157
  const code = String(args[0] || "").trim();
@@ -170,14 +170,14 @@ export function createContactActions(handlers: ContactActionHandlers): PluginAct
170
170
  }),
171
171
  }),
172
172
  list: createAction({
173
- description: "列出已建立的 contact。",
173
+ description: "List established contacts.",
174
174
  input_schema: {
175
175
  zod: z.object({}).passthrough(),
176
176
  json_schema: { type: "object", properties: {} },
177
177
  },
178
- examples: [{ title: "列出 contact", payload: {} }],
178
+ examples: [{ title: "List contacts", payload: {} }],
179
179
  command: {
180
- description: "列出已建立的 contact",
180
+ description: "List established contacts.",
181
181
  mapInput() {
182
182
  return {};
183
183
  },
@@ -190,7 +190,7 @@ export function createContactActions(handlers: ContactActionHandlers): PluginAct
190
190
  }),
191
191
  }),
192
192
  check: createAction({
193
- description: "检查 contact endpoint 当前是否在线可用。",
193
+ description: "Check whether a contact or endpoint is currently online and reachable.",
194
194
  input_schema: {
195
195
  zod: z.object({
196
196
  target: z.string().optional(),
@@ -199,21 +199,21 @@ export function createContactActions(handlers: ContactActionHandlers): PluginAct
199
199
  json_schema: {
200
200
  type: "object",
201
201
  properties: {
202
- target: { type: "string", description: "已保存的 contact " },
203
- endpoint: { type: "string", description: "直接检查的 endpoint" },
202
+ target: { type: "string", description: "Saved contact name." },
203
+ endpoint: { type: "string", description: "Endpoint to check directly." },
204
204
  },
205
205
  },
206
206
  },
207
207
  examples: [
208
- { title: "检查 contact", payload: { target: "alice" } },
209
- { title: "检查 endpoint", payload: { endpoint: "https://example.com" } },
208
+ { title: "Check contact", payload: { target: "alice" } },
209
+ { title: "Check endpoint", payload: { endpoint: "https://example.com" } },
210
210
  ],
211
211
  command: {
212
- description: "检查 contact endpoint 当前是否在线可用",
212
+ description: "Check whether a contact or endpoint is currently online and reachable.",
213
213
  configure(command) {
214
214
  command
215
215
  .argument("[target]")
216
- .option("--to <endpoint>", "直接检查未保存的 endpoint");
216
+ .option("--to <endpoint>", "Directly check an unsaved endpoint.");
217
217
  },
218
218
  mapInput({ args, opts }) {
219
219
  const payload: JsonObject = {};
@@ -232,7 +232,7 @@ export function createContactActions(handlers: ContactActionHandlers): PluginAct
232
232
  }),
233
233
  }),
234
234
  chat: createAction({
235
- description: "和某个 contact 的长期对话线聊天,或读取对话历史。",
235
+ description: "Chat with a contact in its long-lived conversation thread, or read conversation history.",
236
236
  input_schema: {
237
237
  zod: z.object({
238
238
  to: z.string(),
@@ -242,19 +242,19 @@ export function createContactActions(handlers: ContactActionHandlers): PluginAct
242
242
  type: "object",
243
243
  required: ["to"],
244
244
  properties: {
245
- to: { type: "string", description: "目标 contact" },
246
- message: { type: "string", description: "要发送的消息" },
245
+ to: { type: "string", description: "Target contact." },
246
+ message: { type: "string", description: "Message to send." },
247
247
  },
248
248
  },
249
249
  },
250
250
  examples: [
251
- { title: "发送消息", payload: { to: "alice", message: "hello" } },
252
- { title: "读取历史", payload: { to: "alice" } },
251
+ { title: "Send message", payload: { to: "alice", message: "hello" } },
252
+ { title: "Read history", payload: { to: "alice" } },
253
253
  ],
254
254
  command: {
255
- description: "和某个 contact 的长期对话线聊天",
255
+ description: "Chat with a contact in its long-lived conversation thread.",
256
256
  configure(command) {
257
- command.requiredOption("--to <contact>", "目标 contact").argument("[message...]");
257
+ command.requiredOption("--to <contact>", "Target contact.").argument("[message...]");
258
258
  },
259
259
  mapInput({ args, opts }) {
260
260
  const payload: JsonObject = {
@@ -274,7 +274,7 @@ export function createContactActions(handlers: ContactActionHandlers): PluginAct
274
274
  }),
275
275
  }),
276
276
  share: createAction({
277
- description: " contact 分享文本、链接、文件或目录。",
277
+ description: "Share text, links, files, or directories with a contact.",
278
278
  input_schema: {
279
279
  zod: z.object({
280
280
  to: z.string(),
@@ -286,26 +286,26 @@ export function createContactActions(handlers: ContactActionHandlers): PluginAct
286
286
  type: "object",
287
287
  required: ["to"],
288
288
  properties: {
289
- to: { type: "string", description: "目标 contact" },
290
- text: { type: "string", description: "分享文本" },
291
- links: { type: "array", items: { type: "string" }, description: "分享链接" },
292
- paths: { type: "array", items: { type: "string" }, description: "分享文件/目录路径" },
289
+ to: { type: "string", description: "Target contact." },
290
+ text: { type: "string", description: "Text to share." },
291
+ links: { type: "array", items: { type: "string" }, description: "Links to share." },
292
+ paths: { type: "array", items: { type: "string" }, description: "File or directory paths to share." },
293
293
  },
294
294
  },
295
295
  },
296
296
  examples: [
297
297
  {
298
- title: "分享一段文本",
298
+ title: "Share text",
299
299
  payload: { to: "alice", text: "看看这个" },
300
300
  },
301
301
  ],
302
302
  command: {
303
- description: " contact 分享文本、链接、文件或目录",
303
+ description: "Share text, links, files, or directories with a contact.",
304
304
  configure(command) {
305
305
  command
306
- .requiredOption("--to <contact>", "目标 contact")
307
- .option("--text <text>", "分享文本")
308
- .option("--link <url...>", "分享链接")
306
+ .requiredOption("--to <contact>", "Target contact.")
307
+ .option("--text <text>", "Text to share.")
308
+ .option("--link <url...>", "Links to share.")
309
309
  .argument("[paths...]");
310
310
  },
311
311
  mapInput({ args, opts }) {
@@ -331,14 +331,14 @@ export function createContactActions(handlers: ContactActionHandlers): PluginAct
331
331
  }),
332
332
  }),
333
333
  inbox: createAction({
334
- description: "查看 contact inbox",
334
+ description: "View the contact inbox.",
335
335
  input_schema: {
336
336
  zod: z.object({}).passthrough(),
337
337
  json_schema: { type: "object", properties: {} },
338
338
  },
339
- examples: [{ title: "查看 inbox", payload: {} }],
339
+ examples: [{ title: "View inbox", payload: {} }],
340
340
  command: {
341
- description: "查看 contact inbox",
341
+ description: "View the contact inbox.",
342
342
  mapInput() {
343
343
  return {};
344
344
  },
@@ -351,20 +351,20 @@ export function createContactActions(handlers: ContactActionHandlers): PluginAct
351
351
  }),
352
352
  }),
353
353
  receive: createAction({
354
- description: "接收 inbox 中的 share。",
354
+ description: "Receive a share from the inbox.",
355
355
  input_schema: {
356
356
  zod: z.object({ shareId: z.string() }),
357
357
  json_schema: {
358
358
  type: "object",
359
359
  required: ["shareId"],
360
360
  properties: {
361
- shareId: { type: "string", description: "inbox 中的 shareId" },
361
+ shareId: { type: "string", description: "Share ID from the inbox." },
362
362
  },
363
363
  },
364
364
  },
365
- examples: [{ title: "接收 share", payload: { shareId: "share_1" } }],
365
+ examples: [{ title: "Receive share", payload: { shareId: "share_1" } }],
366
366
  command: {
367
- description: "接收 inbox 中的 share",
367
+ description: "Receive a share from the inbox.",
368
368
  configure(command) {
369
369
  command.argument("<shareId>");
370
370
  },
@@ -383,7 +383,7 @@ export function createContactActions(handlers: ContactActionHandlers): PluginAct
383
383
  }),
384
384
  }),
385
385
  remoteping: createAction({
386
- description: "处理远端 ping 请求(内部 endpoint)。",
386
+ description: "Handle a remote ping request (internal endpoint).",
387
387
  execute: async (params) => ({
388
388
  success: true,
389
389
  data: (await handlers.remotePing(
@@ -393,7 +393,7 @@ export function createContactActions(handlers: ContactActionHandlers): PluginAct
393
393
  }),
394
394
  }),
395
395
  remoteapprove: createAction({
396
- description: "处理远端 approve 请求(内部 endpoint)。",
396
+ description: "Handle a remote approve request (internal endpoint).",
397
397
  execute: async (params) => ({
398
398
  success: true,
399
399
  data: (await handlers.remoteApprove(
@@ -403,7 +403,7 @@ export function createContactActions(handlers: ContactActionHandlers): PluginAct
403
403
  }),
404
404
  }),
405
405
  remoteconfirm: createAction({
406
- description: "处理远端 confirm 请求(内部 endpoint)。",
406
+ description: "Handle a remote confirm request (internal endpoint).",
407
407
  execute: async (params) => ({
408
408
  success: true,
409
409
  data: (await handlers.remoteConfirm(
@@ -413,7 +413,7 @@ export function createContactActions(handlers: ContactActionHandlers): PluginAct
413
413
  }),
414
414
  }),
415
415
  remotechat: createAction({
416
- description: "处理远端 chat 请求(内部 endpoint)。",
416
+ description: "Handle a remote chat request (internal endpoint).",
417
417
  execute: async (params) => {
418
418
  const payload = readContactObject(params.input);
419
419
  const body = readContactObject(payload.body);
@@ -428,7 +428,7 @@ export function createContactActions(handlers: ContactActionHandlers): PluginAct
428
428
  },
429
429
  }),
430
430
  remoteshare: createAction({
431
- description: "处理远端 share 请求(内部 endpoint)。",
431
+ description: "Handle a remote share request (internal endpoint).",
432
432
  execute: async (params) => ({
433
433
  success: true,
434
434
  data: (await handlers.remoteShare(params.context, params.input)) as unknown as JsonValue,
@@ -4,6 +4,6 @@
4
4
  */
5
5
 
6
6
  // Source: src/contact/PROMPT.ts.txt
7
- const TEXT_MODULE_CONTENT = "Contact plugin\n\ncontact plugin 用来管理和其他 agent 的联系方式。一个 contact 代表一个已建立联系的远端 agent,并固定拥有一条长期对话历史。contact 可以是单向的:只要本 agent 能访问对方,就可以 checkchatshare。\n\n可用 action:\n- `link`:生成一次性联系码,交给另一个 agent。\n- `approve`:使用对方给的联系码建立 contact。\n- `list`:查看已保存的 agent 联系方式。\n- `check`:检查对方是否在线可用。\n- `chat`:和某个 agent 对话。\n- `share`:分享文本、链接、文件或目录。\n- `inbox`:查看收到的分享。\n- `receive`:接收某条分享。\n\n边界:\n- chat 用于对话,share 用于资料交接。\n- `link` action 返回中的 notes 会说明联系码适合本机、局域网还是公网 agent 使用;本地 localhost 联系码不能交给 server agent approve。\n- public-looking endpoint 仍可能被防火墙/NAT 阻断;以返回的 notes 为准,不要承诺公网一定可达。\n- Agent runtime 会在可用时写入 `DOWNCITY_PUBLIC_HOST` contact link 使用;这不是要求用户手动配置的 token endpoint。\n- `approve` action 会先建立单向关系,再由对方主动 ping 回本 agentping 成功才升级为 bidirectional。\n- local/private agent 连接 public agent 时通常只能 outbound-only,不要说成双向。\n- contact token link/approve 自动交换;不要要求用户手动配置 token 环境变量。\n- `Contact link not found` 表示请求打到的 agent runtime 没有这条 link 记录,优先检查 endpoint/端口/agent 是否一致;过期会明确返回 `Contact link expired`。\n- receive 只接收内容,不自动执行、不安装 skill、不修改项目业务文件。\n- 不自动 approve receive,除非用户明确要求。\n";
7
+ const TEXT_MODULE_CONTENT = "# Contact Plugin\n\nThe contact plugin manages ways to reach other agents. A contact represents an established remote-agent relationship and owns one long-lived conversation history. A contact may be one-way: as long as this agent can reach the other agent, it can `check`, `chat`, and `share`.\n\nAvailable actions:\n- `link`: create a one-time contact code for another agent.\n- `approve`: use a contact code from another agent to establish a contact.\n- `list`: view saved agent contacts.\n- `check`: check whether the other agent is online and reachable.\n- `chat`: talk with a contact.\n- `share`: share text, links, files, or directories.\n- `inbox`: view received shares.\n- `receive`: receive a share.\n\nBoundaries:\n- Use `chat` for conversation and `share` for handing over materials.\n- The notes returned by the `link` action explain whether a contact code is suitable for local-machine, LAN, or public agents. A localhost contact code must not be given to a server agent for `approve`.\n- A public-looking endpoint may still be blocked by firewall or NAT. Trust the returned notes, and do not promise that public access is guaranteed.\n- The Agent runtime writes `DOWNCITY_PUBLIC_HOST` when available for contact links. This is not a token or endpoint that the user must configure manually.\n- The `approve` action first establishes a one-way relationship. The other agent then pings back to this agent, and only a successful ping upgrades the relationship to bidirectional.\n- When a local/private agent connects to a public agent, the connection is usually outbound-only. Do not describe it as bidirectional.\n- Contact tokens are exchanged automatically by `link` and `approve`. Do not ask the user to manually configure token environment variables.\n- `Contact link not found` means the request reached an agent runtime that does not have this link record. First check whether the endpoint, port, and agent match. Expiration is reported explicitly as `Contact link expired`.\n- `receive` only receives content. It does not execute anything, install skills, or modify project business files automatically.\n- Do not automatically approve or receive unless the user explicitly asks.\n";
8
8
 
9
9
  export default TEXT_MODULE_CONTENT;
@@ -1,25 +1,25 @@
1
- Contact plugin
1
+ # Contact Plugin
2
2
 
3
- contact plugin 用来管理和其他 agent 的联系方式。一个 contact 代表一个已建立联系的远端 agent,并固定拥有一条长期对话历史。contact 可以是单向的:只要本 agent 能访问对方,就可以 checkchatshare
3
+ The contact plugin manages ways to reach other agents. A contact represents an established remote-agent relationship and owns one long-lived conversation history. A contact may be one-way: as long as this agent can reach the other agent, it can `check`, `chat`, and `share`.
4
4
 
5
- 可用 action:
6
- - `link`:生成一次性联系码,交给另一个 agent
7
- - `approve`:使用对方给的联系码建立 contact
8
- - `list`:查看已保存的 agent 联系方式。
9
- - `check`:检查对方是否在线可用。
10
- - `chat`:和某个 agent 对话。
11
- - `share`:分享文本、链接、文件或目录。
12
- - `inbox`:查看收到的分享。
13
- - `receive`:接收某条分享。
5
+ Available actions:
6
+ - `link`: create a one-time contact code for another agent.
7
+ - `approve`: use a contact code from another agent to establish a contact.
8
+ - `list`: view saved agent contacts.
9
+ - `check`: check whether the other agent is online and reachable.
10
+ - `chat`: talk with a contact.
11
+ - `share`: share text, links, files, or directories.
12
+ - `inbox`: view received shares.
13
+ - `receive`: receive a share.
14
14
 
15
- 边界:
16
- - chat 用于对话,share 用于资料交接。
17
- - `link` action 返回中的 notes 会说明联系码适合本机、局域网还是公网 agent 使用;本地 localhost 联系码不能交给 server agent approve
18
- - public-looking endpoint 仍可能被防火墙/NAT 阻断;以返回的 notes 为准,不要承诺公网一定可达。
19
- - Agent runtime 会在可用时写入 `DOWNCITY_PUBLIC_HOST` contact link 使用;这不是要求用户手动配置的 token endpoint
20
- - `approve` action 会先建立单向关系,再由对方主动 ping 回本 agentping 成功才升级为 bidirectional
21
- - local/private agent 连接 public agent 时通常只能 outbound-only,不要说成双向。
22
- - contact token link/approve 自动交换;不要要求用户手动配置 token 环境变量。
23
- - `Contact link not found` 表示请求打到的 agent runtime 没有这条 link 记录,优先检查 endpoint/端口/agent 是否一致;过期会明确返回 `Contact link expired`。
24
- - receive 只接收内容,不自动执行、不安装 skill、不修改项目业务文件。
25
- - 不自动 approve receive,除非用户明确要求。
15
+ Boundaries:
16
+ - Use `chat` for conversation and `share` for handing over materials.
17
+ - The notes returned by the `link` action explain whether a contact code is suitable for local-machine, LAN, or public agents. A localhost contact code must not be given to a server agent for `approve`.
18
+ - A public-looking endpoint may still be blocked by firewall or NAT. Trust the returned notes, and do not promise that public access is guaranteed.
19
+ - The Agent runtime writes `DOWNCITY_PUBLIC_HOST` when available for contact links. This is not a token or endpoint that the user must configure manually.
20
+ - The `approve` action first establishes a one-way relationship. The other agent then pings back to this agent, and only a successful ping upgrades the relationship to bidirectional.
21
+ - When a local/private agent connects to a public agent, the connection is usually outbound-only. Do not describe it as bidirectional.
22
+ - Contact tokens are exchanged automatically by `link` and `approve`. Do not ask the user to manually configure token environment variables.
23
+ - `Contact link not found` means the request reached an agent runtime that does not have this link record. First check whether the endpoint, port, and agent match. Expiration is reported explicitly as `Contact link expired`.
24
+ - `receive` only receives content. It does not execute anything, install skills, or modify project business files automatically.
25
+ - Do not automatically approve or receive unless the user explicitly asks.
@@ -8,13 +8,13 @@
8
8
 
9
9
  import type { AgentContext } from "@downcity/agent/internal/types/runtime/agent/AgentContext.js";
10
10
  import type { ContactChatResponse } from "@/contact/types/ContactChat.js";
11
- import type { SessionMessageV1 } from "@downcity/agent/internal/executor/types/SessionMessages.js";
11
+ import type { SessionRecordV1 } from "@downcity/agent/internal/executor/types/SessionRecords.js";
12
12
  import {
13
13
  appendContactMessage,
14
14
  findContactByInboundToken,
15
15
  } from "./ContactStore.js";
16
16
 
17
- function extractMessageText(message: SessionMessageV1 | null | undefined): string {
17
+ function extractMessageText(message: SessionRecordV1 | null | undefined): string {
18
18
  const parts = Array.isArray((message as { parts?: unknown } | null)?.parts)
19
19
  ? ((message as { parts: unknown[] }).parts)
20
20
  : [];
@@ -535,31 +535,31 @@ export class ImagePlugin extends BasePlugin {
535
535
  "",
536
536
  "## Actions",
537
537
  "",
538
- "- `models`:列出当前可用的图片模型,返回 `{ models }`。",
539
- " 当你不知道应该使用哪个模型,且插件没有默认图片模型时先调用,并让用户或当前任务上下文明确模型 ID",
540
- "- `image_create`:在用户明确确认后创建一个异步图片任务,返回 `{ job_id, status }`。",
541
- " - 纯文本生成:填 `prompt`(字符串)。",
542
- " - 编辑 / 参考图:填 `content`,格式:",
543
- " `[{ type: \"text\", text }, { type: \"image\", url }]`。可以多段文本和多张图任意顺序混排。",
544
- " - 同时给了 `content` `prompt` 时,`content` 生效,`prompt` 被忽略。",
545
- " - `url` 支持三种写法:在线 URL、绝对本地路径、相对 Agent 项目根目录的相对路径。",
546
- " 不要传 base64 / data URL,也不要再用旧的 `messages` 字段。",
547
- " - `model` 可选;未传时使用插件配置的默认图片模型。可选参数:`aspect_ratio`(如 `16:9`)、`size`(如 `1024x1024`)、`quality`、`seed`。",
548
- "- `image_result`:用 `job_id` 读取任务状态。",
549
- " - 默认读取一次。`queued` / `running` 时保存好 `job_id`,下一轮再查,不要在同一轮里反复轮询。",
550
- " - 想直接等到出图,可以传 `until_done: true`,可选 `max_wait_ms`(默认 60000,最长 600000)与 `poll_interval_ms`(默认 1500)。超时仍未完成会返回最后一次的中间状态。",
551
- " - `succeeded`:返回的图片 file part 会自动落盘并附加到下一条 assistant 消息,无需自己再拼图。",
552
- " - 回复用户时,可以在消息中使用 Markdown 图片语法 `![](url)` 渲染图片。",
553
- " - `failed`:把 `error` 信息如实回报给用户,不要编造图片结果。",
538
+ "- `models`: list currently available image models and return `{ models }`.",
539
+ " Call this first when you do not know which model to use and the plugin has no default image model. Let the user or current task context specify the model ID.",
540
+ "- `image_create`: create an async image job after explicit user confirmation, returning `{ job_id, status }`.",
541
+ " - Text-only generation: pass `prompt` as a string.",
542
+ " - Edits or reference images: pass `content` in this shape:",
543
+ " `[{ type: \"text\", text }, { type: \"image\", url }]`. Multiple text parts and images may appear in any order.",
544
+ " - If both `content` and `prompt` are provided, `content` takes effect and `prompt` is ignored.",
545
+ " - `url` supports three forms: online URL, absolute local path, or a relative path from the Agent project root.",
546
+ " Do not pass base64/data URLs, and do not use the legacy `messages` field.",
547
+ " - `model` is optional. If omitted, the plugin-configured default image model is used. Optional parameters include `aspect_ratio` such as `16:9`, `size` such as `1024x1024`, `quality`, and `seed`.",
548
+ "- `image_result`: read job status by `job_id`.",
549
+ " - By default, read once. If the status is `queued` or `running`, save the `job_id` and check again in a later turn; do not repeatedly poll in the same turn.",
550
+ " - To wait for the image directly, pass `until_done: true` with optional `max_wait_ms` (default 60000, max 600000) and `poll_interval_ms` (default 1500). If the wait times out, the latest intermediate status is returned.",
551
+ " - `succeeded`: returned image file parts are automatically written to disk and attached to the next assistant message. You do not need to assemble the image manually.",
552
+ " - When replying to the user, you can render images with Markdown image syntax: `![](url)`.",
553
+ " - `failed`: report the `error` truthfully to the user. Do not invent image results.",
554
554
  "",
555
555
  "## Flow",
556
556
  "",
557
- "1. 如果插件没有默认图片模型,先确认模型 ID;需要选模型时调用 `models`。",
558
- "2. 向用户说明将消耗图片生成额度,并等待用户明确确认。",
559
- "3. 用户确认后调用 `image_create` 拿到 `job_id`。",
560
- "4. `image_result` 查询;短任务可加 `until_done: true` 一次拿结果,长任务保存 `job_id` 下一轮再查。",
557
+ "1. If the plugin has no default image model, confirm the model ID first; call `models` when model selection is needed.",
558
+ "2. Explain to the user that image generation will consume image quota, and wait for explicit confirmation.",
559
+ "3. After the user confirms, call `image_create` to get a `job_id`.",
560
+ "4. Query with `image_result`; short jobs may use `until_done: true` to get the result in one call, while long jobs should save the `job_id` and check again in a later turn.",
561
561
  "",
562
- "如有疑问可用 `plugin_read { plugin: \"image\", action: \"...\" }` 查看每个 action 完整的输入 schema 与示例。",
562
+ "When unsure, use `plugin_read { plugin: \"image\", action: \"...\" }` to inspect each action's complete input schema and examples.",
563
563
  ].join("\n");
564
564
  }
565
565
 
@@ -268,9 +268,9 @@ export async function digestMemoryAction(
268
268
  ? Math.max(1, Math.floor(payload.maxMessages as number))
269
269
  : 30;
270
270
  const historyStore = context.session.get(sessionId).getHistoryStore();
271
- const total = await historyStore.size();
271
+ const total = await historyStore.record_count();
272
272
  const start = Math.max(0, total - maxMessages);
273
- const messages = await historyStore.slice(start, total);
273
+ const messages = await historyStore.slice_records(start, total);
274
274
  const lines = messages
275
275
  .map((msg) => extractReadableLine(msg))
276
276
  .filter((line) => line.length > 0);