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 +2 -45
- package/lib/index.js +4 -219
- package/package.json +1 -1
- package/readme.md +502 -544
- package/src/index.ts +3190 -3492
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
|
-
*
|
|
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- \
|
|
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 的  单独发一条(支持的平台) */
|
|
@@ -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: ["
|
|
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 '
|
|
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, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
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  \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
|
-
|
|
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.
|
|
4
|
+
"version": "2.0.4",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"typings": "lib/index.d.ts",
|
|
7
7
|
"files": [
|