feat: v1.10.3 - 修复生图问题、新增取消请求、LLM增强、Seedance 2.0参考功能

This commit is contained in:
Jony
2026-04-13 01:16:34 +08:00
parent 82752d34fc
commit 00295d65c7
5 changed files with 87 additions and 55 deletions
+15
View File
@@ -6,6 +6,21 @@
--- ---
## [1.10.3] - 2026-04-13
### 修复
- 香蕉节点修复返回2张图、灰色图片问题
- 修复 SSL 证书报错,统一由【保存图像】节点保存
### 新增
- 支持【立刻取消】生图请求,可立即重新运行
- 支持工作流历史记录恢复
- 并发上限提升,批量生图速度大幅提升
- 全能LLM新增视频/文档分析、流式实时预览
- Seedance 2.0 新增多图及视频URL参考(优化中)
---
## [Unreleased] ## [Unreleased]
### Added ✨ ### Added ✨
+1 -2
View File
@@ -15,8 +15,7 @@ try:
notify_update_available() # TODO: 测试用,改回 if check_for_updates(): notify_update_available() notify_update_available() # TODO: 测试用,改回 if check_for_updates(): notify_update_available()
if check_for_updates(): notify_new_version() # TODO: 测试用,改回 if check_for_updates(): notify_new_version()
notify_new_version()
except Exception: except Exception:
# 静默失败,不影响插件加载 # 静默失败,不影响插件加载
pass pass
+33 -20
View File
@@ -72,18 +72,40 @@ def check_for_updates() -> bool:
def get_update_changelog() -> list: def get_update_changelog() -> list:
"""获取远程新版本的 commit 摘要(最多3条)""" """从远程 CHANGELOG.md 最新版本块中提取更新内容(最多3条)"""
try: try:
plugin_dir = os.path.dirname(os.path.dirname(__file__)) plugin_dir = os.path.dirname(os.path.dirname(__file__))
# 读取远程最新的 CHANGELOG.md
result = subprocess.run( result = subprocess.run(
['git', 'log', 'HEAD..origin/main', '--pretty=format:%s', '--no-merges'], ['git', 'show', 'origin/main:CHANGELOG.md'],
cwd=plugin_dir, cwd=plugin_dir,
capture_output=True, capture_output=True,
text=True, text=True,
encoding='utf-8' encoding='utf-8'
) )
lines = [l.strip() for l in result.stdout.strip().splitlines() if l.strip()] lines = result.stdout.splitlines()
return lines[:3]
# 找到第一个版本块(## [x.x.x])
in_block = False
items = []
for line in lines:
if line.startswith('## [') and not line.startswith('## [Unreleased]'):
if in_block:
break # 遇到下一个版本块,停止
in_block = True
continue
if in_block:
stripped = line.strip()
# 提取有实际内容的行(跳过标题、空行、分隔线)
if stripped and not stripped.startswith('#') and not stripped.startswith('---') and not stripped.startswith('- '):
# 去掉 markdown 列表符号和加粗
text = stripped.lstrip('- ').replace('**', '').strip()
if text and len(text) > 3:
items.append(text)
if len(items) >= 3:
break
return items
except Exception: except Exception:
return [] return []
@@ -91,7 +113,6 @@ def get_update_changelog() -> list:
def notify_new_version(): def notify_new_version():
"""检测到新版本时,推送蓝色更新通知弹框""" """检测到新版本时,推送蓝色更新通知弹框"""
changelog = get_update_changelog() changelog = get_update_changelog()
print("[o1key] 检测到新版本,准备推送更新通知")
try: try:
import threading import threading
@@ -103,22 +124,16 @@ def notify_new_version():
"o1key.new_version", "o1key.new_version",
{"changelog": changelog} {"changelog": changelog}
) )
print("[o1key] 新版本通知已发送到前端") except Exception:
except Exception as e: pass
print(f"[o1key] 发送新版本通知失败: {e}")
threading.Timer(5.0, _send).start() threading.Timer(3.0, _send).start()
except Exception: except Exception:
pass pass
def notify_update_available(): def notify_update_available():
"""通知用户有更新可用(前端弹窗 + 控制台""" """通知用户有更新可用(前端弹窗)"""
current_version = get_current_version()
version_str = f" (当前版本: {current_version})" if current_version else ""
print(f"[comfyui_o1key] 有新版本可用{version_str}")
try: try:
import threading import threading
from server import PromptServer from server import PromptServer
@@ -129,11 +144,9 @@ def notify_update_available():
"o1key.update_available", "o1key.update_available",
{"message": "欢迎使用o1key工作流,祝您马年,马上有福,马上有钱,马到成功!!!"} {"message": "欢迎使用o1key工作流,祝您马年,马上有福,马上有钱,马到成功!!!"}
) )
print("[o1key] 更新通知已发送到前端") except Exception:
except Exception as e: pass
print(f"[o1key] 发送通知失败: {e}")
# 延迟 5 秒发送,确保前端 WebSocket 已连接 threading.Timer(3.0, _send).start()
threading.Timer(5.0, _send).start()
except Exception: except Exception:
pass pass
+1 -1
View File
@@ -1 +1 @@
v1.10.2 v1.10.3
+37 -32
View File
@@ -1,5 +1,27 @@
import { api } from "../../../scripts/api.js"; import { api } from "../../../scripts/api.js";
function startCountdown(toast, closeBtn, seconds, accentColor) {
let remaining = seconds;
closeBtn.textContent = `× ${remaining}s`;
const interval = setInterval(() => {
remaining--;
if (remaining <= 0) {
clearInterval(interval);
toast.style.transition = "opacity 0.4s ease";
toast.style.opacity = "0";
setTimeout(() => toast.remove(), 400);
} else {
closeBtn.textContent = `× ${remaining}s`;
}
}, 1000);
closeBtn.onclick = () => {
clearInterval(interval);
toast.remove();
};
}
api.addEventListener("o1key.update_available", (event) => { api.addEventListener("o1key.update_available", (event) => {
const message = event.detail?.message || "欢迎使用o1key工作流"; const message = event.detail?.message || "欢迎使用o1key工作流";
@@ -9,7 +31,6 @@ api.addEventListener("o1key.update_available", (event) => {
from { opacity: 0; transform: translateY(16px) scale(0.97); } from { opacity: 0; transform: translateY(16px) scale(0.97); }
to { opacity: 1; transform: translateY(0) scale(1); } to { opacity: 1; transform: translateY(0) scale(1); }
} }
.o1key-toast-close:hover { color: #fff !important; }
`; `;
document.head.appendChild(style); document.head.appendChild(style);
@@ -31,30 +52,14 @@ api.addEventListener("o1key.update_available", (event) => {
`; `;
const header = document.createElement("div"); const header = document.createElement("div");
header.style.cssText = ` header.style.cssText = `display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px;`;
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 10px;
`;
const title = document.createElement("span"); const title = document.createElement("span");
title.textContent = "🐴 o1key 工作流"; title.textContent = "🐴 o1key 工作流";
title.style.cssText = `font-weight: bold; font-size: 13px; color: #82e0aa; letter-spacing: 0.5px;`; title.style.cssText = `font-weight: bold; font-size: 13px; color: #82e0aa; letter-spacing: 0.5px;`;
const closeBtn = document.createElement("button"); const closeBtn = document.createElement("button");
closeBtn.textContent = "×"; closeBtn.style.cssText = `background: none; border: none; color: #82e0aa; font-size: 13px; cursor: pointer; padding: 0; line-height: 1;`;
closeBtn.className = "o1key-toast-close";
closeBtn.style.cssText = `
background: none;
border: none;
color: #82e0aa;
font-size: 20px;
cursor: pointer;
padding: 0;
line-height: 1;
`;
closeBtn.onclick = () => toast.remove();
header.appendChild(title); header.appendChild(title);
header.appendChild(closeBtn); header.appendChild(closeBtn);
@@ -70,6 +75,8 @@ api.addEventListener("o1key.update_available", (event) => {
toast.appendChild(divider); toast.appendChild(divider);
toast.appendChild(text); toast.appendChild(text);
document.body.appendChild(toast); document.body.appendChild(toast);
startCountdown(toast, closeBtn, 5, "#82e0aa");
}); });
api.addEventListener("o1key.new_version", (event) => { api.addEventListener("o1key.new_version", (event) => {
@@ -81,7 +88,6 @@ api.addEventListener("o1key.new_version", (event) => {
from { opacity: 0; transform: translateY(16px) scale(0.97); } from { opacity: 0; transform: translateY(16px) scale(0.97); }
to { opacity: 1; transform: translateY(0) scale(1); } to { opacity: 1; transform: translateY(0) scale(1); }
} }
.o1key-update-close:hover { color: #fff !important; }
`; `;
document.head.appendChild(style); document.head.appendChild(style);
@@ -94,7 +100,7 @@ api.addEventListener("o1key.new_version", (event) => {
color: #d6eaf8; color: #d6eaf8;
border: 1px solid #2e86c1; border: 1px solid #2e86c1;
border-radius: 12px; border-radius: 12px;
padding: 18px 20px 16px 20px; padding: 12px 16px;
font-size: 14px; font-size: 14px;
z-index: 100000; z-index: 100000;
box-shadow: 0 6px 24px rgba(46,134,193,0.35), 0 2px 8px rgba(0,0,0,0.5); box-shadow: 0 6px 24px rgba(46,134,193,0.35), 0 2px 8px rgba(0,0,0,0.5);
@@ -103,40 +109,39 @@ api.addEventListener("o1key.new_version", (event) => {
`; `;
const header = document.createElement("div"); const header = document.createElement("div");
header.style.cssText = `display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px;`; header.style.cssText = `display: flex; align-items: center; justify-content: space-between;`;
const title = document.createElement("span"); const title = document.createElement("span");
title.textContent = "🔔 检测到有新版本发布!"; title.textContent = "🔔 检测到有新版本发布!";
title.style.cssText = `font-weight: bold; font-size: 13px; color: #7fb3d3; letter-spacing: 0.5px;`; title.style.cssText = `font-weight: bold; font-size: 13px; color: #7fb3d3; letter-spacing: 0.5px;`;
const closeBtn = document.createElement("button"); const closeBtn = document.createElement("button");
closeBtn.textContent = "×"; closeBtn.style.cssText = `background: none; border: none; color: #7fb3d3; font-size: 13px; cursor: pointer; padding: 0; line-height: 1;`;
closeBtn.className = "o1key-update-close";
closeBtn.style.cssText = `background: none; border: none; color: #7fb3d3; font-size: 20px; cursor: pointer; padding: 0; line-height: 1;`;
closeBtn.onclick = () => toast.remove();
header.appendChild(title); header.appendChild(title);
header.appendChild(closeBtn); header.appendChild(closeBtn);
const divider = document.createElement("div"); const divider = document.createElement("div");
divider.style.cssText = `height: 1px; background: rgba(46,134,193,0.3); margin-bottom: 10px;`; divider.style.cssText = `height: 1px; background: rgba(46,134,193,0.3); margin: 8px 0;`;
toast.appendChild(header);
toast.appendChild(divider);
const body = document.createElement("div"); const body = document.createElement("div");
const items = changelog.length > 0 ? changelog : ["暂无更新说明"]; const items = changelog.length > 0 ? changelog : ["暂无更新说明"];
items.forEach(item => { items.forEach(item => {
const line = document.createElement("div"); const line = document.createElement("div");
line.textContent = `${item}`; line.textContent = `${item}`;
line.style.cssText = `margin-bottom: 4px; font-size: 13px; line-height: 1.6; color: #d6eaf8;`; line.style.cssText = `margin-bottom: 4px; font-size: 12px; line-height: 1.6; color: #d6eaf8;`;
body.appendChild(line); body.appendChild(line);
}); });
const more = document.createElement("div"); const more = document.createElement("div");
more.textContent = "..."; more.textContent = "...";
more.style.cssText = `color: #7fb3d3; font-size: 13px; margin-top: 4px;`; more.style.cssText = `color: #7fb3d3; font-size: 12px; margin-top: 2px;`;
body.appendChild(more); body.appendChild(more);
toast.appendChild(header);
toast.appendChild(divider);
toast.appendChild(body); toast.appendChild(body);
document.body.appendChild(toast); document.body.appendChild(toast);
startCountdown(toast, closeBtn, 5, "#7fb3d3");
}); });