koishi-plugin-image-prompt 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.d.ts +87 -2
- package/lib/index.js +435 -31
- package/package.json +1 -1
- package/readme.md +100 -13
- package/src/index.ts +584 -35
package/lib/index.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export declare const inject: {
|
|
|
9
9
|
required: string[];
|
|
10
10
|
optional: string[];
|
|
11
11
|
};
|
|
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\u3010AI \u9009\u62E9\u53C2\u8003\u56FE\u7247\u3011\n\n1. \u5728\u300C\u53C2\u8003\u56FE\u7247\u7EC4\u300D\u4E2D\u6CE8\u518C\u5206\u7EC4\uFF1A\u6BCF\u7EC4\u586B\u5199\u82E5\u5E72\u5F20\u300C\u56FE\u7247\u94FE\u63A5 + \u63CF\u8FF0\u300D\uFF08\u63CF\u8FF0\u7528\u4E8E\u8BA9 AI \u5224\u65AD\u8BE5\u56FE\u7684\u7528\u9014\uFF09\u3002\n2. \u5728\u6307\u4EE4\u914D\u7F6E\u7684\u300C\u5F15\u7528\u7684\u53C2\u8003\u56FE\u7247\u7EC4\u540D\u79F0\u300D\u4E2D\u586B\u5165\u7EC4\u540D\uFF08\u53EF\u586B\u591A\u4E2A\uFF09\uFF0C\u8BE5\u6307\u4EE4\u6267\u884C\u65F6\u4F1A\u628A\u7EC4\u5185\u56FE\u7247\u5168\u90E8\u4EA4\u7ED9 AI \u6311\u9009\u3002\n3. \u300CAI \u9009\u56FE\u8BBE\u7F6E\u300D\u53EF\u4FEE\u6539\u5BF9\u8BDD\u6A21\u578B\uFF08\u9ED8\u8BA4 Qwen/Qwen2.5-7B-Instruct\uFF09\u3001\u9009\u62E9\u63D0\u793A\u8BCD\u6A21\u677F\u3001\u8D85\u65F6\u4E0E\u91CD\u8BD5\u7B49\uFF1B\n \u63A5\u53E3\u5730\u5740/\u5BC6\u94A5\u7559\u7A7A\u65F6\u590D\u7528\u7ED8\u56FE\u63A5\u53E3\u7684\u914D\u7F6E\u3002\n4. \
|
|
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\u3010AI \u9009\u62E9\u53C2\u8003\u56FE\u7247\u3011\n\n1. \u5728\u300C\u53C2\u8003\u56FE\u7247\u7EC4\u300D\u4E2D\u6CE8\u518C\u5206\u7EC4\uFF1A\u6BCF\u7EC4\u586B\u5199\u82E5\u5E72\u5F20\u300C\u56FE\u7247\u94FE\u63A5 + \u63CF\u8FF0\u300D\uFF08\u63CF\u8FF0\u7528\u4E8E\u8BA9 AI \u5224\u65AD\u8BE5\u56FE\u7684\u7528\u9014\uFF09\u3002\n **\u63CF\u8FF0\u4E00\u5B9A\u8981\u5199\u5177\u4F53**\uFF08\u53D1\u8272\u53D1\u578B\u3001\u670D\u88C5\u3001\u52A8\u4F5C\u3001\u753B\u98CE\uFF09\u2014\u2014 \u6253\u5206\u5236\u4E0B\u6CA1\u63CF\u8FF0\u7684\u56FE\u6C38\u8FDC\u9009\u4E0D\u4E0A\u3002\n2. \u5728\u6307\u4EE4\u914D\u7F6E\u7684\u300C\u5F15\u7528\u7684\u53C2\u8003\u56FE\u7247\u7EC4\u540D\u79F0\u300D\u4E2D\u586B\u5165\u7EC4\u540D\uFF08\u53EF\u586B\u591A\u4E2A\uFF09\uFF0C\u8BE5\u6307\u4EE4\u6267\u884C\u65F6\u4F1A\u628A\u7EC4\u5185\u56FE\u7247\u5168\u90E8\u4EA4\u7ED9 AI \u6311\u9009\u3002\n3. \u300CAI \u9009\u56FE\u8BBE\u7F6E\u300D\u53EF\u4FEE\u6539\u5BF9\u8BDD\u6A21\u578B\uFF08\u9ED8\u8BA4 Qwen/Qwen2.5-7B-Instruct\uFF09\u3001\u9009\u62E9\u6A21\u5F0F\u3001\u63D0\u793A\u8BCD\u6A21\u677F\u3001\u8D85\u65F6\u4E0E\u91CD\u8BD5\u7B49\uFF1B\n \u63A5\u53E3\u5730\u5740/\u5BC6\u94A5\u7559\u7A7A\u65F6\u590D\u7528\u7ED8\u56FE\u63A5\u53E3\u7684\u914D\u7F6E\u3002\n4. \u300C\u9009\u56FE\u6A21\u5F0F\u300D\u9ED8\u8BA4\u662F**\u6253\u5206\u5236**\uFF1A\u5148\u53EA\u505A\u9700\u6C42\u5206\u6790\uFF08**\u4E0D\u7ED9\u6A21\u578B\u5019\u9009\u56FE**\uFF0C\u5B83\u6CA1\u6709\u300C\u53EF\u6311\u7684\u5BF9\u8C61\u300D\uFF09\uFF0C\n \u518D\u7528\u5173\u952E\u8BCD\u5728\u672C\u5730\u53EC\u56DE\uFF0C\u7136\u540E\u8981\u6C42\u6A21\u578B\u7ED9\u6BCF\u5F20\u5019\u9009\u56FE\u6253 0-100 \u5206\uFF0C\u4F4E\u4E8E\u300C\u6700\u4F4E\u5206\u6570\u7EBF\u300D\u7684\u4E00\u5F8B\u4E0D\u8981\u3002\n \u4E00\u5F20\u90FD\u4E0D\u8FBE\u6807\u5C31\u5982\u5B9E\u544A\u77E5\u7528\u6237\u300C\u56FE\u5E93\u91CC\u6CA1\u6709\u5408\u9002\u7684\u53C2\u8003\u56FE\u300D\uFF0C**\u4E0D\u4F1A\u786C\u51D1**\uFF1B\n \u82E5\u5F00\u542F\u300C\u7F3A\u5C11\u5408\u9002\u53C2\u8003\u56FE\u65F6\u8BE2\u95EE\u7528\u6237\u8865\u5145\u53D1\u9001\u300D\uFF0C\u4F1A\u8BF7\u7528\u6237\u8865\u53D1\u4E00\u5F20\u53C2\u8003\u56FE\uFF08\u7528\u6237\u53D1\u7684\u56FE\u4F1A\u88AB\u76F4\u63A5\u4F7F\u7528\uFF09\u3002\n \u60F3\u56DE\u5230\u8001\u884C\u4E3A\u5C31\u628A\u300C\u9009\u56FE\u6A21\u5F0F\u300D\u6539\u6210\u300C\u65E7\u7248\u300D\u3002\n5. \u5F53\u7528\u6237\u660E\u786E\u8BF4\u300C\u4E0D\u7528\u53C2\u8003 / \u968F\u610F\u753B / \u81EA\u7531\u53D1\u6325\u300D\u65F6\uFF0C\u76F4\u63A5\u8DF3\u8FC7\u9009\u56FE\uFF0C\u4E00\u6B21\u9009\u56FE\u8BF7\u6C42\u90FD\u4E0D\u53D1\u3002\n6. \u300C\u542F\u7528 AI \u667A\u80FD\u9009\u62E9\u53C2\u8003\u56FE\u7247\u300D\u9ED8\u8BA4\u5173\u95ED\uFF0C\u9700\u624B\u52A8\u5F00\u542F\uFF1B\u300CAI \u9009\u56FE\u5931\u8D25\u65F6\u56DE\u9000\u4E3A\u4F7F\u7528\u5019\u9009\u6C60\u5185\u5168\u90E8\u56FE\u7247\u300D\u9ED8\u8BA4\u5173\u95ED\uFF0C\n \u5931\u8D25\u65F6\u672C\u6B21\u4E0D\u4F7F\u7528\u53C2\u8003\u56FE\u7247\uFF08\u5F00\u542F\u5219\u6539\u7528\u5019\u9009\u6C60\u5185\u5168\u90E8\u56FE\u7247\uFF09\u3002\u6CE8\u610F\u300C\u56DE\u9000\u300D\u53EA\u5BF9**\u8BF7\u6C42\u5931\u8D25**\u751F\u6548\uFF0C\n \u5BF9\u300C\u6253\u5206\u4E0D\u8FBE\u6807\u300D\u4E0D\u751F\u6548 \u2014\u2014 \u540E\u8005\u5C31\u8BE5\u4E0D\u5E26\u53C2\u8003\u56FE\u3002\n7. \u300C\u65E7\u7248\u300D\u6A21\u5F0F\u4E0B\u53C2\u8003\u56FE\u8F83\u591A\u65F6\uFF08\u8D85\u8FC7 12 \u5F20\uFF09\u81EA\u52A8\u8D70\u4E24\u7EA7\u68C0\u7D22\uFF1A\u5148\u8BA9\u6A21\u578B\u4EA7\u51FA\u68C0\u7D22\u5173\u952E\u8BCD\u3001\u672C\u5730\u5339\u914D\u53EC\u56DE\uFF0C\n \u518D\u5BF9\u53EC\u56DE\u7ED3\u679C\u7CBE\u6392\uFF1B\u8BC6\u56FE\u6A21\u5F0F\u4E0B\u4E5F\u53EA\u53D1\u9001\u53EC\u56DE\u7684\u8FD9\u51E0\u5F20\u56FE\u7247\uFF0C\u907F\u514D\u6BCF\u6B21\u90FD\u628A\u6574\u4E2A\u56FE\u5E93\u53D1\u7ED9\u6A21\u578B\u3002\n8. \u63CF\u8FF0\u53EF\u4EE5\u7528\u300C\u751F\u6210\u63CF\u8FF0\u300D\u6307\u4EE4\u8BA9\u6A21\u578B\u770B\u56FE\u81EA\u52A8\u751F\u6210\u5E76\u5199\u56DE\u914D\u7F6E\uFF08\u9700\u8981\u652F\u6301\u56FE\u7247\u8F93\u5165\u7684\u6A21\u578B\uFF09\u3002\n \u82E5\u9009\u56FE\u6A21\u578B\u652F\u6301\u8BC6\u522B\u56FE\u7247\uFF08\u591A\u6A21\u6001\uFF09\uFF0C\u53EF\u52FE\u9009\u300C\u9009\u56FE\u6A21\u578B\u652F\u6301\u8BC6\u522B\u56FE\u7247\u300D\uFF0C\u63D2\u4EF6\u4F1A\u628A\u5019\u9009\u56FE\u7247\u672C\u8EAB\u53D1\u7ED9\u6A21\u578B\uFF0C\n \u6A21\u578B\u5BF9\u7740\u771F\u5B9E\u56FE\u7247\u6311\u9009\uFF1B\u5B83\u7ED9\u51FA\u7684\u5173\u952E\u89C6\u89C9\u7279\u5F81\u8FD8\u4F1A\u5E76\u5165\u7ED8\u56FE\u63D0\u793A\u8BCD\uFF0C\u8BA9\u51FA\u56FE\u66F4\u8FD8\u539F\u53C2\u8003\u56FE\u3002\n9. \u751F\u6210\u7ED3\u679C\u53EF\u81EA\u52A8\u5165\u5E93\uFF08\u9ED8\u8BA4\u5173\u95ED\uFF09\uFF0C\u4E0B\u6B21\u80FD\u88AB\u81EA\u5DF1\u68C0\u7D22\u5230\u5E76\u590D\u7528\uFF0C\u5F62\u6210\u95ED\u73AF\uFF1B\n \u5F00\u542F\u300C\u540E\u53F0\u7ED8\u56FE\u300D\u540E\u51FA\u56FE\u4E0D\u518D\u963B\u585E\uFF0C\u5148\u56DE\u300C\u6B63\u5728\u753B\u300D\uFF0C\u753B\u597D\u4E3B\u52A8\u63A8\u9001\u3002\n\n\u63D0\u793A\u8BCD\u6A21\u677F\u53EF\u7528\u5360\u4F4D\u7B26\uFF1A{candidates} \u5019\u9009\u56FE\u7247\u5217\u8868\u3001{userInput} \u7528\u6237\u9644\u52A0\u9700\u6C42\u3001{max} \u6700\u591A\u9009\u62E9\u6570\u91CF\u3001{command} \u6307\u4EE4\u540D\u3001{prompt} \u6307\u4EE4\u63D0\u793A\u8BCD\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";
|
|
13
13
|
/**
|
|
14
14
|
* 解析模型返回的 JSON 选择结果(纯函数,便于单独测试)
|
|
15
15
|
* @param raw 模型的原始回复
|
|
@@ -33,6 +33,56 @@ export declare function computeRetryDelay(status: any, retryAfter: number | unde
|
|
|
33
33
|
export declare function matchCandidatesByKeywords(candidates: CandidateImage[], keywords: string[], topK: number): CandidateImage[];
|
|
34
34
|
/** 去重合并候选(按 url 判重) */
|
|
35
35
|
export declare function mergeCandidates(...lists: CandidateImage[][]): CandidateImage[];
|
|
36
|
+
/** 选图第一步的产物:先想清楚「要什么」,再去看「有什么」 */
|
|
37
|
+
export interface RequirementAnalysis {
|
|
38
|
+
/** 画面主体(一句话) */
|
|
39
|
+
subject: string;
|
|
40
|
+
/** 硬性要素:缺一个就不该选这张图 */
|
|
41
|
+
must: string[];
|
|
42
|
+
/** 加分要素:有更好,没有也能用 */
|
|
43
|
+
nice: string[];
|
|
44
|
+
/** 明确不要出现的 */
|
|
45
|
+
avoid: string[];
|
|
46
|
+
/** 画面需要出现的文字(台词/标题/招牌),交给浏览器渲染 */
|
|
47
|
+
text: string;
|
|
48
|
+
/** 用户表示「不用参考/随意画」时跳过检索 */
|
|
49
|
+
skipReference: boolean;
|
|
50
|
+
/** 判定需要用户补图时,用一句话说明要什么样的图 */
|
|
51
|
+
needTypes: string;
|
|
52
|
+
}
|
|
53
|
+
/** 单张候选图的打分结果(index 从 1 开始,对应候选列表位置) */
|
|
54
|
+
export interface ScoredCandidate {
|
|
55
|
+
index: number;
|
|
56
|
+
score: number;
|
|
57
|
+
why: string;
|
|
58
|
+
}
|
|
59
|
+
/** 从任意文本里挖出第一个 JSON 对象(容忍代码块围栏和前后废话) */
|
|
60
|
+
export declare function extractJsonObject(raw: string | null | undefined): any | null;
|
|
61
|
+
/** 把模型给的字段统一成字符串数组(支持数组 / 逗号顿号换行分隔的字符串) */
|
|
62
|
+
export declare function toStrList(value: any): string[];
|
|
63
|
+
/** 用户这句话是不是「不用参考了」 */
|
|
64
|
+
export declare function isSkipReferenceInput(userInput: string): boolean;
|
|
65
|
+
/** 解析「需求抽取」的返回 */
|
|
66
|
+
export declare function parseAnalysisResult(raw: string | null): RequirementAnalysis | null;
|
|
67
|
+
/** 把「需求要素」转成本地检索用的关键词 */
|
|
68
|
+
export declare function keywordsFromAnalysis(analysis: RequirementAnalysis | null): string[];
|
|
69
|
+
/** 把分数归一化到 0-100(兼容 0.85 这种小数写法、以及 "85分" 这种字符串) */
|
|
70
|
+
export declare function normalizeScore(value: any): number | null;
|
|
71
|
+
/** 解析「逐图打分」的返回 */
|
|
72
|
+
export declare function parseScoreResult(raw: string | null, candidates: CandidateImage[]): ScoredCandidate[];
|
|
73
|
+
/**
|
|
74
|
+
* 按分数阈值筛选:只有达到 minScore 的才留下,按分数从高到低取前 max 张。
|
|
75
|
+
* 一张都不达标时返回空数组 —— 这是「宁可不选也不乱选」的兜底。
|
|
76
|
+
*/
|
|
77
|
+
export declare function selectByScore(scored: ScoredCandidate[], candidates: CandidateImage[], minScore: number, max: number): {
|
|
78
|
+
picked: CandidateImage[];
|
|
79
|
+
best: number;
|
|
80
|
+
passed: number;
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* 去掉重复图:链接相同的直接去掉;描述完全相同的(同一批入库的近似图)只留第一张。
|
|
84
|
+
*/
|
|
85
|
+
export declare function dedupeCandidates(list: CandidateImage[]): CandidateImage[];
|
|
36
86
|
/**
|
|
37
87
|
* 图库容量裁剪:超出容量时淘汰最旧的(按 time 升序),只保留每个组最近 capacity 条
|
|
38
88
|
*/
|
|
@@ -72,6 +122,25 @@ export declare function buildPromptBlock(promptText: string, maxLength?: number)
|
|
|
72
122
|
* QQ 官方语法是 ``——**必须带尺寸,否则手机端 QQ 不渲染**。
|
|
73
123
|
*/
|
|
74
124
|
export declare function buildMarkdownImage(url: string, width?: number, height?: number): string;
|
|
125
|
+
/**
|
|
126
|
+
* 从图片字节里读真实宽高(只看文件头,不解码整张图)。
|
|
127
|
+
* 支持 PNG / JPEG / GIF / WebP。
|
|
128
|
+
*/
|
|
129
|
+
export declare function readImageSize(input: any): {
|
|
130
|
+
width: number;
|
|
131
|
+
height: number;
|
|
132
|
+
} | null;
|
|
133
|
+
/** 按真实比例算 markdown 显示尺寸(等比缩放到宽度上限) */
|
|
134
|
+
export declare function fitImageSize(size: {
|
|
135
|
+
width: number;
|
|
136
|
+
height: number;
|
|
137
|
+
} | null, maxWidth: number, fallback: {
|
|
138
|
+
width: number;
|
|
139
|
+
height: number;
|
|
140
|
+
}): {
|
|
141
|
+
width: number;
|
|
142
|
+
height: number;
|
|
143
|
+
};
|
|
75
144
|
/**
|
|
76
145
|
* 清洗模型生成的描述:去代码块围栏、去引号、压平换行、去掉「描述:」前缀、限长
|
|
77
146
|
*/
|
|
@@ -179,7 +248,11 @@ interface CommandConfig {
|
|
|
179
248
|
markdownImage?: boolean;
|
|
180
249
|
/** 结果图先经 assets 服务上传再发(外链在手机端 QQ 可能拉不到) */
|
|
181
250
|
imageViaAssets?: boolean;
|
|
182
|
-
/** markdown
|
|
251
|
+
/** 自动按图片真实比例生成 markdown 尺寸(关掉则用下面固定的宽高) */
|
|
252
|
+
autoImageSize?: boolean;
|
|
253
|
+
/** 自动尺寸时的显示宽度上限 */
|
|
254
|
+
imageMaxWidth?: number;
|
|
255
|
+
/** 固定宽/高(QQ 要求带尺寸,否则手机端不渲染) */
|
|
183
256
|
imageWidth?: number;
|
|
184
257
|
imageHeight?: number;
|
|
185
258
|
}
|
|
@@ -291,6 +364,18 @@ interface AISelectorConfig {
|
|
|
291
364
|
maxTokensCeiling?: number;
|
|
292
365
|
/** 诊断指令名:发一次选图请求并回显模型原始返回 */
|
|
293
366
|
debugCommand?: string;
|
|
367
|
+
/** 选图模式:score = 抽需求+逐图打分(默认);legacy = 旧的候选全量丢给模型挑 */
|
|
368
|
+
selectionMode?: 'score' | 'legacy';
|
|
369
|
+
/** 打分制的最低分数线(0-100),低于它的图一律不选 */
|
|
370
|
+
minScore?: number;
|
|
371
|
+
/** 打分制第一步「需求分析」的提示词模板 */
|
|
372
|
+
analyzePrompt?: string;
|
|
373
|
+
/** 打分制第二步「逐图打分」的提示词模板 */
|
|
374
|
+
scorePrompt?: string;
|
|
375
|
+
/** 是否合并描述完全相同的重复参考图(默认开) */
|
|
376
|
+
dedupe?: boolean;
|
|
377
|
+
/** 用户说「不用参考/随意画」时是否跳过选图(默认开) */
|
|
378
|
+
respectSkipReference?: boolean;
|
|
294
379
|
}
|
|
295
380
|
/** 交给 AI 挑选的候选图片 */
|
|
296
381
|
interface CandidateImage {
|