koishi-plugin-image-prompt 2.0.4 → 2.1.1

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/lib/index.d.ts CHANGED
@@ -76,6 +76,30 @@ export declare function renderAgentInstructions(template: string, vars: Record<s
76
76
  * 这里压成一行、去掉 markdown 记号和包裹引号、限长,让它永远是「对用户说的一句话」。
77
77
  */
78
78
  export declare function cleanAskMessage(raw: any, max?: number): string;
79
+ /**
80
+ * 从用户的回答里判断他要不要润色提示词。
81
+ * 默认 false —— 用户的原话原封不动交给绘图模型才是对的默认值。
82
+ */
83
+ export declare function parsePolishIntent(text: string): boolean;
84
+ /** 从消息内容里解析 @ 到的人。type="all"(@全体成员)和 @机器人自己 会被跳过 */
85
+ export declare function extractAtIds(content: string, selfId?: string): {
86
+ id: string;
87
+ name: string;
88
+ }[];
89
+ /**
90
+ * 拼头像地址。优先级:自定义模板 > 适配器直接给的 > 平台内置规则。
91
+ * 拼不出来返回空字符串(调用方再决定是问适配器还是放弃)。
92
+ */
93
+ export declare function buildAvatarUrl(input: {
94
+ userId: string;
95
+ platform?: string;
96
+ selfId?: string;
97
+ appId?: string;
98
+ /** 发送者自己的头像(适配器已经在消息里带过来了) */
99
+ authorAvatar?: string;
100
+ template?: string;
101
+ size?: number;
102
+ }): string;
79
103
  /**
80
104
  * 图库容量裁剪:超出容量时淘汰最旧的(按 time 升序),只保留每个组最近 capacity 条
81
105
  */
@@ -206,6 +230,7 @@ interface CommandConfig {
206
230
  referenceGroups?: ReferenceGroup[];
207
231
  aiSelector?: AISelectorConfig;
208
232
  agent?: AgentConfig;
233
+ avatar?: AvatarConfig;
209
234
  showPrompt?: boolean;
210
235
  promptMaxLength?: number;
211
236
  appendUserInput?: boolean;
@@ -317,6 +342,23 @@ interface AgentConfig {
317
342
  historyTurns: number;
318
343
  /** 把每一轮的工具调用打到日志里,方便排查 */
319
344
  debugLog: boolean;
345
+ /** 用户没给任何参考图时,开画前先问一句「要不要参考图」 */
346
+ askIfNoReference: boolean;
347
+ /** 开画前先问一句「要不要润色提示词」(默认不润色,原话直出) */
348
+ askBeforePolish: boolean;
349
+ }
350
+ /** 头像参考图配置 */
351
+ interface AvatarConfig {
352
+ /** 总开关:能不能拿用户头像当参考图 */
353
+ enabled: boolean;
354
+ /** 用户 @ 了谁,就自动把那个人的头像作为参考图(@ 本身就是明确指定) */
355
+ autoAt: boolean;
356
+ /** 用户没发图也没 @ 人时,自动拿他自己的头像当参考图 */
357
+ autoSelf: boolean;
358
+ /** 头像尺寸(边长像素) */
359
+ size: number;
360
+ /** 自定义头像地址模板,留空用内置规则。占位符:{userId} {platform} {selfId} {appId} {size} */
361
+ urlTemplate: string;
320
362
  }
321
363
  /** agent 参考图登记表里的一条 */
322
364
  export interface RefEntry {
@@ -324,7 +366,7 @@ export interface RefEntry {
324
366
  url: string;
325
367
  description: string;
326
368
  group: string;
327
- source: 'gallery' | 'user' | 'cmd';
369
+ source: 'gallery' | 'user' | 'cmd' | 'avatar';
328
370
  }
329
371
  /** 交给 AI 挑选的候选图片 */
330
372
  interface CandidateImage {
package/lib/index.js CHANGED
@@ -33,12 +33,14 @@ __export(src_exports, {
33
33
  Config: () => Config,
34
34
  apply: () => apply,
35
35
  buildAgentTools: () => buildAgentTools,
36
+ buildAvatarUrl: () => buildAvatarUrl,
36
37
  buildMarkdownImage: () => buildMarkdownImage,
37
38
  buildPromptBlock: () => buildPromptBlock,
38
39
  buildPromptEcho: () => buildPromptEcho,
39
40
  cleanAskMessage: () => cleanAskMessage,
40
41
  computeRetryDelay: () => computeRetryDelay,
41
42
  describeSelectorError: () => describeSelectorError,
43
+ extractAtIds: () => extractAtIds,
42
44
  extractJsonObject: () => extractJsonObject,
43
45
  extractResponseText: () => extractResponseText,
44
46
  extractServerMessage: () => extractServerMessage,
@@ -50,6 +52,7 @@ __export(src_exports, {
50
52
  mergePrompt: () => mergePrompt,
51
53
  name: () => name,
52
54
  parseJsonToolCall: () => parseJsonToolCall,
55
+ parsePolishIntent: () => parsePolishIntent,
53
56
  parseRetryAfterHeader: () => parseRetryAfterHeader,
54
57
  pickAgentMessage: () => pickAgentMessage,
55
58
  previewJson: () => previewJson,
@@ -226,7 +229,7 @@ function resolveReferences(refs, registry) {
226
229
  }
227
230
  return { ids, unknown };
228
231
  }
229
- var AGENT_TOOL_NAMES = ["gallery_search", "ask_user", "draw"];
232
+ var AGENT_TOOL_NAMES = ["gallery_search", "ask_user", "get_avatar", "draw"];
230
233
  function buildAgentTools() {
231
234
  return [
232
235
  {
@@ -258,6 +261,20 @@ function buildAgentTools() {
258
261
  }
259
262
  }
260
263
  },
264
+ {
265
+ type: "function",
266
+ function: {
267
+ name: "get_avatar",
268
+ description: "\u53D6\u5934\u50CF\u5F53\u53C2\u8003\u56FE\uFF0C\u8FD4\u56DE\u5B83\u7684\u7F16\u53F7\u3002**\u53EA\u80FD\u53D6\u4E24\u79CD\u4EBA\u7684\u5934\u50CF**\uFF1A\u53D1\u6307\u4EE4\u7684\u4EBA\u81EA\u5DF1\uFF08userId \u7559\u7A7A/\u5199 me\uFF09\uFF0C\u6216\u4ED6\u8FD9\u6B21\u6D88\u606F\u91CC\u660E\u786E @ \u5230\u7684\u4EBA\uFF08\u586B\u4E0A\u4E0B\u6587\u300C\u53EF\u53D6\u5934\u50CF\u7684\u4EBA\u300D\u91CC\u5217\u51FA\u7684 id/\u540D\u5B57\uFF09\u3002\u5176\u5B83 id \u4E00\u5F8B\u4F1A\u88AB\u62D2\u7EDD\u3002",
269
+ parameters: {
270
+ type: "object",
271
+ properties: {
272
+ userId: { type: "string", description: "\u7559\u7A7A\u6216\u5199 me/self/\u6211 = \u53D1\u6307\u4EE4\u7684\u4EBA\u81EA\u5DF1\uFF1B\u4E5F\u53EF\u4EE5\u586B\u4E0A\u4E0B\u6587\u91CC\u300C\u53EF\u53D6\u5934\u50CF\u7684\u4EBA\u300D\u5217\u51FA\u7684 id \u6216\u6635\u79F0\uFF08\u5373\u88AB @ \u7684\u4EBA\uFF09\u3002**\u4E0D\u8981\u81EA\u5DF1\u731C id**" }
273
+ },
274
+ required: []
275
+ }
276
+ }
277
+ },
261
278
  {
262
279
  type: "function",
263
280
  function: {
@@ -266,8 +283,8 @@ function buildAgentTools() {
266
283
  parameters: {
267
284
  type: "object",
268
285
  properties: {
269
- // 提示词要短:宁可朴素,也不要堆术语写成几百字的「专业」prompt
270
- prompt: { type: "string", description: "\u7ED8\u56FE\u63D0\u793A\u8BCD\u3002\u8BF4\u4EBA\u8BDD\u3001\u5199\u7B80\u77ED\u5C31\u884C\uFF0C\u4E2D\u6587\u5373\u53EF\uFF08\u7ED8\u56FE\u6A21\u578B\u542C\u5F97\u61C2\u4E2D\u6587\uFF09\uFF1B\u4E0D\u8981\u628A\u7528\u6237\u7684\u8BDD\u6269\u5199\u6210\u51E0\u767E\u5B57\uFF0C\u4E5F\u4E0D\u8981\u5806\u780C\u98CE\u683C/\u6750\u8D28/\u5149\u7EBF\u672F\u8BED\u3002\u753B\u9762\u4E0A\u5FC5\u987B\u51FA\u73B0\u7684\u6587\u5B57\u8981\u539F\u6837\u5199\u8FDB\u53BB" },
286
+ // 提示词要短;用户没说要润色就原封不动用他的原话
287
+ prompt: { type: "string", description: "\u7ED8\u56FE\u63D0\u793A\u8BCD\u3002**\u9ED8\u8BA4\u539F\u5C01\u4E0D\u52A8\u7528\u7528\u6237\u7684\u8BDD**\uFF1A\u7B80\u77ED\u3001\u8BF4\u4EBA\u8BDD\uFF0C\u4E0D\u8981\u6269\u5199\u6210\u51E0\u767E\u5B57\uFF0C\u4E0D\u8981\u8865\u753B\u98CE/\u5149\u7EBF/\u6750\u8D28\u672F\u8BED\uFF0C\u4E0D\u8981\u7FFB\u6210\u82F1\u6587\uFF1B\u53EA\u6709\u7528\u6237\u8BF4\u8FC7\u300C\u5E2E\u6211\u6DA6\u8272 / \u4F18\u5316\u4E00\u4E0B\u300D\u624D\u52A0\u5DE5\u3002\u4E2D\u6587\u5373\u53EF\uFF08\u7ED8\u56FE\u6A21\u578B\u542C\u5F97\u61C2\u4E2D\u6587\uFF09\u3002\u753B\u9762\u4E0A\u5FC5\u987B\u51FA\u73B0\u7684\u6587\u5B57\u8981\u539F\u6837\u5199\u8FDB\u53BB" },
271
288
  references: {
272
289
  type: "array",
273
290
  items: { type: "string" },
@@ -346,6 +363,53 @@ function cleanAskMessage(raw, max = 200) {
346
363
  if (text.length > max) text = text.slice(0, max) + "\u2026";
347
364
  return text;
348
365
  }
366
+ function parsePolishIntent(text) {
367
+ const t = String(text || "");
368
+ if (!t) return false;
369
+ if (/不(用|要|必)?(润色|优化|加工|改)|别(润色|优化|加工)|原样|原封不动|直接画|不用了/.test(t)) return false;
370
+ return /润色|优化一下|加工|丰富|扩写|细化|详细[一点些]|写(得)?(更)?(完整|详细)|帮我(写|改)/.test(t);
371
+ }
372
+ function extractAtIds(content, selfId) {
373
+ if (!content) return [];
374
+ const out = [];
375
+ const seen = /* @__PURE__ */ new Set();
376
+ for (const el of import_koishi.h.select(content, "at")) {
377
+ const id = String(el.attrs.id ?? el.attrs.user ?? "").trim();
378
+ if (!id || id === selfId) continue;
379
+ if (String(el.attrs.type || "") === "all") continue;
380
+ if (seen.has(id)) continue;
381
+ seen.add(id);
382
+ out.push({ id, name: String(el.attrs.name || el.attrs.nick || "").trim() });
383
+ }
384
+ return out;
385
+ }
386
+ function buildAvatarUrl(input) {
387
+ const userId = String(input?.userId || "").trim();
388
+ if (!userId) return "";
389
+ const size = Number(input.size) > 0 ? Number(input.size) : 640;
390
+ const platform = String(input.platform || "");
391
+ const appId = String(input.appId || "");
392
+ if (input.template) {
393
+ return String(input.template).replace(/\{(\w+)\}/g, (_m, key) => {
394
+ const vars = {
395
+ userId,
396
+ platform,
397
+ size: String(size),
398
+ selfId: String(input.selfId || ""),
399
+ appId
400
+ };
401
+ return vars[key] ?? "";
402
+ });
403
+ }
404
+ if (input.authorAvatar) return String(input.authorAvatar);
405
+ if (appId && (platform === "qq" || platform === "qqguild")) {
406
+ return `https://q.qlogo.cn/qqapp/${appId}/${userId}/${size}`;
407
+ }
408
+ if (/^(qq|onebot|red|qqguild)$/.test(platform) && /^\d{5,12}$/.test(userId)) {
409
+ return `https://q1.qlogo.cn/g?b=qq&nk=${userId}&s=${size}`;
410
+ }
411
+ return "";
412
+ }
349
413
  function trimGallery(records, capacity) {
350
414
  const limit = capacity > 0 ? capacity : 50;
351
415
  const byGroup = /* @__PURE__ */ new Map();
@@ -721,6 +785,9 @@ var DEFAULT_AGENT_INSTRUCTIONS = `\u4F60\u662F QQ \u7FA4\u91CC\u7684\u7ED8\u56FE
721
785
  - gallery_search\uFF1A\u6309\u5173\u952E\u8BCD\u641C\u7D22\u53C2\u8003\u56FE\u5E93\u3002**\u6D89\u53CA\u5177\u4F53\u89D2\u8272/\u7ACB\u7ED8\u65F6\u5FC5\u987B\u5148\u641C\u4E00\u6B21**\u3002
722
786
  \u591A\u4E2A\u5173\u952E\u8BCD\u7528\u7A7A\u683C\u5206\u9694\uFF08\u5982\u300C\u767D\u53D1 \u7ACB\u7ED8\u300D\uFF09\uFF0C\u5168\u90E8\u547D\u4E2D\u7684\u6392\u5728\u6700\u524D\uFF1B\u641C\u4E0D\u5230\u5C31\u6362\u4E2A\u8BCD\u518D\u641C\u3002
723
787
  - ask_user\uFF1A\u628A\u95EE\u9898\u53D1\u7ED9\u7528\u6237**\u5E76\u7B49\u4ED6\u56DE\u590D**\uFF08\u4ED6\u53D1\u7684\u56FE\u4E5F\u4F1A\u4E00\u8D77\u5E26\u56DE\u6765\uFF09\u3002
788
+ - get_avatar\uFF1A\u53D6\u5934\u50CF\u5F53\u53C2\u8003\u56FE\u3002**\u53EA\u80FD\u53D6\u4E24\u79CD\u4EBA**\uFF1A\u53D1\u6307\u4EE4\u7684\u4EBA\u81EA\u5DF1\uFF08userId \u7559\u7A7A\u6216\u5199 me\uFF09\uFF0C
789
+ \u4EE5\u53CA\u4ED6\u8FD9\u6B21\u6D88\u606F\u91CC\u660E\u786E @ \u5230\u7684\u4EBA\uFF08\u586B\u4E0A\u4E0B\u6587\u300C\u53EF\u53D6\u5934\u50CF\u7684\u4EBA\u300D\u91CC\u5217\u51FA\u7684 id \u6216\u6635\u79F0\uFF09\u3002
790
+ \u5176\u5B83\u4EFB\u4F55 id \u90FD\u4F1A\u88AB\u62D2\u7EDD\uFF0C\u4E0D\u8981\u731C\u3002
724
791
  - draw\uFF1A\u771F\u6B63\u5F00\u59CB\u753B\u3002\u628A prompt \u548C\u6311\u4E2D\u7684\u53C2\u8003\u56FE\u7F16\u53F7\u4EA4\u8FDB\u53BB\uFF0C\u753B\u597D\u4F1A\u81EA\u52A8\u53D1\u5230\u7FA4\u91CC\u3002
725
792
 
726
793
  \u5DE5\u4F5C\u89C4\u5219\uFF1A
@@ -735,25 +802,43 @@ var DEFAULT_AGENT_INSTRUCTIONS = `\u4F60\u662F QQ \u7FA4\u91CC\u7684\u7ED8\u56FE
735
802
  4. \u753B\u9762\u4E0A\u8981\u51FA\u73B0\u6587\u5B57\uFF08\u53F0\u8BCD\u3001\u6807\u9898\u3001\u62DB\u724C\u3001\u5B57\u5E55\uFF09\u65F6\uFF0C\u628A\u6587\u5B57\u539F\u6837\u5199\u8FDB prompt\uFF0C\u5E76\u8BF4\u660E\u300C\u8FD9\u4E9B\u5B57\u5FC5\u987B\u539F\u6837\u51FA\u73B0\uFF0C\u4E0D\u80FD\u53D8\u5F62\u6216\u81EA\u521B\u5B57\u5F62\u300D\u3002
736
803
  5. draw \u8FD4\u56DE ok=false \u65F6\uFF0C\u770B error \u51B3\u5B9A\uFF1A\u80FD\u6539\u7684\uFF08\u63D0\u793A\u8BCD\u95EE\u9898\uFF09\u5C31\u6362\u4E2A\u5199\u6CD5\u91CD\u8BD5\uFF0C\u6539\u4E0D\u4E86\u7684\uFF08\u9650\u6D41/\u914D\u989D\uFF09\u5C31\u5982\u5B9E\u544A\u8BC9\u7528\u6237\u3002
737
804
  6. \u6D41\u7A0B\u7ED3\u675F\u540E\u7528\u4E2D\u6587\u56DE\u4E00\u53E5\u7B80\u77ED\u7684\u7ED3\u679C\u8BF4\u660E\uFF08\u4E0D\u8981\u590D\u8FF0 prompt\uFF0C\u4E0D\u8981\u5199\u5C0F\u4F5C\u6587\uFF0C\u4E0D\u8981\u518D\u95EE\u300C\u8FD8\u8981\u6211\u505A\u4EC0\u4E48\u300D\uFF09\u3002
738
- 7. \u56FE\u7247\u7F16\u53F7\uFF1Agallery_search \u7ED3\u679C\u91CC\u7684 id\u3001\u7528\u6237\u53D1\u7684\u56FE\uFF08user1\u3001user2\u2026\uFF09\u3001\u6307\u4EE4\u9ED8\u8BA4\u56FE\uFF08cmd1\u2026\uFF09\u90FD\u53EF\u4EE5\u76F4\u63A5\u5199\u8FDB draw \u7684 references\u3002
739
- \u53EA\u586B\u4F60\u786E\u8BA4\u5B58\u5728\u7684\u7F16\u53F7\uFF0C**\u7EDD\u5BF9\u4E0D\u8981\u7F16\u9020 id**\u3002
740
- 8. \u3010prompt \u8981\u77ED\uFF0C\u8981\u8BF4\u4EBA\u8BDD\u3011**\u4E0D\u8981**\u628A\u7528\u6237\u7684\u8BDD\u6269\u5199\u6210\u51E0\u767E\u5B57\u7684\u300C\u4E13\u4E1A\u300D\u63D0\u793A\u8BCD\uFF1A
805
+ 7. \u56FE\u7247\u7F16\u53F7\uFF1Agallery_search \u7ED3\u679C\u91CC\u7684 id\u3001\u7528\u6237\u968F\u6D88\u606F\u53D1\u7684\u56FE\u3001\u5934\u50CF\u3001\u6307\u4EE4\u9ED8\u8BA4\u56FE\u90FD\u53EF\u4EE5\u76F4\u63A5\u5199\u8FDB draw \u7684 references\u3002
806
+ \u53EA\u586B\u4E0A\u4E0B\u6587\u91CC**\u660E\u786E\u5217\u51FA\u8FC7**\u7684\u7F16\u53F7\uFF0C**\u7EDD\u5BF9\u4E0D\u8981\u7F16\u9020 id**\u3002
807
+ - \u7528\u6237\u968F\u6D88\u606F\u53D1\u7684\u56FE\u4F1A\u81EA\u52A8\u5E26\u4E0A\uFF0C\u4E0D\u7528\u4F60\u518D\u586B\uFF1B
808
+ - \u4ED6 @ \u4E86\u8C01\uFF0C\u90A3\u4E2A\u4EBA\u7684\u5934\u50CF\u4E5F\u4F1A\u81EA\u52A8\u5E26\u4E0A\u3002
809
+ 8. \u3010\u6CA1\u6307\u5B9A\u53C2\u8003\u56FE\u65F6\u5148\u95EE\u4E00\u53E5\u3011\u7528\u6237\u8FD9\u6B21\u6CA1\u53D1\u56FE\u3001\u6CA1 @ \u4EBA\u3001\u6307\u4EE4\u672C\u8EAB\u4E5F\u6CA1\u6709\u9ED8\u8BA4\u53C2\u8003\u56FE\uFF0C\u4F60\u4E5F\u641C\u4E0D\u5230\u5408\u9002\u7684\u7ACB\u7ED8\u65F6\uFF0C
810
+ **\u4E0D\u8981\u76F4\u63A5 draw**\u3002\u5148\u7528 ask_user \u95EE\u4E00\u53E5\u8981\u4E0D\u8981\u53C2\u8003\u56FE\uFF0C\u5E76\u7ED9\u51FA\u9009\u9879\uFF08\u4F8B\u5982\u300C\u7528\u4F60\u81EA\u5DF1\u7684\u5934\u50CF / \u7528 @\u67D0\u67D0 \u7684\u5934\u50CF /
811
+ \u6211\u5E2E\u4F60\u4ECE\u56FE\u5E93\u627E\u4E00\u5F20 / \u4E0D\u7528\u53C2\u8003\u76F4\u63A5\u753B\u300D\uFF09\u3002\u7528\u6237\u8BF4\u300C\u4E0D\u7528 / \u968F\u4FBF / \u76F4\u63A5\u753B\u300D\u5C31\u7ACB\u523B\u5F00\u753B\uFF0C**\u4E0D\u8981\u95EE\u7B2C\u4E8C\u6B21**\u3002
812
+ 9. \u3010\u5934\u50CF\u53EA\u80FD\u53D6\u300C\u6211\u300D\u548C\u300C\u88AB @ \u7684\u4EBA\u300D\u3011
813
+ - \u7528\u6237\u8BF4\u300C\u753B\u6211\u300D\u300C\u7528\u6211\u7684\u5F62\u8C61\u300D\u300C\u6211\u7684\u5934\u50CF\u300D\u2192 get_avatar \u7684 userId **\u7559\u7A7A**\uFF0C\u53D6\u4ED6\u81EA\u5DF1\u7684\u5934\u50CF\uFF1B
814
+ - \u7528\u6237 @ \u4E86\u8C01 \u2192 \u90A3\u4E2A\u4EBA\u7684\u5934\u50CF\u5DF2\u7ECF\u81EA\u52A8\u5E26\u4E0A\u4E86\uFF08\u4E0A\u4E0B\u6587\u91CC\u4F1A\u5217\u51FA\u7F16\u53F7\uFF09\uFF0C\u76F4\u63A5\u7528\u90A3\u4E2A\u7F16\u53F7\u5373\u53EF\uFF0C
815
+ \u9700\u8981\u65F6\u4E5F\u53EF\u4EE5\u628A\u4ED6\u7684 id \u6216\u6635\u79F0\u586B\u8FDB get_avatar \u518D\u53D6\u4E00\u6B21\uFF1B
816
+ - **\u9664\u6B64\u4E4B\u5916\u6CA1\u6709\u7B2C\u4E09\u79CD\u4EBA**\u3002\u6CA1 @ \u522B\u4EBA\u65F6\u7EDD\u4E0D\u8BB8\u53D6\u522B\u4EBA\u7684\u5934\u50CF\uFF0C\u4E5F\u4E0D\u8981\u81EA\u5DF1\u7F16 userId
817
+ \uFF08\u7F16\u51FA\u6765\u7684 id \u4F1A\u62FF\u5230\u5B8C\u5168\u4E0D\u76F8\u5E72\u7684\u4EBA\u7684\u5934\u50CF\uFF0C\u8FD9\u662F\u4E25\u91CD\u9519\u8BEF\uFF09\u3002
818
+ 10. \u3010\u9ED8\u8BA4\u4E0D\u6DA6\u8272\uFF0C\u7528\u6237\u70B9\u5934\u624D\u6DA6\u8272\u3011\u628A\u7528\u6237\u7684\u8BDD**\u539F\u5C01\u4E0D\u52A8**\u4EA4\u7ED9\u7ED8\u56FE\u6A21\u578B\u5C31\u662F\u6700\u597D\u7684\u9ED8\u8BA4\u503C\uFF1A
819
+ - **\u4E0D\u8981**\u4E3B\u52A8\u6269\u5199\u3001\u4E0D\u8981\u8865\u753B\u98CE/\u5149\u7EBF/\u6750\u8D28/\u955C\u5934\u3001\u4E0D\u8981\u7FFB\u6210\u82F1\u6587\u3001\u4E0D\u8981\u52A0\u300Cmasterpiece\u300D\u8FD9\u7C7B\u8BCD\uFF1B
820
+ - \u7528\u6237\u660E\u786E\u8BF4\u300C\u5E2E\u6211\u6DA6\u8272 / \u4F18\u5316\u4E00\u4E0B / \u5199\u8BE6\u7EC6\u70B9\u300D\u65F6\uFF0C\u4F60\u624D\u628A\u63D0\u793A\u8BCD\u5199\u5F97\u66F4\u5B8C\u6574\uFF1B
821
+ - draw \u5DE5\u5177\u8FD4\u56DE asked=true \u65F6\u770B\u5B83\u7ED9\u7684 polish \u5B57\u6BB5\uFF1Apolish=true \u624D\u6DA6\u8272\uFF0Cfalse \u6216\u6CA1\u7ED9\u5C31**\u4E00\u4E2A\u5B57\u90FD\u522B\u6539**\uFF1B
741
822
  - \u7528\u6237\u7528\u4E2D\u6587\u63D0\u7684\u9700\u6C42\uFF0Cprompt \u5C31\u5199\u4E2D\u6587\uFF08\u7ED8\u56FE\u6A21\u578B\u542C\u5F97\u61C2\u4E2D\u6587\uFF0C\u7406\u89E3\u529B\u4E5F\u591F\u7528\uFF09\uFF1B
742
- - \u522B\u4E3A\u4E86\u663E\u5F97\u4E13\u4E1A\u5C31\u53BB\u5806\u98CE\u683C / \u6750\u8D28 / \u5149\u7EBF / \u955C\u5934\u672F\u8BED\uFF0C\u66F4\u522B\u523B\u610F\u7FFB\u6210\u82F1\u6587\uFF1B
743
823
  - \u53EA\u4FDD\u7559\u7528\u6237\u771F\u6B63\u8BF4\u8FC7\u7684\u5185\u5BB9 + \u753B\u9762\u5FC5\u987B\u6709\u7684\u8981\u7D20\uFF0C**\u4E0D\u8981\u66FF\u4ED6\u8111\u8865\u7EC6\u8282**\uFF1B
744
824
  - \u63D0\u793A\u8BCD\u8D8A\u957F\uFF0C\u5404\u8981\u7D20\u4E92\u76F8\u7A00\u91CA\uFF0C\u51FA\u56FE\u53CD\u800C\u8D8A\u8D70\u6837\u3002\u4E00\u4E24\u53E5\u8BDD\u80FD\u628A\u753B\u9762\u8BF4\u6E05\u5C31\u591F\u4E86\u3002
745
825
 
746
826
  \u5982\u679C\u4F60\u6240\u5728\u7684\u63A5\u53E3\u4E0D\u652F\u6301\u51FD\u6570\u8C03\u7528\uFF0C\u5C31**\u53EA\u8F93\u51FA\u4E00\u884C JSON** \u6765\u8C03\u7528\u5DE5\u5177\uFF0C\u4F8B\u5982\uFF1A
747
827
  {"tool":"gallery_search","args":{"keyword":"\u767D\u53D1 \u7ACB\u7ED8"}}
748
828
  {"tool":"ask_user","args":{"question":"\u60F3\u8981\u4EC0\u4E48\u753B\u98CE\uFF1F"}}
829
+ {"tool":"get_avatar","args":{"userId":""}}\uFF08\u7559\u7A7A = \u53D1\u6307\u4EE4\u7684\u4EBA\u81EA\u5DF1\uFF1B\u4E5F\u53EF\u4EE5\u586B\u88AB @ \u7684\u4EBA\u7684 id\uFF0C\u4E0D\u8BB8\u81EA\u5DF1\u7F16\uFF09
749
830
  {"tool":"draw","args":{"prompt":"...","references":["ref1","user1"]}}
750
831
  \u4E0D\u60F3\u8C03\u7528\u5DE5\u5177\u65F6\uFF0C\u6B63\u5E38\u8F93\u51FA\u7ED9\u7528\u6237\u770B\u7684\u4E2D\u6587\u5373\u53EF\u3002`;
751
- var AGENT_CONFIRM_RULE_ON = `**\u5FC5\u987B\u5148 ask_user**\uFF1A\u7528\u4E00\u53E5\u8BDD\u544A\u8BC9\u7528\u6237\u300C\u8FD9\u6B21\u4F1A\u53C2\u8003\u54EA\u51E0\u5F20\u56FE + \u5927\u81F4\u753B\u6210\u4EC0\u4E48\u6837\u300D\uFF0C\u7528\u6237\u70B9\u5934\u540E\u624D\u80FD\u8C03\u7528 draw\u3002
832
+ var AGENT_CONFIRM_RULE_ON = `**\u5FC5\u987B\u5148 ask_user**\uFF1A\u7528\u4E00\u53E5\u8BDD\u544A\u8BC9\u7528\u6237\u300C\u8FD9\u6B21\u4F1A\u53C2\u8003\u54EA\u51E0\u5F20\u56FE + \u5927\u81F4\u753B\u6210\u4EC0\u4E48\u6837\u300D\uFF0C
833
+ \u5E76\u987A\u5E26\u95EE\u4E00\u53E5\u300C\u63D0\u793A\u8BCD\u8981\u4E0D\u8981\u6211\u5E2E\u4F60\u6DA6\u8272\uFF08\u9ED8\u8BA4\u76F4\u63A5\u7528\u4F60\u7684\u539F\u8BDD\uFF09\u300D\uFF0C\u7528\u6237\u70B9\u5934\u540E\u624D\u80FD\u8C03\u7528 draw\u3002
834
+ - \u7528\u6237\u8BF4\u300C\u6DA6\u8272 / \u4F18\u5316 / \u4E30\u5BCC\u4E00\u4E0B\u300D\u2192 \u4F60\u518D\u628A\u63D0\u793A\u8BCD\u5199\u5F97\u66F4\u5B8C\u6574\uFF1B
835
+ - \u7528\u6237\u8BF4\u300C\u76F4\u63A5\u753B / \u4E0D\u7528 / \u539F\u6837\u300D\u6216\u6CA1\u63D0\u8FD9\u4EF6\u4E8B \u2192 **\u539F\u5C01\u4E0D\u52A8\u7528\u4ED6\u7684\u539F\u8BDD**\uFF0C\u4E00\u4E2A\u5B57\u90FD\u522B\u6DA6\u8272\u3002
752
836
  \u7528\u6237\u56DE\u590D\u4E86\u5426\u5B9A\u6216\u63D0\u51FA\u4FEE\u6539\u610F\u89C1\uFF0C\u5C31\u6309\u4ED6\u8BF4\u7684\u6539\uFF0C\u518D\u786E\u8BA4\u4E00\u6B21\u6216\u76F4\u63A5\u753B\uFF08\u4ED6\u8BF4\u300C\u76F4\u63A5\u753B\u300D\u5C31\u4E0D\u7528\u518D\u95EE\uFF09\u3002`;
753
837
  var AGENT_CONFIRM_RULE_OFF = `\u7528\u6237\u9700\u6C42\u5DF2\u7ECF\u660E\u786E\u7684\uFF0C\u76F4\u63A5\u8C03\u7528 draw\uFF0C\u4E0D\u7528\u591A\u95EE\u4E00\u53E5\u3002\u53EA\u6709\u771F\u7684\u7F3A\u5173\u952E\u4FE1\u606F\u624D ask_user\u3002`;
754
838
  var AGENT_JSON_FALLBACK_RULE = `\uFF08\u6CE8\u610F\uFF1A\u5F53\u524D\u63A5\u53E3\u4E0D\u652F\u6301\u51FD\u6570\u8C03\u7528\uFF09\u8BF7\u4F60**\u53EA\u7528\u4E00\u884C JSON** \u6765\u8C03\u7528\u5DE5\u5177\uFF0C\u4E0D\u8981\u8F93\u51FA\u522B\u7684\u5185\u5BB9\uFF1A
755
839
  {"tool":"gallery_search","args":{"keyword":"\u767D\u53D1 \u7ACB\u7ED8"}}
756
840
  {"tool":"ask_user","args":{"question":"\u60F3\u8981\u4EC0\u4E48\u753B\u98CE\uFF1F"}}
841
+ {"tool":"get_avatar","args":{"userId":""}}\uFF08\u7559\u7A7A = \u53D1\u6307\u4EE4\u7684\u4EBA\u81EA\u5DF1\uFF1B\u4E5F\u53EF\u4EE5\u586B\u88AB @ \u7684\u4EBA\u7684 id\uFF0C\u4E0D\u8BB8\u81EA\u5DF1\u7F16\uFF09
757
842
  {"tool":"draw","args":{"prompt":"...","references":["ref1","ref2"]}}
758
843
  \u4E0D\u9700\u8981\u8C03\u7528\u5DE5\u5177\u65F6\uFF0C\u6B63\u5E38\u8F93\u51FA\u7ED9\u7528\u6237\u770B\u7684\u4E2D\u6587\u5373\u53EF\u3002`;
759
844
  var defaultCommands = [
@@ -1299,9 +1384,20 @@ var Config = import_koishi.Schema.intersect([
1299
1384
  model: import_koishi.Schema.string().description("agent \u4E13\u7528\u7684\u6A21\u578B\uFF08\u7559\u7A7A\u5219\u7528\u300CAI \u6A21\u578B\u63A5\u53E3\u300D\u91CC\u7684\u6A21\u578B\uFF09\u3002**\u9700\u8981\u652F\u6301 function calling**\uFF1B\u4E0D\u652F\u6301\u65F6\u63D2\u4EF6\u4F1A\u81EA\u52A8\u6539\u7528\u300C\u4E00\u884C JSON\u300D\u534F\u8BAE"),
1300
1385
  baseUrl: import_koishi.Schema.string().role("link").description("agent \u4E13\u7528\u63A5\u53E3\u5730\u5740\uFF08\u7559\u7A7A\u5219\u590D\u7528\u300CAI \u6A21\u578B\u63A5\u53E3\u300D\u7684\u5730\u5740\uFF09"),
1301
1386
  apiKey: import_koishi.Schema.string().role("secret").description("agent \u4E13\u7528\u5BC6\u94A5\uFF08\u7559\u7A7A\u5219\u590D\u7528\u300CAI \u6A21\u578B\u63A5\u53E3\u300D\u7684\u5BC6\u94A5\uFF09"),
1302
- instructions: import_koishi.Schema.string().role("textarea", { rows: [16, 8] }).default(DEFAULT_AGENT_INSTRUCTIONS).description("\u9A71\u52A8 agent \u884C\u4E3A\u7684\u7CFB\u7EDF\u63D0\u793A\u8BCD\uFF08\u53EA\u5199\u300C\u6709\u54EA\u4E9B\u5DE5\u5177 + \u4EC0\u4E48\u65F6\u5019\u7528\u300D\uFF0C\u522B\u5199\u6B7B\u6D41\u7A0B\uFF09\u3002\u53EF\u7528\u5360\u4F4D\u7B26\uFF1A{confirmRule} \u5F00\u753B\u786E\u8BA4\u89C4\u5219\u3001{command} \u6307\u4EE4\u540D\u3001{prompt} \u6307\u4EE4\u63D0\u793A\u8BCD\u3001{userInput} \u7528\u6237\u9644\u52A0\u9700\u6C42\u3001{imageCount} \u7528\u6237\u968F\u6D88\u606F\u53D1\u7684\u56FE\u6570\u91CF\u3001{refCount} \u53EF\u68C0\u7D22\u7684\u53C2\u8003\u56FE\u6570\u91CF\u3002\u6307\u4EE4\u540D/\u63D0\u793A\u8BCD\u7B49\u4E0A\u4E0B\u6587\u4F1A\u81EA\u52A8\u9644\u5728\u63D0\u793A\u8BCD\u672B\u5C3E\uFF0C\u4E0D\u7528\u81EA\u5DF1\u5F15\u7528")
1387
+ instructions: import_koishi.Schema.string().role("textarea", { rows: [16, 8] }).default(DEFAULT_AGENT_INSTRUCTIONS).description("\u9A71\u52A8 agent \u884C\u4E3A\u7684\u7CFB\u7EDF\u63D0\u793A\u8BCD\uFF08\u53EA\u5199\u300C\u6709\u54EA\u4E9B\u5DE5\u5177 + \u4EC0\u4E48\u65F6\u5019\u7528\u300D\uFF0C\u522B\u5199\u6B7B\u6D41\u7A0B\uFF09\u3002\u53EF\u7528\u5360\u4F4D\u7B26\uFF1A{confirmRule} \u5F00\u753B\u786E\u8BA4\u89C4\u5219\u3001{command} \u6307\u4EE4\u540D\u3001{prompt} \u6307\u4EE4\u63D0\u793A\u8BCD\u3001{userInput} \u7528\u6237\u9644\u52A0\u9700\u6C42\u3001{imageCount} \u7528\u6237\u968F\u6D88\u606F\u53D1\u7684\u56FE\u6570\u91CF\u3001{refCount} \u53EF\u68C0\u7D22\u7684\u53C2\u8003\u56FE\u6570\u91CF\u3002\u6307\u4EE4\u540D/\u63D0\u793A\u8BCD\u7B49\u4E0A\u4E0B\u6587\u4F1A\u81EA\u52A8\u9644\u5728\u63D0\u793A\u8BCD\u672B\u5C3E\uFF0C\u4E0D\u7528\u81EA\u5DF1\u5F15\u7528"),
1388
+ askIfNoReference: import_koishi.Schema.boolean().default(true).description("\u7528\u6237\u8FD9\u6B21\u65E2\u6CA1\u53D1\u56FE\u3001\u4E5F\u6CA1 @ \u4EBA\u3001\u6307\u4EE4\u672C\u8EAB\u4E5F\u6CA1\u6709\u9ED8\u8BA4\u53C2\u8003\u56FE\u65F6\uFF0C\u5F00\u753B\u524D\u5148\u95EE\u4E00\u53E5\u300C\u8981\u4E0D\u8981\u53C2\u8003\u56FE\u300D\uFF08\u53EF\u4EE5\u7528\u4ED6\u81EA\u5DF1\u7684\u5934\u50CF / @ \u522B\u4EBA\u7684\u5934\u50CF\uFF09\u3002\u8FD9\u6761\u662F\u63D2\u4EF6\u515C\u5E95\u6267\u884C\u7684\uFF0C\u6A21\u578B\u81EA\u5DF1\u5148\u95EE\u8FC7\u5C31\u4E0D\u518D\u95EE"),
1389
+ askBeforePolish: import_koishi.Schema.boolean().default(true).description("\u5F00\u753B\u524D\u5148\u95EE\u7528\u6237\u300C\u63D0\u793A\u8BCD\u8981\u4E0D\u8981\u6211\u5E2E\u4F60\u6DA6\u8272\u300D\u3002**\u9ED8\u8BA4\u662F\u539F\u5C01\u4E0D\u52A8\u628A\u7528\u6237\u7684\u539F\u8BDD\u4EA4\u7ED9\u7ED8\u56FE\u6A21\u578B**\uFF0C\u53EA\u6709\u7528\u6237\u8BF4\u300C\u6DA6\u8272 / \u4F18\u5316\u300D\u624D\u52A0\u5DE5\u3002\u8FD9\u6761\u540C\u6837\u662F\u63D2\u4EF6\u515C\u5E95\uFF0C\u6A21\u578B\u81EA\u5DF1\u5148\u95EE\u8FC7\u5C31\u4E0D\u518D\u95EE")
1303
1390
  }).collapse().description("Agent \u914D\u7F6E\uFF08\u6307\u4EE4\u8F83\u957F\uFF0C\u5DF2\u6298\u53E0\uFF09")
1304
1391
  }).description("Agent \u6A21\u5F0F"),
1392
+ import_koishi.Schema.object({
1393
+ avatar: import_koishi.Schema.object({
1394
+ enabled: import_koishi.Schema.boolean().default(true).description("\u5F00\u542F\u5934\u50CF\u53C2\u8003\u56FE\uFF1A\u53EF\u4EE5\u628A\u7FA4\u53CB\u7684\u5934\u50CF\u5F53\u53C2\u8003\u56FE\u6765\u753B"),
1395
+ autoAt: import_koishi.Schema.boolean().default(true).description("\u7528\u6237 @ \u4E86\u8C01\uFF0C\u5C31\u81EA\u52A8\u628A\u90A3\u4E2A\u4EBA\u7684\u5934\u50CF\u4F5C\u4E3A\u53C2\u8003\u56FE\uFF08@ \u672C\u8EAB\u5C31\u662F\u660E\u786E\u7684\u6307\u5B9A\uFF09"),
1396
+ autoSelf: import_koishi.Schema.boolean().default(false).description("\u7528\u6237\u6CA1\u53D1\u56FE\u4E5F\u6CA1 @ \u4EBA\u65F6\uFF0C\u81EA\u52A8\u62FF\u4ED6\u81EA\u5DF1\u7684\u5934\u50CF\u5F53\u53C2\u8003\u56FE\u3002\u5173\u6389\u4E5F\u6CA1\u5173\u7CFB\uFF0C\u300C\u7528\u6211\u7684\u5934\u50CF\u753B\u300D\u8FD9\u7C7B\u9700\u6C42 agent \u4F1A\u81EA\u5DF1\u8C03\u7528 get_avatar"),
1397
+ size: import_koishi.Schema.number().default(640).min(64).max(1024).step(64).description("\u5934\u50CF\u8FB9\u957F\uFF08\u50CF\u7D20\uFF09"),
1398
+ urlTemplate: import_koishi.Schema.string().default("").description("\u81EA\u5B9A\u4E49\u5934\u50CF\u5730\u5740\u6A21\u677F\uFF0C\u7559\u7A7A\u7528\u5185\u7F6E\u89C4\u5219\u3002\u5360\u4F4D\u7B26\uFF1A{userId} \u7528\u6237 id\u3001{platform} \u5E73\u53F0\u3001{selfId} \u673A\u5668\u4EBA id\u3001{appId} \u673A\u5668\u4EBA appid\u3001{size} \u5C3A\u5BF8")
1399
+ }).description("\u5934\u50CF\u53C2\u8003\u56FE")
1400
+ }).description("\u5934\u50CF\u53C2\u8003\u56FE"),
1305
1401
  import_koishi.Schema.object({
1306
1402
  appendUserInput: import_koishi.Schema.boolean().default(true).description("\u628A\u7528\u6237\u968F\u6307\u4EE4\u53D1\u7684\u9644\u52A0\u9700\u6C42\u5E76\u5165\u7ED8\u56FE\u63D0\u793A\u8BCD\uFF08\u4F8B\u5982\u300C\u624B\u529E\u5316 xxx \u5728\u5077\u5403\u767D\u996D\u88AB\u53D1\u73B0\u7684\u8868\u60C5\u300D\uFF09"),
1307
1403
  promptOptimize: import_koishi.Schema.union([
@@ -1470,6 +1566,8 @@ function apply(ctx, config) {
1470
1566
  needimages: "\u8BF7\u63D0\u4F9B\u81F3\u5C11\u4E00\u5F20\u56FE\u7247",
1471
1567
  agentfailed: "\u7ED8\u56FE\u52A9\u624B\u8FD9\u6B21\u6CA1\u8DD1\u8D77\u6765\uFF08{0}\uFF09\u3002\u53EF\u4EE5\u5148\u5173\u6389\u300CAgent \u6A21\u5F0F\u300D\u7167\u5E38\u753B\u56FE\uFF0C\u6216\u6362\u4E00\u4E2A\u652F\u6301\u5DE5\u5177\u8C03\u7528\u7684\u6A21\u578B\u3002",
1472
1568
  agentnoresult: "\u8FD9\u6B21\u6CA1\u80FD\u7406\u51FA\u4E2A\u7ED3\u679C\u6765\uFF0C\u9EBB\u70E6\u518D\u8BF4\u4E00\u6B21\u4F60\u60F3\u753B\u4EC0\u4E48\uFF5E",
1569
+ askreference: "\u8FD9\u6B21\u6CA1\u6709\u6307\u5B9A\u53C2\u8003\u56FE\u3002\u8981\u53C2\u8003\u56FE\u7247\u5417\uFF1F\u53EF\u4EE5\u76F4\u63A5\u53D1\u56FE\u3001@ \u4E00\u4E2A\u4EBA\u7528\u4ED6\u7684\u5934\u50CF\uFF0C\u6216\u8005\u8BF4\u300C\u7528\u6211\u7684\u5934\u50CF\u300D\uFF1B\u4E0D\u9700\u8981\u5C31\u56DE\u300C\u76F4\u63A5\u753B\u300D\u3002\n\u53E6\u5916\uFF0C\u63D0\u793A\u8BCD\u8981\u6211\u5E2E\u4F60\u6DA6\u8272\u4E00\u4E0B\u5417\uFF1F\u9ED8\u8BA4\u76F4\u63A5\u7528\u4F60\u7684\u539F\u8BDD\u3002",
1570
+ askpolish: "\u8FD9\u6B21\u76F4\u63A5\u6309\u4F60\u7684\u539F\u8BDD\u5F00\u753B\u3002\u8981\u6211\u5148\u5E2E\u4F60\u6DA6\u8272\u4E00\u4E0B\u63D0\u793A\u8BCD\u5417\uFF1F\u56DE\u300C\u6DA6\u8272\u300D\u6211\u52A0\u5DE5\u4E00\u4E0B\uFF0C\u56DE\u300C\u76F4\u63A5\u753B\u300D\u5C31\u539F\u6837\u4EA4\u7ED9\u7ED8\u56FE\u6A21\u578B\u3002",
1473
1571
  optimizefailed: "\uFF08\u63D0\u793A\u8BCD\u878D\u5408\u5931\u8D25\uFF0C\u5DF2\u6539\u4E3A\u8FFD\u52A0\u6A21\u5F0F\uFF09",
1474
1572
  bgstart: "\u5DF2\u5F00\u59CB\u540E\u53F0\u7ED8\u56FE\uFF08{0} \u5F20\u56FE\uFF09\uFF0C\u753B\u597D\u540E\u4F1A\u5728\u8FD9\u91CC\u901A\u77E5\u4F60...",
1475
1573
  bgqueue: "\uFF08\u5F53\u524D\u6709 {0} \u4E2A\u4EFB\u52A1\u5728\u6392\u961F\uFF09",
@@ -1538,7 +1636,43 @@ function apply(ctx, config) {
1538
1636
  for (const item of pool) register("gallery", item.url, item.description, item.group);
1539
1637
  const baseIds = (defaultImageUrls || []).filter(Boolean).map((url) => register("cmd", url, "", "\u6307\u4EE4\u9ED8\u8BA4\u56FE"));
1540
1638
  const userIds = extractImagesFromSession(session).map((url) => register("user", url, "", "\u7528\u6237\u53D1\u9001"));
1541
- logInfo2(`[${cmdConfig.name}] agent \u542F\u52A8\uFF1A\u53EF\u641C\u7D22\u53C2\u8003\u56FE ${pool.length} \u5F20\uFF0C\u9ED8\u8BA4\u56FE ${baseIds.length} \u5F20\uFF0C\u7528\u6237\u968F\u6D88\u606F\u53D1\u7684\u56FE ${userIds.length} \u5F20`);
1639
+ const avatarCfg = config.avatar || {};
1640
+ const avatarOn = avatarCfg.enabled !== false;
1641
+ const atTargets = avatarOn ? collectAtTargets(session) : [];
1642
+ let selfAvatarId = "";
1643
+ const atAvatarIds = [];
1644
+ const atAvatarById = /* @__PURE__ */ new Map();
1645
+ const avatarAllowed = /* @__PURE__ */ new Map();
1646
+ avatarAllowed.set(session.userId, "\u53D1\u6307\u4EE4\u7684\u4EBA\u81EA\u5DF1");
1647
+ for (const t of atTargets) if (t.id) avatarAllowed.set(t.id, t.name || t.id);
1648
+ const resolveAvatarUser = (raw) => {
1649
+ const text = String(raw || "").trim();
1650
+ if (!text || text === session.userId || /^(me|self|自己|我|本人|我的头像|我自己)$/i.test(text)) {
1651
+ return session.userId;
1652
+ }
1653
+ if (avatarAllowed.has(text)) return text;
1654
+ const lower = text.toLowerCase();
1655
+ for (const [id, name2] of avatarAllowed) {
1656
+ if (name2 && (name2 === text || name2.toLowerCase() === lower)) return id;
1657
+ }
1658
+ return "";
1659
+ };
1660
+ if (avatarOn) {
1661
+ const selfUrl = await fetchAvatarUrl(session, session.userId);
1662
+ if (selfUrl) {
1663
+ selfAvatarId = register("avatar", selfUrl, "\u53D1\u6307\u4EE4\u7684\u4EBA\u7684\u5934\u50CF", "\u5934\u50CF");
1664
+ }
1665
+ if (avatarCfg.autoAt !== false) {
1666
+ for (const target of atTargets) {
1667
+ const url = await fetchAvatarUrl(session, target.id);
1668
+ if (!url) continue;
1669
+ const id = register("avatar", url, `${target.name || target.id} \u7684\u5934\u50CF`, "\u5934\u50CF");
1670
+ if (!atAvatarIds.includes(id)) atAvatarIds.push(id);
1671
+ atAvatarById.set(target.id, id);
1672
+ }
1673
+ }
1674
+ }
1675
+ logInfo2(`[${cmdConfig.name}] agent \u542F\u52A8\uFF1A\u53EF\u641C\u7D22\u53C2\u8003\u56FE ${pool.length} \u5F20\uFF0C\u9ED8\u8BA4\u56FE ${baseIds.length} \u5F20\uFF0C\u7528\u6237\u968F\u6D88\u606F\u53D1\u7684\u56FE ${userIds.length} \u5F20\uFF0C\u5934\u50CF ${atAvatarIds.length + (selfAvatarId ? 1 : 0)} \u5F20`);
1542
1676
  const historyKey = agentHistoryKey(session);
1543
1677
  const history = historyTurns > 0 ? (agentHistories.get(historyKey) || []).slice() : [];
1544
1678
  const newHistory = [];
@@ -1547,7 +1681,14 @@ function apply(ctx, config) {
1547
1681
  };
1548
1682
  remember({ role: "user", content: userInputText || "\uFF08\u7528\u6237\u6CA1\u6709\u9644\u52A0\u8BF4\u660E\uFF09" });
1549
1683
  const messages = [
1550
- { role: "system", content: buildAgentSystemPrompt(cmdConfig, userInputText, userIds.length, pool.length, baseIds, agentCfg) },
1684
+ { role: "system", content: buildAgentSystemPrompt(cmdConfig, userInputText, pool.length, {
1685
+ userIds,
1686
+ baseIds,
1687
+ atAvatarIds,
1688
+ selfAvatarId,
1689
+ atTargets,
1690
+ selfUserId: session.userId
1691
+ }, agentCfg, avatarAllowed) },
1551
1692
  ...history,
1552
1693
  { role: "user", content: userInputText ? userInputText : "\uFF08\u7528\u6237\u6CA1\u6709\u9644\u52A0\u8BF4\u660E\uFF0C\u8BF7\u6309\u6307\u4EE4\u81EA\u5E26\u7684\u63D0\u793A\u8BCD\u6765\uFF09" }
1553
1694
  ];
@@ -1557,6 +1698,8 @@ function apply(ctx, config) {
1557
1698
  let finalText = "";
1558
1699
  let drew = false;
1559
1700
  let failed = "";
1701
+ let askedOnce = false;
1702
+ let drawAsked = false;
1560
1703
  for (let iteration = 0; iteration < maxIterations; iteration++) {
1561
1704
  if (!isActive || !ctx.scope.isActive) break;
1562
1705
  const res = await requestAgentChat(messages, toolsSupported ? tools : void 0);
@@ -1607,10 +1750,12 @@ ${output}` }
1607
1750
  return toolGallerySearch(args);
1608
1751
  case "ask_user":
1609
1752
  return toolAskUser(args);
1753
+ case "get_avatar":
1754
+ return toolGetAvatar(args);
1610
1755
  case "draw":
1611
1756
  return toolDraw(args);
1612
1757
  default:
1613
- return JSON.stringify({ ok: false, error: `\u6CA1\u6709\u53EB\u300C${name2}\u300D\u7684\u5DE5\u5177\uFF0C\u53EF\u7528\u7684\u662F gallery_search / ask_user / draw` });
1758
+ return JSON.stringify({ ok: false, error: `\u6CA1\u6709\u53EB\u300C${name2}\u300D\u7684\u5DE5\u5177\uFF0C\u53EF\u7528\u7684\u662F gallery_search / ask_user / get_avatar / draw` });
1614
1759
  }
1615
1760
  }
1616
1761
  function toolGallerySearch(args) {
@@ -1639,9 +1784,36 @@ ${output}` }
1639
1784
  }))
1640
1785
  });
1641
1786
  }
1787
+ async function toolGetAvatar(args) {
1788
+ if (!avatarOn) return JSON.stringify({ ok: false, error: "\u5934\u50CF\u53C2\u8003\u56FE\u529F\u80FD\u5DF2\u5173\u95ED" });
1789
+ const raw = String(args?.userId ?? args?.id ?? args?.user ?? "").trim();
1790
+ const userId = resolveAvatarUser(raw);
1791
+ if (!userId) {
1792
+ const options = [...avatarAllowed.entries()].map(([id2, name2]) => ({ userId: id2, who: name2 }));
1793
+ return JSON.stringify({
1794
+ ok: false,
1795
+ error: `\u4E0D\u8BA4\u8BC6\u300C${raw}\u300D\u3002\u5934\u50CF\u53EA\u80FD\u53D6\u300C\u53D1\u6307\u4EE4\u7684\u4EBA\u81EA\u5DF1\u300D\u548C\u300C\u4ED6\u8FD9\u6B21 @ \u5230\u7684\u4EBA\u300D\uFF0C\u4E0D\u80FD\u81EA\u5DF1\u7F16 id`,
1796
+ available: options,
1797
+ note: `\u8981\u753B\u7684\u5982\u679C\u662F\u53D1\u6307\u4EE4\u7684\u4EBA\u81EA\u5DF1\uFF0C\u628A userId \u7559\u7A7A\u518D\u8C03\u4E00\u6B21\uFF1B\u5982\u679C\u662F\u522B\u4EBA\uFF0C\u8BA9\u4ED6 @ \u90A3\u4E2A\u4EBA\u518D\u53D1\u4E00\u6B21\u6307\u4EE4\u3002\u73B0\u5728\u53EF\u53D6\uFF1A${options.map((o) => o.who).join("\u3001")}`
1798
+ });
1799
+ }
1800
+ const isSelf = userId === session.userId;
1801
+ const who = avatarAllowed.get(userId) || (isSelf ? "\u53D1\u6307\u4EE4\u7684\u4EBA\u81EA\u5DF1" : userId);
1802
+ const cached = isSelf ? selfAvatarId : atAvatarById.get(userId);
1803
+ if (cached) return JSON.stringify({ ok: true, id: cached, userId, note: `${who}\u7684\u5934\u50CF` });
1804
+ const url = await fetchAvatarUrl(session, userId);
1805
+ if (!url) {
1806
+ return JSON.stringify({ ok: false, error: `\u6CA1\u53D6\u5230\u300C${who}\u300D\u7684\u5934\u50CF\uFF08\u8FD9\u4E2A\u5E73\u53F0\u53EF\u80FD\u4E0D\u63D0\u4F9B\u5934\u50CF\u5730\u5740\uFF09` });
1807
+ }
1808
+ const id = register("avatar", url, `${who}\u7684\u5934\u50CF`, "\u5934\u50CF");
1809
+ if (isSelf) selfAvatarId = id;
1810
+ else atAvatarById.set(userId, id);
1811
+ return JSON.stringify({ ok: true, id, userId, note: `${who}\u7684\u5934\u50CF` });
1812
+ }
1642
1813
  async function toolAskUser(args) {
1643
1814
  const question = cleanAskMessage(args?.question ?? args?.text ?? args?.message);
1644
1815
  if (!question) return JSON.stringify({ ok: false, error: "question \u4E0D\u80FD\u4E3A\u7A7A" });
1816
+ askedOnce = true;
1645
1817
  try {
1646
1818
  await sendNotice(session, question);
1647
1819
  } catch (error) {
@@ -1666,10 +1838,43 @@ ${output}` }
1666
1838
  const ids = images.map((url) => register("user", url, "", "\u7528\u6237\u53D1\u9001"));
1667
1839
  remember({ role: "user", content: text || (ids.length ? `\uFF08\u7528\u6237\u53D1\u4E86 ${ids.length} \u5F20\u56FE\u7247\uFF09` : "\uFF08\u7528\u6237\u4EC0\u4E48\u90FD\u6CA1\u8BF4\uFF09") });
1668
1840
  logInfo2(`agent \u63D0\u95EE\u300C${question}\u300D-> \u7528\u6237\u56DE\u590D: ${text || "\uFF08\u65E0\u6587\u5B57\uFF09"}\uFF0C\u56FE\u7247 ${ids.length} \u5F20`);
1841
+ const avatars = [];
1842
+ if (avatarOn) {
1843
+ if (avatarCfg.autoAt !== false) {
1844
+ for (const target of extractAtIds(String(answer || ""), session.selfId)) {
1845
+ if (!target.id) continue;
1846
+ if (!avatarAllowed.has(target.id)) avatarAllowed.set(target.id, target.name || target.id);
1847
+ const who = avatarAllowed.get(target.id) || target.id;
1848
+ const cached = atAvatarById.get(target.id);
1849
+ if (cached) {
1850
+ if (!avatars.some((a) => a.id === cached)) avatars.push({ id: cached, note: `${who} \u7684\u5934\u50CF` });
1851
+ continue;
1852
+ }
1853
+ const url = await fetchAvatarUrl(session, target.id);
1854
+ if (!url) continue;
1855
+ const id = register("avatar", url, `${who} \u7684\u5934\u50CF`, "\u5934\u50CF");
1856
+ atAvatarById.set(target.id, id);
1857
+ if (!atAvatarIds.includes(id)) atAvatarIds.push(id);
1858
+ avatars.push({ id, note: `${who} \u7684\u5934\u50CF` });
1859
+ }
1860
+ }
1861
+ if (/头像|我的形象|画我|我自己/.test(text) && !avatars.some((a) => a.id === selfAvatarId)) {
1862
+ let id = selfAvatarId;
1863
+ if (!id) {
1864
+ const url = await fetchAvatarUrl(session, session.userId);
1865
+ if (url) {
1866
+ id = register("avatar", url, "\u53D1\u6307\u4EE4\u7684\u4EBA\u7684\u5934\u50CF", "\u5934\u50CF");
1867
+ selfAvatarId = id;
1868
+ }
1869
+ }
1870
+ if (id) avatars.push({ id, note: "\u53D1\u6307\u4EE4\u7684\u4EBA\u81EA\u5DF1\u7684\u5934\u50CF" });
1871
+ }
1872
+ }
1669
1873
  return JSON.stringify({
1670
1874
  ok: true,
1671
1875
  text,
1672
- images: ids.map((id, i) => ({ id, note: `\u7528\u6237\u8FD9\u6B21\u53D1\u7684\u7B2C ${i + 1} \u5F20\u56FE` }))
1876
+ images: ids.map((id, i) => ({ id, note: `\u7528\u6237\u8FD9\u6B21\u53D1\u7684\u7B2C ${i + 1} \u5F20\u56FE` })),
1877
+ ...avatars.length ? { avatars } : {}
1673
1878
  });
1674
1879
  }
1675
1880
  async function toolDraw(args) {
@@ -1682,9 +1887,35 @@ ${output}` }
1682
1887
  if (id && !wanted.includes(id)) wanted.push(id);
1683
1888
  };
1684
1889
  baseIds.forEach(pushId);
1890
+ userIds.forEach(pushId);
1891
+ atAvatarIds.forEach(pushId);
1892
+ if (avatarOn && avatarCfg.autoSelf) pushId(selfAvatarId);
1685
1893
  ids.forEach(pushId);
1686
1894
  const capped = wanted.slice(0, maxSelect);
1687
1895
  const imageUrls = capped.map((id) => registry.get(id)?.url).filter(Boolean);
1896
+ const needRef = !capped.length && agentCfg.askIfNoReference !== false;
1897
+ const needPolish = agentCfg.askBeforePolish !== false;
1898
+ if (!drawAsked && !askedOnce && (needRef || needPolish)) {
1899
+ drawAsked = true;
1900
+ const asked = await toolAskUser({
1901
+ question: needRef ? session.text("image-prompt.messages.askreference") : session.text("image-prompt.messages.askpolish")
1902
+ });
1903
+ let parsed = {};
1904
+ try {
1905
+ parsed = JSON.parse(asked);
1906
+ } catch {
1907
+ parsed = {};
1908
+ }
1909
+ const polish = parsed.ok ? parsePolishIntent(parsed.text) : false;
1910
+ return JSON.stringify({
1911
+ ok: false,
1912
+ asked: true,
1913
+ polish,
1914
+ ...parsed.images?.length ? { newImages: parsed.images } : {},
1915
+ ...parsed.avatars?.length ? { newAvatars: parsed.avatars } : {},
1916
+ note: polish ? "\u5DF2\u7ECF\u66FF\u4F60\u95EE\u8FC7\u7528\u6237\u4E86\uFF1A\u4ED6\u8BF4\u8981\u6DA6\u8272\uFF0C\u53EF\u4EE5\u628A\u63D0\u793A\u8BCD\u5199\u5F97\u66F4\u5B8C\u6574\u3002\u4ED6\u7ED9\u4E86\u56FE/\u5934\u50CF\u4E5F\u8981\u5199\u8FDB references\u3002\u91CD\u65B0\u8C03\u7528 draw \u5F00\u753B\uFF0C\u4E0D\u8981\u518D\u95EE\u7B2C\u4E8C\u6B21" : "\u5DF2\u7ECF\u66FF\u4F60\u95EE\u8FC7\u7528\u6237\u4E86\uFF1A\u63D0\u793A\u8BCD**\u539F\u5C01\u4E0D\u52A8\u7528\u4ED6\u7684\u539F\u8BDD**\uFF0C\u4E0D\u8981\u6DA6\u8272\u3001\u4E0D\u8981\u6269\u5199\u3001\u4E0D\u8981\u7FFB\u8BD1\u3002\u4ED6\u7ED9\u4E86\u56FE/\u5934\u50CF\u5C31\u5199\u8FDB references\u3002\u91CD\u65B0\u8C03\u7528 draw \u5F00\u753B\uFF0C\u4E0D\u8981\u518D\u95EE\u7B2C\u4E8C\u6B21"
1917
+ });
1918
+ }
1688
1919
  const finalPrompt = args?.negative_prompt ? `${prompt}
1689
1920
 
1690
1921
  Negative prompt: ${String(args.negative_prompt).trim()}` : prompt;
@@ -1701,12 +1932,12 @@ Negative prompt: ${String(args.negative_prompt).trim()}` : prompt;
1701
1932
  });
1702
1933
  }
1703
1934
  }
1704
- function buildAgentSystemPrompt(cmdConfig, userInputText, imageCount, refCount, baseIds, agentCfg) {
1935
+ function buildAgentSystemPrompt(cmdConfig, userInputText, refCount, refs, agentCfg, avatarAllowed) {
1705
1936
  const instructions = renderAgentInstructions(agentCfg.instructions || DEFAULT_AGENT_INSTRUCTIONS, {
1706
1937
  command: cmdConfig.name || "",
1707
1938
  prompt: cmdConfig.prompt || "",
1708
1939
  userInput: userInputText || "",
1709
- imageCount,
1940
+ imageCount: refs.userIds.length,
1710
1941
  refCount,
1711
1942
  confirmRule: agentCfg.confirmBeforeDraw !== false ? AGENT_CONFIRM_RULE_ON : AGENT_CONFIRM_RULE_OFF
1712
1943
  });
@@ -1716,12 +1947,33 @@ Negative prompt: ${String(args.negative_prompt).trim()}` : prompt;
1716
1947
  `- \u7ED8\u56FE\u6307\u4EE4\uFF1A${cmdConfig.name}`,
1717
1948
  `- \u6307\u4EE4\u81EA\u5E26\u7684\u63D0\u793A\u8BCD\uFF1A${cmdConfig.prompt || "\uFF08\u7A7A\uFF0C\u8FD9\u662F\u81EA\u5B9A\u4E49\u6307\u4EE4\uFF09"}`,
1718
1949
  `- \u7528\u6237\u8FD9\u6B21\u8BF4\u7684\u8BDD\uFF1A${userInputText || "\uFF08\u7528\u6237\u6CA1\u8BF4\u8BDD\uFF09"}`,
1719
- `- \u7528\u6237\u968F\u6D88\u606F\u53D1\u7684\u56FE\uFF1A${imageCount} \u5F20${imageCount ? "\uFF08\u7F16\u53F7\u89C1\u4E0B\u65B9\uFF0C\u53EF\u4EE5\u76F4\u63A5\u5199\u8FDB draw \u7684 references\uFF09" : ""}`,
1950
+ `- \u7528\u6237\u968F\u6D88\u606F\u53D1\u7684\u56FE\uFF1A${refs.userIds.length ? `${refs.userIds.join("\u3001")}\uFF08\u5DF2\u81EA\u52A8\u5E26\u4E0A\uFF0C\u4E0D\u7528\u518D\u586B\uFF09` : "0 \u5F20"}`,
1720
1951
  `- \u56FE\u5E93\u91CC\u53EF\u4EE5\u641C\u5230\u7684\u53C2\u8003\u56FE\uFF1A${refCount} \u5F20`
1721
1952
  ];
1722
- if (baseIds.length) lines.push(`- \u6307\u4EE4\u9ED8\u8BA4\u53C2\u8003\u56FE\uFF08\u5DF2\u81EA\u52A8\u5E26\u4E0A\uFF0C\u4E0D\u7528\u518D\u586B\uFF09\uFF1A${baseIds.join("\u3001")}`);
1953
+ if (refs.baseIds.length) lines.push(`- \u6307\u4EE4\u9ED8\u8BA4\u53C2\u8003\u56FE\uFF08\u5DF2\u81EA\u52A8\u5E26\u4E0A\uFF0C\u4E0D\u7528\u518D\u586B\uFF09\uFF1A${refs.baseIds.join("\u3001")}`);
1723
1954
  if (cmdConfig.custom) lines.push("- \u8FD9\u662F\u81EA\u5B9A\u4E49\u6307\u4EE4\uFF1A\u7528\u6237\u6CA1\u8BF4\u6E05\u695A\u8981\u753B\u4EC0\u4E48\u65F6\uFF0C\u5148\u7528 ask_user \u95EE\u4E00\u53E5");
1724
- return instructions + lines.join("\n");
1955
+ const avatarLines = ["", "## \u53EF\u53D6\u5934\u50CF\u7684\u4EBA\uFF08get_avatar \u53EA\u8BA4\u8FD9\u4E9B\uFF09"];
1956
+ if (refs.selfAvatarId) {
1957
+ avatarLines.push(`- \u53D1\u6307\u4EE4\u7684\u4EBA\u81EA\u5DF1\uFF1A\u7F16\u53F7 ${refs.selfAvatarId}\uFF08\u4ED6\u60F3\u753B\u300C\u6211\u300D\u65F6\u7528\u8FD9\u4E2A\u7F16\u53F7\uFF0C\u6216 get_avatar \u7684 userId \u7559\u7A7A\u518D\u53D6\u4E00\u6B21\uFF09`);
1958
+ } else {
1959
+ avatarLines.push("- \u53D1\u6307\u4EE4\u7684\u4EBA\u81EA\u5DF1\uFF1Aget_avatar \u7684 userId **\u7559\u7A7A**\u5373\u53EF\uFF08\u8FD9\u8F6E\u8FD8\u6CA1\u63D0\u524D\u53D6\uFF0C\u53D6\u4E86\u624D\u6709\u7F16\u53F7\uFF09");
1960
+ }
1961
+ if (refs.atAvatarIds.length) {
1962
+ const pairs = refs.atTargets.map((t, i) => `${refs.atAvatarIds[i] || "?"}=${t.name || t.id}`).join("\u3001");
1963
+ avatarLines.push(`- \u88AB @ \u7684\u4EBA\uFF08\u5DF2\u81EA\u52A8\u5E26\u4E0A\uFF0C\u4E0D\u7528\u518D\u586B\uFF09\uFF1A${pairs}`);
1964
+ } else if (refs.atTargets.length) {
1965
+ avatarLines.push(`- \u88AB @ \u7684\u4EBA\uFF1A${refs.atTargets.map((t) => `${t.name || t.id}\uFF08id=${t.id}\uFF09`).join("\u3001")}\uFF0C\u8FD8\u6CA1\u53D6\u5230\u5934\u50CF\uFF0C\u9700\u8981\u5C31\u7528 get_avatar \u586B\u4ED6\u7684 id \u518D\u8BD5`);
1966
+ }
1967
+ const others = [...(avatarAllowed || /* @__PURE__ */ new Map()).entries()].filter(([id]) => id !== refs.selfUserId && !refs.atTargets.some((t) => t.id === id));
1968
+ if (others.length) {
1969
+ avatarLines.push(`- \u540E\u7EED\u5BF9\u8BDD\u91CC\u53C8 @ \u5230\u7684\uFF1A${others.map(([id, name2]) => `${name2}\uFF08id=${id}\uFF09`).join("\u3001")}`);
1970
+ }
1971
+ if (refs.atTargets.length || others.length) {
1972
+ avatarLines.push("- \u4E0A\u9762\u8FD9\u4E9B\u4EBA\u4E4B\u5916\u7684 id **\u4E00\u5F8B\u4F1A\u88AB\u62D2\u7EDD**\uFF0C\u4E0D\u8981\u4ECE\u56FE\u5E93\u63CF\u8FF0\u3001\u5386\u53F2\u6D88\u606F\u6216\u4EFB\u4F55\u522B\u5904\u6284\u4E00\u4E2A id \u5F53\u5934\u50CF\u7528");
1973
+ } else {
1974
+ avatarLines.push("- \u8FD9\u6B21\u6CA1\u6709 @ \u4EFB\u4F55\u4EBA\uFF0C\u6240\u4EE5**\u53EA\u80FD\u53D6\u53D1\u6307\u4EE4\u8005\u81EA\u5DF1\u7684\u5934\u50CF**\uFF08userId \u7559\u7A7A\uFF09\u3002\u4E0D\u8981\u586B\u4EFB\u4F55 id");
1975
+ }
1976
+ return instructions + lines.join("\n") + avatarLines.join("\n");
1725
1977
  }
1726
1978
  async function requestAgentChat(messages, tools) {
1727
1979
  const agentCfg = config.agent || {};
@@ -1870,6 +2122,19 @@ ${echo}` : echo);
1870
2122
  promptText = mode === "rewrite" && await optimizePromptText("", text) || text;
1871
2123
  }
1872
2124
  const images = [...defaultImageUrls || [], ...extractImagesFromSession(session)];
2125
+ const avatarCfg = config.avatar || {};
2126
+ if (avatarCfg.enabled !== false) {
2127
+ if (avatarCfg.autoAt !== false) {
2128
+ for (const target of collectAtTargets(session)) {
2129
+ const url = await fetchAvatarUrl(session, target.id);
2130
+ if (url) images.push(url);
2131
+ }
2132
+ }
2133
+ if (avatarCfg.autoSelf && !images.length) {
2134
+ const url = await fetchAvatarUrl(session, session.userId);
2135
+ if (url) images.push(url);
2136
+ }
2137
+ }
1873
2138
  const remaining = Math.max(0, maxImages - images.length);
1874
2139
  if (remaining > 0) {
1875
2140
  const [msgId] = await session.send(
@@ -2288,6 +2553,33 @@ ${lines.join("\n")}`]);
2288
2553
  if (!content) return "";
2289
2554
  return import_koishi.h.select(content, "text").map((el) => el.attrs.content || "").join(" ").trim();
2290
2555
  }
2556
+ function collectAtTargets(session) {
2557
+ const raw = String(session?.content || session.stripped?.content || "");
2558
+ return extractAtIds(raw, session.selfId);
2559
+ }
2560
+ async function fetchAvatarUrl(session, userId) {
2561
+ if (!userId) return "";
2562
+ const cfg = config.avatar || {};
2563
+ const own = userId === session.userId;
2564
+ const url = buildAvatarUrl({
2565
+ userId,
2566
+ platform: session.platform,
2567
+ selfId: session.selfId,
2568
+ appId: session?.bot?.config?.id,
2569
+ authorAvatar: own ? String(session?.author?.avatar || "") : "",
2570
+ template: cfg.urlTemplate,
2571
+ size: Number(cfg.size) > 0 ? Number(cfg.size) : 640
2572
+ });
2573
+ if (url) return url;
2574
+ try {
2575
+ const member = session.guildId ? await session.bot?.getGuildMember?.(session.guildId, userId) : null;
2576
+ const got = member?.avatar || member?.user?.avatar;
2577
+ if (got) return String(got);
2578
+ } catch (error) {
2579
+ logInfo2(`\u5411\u9002\u914D\u5668\u7D22\u53D6\u5934\u50CF\u5931\u8D25: ${error}`);
2580
+ }
2581
+ return "";
2582
+ }
2291
2583
  function extractImagesFromSession(session) {
2292
2584
  const images = [];
2293
2585
  const currentImages = extractImagesFromMessage(session.stripped.content);
@@ -2453,12 +2745,14 @@ ${lines.join("\n")}`]);
2453
2745
  Config,
2454
2746
  apply,
2455
2747
  buildAgentTools,
2748
+ buildAvatarUrl,
2456
2749
  buildMarkdownImage,
2457
2750
  buildPromptBlock,
2458
2751
  buildPromptEcho,
2459
2752
  cleanAskMessage,
2460
2753
  computeRetryDelay,
2461
2754
  describeSelectorError,
2755
+ extractAtIds,
2462
2756
  extractJsonObject,
2463
2757
  extractResponseText,
2464
2758
  extractServerMessage,
@@ -2470,6 +2764,7 @@ ${lines.join("\n")}`]);
2470
2764
  mergePrompt,
2471
2765
  name,
2472
2766
  parseJsonToolCall,
2767
+ parsePolishIntent,
2473
2768
  parseRetryAfterHeader,
2474
2769
  pickAgentMessage,
2475
2770
  previewJson,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-image-prompt",
3
3
  "description": "多功能 AI 图像处理插件:Agent 模式把「查不查图库 / 要不要追问 / 什么时候开画」全交给模型自己决定,支持手办化、Coser 化、Minecraft 化等 47 种风格与自定义提示词",
4
- "version": "2.0.4",
4
+ "version": "2.1.1",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [