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 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 (material or optical adjustments; a background change or light override when explicitly asked) as one short natural English clause. Placeholder default; the full prompt is restored via config override from the private design doc.`;
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 (species, per-part colors, accessories, body surface, tail, pose, background). Do not invent details; use "none" when absent. Placeholder default; full prompt (with exact schema) is in the private design doc.`;
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. (Generic placeholder; the full locked wording is in the private design doc.)`;
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. (Generic placeholder; the full locked wording is in the private design doc.)`;
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
- return `Place the character on a plain solid ${c} seamless studio backdrop that fully replaces the source background. (Generic placeholder; full wording in private doc.)`;
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
- return `Place the character against ${d}, fully replacing the source background. (Generic placeholder; full wording in private doc.)`;
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 backdrop = decision.background ? buildBackdropFromOverride(decision.background) : buildBackdropClause(deps.defaultBackgroundColor);
424
- const promptText = `${IDENTITY_ANCHOR} ${backdrop} ${LIGHTFIELD_ANCHOR} ${decision.prompt}`;
425
- logger.info("brain prompt len=%d ds=%d backdrop=%s lightfield=%d preview=%s", promptText.length, decision.prompt.length, decision.background?.slice(0, 40) || deps.defaultBackgroundColor || "yellow", LIGHTFIELD_ANCHOR.length, promptText.slice(0, 160).replace(/\s+/g, " "));
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),