koishi-plugin-aka-comfy-agent 0.2.0 → 0.2.2
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/dist/index.d.mts +16 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +42 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +42 -14
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -11,6 +11,20 @@ interface LlmProviderConfig {
|
|
|
11
11
|
/** 视觉模型请求正文(仅 vision 使用;留空则用默认) */
|
|
12
12
|
userText: string;
|
|
13
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* 程序级锚点 / 背景模板的可配置覆盖(框架化 = 默认留空,回退 prompts.ts 框架默认)。
|
|
16
|
+
* 完整措辞只保留在私有文档,经此处 koishi.yml 配置还原,无需改源码。
|
|
17
|
+
*/
|
|
18
|
+
interface PromptOverrideConfig {
|
|
19
|
+
/** 身份锁定锚点(完整措辞;留空 = 用 prompts.ts 框架默认) */
|
|
20
|
+
identityAnchor: string;
|
|
21
|
+
/** 三点布光光场锚点(完整措辞;留空 = 用 prompts.ts 框架默认) */
|
|
22
|
+
lightfieldAnchor: string;
|
|
23
|
+
/** 背景替换模板,含 {color} 占位(留空 = 用 prompts.ts 框架默认) */
|
|
24
|
+
backgroundClauseTemplate: string;
|
|
25
|
+
/** 背景覆盖模板,含 {desc} 占位(留空 = 用 prompts.ts 框架默认) */
|
|
26
|
+
backgroundOverrideTemplate: string;
|
|
27
|
+
}
|
|
14
28
|
interface Config {
|
|
15
29
|
mainLLM: LlmProviderConfig;
|
|
16
30
|
visionLLM: LlmProviderConfig;
|
|
@@ -20,6 +34,8 @@ interface Config {
|
|
|
20
34
|
};
|
|
21
35
|
/** 背景色兜底:DS 未给或非法时用此值 */
|
|
22
36
|
defaultBackgroundColor: string;
|
|
37
|
+
/** 程序级锚点/背景模板覆盖(框架化;完整措辞经此还原) */
|
|
38
|
+
prompt: PromptOverrideConfig;
|
|
23
39
|
session: {
|
|
24
40
|
maxTurns: number;
|
|
25
41
|
idleTimeoutMs: number;
|
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,20 @@ interface LlmProviderConfig {
|
|
|
11
11
|
/** 视觉模型请求正文(仅 vision 使用;留空则用默认) */
|
|
12
12
|
userText: string;
|
|
13
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* 程序级锚点 / 背景模板的可配置覆盖(框架化 = 默认留空,回退 prompts.ts 框架默认)。
|
|
16
|
+
* 完整措辞只保留在私有文档,经此处 koishi.yml 配置还原,无需改源码。
|
|
17
|
+
*/
|
|
18
|
+
interface PromptOverrideConfig {
|
|
19
|
+
/** 身份锁定锚点(完整措辞;留空 = 用 prompts.ts 框架默认) */
|
|
20
|
+
identityAnchor: string;
|
|
21
|
+
/** 三点布光光场锚点(完整措辞;留空 = 用 prompts.ts 框架默认) */
|
|
22
|
+
lightfieldAnchor: string;
|
|
23
|
+
/** 背景替换模板,含 {color} 占位(留空 = 用 prompts.ts 框架默认) */
|
|
24
|
+
backgroundClauseTemplate: string;
|
|
25
|
+
/** 背景覆盖模板,含 {desc} 占位(留空 = 用 prompts.ts 框架默认) */
|
|
26
|
+
backgroundOverrideTemplate: string;
|
|
27
|
+
}
|
|
14
28
|
interface Config {
|
|
15
29
|
mainLLM: LlmProviderConfig;
|
|
16
30
|
visionLLM: LlmProviderConfig;
|
|
@@ -20,6 +34,8 @@ interface Config {
|
|
|
20
34
|
};
|
|
21
35
|
/** 背景色兜底:DS 未给或非法时用此值 */
|
|
22
36
|
defaultBackgroundColor: string;
|
|
37
|
+
/** 程序级锚点/背景模板覆盖(框架化;完整措辞经此还原) */
|
|
38
|
+
prompt: PromptOverrideConfig;
|
|
23
39
|
session: {
|
|
24
40
|
maxTurns: number;
|
|
25
41
|
idleTimeoutMs: number;
|
package/dist/index.js
CHANGED
|
@@ -32,8 +32,8 @@ var import_koishi3 = require("koishi");
|
|
|
32
32
|
var import_koishi = require("koishi");
|
|
33
33
|
|
|
34
34
|
// src/llm/prompts.ts
|
|
35
|
-
var MAIN_SYSTEM_PROMPT = `You are the edit-intent author for an image re-render pipeline. The pipeline prepends fixed identity, backdrop and lighting anchors before your output. Describe only the user's requested look
|
|
36
|
-
var GLM_PROBE_PROMPT = `You are an asset extractor for a character image. From the screenshot, list every visual detail that a re-render could drift, and output a structured English JSON inventory
|
|
35
|
+
var MAIN_SYSTEM_PROMPT = `You are the edit-intent author for an image re-render pipeline. The pipeline prepends fixed identity, backdrop and lighting anchors before your output. Describe only the user's requested look — material or optical adjustments, or a background change / light override when explicitly asked — as one short natural English clause.`;
|
|
36
|
+
var GLM_PROBE_PROMPT = `You are an asset extractor for a character image. From the screenshot, list every visual detail that a re-render could drift, and output a structured English JSON inventory covering species, per-part colors, accessories, body surface, tail, pose, and background. Do not invent details; use "none" when absent.`;
|
|
37
37
|
var VISION_USER_TEXT = "分析这张游戏角色截图,输出资产清单 JSON。";
|
|
38
38
|
var VISION_CROSSCHECK_TEXT = `这是对同一张源图的【资产清单对抗复核】。
|
|
39
39
|
|
|
@@ -42,15 +42,19 @@ var VISION_CROSSCHECK_TEXT = `这是对同一张源图的【资产清单对抗
|
|
|
42
42
|
|
|
43
43
|
请基于源图逐项对抗验证上一轮的每一项字段,明确指出错误/遗漏/脑补,修正会导致重绘跑偏的项,保持英文枚举与同一 schema 不变;不确定时写 "none"。只输出修正后的权威 JSON。`;
|
|
44
44
|
var VISION_REPORT_LABEL = "资产清单(GLM 修正后)";
|
|
45
|
-
var IDENTITY_ANCHOR = `Preserve the subject, its pose, outfit, accessories and colors of the source image exactly, keeping the same composition and framing, at high resolution, with no UI and no watermark
|
|
46
|
-
var LIGHTFIELD_ANCHOR = `Evenly light the character's front with gentle volume, keep the shadows soft and the face readable, and add a subtle rim so the silhouette lifts off the backdrop with a soft contact shadow
|
|
47
|
-
function buildBackdropClause(color) {
|
|
45
|
+
var IDENTITY_ANCHOR = `Preserve the subject, its pose, outfit, accessories and colors of the source image exactly, keeping the same composition and framing, at high resolution, with no UI and no watermark.`;
|
|
46
|
+
var LIGHTFIELD_ANCHOR = `Evenly light the character's front with gentle volume, keep the shadows soft and the face readable, and add a subtle rim so the silhouette lifts off the backdrop with a soft contact shadow.`;
|
|
47
|
+
function buildBackdropClause(color, template) {
|
|
48
48
|
const c = (color || "yellow").trim().toLowerCase();
|
|
49
|
-
|
|
49
|
+
const t = template?.trim();
|
|
50
|
+
if (t) return t.replace("{color}", c);
|
|
51
|
+
return `Place the character on a plain solid ${c} seamless studio backdrop that fully replaces the source background.`;
|
|
50
52
|
}
|
|
51
|
-
function buildBackdropFromOverride(desc) {
|
|
53
|
+
function buildBackdropFromOverride(desc, template) {
|
|
52
54
|
const d = (desc || "").trim().replace(/\s+/g, " ");
|
|
53
|
-
|
|
55
|
+
const t = template?.trim();
|
|
56
|
+
if (t) return t.replace("{desc}", d);
|
|
57
|
+
return `Place the character against ${d}, fully replacing the source background.`;
|
|
54
58
|
}
|
|
55
59
|
|
|
56
60
|
// src/config.ts
|
|
@@ -70,6 +74,12 @@ var Config = import_koishi.Schema.object({
|
|
|
70
74
|
timeoutMs: import_koishi.Schema.number().min(3e4).max(6e5).default(18e4).description("超时(ms)")
|
|
71
75
|
}).description("ComfyUI"),
|
|
72
76
|
defaultBackgroundColor: import_koishi.Schema.string().default("yellow").description("背景色兜底(DS 未给或非法时使用;英文颜色词)"),
|
|
77
|
+
prompt: import_koishi.Schema.object({
|
|
78
|
+
identityAnchor: import_koishi.Schema.string().role("textarea").default("").description("身份锁定锚点完整措辞(留空=用 prompts.ts 框架默认;完整原文见私有文档)"),
|
|
79
|
+
lightfieldAnchor: import_koishi.Schema.string().role("textarea").default("").description("三点布光光场锚点完整措辞(留空=用 prompts.ts 框架默认;完整原文见私有文档)"),
|
|
80
|
+
backgroundClauseTemplate: import_koishi.Schema.string().role("textarea").default("").description("背景替换模板,含 {color} 占位(留空=用 prompts.ts 框架默认;完整原文见私有文档)"),
|
|
81
|
+
backgroundOverrideTemplate: import_koishi.Schema.string().role("textarea").default("").description("背景覆盖模板,含 {desc} 占位(留空=用 prompts.ts 框架默认;完整原文见私有文档)")
|
|
82
|
+
}).description("程序级锚点/背景模板覆盖(框架化:发布包默认空,完整措辞经此 koishi.yml 配置还原,无需改源码)"),
|
|
73
83
|
session: import_koishi.Schema.object({
|
|
74
84
|
maxTurns: import_koishi.Schema.number().min(1).max(50).default(10).description("最大轮次"),
|
|
75
85
|
idleTimeoutMs: import_koishi.Schema.number().min(6e4).max(24 * 60 * 60 * 1e3).default(10 * 60 * 1e3).description("空闲销毁(ms)"),
|
|
@@ -420,9 +430,11 @@ async function runVisionAnalysis(vision, dataUrl, systemPrompt, userText) {
|
|
|
420
430
|
async function runGenerateOnly(deps, session, userFeedback) {
|
|
421
431
|
const { main, comfy, lock, logger } = deps;
|
|
422
432
|
const decision = await runMainLlm(main, session, userFeedback, deps.mainSystemPrompt);
|
|
423
|
-
const
|
|
424
|
-
const
|
|
425
|
-
|
|
433
|
+
const identity = deps.identityAnchor?.trim() || IDENTITY_ANCHOR;
|
|
434
|
+
const lightfield = deps.lightfieldAnchor?.trim() || LIGHTFIELD_ANCHOR;
|
|
435
|
+
const backdrop = decision.background ? buildBackdropFromOverride(decision.background, deps.backgroundOverrideTemplate) : buildBackdropClause(deps.defaultBackgroundColor, deps.backgroundClauseTemplate);
|
|
436
|
+
const promptText = `${identity} ${backdrop} ${lightfield} ${decision.prompt}`;
|
|
437
|
+
logger.info("brain prompt len=%d ds=%d anchor=%d lightfield=%d preview=%s", promptText.length, decision.prompt.length, identity.length, lightfield.length, promptText.slice(0, 160).replace(/\s+/g, " "));
|
|
426
438
|
logger.info("brain note=%s", decision.note ?? "");
|
|
427
439
|
let seed = session.params.seed;
|
|
428
440
|
if (!Number.isFinite(seed) || seed < 0) seed = randomSeed();
|
|
@@ -686,7 +698,11 @@ function createRenderFacade(deps) {
|
|
|
686
698
|
visionUserText: deps.visionUserText,
|
|
687
699
|
visionCrosscheckRounds: deps.visionCrosscheckRounds,
|
|
688
700
|
visionCrosscheckText: deps.visionCrosscheckText,
|
|
689
|
-
defaultBackgroundColor: deps.defaultBackgroundColor
|
|
701
|
+
defaultBackgroundColor: deps.defaultBackgroundColor,
|
|
702
|
+
identityAnchor: deps.identityAnchor,
|
|
703
|
+
lightfieldAnchor: deps.lightfieldAnchor,
|
|
704
|
+
backgroundClauseTemplate: deps.backgroundClauseTemplate,
|
|
705
|
+
backgroundOverrideTemplate: deps.backgroundOverrideTemplate
|
|
690
706
|
},
|
|
691
707
|
downloaded.dataUrl
|
|
692
708
|
);
|
|
@@ -736,7 +752,11 @@ function createRenderFacade(deps) {
|
|
|
736
752
|
visionUserText: deps.visionUserText,
|
|
737
753
|
visionCrosscheckRounds: deps.visionCrosscheckRounds,
|
|
738
754
|
visionCrosscheckText: deps.visionCrosscheckText,
|
|
739
|
-
defaultBackgroundColor: deps.defaultBackgroundColor
|
|
755
|
+
defaultBackgroundColor: deps.defaultBackgroundColor,
|
|
756
|
+
identityAnchor: deps.identityAnchor,
|
|
757
|
+
lightfieldAnchor: deps.lightfieldAnchor,
|
|
758
|
+
backgroundClauseTemplate: deps.backgroundClauseTemplate,
|
|
759
|
+
backgroundOverrideTemplate: deps.backgroundOverrideTemplate
|
|
740
760
|
},
|
|
741
761
|
session,
|
|
742
762
|
input.instruction,
|
|
@@ -1268,6 +1288,10 @@ function apply(ctx, config) {
|
|
|
1268
1288
|
visionCrosscheckRounds: config.visionCrosscheckRounds,
|
|
1269
1289
|
visionCrosscheckText: VISION_CROSSCHECK_TEXT,
|
|
1270
1290
|
defaultBackgroundColor: config.defaultBackgroundColor,
|
|
1291
|
+
identityAnchor: config.prompt?.identityAnchor?.trim() || IDENTITY_ANCHOR,
|
|
1292
|
+
lightfieldAnchor: config.prompt?.lightfieldAnchor?.trim() || LIGHTFIELD_ANCHOR,
|
|
1293
|
+
backgroundClauseTemplate: config.prompt?.backgroundClauseTemplate?.trim() || void 0,
|
|
1294
|
+
backgroundOverrideTemplate: config.prompt?.backgroundOverrideTemplate?.trim() || void 0,
|
|
1271
1295
|
// Comfy 生成轮询期间编辑「正在生成」进度消息(约每 15s 一次,由 brain onTick 触发)
|
|
1272
1296
|
onGenerateProgress: (elapsedMs) => {
|
|
1273
1297
|
const g = genProgress;
|
|
@@ -1352,7 +1376,11 @@ function apply(ctx, config) {
|
|
|
1352
1376
|
visionUserText: config.visionLLM.userText?.trim() || VISION_USER_TEXT,
|
|
1353
1377
|
visionCrosscheckRounds: config.visionCrosscheckRounds,
|
|
1354
1378
|
visionCrosscheckText: VISION_CROSSCHECK_TEXT,
|
|
1355
|
-
defaultBackgroundColor: config.defaultBackgroundColor
|
|
1379
|
+
defaultBackgroundColor: config.defaultBackgroundColor,
|
|
1380
|
+
identityAnchor: config.prompt?.identityAnchor?.trim() || IDENTITY_ANCHOR,
|
|
1381
|
+
lightfieldAnchor: config.prompt?.lightfieldAnchor?.trim() || LIGHTFIELD_ANCHOR,
|
|
1382
|
+
backgroundClauseTemplate: config.prompt?.backgroundClauseTemplate?.trim() || void 0,
|
|
1383
|
+
backgroundOverrideTemplate: config.prompt?.backgroundOverrideTemplate?.trim() || void 0
|
|
1356
1384
|
});
|
|
1357
1385
|
const lastGeneratedStore = {
|
|
1358
1386
|
get: (id) => runtime.lastGenByConv.get(id),
|