koishi-plugin-image-prompt 2.0.3 → 2.0.4

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
@@ -2,14 +2,13 @@ import { Context, Schema } from 'koishi';
2
2
  export declare const name = "image-prompt";
3
3
  /**
4
4
  * 依赖声明:http / logger / i18n 是必需的;
5
- * puppeteer 是**可选**的——只有开启「文字渲染参考图」时才需要浏览器服务,
6
- * 没装也能正常绘图(Koishi 会在它可用时把它注入进来,并等它就绪后再启动本插件)。
5
+ * assets 是**可选**的(结果图先上传再发,外链在手机端 QQ 常常拉不到)。
7
6
  */
8
7
  export declare const inject: {
9
8
  required: string[];
10
9
  optional: string[];
11
10
  };
12
- export declare const usage = "\n---\n\n\u6B64\u63D2\u4EF6\u76F4\u63A5\u8C03\u7528 OpenAI \u517C\u5BB9\u7684 Chat Completions \u63A5\u53E3\u751F\u6210\u56FE\u7247\n\n\u8BF7\u5728\u63D2\u4EF6\u8BBE\u7F6E\u4E2D\u586B\u5199\uFF1A\n\n- API \u670D\u52A1\u5668\u5730\u5740\uFF08baseUrl\uFF09\n- \u4F7F\u7528\u7684\u6A21\u578B\uFF08model\uFF09\n- API \u5BC6\u94A5\uFF08apiKey\uFF09\n\n\u3010Agent \u6A21\u5F0F\uFF08\u9ED8\u8BA4\uFF0C\u63A8\u8350\uFF09\u3011\n\n\u6307\u4EE4\u4E00\u89E6\u53D1\uFF0C\u63D2\u4EF6\u5C31\u628A\u300C\u7528\u6237\u8BF4\u4E86\u4EC0\u4E48 + \u6307\u4EE4\u63D0\u793A\u8BCD + \u53EF\u7528\u7684\u53C2\u8003\u56FE\u300D\u5168\u90E8\u4EA4\u7ED9**\u5BF9\u8BDD\u6A21\u578B**\uFF0C\n\u7531\u6A21\u578B\u81EA\u5DF1\u51B3\u5B9A\u4E0B\u4E00\u6B65 \u2014\u2014 \u8DDF NeoBot \u4E00\u4E2A\u5957\u8DEF\uFF1A\n\n- **gallery_search**\uFF1A\u6A21\u578B\u81EA\u5DF1\u6309\u5173\u952E\u8BCD\u641C\u53C2\u8003\u56FE\u5E93\uFF08\u5173\u952E\u8BCD\u7531\u5B83\u81EA\u5DF1\u62DF\uFF0C\u4E0D\u7528\u4F60\u5728\u914D\u7F6E\u91CC\u5199\u89C4\u5219\uFF09\n- **ask_user**\uFF1A\u95EE\u9898\u4E0D\u6E05\u695A\u3001\u7F3A\u53C2\u8003\u56FE\u3001\u5F00\u753B\u524D\u8981\u786E\u8BA4\uFF0C\u6A21\u578B\u81EA\u5DF1\u5F00\u53E3\u95EE\uFF0C\u5E76\u7B49\u7528\u6237\u56DE\u8BDD\n- **draw**\uFF1A\u628A prompt \u548C\u5B83\u6311\u4E2D\u7684\u53C2\u8003\u56FE\u7F16\u53F7\u4EA4\u51FA\u53BB\uFF0C\u771F\u6B63\u5F00\u59CB\u753B\n\n\u4E5F\u5C31\u662F\u8BF4\uFF1A**\u53C2\u8003\u56FE\u9009\u8C01\u3001\u8981\u4E0D\u8981\u8FFD\u95EE\u3001\u4EC0\u4E48\u65F6\u5019\u5F00\u753B\uFF0C\u5168\u90E8\u662F\u6A21\u578B\u81EA\u5DF1\u51B3\u5B9A\u7684**\uFF0C\n\u63D2\u4EF6\u4E0D\u518D\u5199\u6B7B\u300C\u6253\u5206 \u2192 \u9608\u503C \u2192 \u4E0D\u591F\u5C31\u95EE\u7528\u6237\u300D\u8FD9\u5957\u6D41\u7A0B\u3002\n\u6A21\u578B\u60F3\u641C\u51E0\u6B21\u56FE\u5E93\u3001\u60F3\u548C\u7528\u6237\u6765\u56DE\u51E0\u8F6E\u90FD\u884C\uFF0C\u76F4\u5230\u5B83\u8BA4\u4E3A\u53EF\u4EE5\u753B\u4E86\u3002\n\n\u8981\u6C42\uFF1A\u586B\u5199\u7684\u5BF9\u8BDD\u6A21\u578B\u5FC5\u987B**\u652F\u6301 function calling\uFF08\u5DE5\u5177\u8C03\u7528\uFF09**\u3002\n\u4E0D\u652F\u6301\u4E5F\u6CA1\u5173\u7CFB \u2014\u2014 \u63D2\u4EF6\u5185\u7F6E\u4E86\u300C\u53EA\u7528\u4E00\u884C JSON \u8C03\u7528\u5DE5\u5177\u300D\u7684\u515C\u5E95\u534F\u8BAE\uFF0C\u6A21\u578B\u7167\u6837\u80FD\u8DD1\u6D41\u7A0B\u3002\n\n\u76F8\u5173\u5F00\u5173\uFF1A\n- \u300C\u542F\u7528 Agent \u6A21\u5F0F\u300D\u9ED8\u8BA4\u5F00\u3002\u5173\u6389\u5C31\u9000\u5316\u6210\u300C\u6307\u4EE4\u63D0\u793A\u8BCD + \u7528\u6237\u9644\u52A0\u9700\u6C42\u76F4\u63A5\u753B\u300D\uFF0C\u4E0D\u67E5\u56FE\u5E93\u4E5F\u4E0D\u8FFD\u95EE\u3002\n- \u300C\u5F00\u753B\u524D\u5148\u95EE\u4E00\u53E5\u300D\u9ED8\u8BA4\u5F00\uFF1A\u6A21\u578B\u753B\u4E4B\u524D\u4F1A\u5148\u7528 ask_user \u628A\u300C\u672C\u6B21\u53C2\u8003\u54EA\u51E0\u5F20\u56FE + \u5927\u81F4\u753B\u9762\u300D\u544A\u8BC9\u4F60\uFF0C\u4F60\u70B9\u5934\u5B83\u624D\u753B\u3002\n- \u300C\u6700\u591A\u53C2\u8003\u56FE\u6570\u91CF\u300D\u300C\u5355\u6B21\u641C\u7D22\u8FD4\u56DE\u6761\u6570\u300D\u300C\u8BE2\u95EE\u7B49\u5F85\u65F6\u95F4\u300D\u300C\u6700\u591A\u6765\u56DE\u8F6E\u6570\u300D\u90FD\u5728 agent \u914D\u7F6E\u91CC\u8C03\u3002\n\n\u3010\u53C2\u8003\u56FE\u7247\u7EC4 / \u56FE\u5E93\u3011\n\n1. \u5728\u300C\u53C2\u8003\u56FE\u7247\u7EC4\u300D\u91CC\u6CE8\u518C\u5206\u7EC4\uFF1A\u6BCF\u7EC4\u586B\u300C\u56FE\u7247\u94FE\u63A5 + \u63CF\u8FF0\u300D\u3002**\u63CF\u8FF0\u8981\u5199\u5177\u4F53**\uFF08\u53D1\u8272\u53D1\u578B\u3001\u670D\u88C5\u3001\u52A8\u4F5C\u3001\u753B\u98CE\uFF09\uFF0C\n \u6A21\u578B\u5C31\u662F\u9760\u8FD9\u53E5\u63CF\u8FF0\u641C\u5230\u5B83\u7684\u3002\n2. \u5728\u6307\u4EE4\u914D\u7F6E\u7684\u300C\u5F15\u7528\u7684\u53C2\u8003\u56FE\u7247\u7EC4\u540D\u79F0\u300D\u91CC\u586B\u7EC4\u540D\uFF08\u53EF\u591A\u4E2A\uFF09\uFF1B\u6A21\u578B\u53EA\u4F1A\u5728\u8FD9\u4E2A\u8303\u56F4\u5185\u641C\u3002\n \u7559\u7A7A\u4E14\u5F00\u542F\u300C\u5141\u8BB8\u641C\u7D22\u5168\u90E8\u7EC4\u300D\u65F6\uFF0C\u6240\u6709\u7EC4\u90FD\u80FD\u641C\u5230\u3002\n3. \u300C\u751F\u6210\u63CF\u8FF0\u300D\u6307\u4EE4\u53EF\u4EE5\u8BA9\u6A21\u578B\u770B\u56FE\u81EA\u52A8\u5199\u63CF\u8FF0\u5E76\u5199\u56DE\u914D\u7F6E\uFF08\u9700\u8981\u652F\u6301\u56FE\u7247\u8F93\u5165\u7684\u6A21\u578B\uFF09\u3002\n4. \u751F\u6210\u7ED3\u679C\u53EF\u81EA\u52A8\u5165\u5E93\uFF08\u9ED8\u8BA4\u5173\u95ED\uFF09\uFF0C\u4E0B\u6B21\u80FD\u88AB\u81EA\u5DF1\u641C\u5230\u5E76\u590D\u7528\uFF0C\u5F62\u6210\u95ED\u73AF\u3002\n\n\u3010\u5176\u5B83\u3011\n\n- \u300C\u6536\u5230\u63D0\u793A\u300D\u9ED8\u8BA4\u5F00\uFF1A\u6307\u4EE4\u89E6\u53D1\u7ACB\u523B\u56DE\u4E00\u6761\u300C\u6536\u5230\uFF0C\u6B63\u5728\u51C6\u5907...\u300D\uFF0C\u4E0D\u8BA9\u7528\u6237\u4EE5\u4E3A\u5361\u4F4F\u3002\n- \u300C\u540E\u53F0\u7ED8\u56FE\u300D\u5F00\u542F\u540E\u51FA\u56FE\u4E0D\u963B\u585E\uFF0C\u5148\u56DE\u300C\u6B63\u5728\u753B\u300D\uFF0C\u753B\u597D\u4E3B\u52A8\u63A8\u9001\u3002\n- \u300C\u6587\u5B57\u6E32\u67D3\u53C2\u8003\u56FE\u300D\u628A\u753B\u9762\u4E0A\u7684\u6587\u5B57\uFF08\u53F0\u8BCD/\u62DB\u724C\uFF09\u5148\u6E32\u67D3\u6210\u56FE\u7247\u4E00\u8D77\u53D1\u7ED9\u7ED8\u56FE\u6A21\u578B\uFF0C\u89E3\u51B3\u4E2D\u6587\u5D29\u5B57\u3002\n- \u56DE\u663E\u63D0\u793A\u8BCD\u3001\u7ED3\u679C\u56FE\u5C3A\u5BF8/\u8D70 assets \u7B49\u90FD\u5728\u300C\u6D88\u606F\u53D1\u9001\u300D\u91CC\u3002\n\nAgent \u6307\u4EE4\u6A21\u677F\u53EF\u7528\u5360\u4F4D\u7B26\uFF1A{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\n\n---\n\u6B64\u9879\u76EE\u6240\u9700\u7684koishi\u670D\u52A1\uFF1A\u5FC5\u9700 'http', 'logger', 'i18n'\uFF1B\u53EF\u9009 'puppeteer'\uFF08\u4EC5\u300C\u6587\u5B57\u6E32\u67D3\u53C2\u8003\u56FE\u300D\u9700\u8981\uFF09\n\n---\n";
11
+ export declare const usage = "\n---\n\n\u6B64\u63D2\u4EF6\u76F4\u63A5\u8C03\u7528 OpenAI \u517C\u5BB9\u7684 Chat Completions \u63A5\u53E3\u751F\u6210\u56FE\u7247\n\n\u8BF7\u5728\u63D2\u4EF6\u8BBE\u7F6E\u4E2D\u586B\u5199\uFF1A\n\n- API \u670D\u52A1\u5668\u5730\u5740\uFF08baseUrl\uFF09\n- \u4F7F\u7528\u7684\u6A21\u578B\uFF08model\uFF09\n- API \u5BC6\u94A5\uFF08apiKey\uFF09\n\n\u3010Agent \u6A21\u5F0F\uFF08\u9ED8\u8BA4\uFF0C\u63A8\u8350\uFF09\u3011\n\n\u6307\u4EE4\u4E00\u89E6\u53D1\uFF0C\u63D2\u4EF6\u5C31\u628A\u300C\u7528\u6237\u8BF4\u4E86\u4EC0\u4E48 + \u6307\u4EE4\u63D0\u793A\u8BCD + \u53EF\u7528\u7684\u53C2\u8003\u56FE\u300D\u5168\u90E8\u4EA4\u7ED9**\u5BF9\u8BDD\u6A21\u578B**\uFF0C\n\u7531\u6A21\u578B\u81EA\u5DF1\u51B3\u5B9A\u4E0B\u4E00\u6B65 \u2014\u2014 \u8DDF NeoBot \u4E00\u4E2A\u5957\u8DEF\uFF1A\n\n- **gallery_search**\uFF1A\u6A21\u578B\u81EA\u5DF1\u6309\u5173\u952E\u8BCD\u641C\u53C2\u8003\u56FE\u5E93\uFF08\u5173\u952E\u8BCD\u7531\u5B83\u81EA\u5DF1\u62DF\uFF0C\u4E0D\u7528\u4F60\u5728\u914D\u7F6E\u91CC\u5199\u89C4\u5219\uFF09\n- **ask_user**\uFF1A\u95EE\u9898\u4E0D\u6E05\u695A\u3001\u7F3A\u53C2\u8003\u56FE\u3001\u5F00\u753B\u524D\u8981\u786E\u8BA4\uFF0C\u6A21\u578B\u81EA\u5DF1\u5F00\u53E3\u95EE\uFF0C\u5E76\u7B49\u7528\u6237\u56DE\u8BDD\n- **draw**\uFF1A\u628A prompt \u548C\u5B83\u6311\u4E2D\u7684\u53C2\u8003\u56FE\u7F16\u53F7\u4EA4\u51FA\u53BB\uFF0C\u771F\u6B63\u5F00\u59CB\u753B\n\n\u4E5F\u5C31\u662F\u8BF4\uFF1A**\u53C2\u8003\u56FE\u9009\u8C01\u3001\u8981\u4E0D\u8981\u8FFD\u95EE\u3001\u4EC0\u4E48\u65F6\u5019\u5F00\u753B\uFF0C\u5168\u90E8\u662F\u6A21\u578B\u81EA\u5DF1\u51B3\u5B9A\u7684**\uFF0C\n\u63D2\u4EF6\u4E0D\u518D\u5199\u6B7B\u300C\u6253\u5206 \u2192 \u9608\u503C \u2192 \u4E0D\u591F\u5C31\u95EE\u7528\u6237\u300D\u8FD9\u5957\u6D41\u7A0B\u3002\n\u6A21\u578B\u60F3\u641C\u51E0\u6B21\u56FE\u5E93\u3001\u60F3\u548C\u7528\u6237\u6765\u56DE\u51E0\u8F6E\u90FD\u884C\uFF0C\u76F4\u5230\u5B83\u8BA4\u4E3A\u53EF\u4EE5\u753B\u4E86\u3002\n\n\u8981\u6C42\uFF1A\u586B\u5199\u7684\u5BF9\u8BDD\u6A21\u578B\u5FC5\u987B**\u652F\u6301 function calling\uFF08\u5DE5\u5177\u8C03\u7528\uFF09**\u3002\n\u4E0D\u652F\u6301\u4E5F\u6CA1\u5173\u7CFB \u2014\u2014 \u63D2\u4EF6\u5185\u7F6E\u4E86\u300C\u53EA\u7528\u4E00\u884C JSON \u8C03\u7528\u5DE5\u5177\u300D\u7684\u515C\u5E95\u534F\u8BAE\uFF0C\u6A21\u578B\u7167\u6837\u80FD\u8DD1\u6D41\u7A0B\u3002\n\n\u76F8\u5173\u5F00\u5173\uFF1A\n- \u300C\u542F\u7528 Agent \u6A21\u5F0F\u300D\u9ED8\u8BA4\u5F00\u3002\u5173\u6389\u5C31\u9000\u5316\u6210\u300C\u6307\u4EE4\u63D0\u793A\u8BCD + \u7528\u6237\u9644\u52A0\u9700\u6C42\u76F4\u63A5\u753B\u300D\uFF0C\u4E0D\u67E5\u56FE\u5E93\u4E5F\u4E0D\u8FFD\u95EE\u3002\n- \u300C\u5F00\u753B\u524D\u5148\u95EE\u4E00\u53E5\u300D\u9ED8\u8BA4\u5F00\uFF1A\u6A21\u578B\u753B\u4E4B\u524D\u4F1A\u5148\u7528 ask_user \u628A\u300C\u672C\u6B21\u53C2\u8003\u54EA\u51E0\u5F20\u56FE + \u5927\u81F4\u753B\u9762\u300D\u544A\u8BC9\u4F60\uFF0C\u4F60\u70B9\u5934\u5B83\u624D\u753B\u3002\n- \u300C\u6700\u591A\u53C2\u8003\u56FE\u6570\u91CF\u300D\u300C\u5355\u6B21\u641C\u7D22\u8FD4\u56DE\u6761\u6570\u300D\u300C\u8BE2\u95EE\u7B49\u5F85\u65F6\u95F4\u300D\u300C\u6700\u591A\u6765\u56DE\u8F6E\u6570\u300D\u90FD\u5728 agent \u914D\u7F6E\u91CC\u8C03\u3002\n\n\u3010\u53C2\u8003\u56FE\u7247\u7EC4 / \u56FE\u5E93\u3011\n\n1. \u5728\u300C\u53C2\u8003\u56FE\u7247\u7EC4\u300D\u91CC\u6CE8\u518C\u5206\u7EC4\uFF1A\u6BCF\u7EC4\u586B\u300C\u56FE\u7247\u94FE\u63A5 + \u63CF\u8FF0\u300D\u3002**\u63CF\u8FF0\u8981\u5199\u5177\u4F53**\uFF08\u53D1\u8272\u53D1\u578B\u3001\u670D\u88C5\u3001\u52A8\u4F5C\u3001\u753B\u98CE\uFF09\uFF0C\n \u6A21\u578B\u5C31\u662F\u9760\u8FD9\u53E5\u63CF\u8FF0\u641C\u5230\u5B83\u7684\u3002\n2. \u5728\u6307\u4EE4\u914D\u7F6E\u7684\u300C\u5F15\u7528\u7684\u53C2\u8003\u56FE\u7247\u7EC4\u540D\u79F0\u300D\u91CC\u586B\u7EC4\u540D\uFF08\u53EF\u591A\u4E2A\uFF09\uFF1B\u6A21\u578B\u53EA\u4F1A\u5728\u8FD9\u4E2A\u8303\u56F4\u5185\u641C\u3002\n \u7559\u7A7A\u4E14\u5F00\u542F\u300C\u5141\u8BB8\u641C\u7D22\u5168\u90E8\u7EC4\u300D\u65F6\uFF0C\u6240\u6709\u7EC4\u90FD\u80FD\u641C\u5230\u3002\n3. \u300C\u751F\u6210\u63CF\u8FF0\u300D\u6307\u4EE4\u53EF\u4EE5\u8BA9\u6A21\u578B\u770B\u56FE\u81EA\u52A8\u5199\u63CF\u8FF0\u5E76\u5199\u56DE\u914D\u7F6E\uFF08\u9700\u8981\u652F\u6301\u56FE\u7247\u8F93\u5165\u7684\u6A21\u578B\uFF09\u3002\n4. \u751F\u6210\u7ED3\u679C\u53EF\u81EA\u52A8\u5165\u5E93\uFF08\u9ED8\u8BA4\u5173\u95ED\uFF09\uFF0C\u4E0B\u6B21\u80FD\u88AB\u81EA\u5DF1\u641C\u5230\u5E76\u590D\u7528\uFF0C\u5F62\u6210\u95ED\u73AF\u3002\n\n\u3010\u5176\u5B83\u3011\n\n- \u300C\u6536\u5230\u63D0\u793A\u300D\u9ED8\u8BA4\u5F00\uFF1A\u6307\u4EE4\u89E6\u53D1\u7ACB\u523B\u56DE\u4E00\u6761\u300C\u6536\u5230\uFF0C\u6B63\u5728\u51C6\u5907...\u300D\uFF0C\u4E0D\u8BA9\u7528\u6237\u4EE5\u4E3A\u5361\u4F4F\u3002\n- \u300C\u540E\u53F0\u7ED8\u56FE\u300D\u5F00\u542F\u540E\u51FA\u56FE\u4E0D\u963B\u585E\uFF0C\u5148\u56DE\u300C\u6B63\u5728\u753B\u300D\uFF0C\u753B\u597D\u4E3B\u52A8\u63A8\u9001\u3002\n- \u56DE\u663E\u63D0\u793A\u8BCD\u3001\u7ED3\u679C\u56FE\u5C3A\u5BF8/\u8D70 assets \u7B49\u90FD\u5728\u300C\u6D88\u606F\u53D1\u9001\u300D\u91CC\u3002\n\nAgent \u6307\u4EE4\u6A21\u677F\u53EF\u7528\u5360\u4F4D\u7B26\uFF1A{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\n\n---\n\u6B64\u9879\u76EE\u6240\u9700\u7684koishi\u670D\u52A1\uFF1A\u5FC5\u9700 'http', 'logger', 'i18n'\uFF1B\u53EF\u9009 'assets'\uFF08\u7ED3\u679C\u56FE\u4E0A\u4F20\uFF09\n\n---\n";
13
12
  /**
14
13
  * 计算重试等待时间(毫秒):限流类错误优先用 Retry-After,否则指数退避
15
14
  * @param status HTTP 状态码
@@ -181,18 +180,6 @@ export declare function isPassiveReplyError(error: any): boolean;
181
180
  export declare function resolveTokenParam(model: string, mode?: string): string;
182
181
  /** 用指定参数名重建请求体(避免同时存在两个长度参数被接口拒绝) */
183
182
  export declare function withTokenParam(body: any, param: string): any;
184
- /** HTML 转义,避免渲染时把文字当标签吃掉 */
185
- export declare function escapeHtml(text: string): string;
186
- /** 把要渲染的文字拼成一份 HTML(供无头浏览器截图) */
187
- export declare function buildTextHtml(lines: string[], cfg?: Partial<TextRenderConfig>): string;
188
- /**
189
- * 从提示词/用户输入里提取「需要在画面上真实出现的文字」
190
- * 只提取含中日韩文字的片段——纯英文/数字一般不会因为渲染而崩字
191
- */
192
- export declare function extractTextToRender(text: string, options?: {
193
- loose?: boolean;
194
- maxChars?: number;
195
- }): string[];
196
183
  interface CommandConfig {
197
184
  basename: string;
198
185
  nested: {
@@ -226,7 +213,6 @@ interface CommandConfig {
226
213
  optimizePrompt?: string;
227
214
  resultGallery?: ResultGalleryConfig;
228
215
  backgroundDrawing?: BackgroundDrawingConfig;
229
- textRender?: TextRenderConfig;
230
216
  /** 指令一触发就立刻回一条「收到」,避免用户以为卡住 */
231
217
  ackOnStart?: boolean;
232
218
  /** 结果图用 markdown 的 ![](url) 单独发一条(支持的平台) */
@@ -241,35 +227,6 @@ interface CommandConfig {
241
227
  imageWidth?: number;
242
228
  imageHeight?: number;
243
229
  }
244
- /** 文字渲染参考图配置(把要在画面上出现的文字先渲染成图片,避免中文崩字) */
245
- interface TextRenderConfig {
246
- enabled: boolean;
247
- /** 自动从提示词里识别需要出现在画面上的文字并渲染 */
248
- autoDetect: boolean;
249
- /** 引号内没有其它线索时,也允许直接提取中文片段 */
250
- loose: boolean;
251
- /** 手动渲染指令名 */
252
- commandName: string;
253
- /** 手动渲染后,多少秒内的绘图指令自动带上它 */
254
- pendingTTL: number;
255
- /** 渲染后先把参考图发出来给用户看 */
256
- sendPreview: boolean;
257
- /** 渲染结果并入绘图参考图 */
258
- attachToDraw: boolean;
259
- width: number;
260
- fontSize: number;
261
- lineHeight: number;
262
- padding: number;
263
- background: string;
264
- color: string;
265
- fontFamily: string;
266
- align: 'center' | 'left';
267
- bold: boolean;
268
- strokeWidth: number;
269
- strokeColor: string;
270
- maxChars: number;
271
- scale: number;
272
- }
273
230
  /** 生成结果入库(图库)配置 */
274
231
  interface ResultGalleryConfig {
275
232
  enabled: boolean;
package/lib/index.js CHANGED
@@ -36,15 +36,12 @@ __export(src_exports, {
36
36
  buildMarkdownImage: () => buildMarkdownImage,
37
37
  buildPromptBlock: () => buildPromptBlock,
38
38
  buildPromptEcho: () => buildPromptEcho,
39
- buildTextHtml: () => buildTextHtml,
40
39
  cleanAskMessage: () => cleanAskMessage,
41
40
  computeRetryDelay: () => computeRetryDelay,
42
41
  describeSelectorError: () => describeSelectorError,
43
- escapeHtml: () => escapeHtml,
44
42
  extractJsonObject: () => extractJsonObject,
45
43
  extractResponseText: () => extractResponseText,
46
44
  extractServerMessage: () => extractServerMessage,
47
- extractTextToRender: () => extractTextToRender,
48
45
  fitImageSize: () => fitImageSize,
49
46
  httpErrorText: () => httpErrorText,
50
47
  inject: () => inject,
@@ -77,7 +74,7 @@ var nodePath = __toESM(require("node:path"));
77
74
  var name = "image-prompt";
78
75
  var inject = {
79
76
  required: ["http", "logger", "i18n"],
80
- optional: ["puppeteer", "assets"]
77
+ optional: ["assets"]
81
78
  };
82
79
  var usage = `
83
80
  ---
@@ -124,13 +121,12 @@ var usage = `
124
121
 
125
122
  - \u300C\u6536\u5230\u63D0\u793A\u300D\u9ED8\u8BA4\u5F00\uFF1A\u6307\u4EE4\u89E6\u53D1\u7ACB\u523B\u56DE\u4E00\u6761\u300C\u6536\u5230\uFF0C\u6B63\u5728\u51C6\u5907...\u300D\uFF0C\u4E0D\u8BA9\u7528\u6237\u4EE5\u4E3A\u5361\u4F4F\u3002
126
123
  - \u300C\u540E\u53F0\u7ED8\u56FE\u300D\u5F00\u542F\u540E\u51FA\u56FE\u4E0D\u963B\u585E\uFF0C\u5148\u56DE\u300C\u6B63\u5728\u753B\u300D\uFF0C\u753B\u597D\u4E3B\u52A8\u63A8\u9001\u3002
127
- - \u300C\u6587\u5B57\u6E32\u67D3\u53C2\u8003\u56FE\u300D\u628A\u753B\u9762\u4E0A\u7684\u6587\u5B57\uFF08\u53F0\u8BCD/\u62DB\u724C\uFF09\u5148\u6E32\u67D3\u6210\u56FE\u7247\u4E00\u8D77\u53D1\u7ED9\u7ED8\u56FE\u6A21\u578B\uFF0C\u89E3\u51B3\u4E2D\u6587\u5D29\u5B57\u3002
128
124
  - \u56DE\u663E\u63D0\u793A\u8BCD\u3001\u7ED3\u679C\u56FE\u5C3A\u5BF8/\u8D70 assets \u7B49\u90FD\u5728\u300C\u6D88\u606F\u53D1\u9001\u300D\u91CC\u3002
129
125
 
130
126
  Agent \u6307\u4EE4\u6A21\u677F\u53EF\u7528\u5360\u4F4D\u7B26\uFF1A{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
131
127
 
132
128
  ---
133
- \u6B64\u9879\u76EE\u6240\u9700\u7684koishi\u670D\u52A1\uFF1A\u5FC5\u9700 'http', 'logger', 'i18n'\uFF1B\u53EF\u9009 'puppeteer'\uFF08\u4EC5\u300C\u6587\u5B57\u6E32\u67D3\u53C2\u8003\u56FE\u300D\u9700\u8981\uFF09
129
+ \u6B64\u9879\u76EE\u6240\u9700\u7684koishi\u670D\u52A1\uFF1A\u5FC5\u9700 'http', 'logger', 'i18n'\uFF1B\u53EF\u9009 'assets'\uFF08\u7ED3\u679C\u56FE\u4E0A\u4F20\uFF09
134
130
 
135
131
  ---
136
132
  `;
@@ -696,66 +692,6 @@ function withTokenParam(body, param) {
696
692
  if (value !== void 0) next[param] = value;
697
693
  return next;
698
694
  }
699
- function escapeHtml(text) {
700
- return String(text).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
701
- }
702
- function buildTextHtml(lines, cfg = {}) {
703
- const width = cfg.width || 1024;
704
- const fontSize = cfg.fontSize || 96;
705
- const lineHeight = cfg.lineHeight || 1.4;
706
- const padding = cfg.padding || 48;
707
- const background = cfg.background || "#ffffff";
708
- const color = cfg.color || "#111111";
709
- const fontFamily = cfg.fontFamily || "Microsoft YaHei, PingFang SC, Noto Sans CJK SC, sans-serif";
710
- const align = cfg.align === "left" ? "left" : "center";
711
- const weight = cfg.bold ? "700" : "400";
712
- const strokeWidth = cfg.strokeWidth || 0;
713
- const strokeColor = cfg.strokeColor || "#ffffff";
714
- const stroke = strokeWidth > 0 ? `-webkit-text-stroke: ${strokeWidth}px ${strokeColor}; paint-order: stroke fill;` : "";
715
- const body = lines.map((line) => `<div class="line">${escapeHtml(line)}</div>`).join("");
716
- return `<!DOCTYPE html><html><head><meta charset="utf-8"><style>
717
- * { margin: 0; padding: 0; box-sizing: border-box; }
718
- html, body { background: ${background}; }
719
- #stage { display: inline-block; min-width: ${width}px; padding: ${padding}px; }
720
- .line { font-family: ${fontFamily}; font-size: ${fontSize}px; line-height: ${lineHeight};
721
- color: ${color}; font-weight: ${weight}; text-align: ${align};
722
- white-space: pre-wrap; word-break: break-word; ${stroke} }
723
- </style></head><body><div id="stage">${body}</div></body></html>`;
724
- }
725
- var CJK_RE = /[\u3400-\u4dbf\u4e00-\u9fff\u3040-\u30ff\uac00-\ud7af\uf900-\ufaff]/;
726
- function extractTextToRender(text, options = {}) {
727
- const source = String(text || "");
728
- if (!source.trim()) return [];
729
- const maxChars = options.maxChars && options.maxChars > 0 ? options.maxChars : 200;
730
- const results = [];
731
- const push = (raw) => {
732
- const value = String(raw || "").trim().replace(/^[\s"'`「『“《【((\[]+/, "").replace(/[\s"'`」』”》】))\]]+$/, "").replace(/\s+/g, " ");
733
- if (!value) return;
734
- if (value.length > maxChars) return;
735
- if (!CJK_RE.test(value)) return;
736
- if (results.includes(value)) return;
737
- results.push(value);
738
- };
739
- const patterns = [
740
- /「([^」\n]{1,200})」/g,
741
- /『([^』\n]{1,200})』/g,
742
- /“([^”\n]{1,200})”/g,
743
- /《([^》\n]{1,200})》/g,
744
- /【([^】\n]{1,200})】/g,
745
- /"([^"\n]{1,200})"/g,
746
- /'([^'\n]{1,200})'/g,
747
- /(?:台词|字幕|标语|招牌|标题|写着|写着的是|对话)\s*[::]?\s*([^\n。;;!!??]{1,200})/g
748
- ];
749
- for (const pattern of patterns) {
750
- let match;
751
- while (match = pattern.exec(source)) push(match[1]);
752
- }
753
- if (results.length === 0 && options.loose) {
754
- const chunks = source.match(/[\u3400-\u4dbf\u4e00-\u9fff][\u3400-\u4dbf\u4e00-\u9fff\u3001\u3002\uff0c\uff01\uff1f\uff1a\u201c\u201d\s]{3,}/g);
755
- for (const chunk of chunks || []) push(chunk);
756
- }
757
- return results;
758
- }
759
695
  var DEFAULT_OPTIMIZE_PROMPT = `\u4F60\u662F\u7ED8\u56FE\u63D0\u793A\u8BCD\u4F18\u5316\u52A9\u624B\u3002\u4E0B\u9762\u662F\u300C\u7ED8\u56FE\u6307\u4EE4\u7684\u539F\u59CB\u63D0\u793A\u8BCD\u300D\u548C\u300C\u7528\u6237\u672C\u6B21\u7684\u9700\u6C42\u300D\u3002
760
696
 
761
697
  \u8BF7\u8F93\u51FA\u4E00\u4EFD**\u7B80\u77ED**\u7684\u3001\u53EF\u76F4\u63A5\u7528\u4E8E\u7ED8\u56FE\u6A21\u578B\u7684\u63D0\u793A\u8BCD\u3002\u89C4\u5219\uFF1A
@@ -1378,33 +1314,6 @@ var Config = import_koishi.Schema.intersect([
1378
1314
  showPrompt: import_koishi.Schema.boolean().default(true).description("\u53D1\u9001\u4F18\u5316\u540E\u7684\u63D0\u793A\u8BCD\uFF08QQ / QQ \u9891\u9053\u7528\u4EE3\u7801\u5757\u5305\u88F9\uFF0C\u5176\u5B83\u5E73\u53F0\u53D1\u7EAF\u6587\u672C\uFF09"),
1379
1315
  promptMaxLength: import_koishi.Schema.number().default(4e3).min(0).max(2e4).step(100).description("\u56DE\u663E\u63D0\u793A\u8BCD\u7684\u6700\u5927\u5B57\u7B26\u6570\uFF0C\u8D85\u51FA\u90E8\u5206\u622A\u65AD\u5E76\u6807\u6CE8\uFF1B\u8BBE\u4E3A 0 \u8868\u793A\u4E0D\u622A\u65AD\uFF08QQ markdown \u6709\u957F\u5EA6\u4E0A\u9650\uFF0C\u592A\u957F\u53EF\u80FD\u88AB\u62D2\u6536\uFF09")
1380
1316
  }).description("\u63D0\u793A\u8BCD\u8BBE\u7F6E"),
1381
- import_koishi.Schema.object({
1382
- textRender: import_koishi.Schema.object({
1383
- enabled: import_koishi.Schema.boolean().default(false).description("\u5F00\u542F\u300C\u6587\u5B57\u6E32\u67D3\u53C2\u8003\u56FE\u300D\uFF1A\u628A\u8981\u5728\u753B\u9762\u4E0A\u51FA\u73B0\u7684\u6587\u5B57\uFF08\u53F0\u8BCD/\u6807\u9898/\u6807\u8BED\uFF09\u5148\u7528\u6D4F\u89C8\u5668\u6E32\u67D3\u6210\u56FE\u7247\uFF0C\u4E00\u8D77\u53D1\u7ED9\u7ED8\u56FE\u6A21\u578B\uFF0C\u89E3\u51B3\u4E2D\u6587\u5D29\u5B57\u95EE\u9898\uFF08\u9700\u8981\u5B89\u88C5\u5E76\u542F\u7528 koishi-plugin-puppeteer\uFF09"),
1384
- autoDetect: import_koishi.Schema.boolean().default(true).description("\u81EA\u52A8\u8BC6\u522B\u63D0\u793A\u8BCD\u91CC\u9700\u8981\u51FA\u73B0\u5728\u753B\u9762\u4E0A\u7684\u4E2D\u6587\u6587\u5B57\u5E76\u6E32\u67D3\uFF08\u8BC6\u522B\u300C\u300D\u201C\u201D\u300A\u300B\u3010\u3011\u4EE5\u53CA\u300C\u53F0\u8BCD\uFF1A\u300D\u7B49\uFF09"),
1385
- loose: import_koishi.Schema.boolean().default(false).description("\u5BBD\u677E\u6A21\u5F0F\uFF1A\u5F15\u53F7\u90FD\u6CA1\u7528\u4E0A\u65F6\uFF0C\u4E5F\u76F4\u63A5\u63D0\u53D6\u8FDE\u7EED\u7684\u4E2D\u6587\u7247\u6BB5\uFF08\u53EF\u80FD\u8BEF\u5224\uFF09"),
1386
- commandName: import_koishi.Schema.string().default("\u6E32\u67D3\u6587\u5B57").description("\u624B\u52A8\u6E32\u67D3\u6307\u4EE4\u540D\uFF08\u6302\u5728\u4E3B\u6307\u4EE4\u6839\u4E0B\uFF09\uFF0C\u7528\u6CD5\uFF1A\u6E32\u67D3\u6587\u5B57 \u8981\u753B\u7684\u6587\u5B57"),
1387
- pendingTTL: import_koishi.Schema.number().default(600).min(0).max(86400).step(30).description("\u624B\u52A8\u6E32\u67D3\u540E\uFF0C\u591A\u5C11\u79D2\u5185\u7684\u7ED8\u56FE\u6307\u4EE4\u81EA\u52A8\u5E26\u4E0A\u8FD9\u5F20\u53C2\u8003\u56FE\uFF080 \u8868\u793A\u53EA\u5728\u4E0B\u4E00\u6B21\u751F\u6548\u524D\u4E00\u76F4\u6709\u6548\uFF09"),
1388
- sendPreview: import_koishi.Schema.boolean().default(true).description("\u6E32\u67D3\u540E\u5148\u628A\u53C2\u8003\u56FE\u53D1\u51FA\u6765\u7ED9\u4F60\u770B"),
1389
- attachToDraw: import_koishi.Schema.boolean().default(true).description("\u628A\u6E32\u67D3\u7ED3\u679C\u5E76\u5165\u7ED8\u56FE\u53C2\u8003\u56FE\u4E00\u8D77\u53D1\u7ED9\u7ED8\u56FE\u6A21\u578B"),
1390
- width: import_koishi.Schema.number().default(1024).min(256).max(4096).step(64).description("\u753B\u5E03\u6700\u5C0F\u5BBD\u5EA6\uFF08\u50CF\u7D20\uFF09"),
1391
- fontSize: import_koishi.Schema.number().default(96).min(12).max(400).step(4).description("\u5B57\u53F7"),
1392
- lineHeight: import_koishi.Schema.number().default(1.4).min(1).max(3).step(0.1).description("\u884C\u9AD8"),
1393
- padding: import_koishi.Schema.number().default(48).min(0).max(400).step(4).description("\u5185\u8FB9\u8DDD"),
1394
- background: import_koishi.Schema.string().default("#ffffff").description("\u80CC\u666F\u8272\uFF08\u586B transparent \u53EF\u8F93\u51FA\u900F\u660E\u5E95\uFF0C\u9002\u5408\u8D34\u5728\u753B\u9762\u4E0A\u7684\u5B57\u5E55\uFF09"),
1395
- color: import_koishi.Schema.string().default("#111111").description("\u6587\u5B57\u989C\u8272"),
1396
- fontFamily: import_koishi.Schema.string().default("Microsoft YaHei, PingFang SC, Noto Sans CJK SC, sans-serif").description("\u5B57\u4F53\uFF08\u6309\u5148\u540E\u987A\u5E8F\u56DE\u9000\uFF09"),
1397
- align: import_koishi.Schema.union([
1398
- import_koishi.Schema.const("center").description("\u5C45\u4E2D"),
1399
- import_koishi.Schema.const("left").description("\u5DE6\u5BF9\u9F50")
1400
- ]).default("center").description("\u5BF9\u9F50\u65B9\u5F0F"),
1401
- bold: import_koishi.Schema.boolean().default(false).description("\u52A0\u7C97"),
1402
- strokeWidth: import_koishi.Schema.number().default(0).min(0).max(40).step(1).description("\u63CF\u8FB9\u5BBD\u5EA6\uFF080 \u4E0D\u63CF\u8FB9\uFF1B\u5B57\u5E55\u5EFA\u8BAE 6-10\uFF09"),
1403
- strokeColor: import_koishi.Schema.string().default("#ffffff").description("\u63CF\u8FB9\u989C\u8272"),
1404
- maxChars: import_koishi.Schema.number().default(200).min(10).max(2e3).step(10).description("\u5355\u6761\u6587\u5B57\u6700\u5927\u5B57\u7B26\u6570\uFF0C\u8D85\u8FC7\u5219\u4E0D\u6E32\u67D3"),
1405
- scale: import_koishi.Schema.number().default(2).min(1).max(4).step(1).description("\u622A\u56FE\u7F29\u653E\u500D\u6570\uFF08\u8D8A\u5927\u8D8A\u6E05\u6670\uFF0C\u6587\u4EF6\u4E5F\u8D8A\u5927\uFF09")
1406
- }).collapse().description("\u6587\u5B57\u6E32\u67D3\u914D\u7F6E\u9879")
1407
- }).description("\u6587\u5B57\u6E32\u67D3\u53C2\u8003\u56FE\uFF08\u9632\u5D29\u5B57\uFF09"),
1408
1317
  import_koishi.Schema.object({
1409
1318
  ackOnStart: import_koishi.Schema.boolean().default(true).description("\u6307\u4EE4\u4E00\u89E6\u53D1\u5C31\u7ACB\u523B\u56DE\u4E00\u6761\u300C\u6536\u5230\uFF0C\u6B63\u5728\u51C6\u5907...\u300D\u3002\u540E\u9762\u7684\u300C\u4F18\u5316\u63D0\u793A\u8BCD + agent \u601D\u8003\u300D\u662F\u4E24\u8F6E\u6A21\u578B\u8BF7\u6C42\u3001\u53EF\u80FD\u8981\u51E0\u5341\u79D2\uFF0C\u4E0D\u53D1\u8FD9\u6761\u7528\u6237\u4F1A\u4EE5\u4E3A\u673A\u5668\u4EBA\u5361\u4F4F\u4E86"),
1410
1319
  markdownImage: import_koishi.Schema.boolean().default(true).description("\u751F\u6210\u7ED3\u679C\u7528 markdown \u7684 ![](\u56FE\u7247\u94FE\u63A5) \u5355\u72EC\u53D1\u4E00\u6761\uFF1B\u4E0D\u652F\u6301 markdown \u7684\u5E73\u53F0\u81EA\u52A8\u9000\u56DE\u666E\u901A\u56FE\u7247\u6D88\u606F"),
@@ -1564,14 +1473,7 @@ function apply(ctx, config) {
1564
1473
  optimizefailed: "\uFF08\u63D0\u793A\u8BCD\u878D\u5408\u5931\u8D25\uFF0C\u5DF2\u6539\u4E3A\u8FFD\u52A0\u6A21\u5F0F\uFF09",
1565
1474
  bgstart: "\u5DF2\u5F00\u59CB\u540E\u53F0\u7ED8\u56FE\uFF08{0} \u5F20\u56FE\uFF09\uFF0C\u753B\u597D\u540E\u4F1A\u5728\u8FD9\u91CC\u901A\u77E5\u4F60...",
1566
1475
  bgqueue: "\uFF08\u5F53\u524D\u6709 {0} \u4E2A\u4EFB\u52A1\u5728\u6392\u961F\uFF09",
1567
- bgdone: "\u753B\u597D\u4E86\uFF1A",
1568
- textrenderNopp: "\u6587\u5B57\u6E32\u67D3\u9700\u8981\u5B89\u88C5\u5E76\u542F\u7528 koishi-plugin-puppeteer\uFF08\u6D4F\u89C8\u5668\u670D\u52A1\uFF09",
1569
- textrenderEmpty: "\u8BF7\u63D0\u4F9B\u8981\u6E32\u67D3\u7684\u6587\u5B57\uFF0C\u4F8B\u5982\uFF1A{0} \u4F60\u597D\u4E16\u754C",
1570
- textrenderFailed: "\u6587\u5B57\u6E32\u67D3\u5931\u8D25\uFF1A{0}",
1571
- textrenderOk: "\u6587\u5B57\u53C2\u8003\u56FE\u5DF2\u6E32\u67D3\uFF0C{0} \u79D2\u5185\u7684\u7ED8\u56FE\u6307\u4EE4\u4F1A\u81EA\u52A8\u5E26\u4E0A\u5B83",
1572
- textrenderOkForever: "\u6587\u5B57\u53C2\u8003\u56FE\u5DF2\u6E32\u67D3\uFF0C\u4E0B\u6B21\u7ED8\u56FE\u4F1A\u81EA\u52A8\u5E26\u4E0A\u5B83",
1573
- textrenderAttached: "\uFF08\u5DF2\u9644\u4E0A\u6587\u5B57\u53C2\u8003\u56FE\uFF1A{0}\uFF09",
1574
- textrenderPreview: "\u6587\u5B57\u53C2\u8003\u56FE\uFF1A"
1476
+ bgdone: "\u753B\u597D\u4E86\uFF1A"
1575
1477
  }
1576
1478
  }
1577
1479
  });
@@ -1885,20 +1787,7 @@ Negative prompt: ${String(args.negative_prompt).trim()}` : prompt;
1885
1787
  const commandName = cmdConfig.name;
1886
1788
  const requireInput = options.requireInput !== false;
1887
1789
  const files = await downloadFiles(imageUrls);
1888
- let text = promptText;
1889
- if (config.textRender?.enabled) {
1890
- const textRef = await resolveTextReference(session, text, userInputText, "");
1891
- if (textRef) {
1892
- files.push(textRef.file);
1893
- text = `${text}
1894
-
1895
- Text in the image must be rendered exactly as shown in the attached text-reference image; copy the glyphs precisely, never distort or invent characters.`;
1896
- logInfo2("\u5DF2\u9644\u52A0\u6587\u5B57\u6E32\u67D3\u53C2\u8003\u56FE");
1897
- if (config.textRender?.sendPreview !== false) {
1898
- await reply(session, [session.text("image-prompt.messages.textrenderPreview"), import_koishi.h.image(textRef.file.data, "image/png")]);
1899
- }
1900
- }
1901
- }
1790
+ const text = promptText;
1902
1791
  if (files.length === 0 && requireInput) return { ok: false, error: "invalidimage" };
1903
1792
  if (config.showPrompt !== false) {
1904
1793
  const echo = buildPromptBlock(text, config.promptMaxLength || 4e3);
@@ -2081,107 +1970,6 @@ ${echo}` : echo);
2081
1970
  if (source === "both") return [userInput, promptText].filter(Boolean).join(" | ");
2082
1971
  return promptText;
2083
1972
  }
2084
- const pendingTextRefs = /* @__PURE__ */ new Map();
2085
- function textRefKey(session) {
2086
- return `${session.platform}:${session.channelId || session.userId || ""}`;
2087
- }
2088
- function takePendingTextRef(session) {
2089
- const cfg = config.textRender || {};
2090
- const key = textRefKey(session);
2091
- const item = pendingTextRefs.get(key);
2092
- if (!item) return null;
2093
- const ttl = (cfg.pendingTTL || 0) * 1e3;
2094
- if (ttl > 0 && Date.now() - item.time > ttl) {
2095
- pendingTextRefs.delete(key);
2096
- return null;
2097
- }
2098
- pendingTextRefs.delete(key);
2099
- return { file: item.file, text: item.text };
2100
- }
2101
- async function renderTextToImage(text) {
2102
- const cfg = config.textRender || {};
2103
- const lines = String(text || "").split("\n").map((line) => line.trim()).filter(Boolean);
2104
- if (lines.length === 0) return null;
2105
- const puppeteer = ctx.puppeteer;
2106
- if (!puppeteer || typeof puppeteer.page !== "function") {
2107
- ctx.logger.warn("\u6587\u5B57\u6E32\u67D3\u9700\u8981 koishi-plugin-puppeteer\uFF08\u6D4F\u89C8\u5668\u670D\u52A1\uFF09\uFF0C\u5F53\u524D\u4E0D\u53EF\u7528");
2108
- return null;
2109
- }
2110
- const html = buildTextHtml(lines, cfg);
2111
- let page;
2112
- try {
2113
- page = await puppeteer.page();
2114
- await page.setViewport({
2115
- width: cfg.width || 1024,
2116
- height: 400,
2117
- deviceScaleFactor: cfg.scale || 2
2118
- });
2119
- await page.setContent(html, { waitUntil: "load" });
2120
- await page.evaluate(() => document.fonts?.ready).catch(() => {
2121
- });
2122
- const stage = await page.$("#stage");
2123
- const clip = stage ? await stage.boundingBox() : null;
2124
- const transparent = String(cfg.background || "").toLowerCase() === "transparent";
2125
- const buffer = clip ? await page.screenshot({ clip, omitBackground: transparent }) : await page.screenshot({ omitBackground: transparent });
2126
- const data = Buffer.isBuffer(buffer) ? buffer : Buffer.from(buffer);
2127
- logInfo2(`\u6587\u5B57\u6E32\u67D3\u5B8C\u6210: ${lines.length} \u884C, ${data.length} \u5B57\u8282`);
2128
- return { data, mime: "image/png" };
2129
- } catch (error) {
2130
- ctx.logger.warn(`\u6587\u5B57\u6E32\u67D3\u5931\u8D25: ${error}`);
2131
- return null;
2132
- } finally {
2133
- try {
2134
- await page?.close();
2135
- } catch {
2136
- }
2137
- }
2138
- }
2139
- async function resolveTextReference(session, promptText, userInput, modelText) {
2140
- const cfg = config.textRender || {};
2141
- if (!cfg.enabled || cfg.attachToDraw === false) return null;
2142
- const pending = takePendingTextRef(session);
2143
- if (pending) return pending;
2144
- const fromModel = (modelText || "").trim();
2145
- if (fromModel) {
2146
- const file2 = await renderTextToImage(fromModel);
2147
- if (file2) return { file: file2, text: fromModel };
2148
- }
2149
- if (cfg.autoDetect === false) return null;
2150
- const found = [
2151
- ...extractTextToRender(promptText, { loose: cfg.loose, maxChars: cfg.maxChars }),
2152
- ...extractTextToRender(userInput, { loose: cfg.loose, maxChars: cfg.maxChars })
2153
- ];
2154
- const text = Array.from(new Set(found)).join("\n");
2155
- if (!text) return null;
2156
- logInfo2(`\u81EA\u52A8\u8BC6\u522B\u5230\u9700\u8981\u6E32\u67D3\u7684\u6587\u5B57: ${text}`);
2157
- const file = await renderTextToImage(text);
2158
- return file ? { file, text } : null;
2159
- }
2160
- const textCmdName = (config.textRender?.commandName || "\u6E32\u67D3\u6587\u5B57").trim() || "\u6E32\u67D3\u6587\u5B57";
2161
- ctx.command(`${config.basename}/${textCmdName} [...text:text]`).usage("\u628A\u6587\u5B57\u6E32\u67D3\u6210\u56FE\u7247\uFF0C\u4F5C\u4E3A\u7ED8\u56FE\u53C2\u8003\u56FE\uFF08\u89E3\u51B3\u4E2D\u6587\u5D29\u5B57\uFF09").action(async ({ session }, ...args) => {
2162
- if (!isActive || !ctx.scope.isActive) return;
2163
- if (!session) return;
2164
- const quote = import_koishi.h.quote(session.messageId);
2165
- const cfg = config.textRender || {};
2166
- const raw = args.filter(Boolean).join(" ").trim() || stripCommandName(extractTextFromMessage(session.stripped.content), textCmdName).trim();
2167
- if (!raw) return `${quote}${session.text("image-prompt.messages.textrenderEmpty", [textCmdName])}`;
2168
- const puppeteer = ctx.puppeteer;
2169
- if (!puppeteer || typeof puppeteer.page !== "function") {
2170
- return `${quote}${session.text("image-prompt.messages.textrenderNopp")}`;
2171
- }
2172
- const file = await renderTextToImage(raw);
2173
- if (!file) return `${quote}${session.text("image-prompt.messages.textrenderFailed", ["\u6E32\u67D3\u5F02\u5E38"])}`;
2174
- if (cfg.attachToDraw !== false) {
2175
- pendingTextRefs.set(textRefKey(session), { file, text: raw, time: Date.now() });
2176
- }
2177
- const ttl = cfg.pendingTTL || 0;
2178
- const tip = ttl > 0 ? session.text("image-prompt.messages.textrenderOk", [ttl]) : session.text("image-prompt.messages.textrenderOkForever");
2179
- if (cfg.sendPreview !== false) {
2180
- await reply(session, [import_koishi.h.image(file.data, "image/png"), tip]);
2181
- return;
2182
- }
2183
- return `${quote}${tip}`;
2184
- });
2185
1973
  const debugCmdName = (config.aiSelector?.debugCommand || "\u6D4B\u8BD5\u9009\u56FE").trim() || "\u6D4B\u8BD5\u9009\u56FE";
2186
1974
  ctx.command(`${config.basename}/${debugCmdName}`).usage("\u53D1\u4E00\u6B21\u9009\u56FE\u8BF7\u6C42\u5E76\u56DE\u663E\u6A21\u578B\u539F\u59CB\u8FD4\u56DE\uFF0C\u7528\u4E8E\u6392\u67E5\u300C\u54CD\u5E94\u4E2D\u6CA1\u6709\u6587\u672C\u5185\u5BB9\u300D").action(async ({ session }) => {
2187
1975
  if (!isActive || !ctx.scope.isActive) return;
@@ -2668,15 +2456,12 @@ ${lines.join("\n")}`]);
2668
2456
  buildMarkdownImage,
2669
2457
  buildPromptBlock,
2670
2458
  buildPromptEcho,
2671
- buildTextHtml,
2672
2459
  cleanAskMessage,
2673
2460
  computeRetryDelay,
2674
2461
  describeSelectorError,
2675
- escapeHtml,
2676
2462
  extractJsonObject,
2677
2463
  extractResponseText,
2678
2464
  extractServerMessage,
2679
- extractTextToRender,
2680
2465
  fitImageSize,
2681
2466
  httpErrorText,
2682
2467
  inject,
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.3",
4
+ "version": "2.0.4",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [