Skip to content

Commit 7d0727d

Browse files
committed
2.0.1
1 parent 9afbb33 commit 7d0727d

45 files changed

Lines changed: 5309 additions & 1591 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

config/config_template.json

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,25 +22,33 @@
2222
"display_name": "",
2323
"is_default": true,
2424
"temperature": 0.7,
25-
"max_tokens": 1000,
25+
"max_tokens": 1024,
2626
"top_p": 0.9
2727
},
2828
{
2929
"name": "glm-4.5-flash",
3030
"display_name": "",
3131
"is_default": false,
3232
"temperature": 0.7,
33-
"max_tokens": 1000,
33+
"max_tokens": 1024,
3434
"top_p": 0.9
3535
}
3636
],
3737
"vlm_models": [
3838
{
39-
"name": "glm-4v-flash",
39+
"name": "glm-4.6V-Flash",
4040
"display_name": "",
4141
"is_default": true,
4242
"temperature": 0.7,
43-
"max_tokens": 500,
43+
"max_tokens": 1024,
44+
"top_p": 0.9
45+
},
46+
{
47+
"name": "glm-4v-flash",
48+
"display_name": "",
49+
"is_default": false,
50+
"temperature": 0.7,
51+
"max_tokens": 1024,
4452
"top_p": 0.9
4553
}
4654
]
@@ -57,11 +65,11 @@
5765
"filter_thinking_output": true,
5866
"llm_models": [
5967
{
60-
"name": "gemini-2.5-pro-nothinking",
68+
"name": "gemini-3-flash-preview-nothinking",
6169
"display_name": "",
6270
"is_default": true,
6371
"temperature": 0.7,
64-
"max_tokens": 1000,
72+
"max_tokens": 1024,
6573
"top_p": 0.9
6674
}
6775
],
@@ -71,7 +79,7 @@
7179
"display_name": "",
7280
"is_default": true,
7381
"temperature": 0.7,
74-
"max_tokens": 500,
82+
"max_tokens": 1024,
7583
"top_p": 0.9
7684
}
7785
]

config/system_prompts_template.json

Lines changed: 7 additions & 7 deletions
Large diffs are not rendered by default.

config_manager.py

Lines changed: 57 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ def __init__(self):
6666
self.default_user_tags = {"favorites": []}
6767

6868
# 默认标签选择
69-
self.default_tags_selection = {"selected_file": "default.csv"}
69+
self.default_tags_selection = {"selected_file": "用户标签.csv"}
7070

7171

7272

@@ -358,28 +358,37 @@ def load_tags_csv(self, filename: str) -> dict:
358358
return {} # 空文件
359359

360360
for row in reader:
361-
if len(row) < 3:
361+
# 过滤无效行
362+
if not row or not any(cell.strip() for cell in row):
363+
continue
364+
365+
# 至少需要两列:标签名, 标签值
366+
if len(row) < 2:
362367
continue
363368

364369
tag_name = row[0].strip()
365370
tag_value = row[1].strip()
366-
# 分类路径:从第3列开始,过滤空值
367-
categories = [c.strip() for c in row[2:] if c.strip()]
368371

369-
if not tag_name or not categories:
372+
if not tag_name:
370373
continue
374+
375+
# 分类路径:从第3列开始,过滤空值
376+
categories = [c.strip() for c in row[2:] if c.strip()]
371377

372378
# 构建嵌套结构
373379
current = result
374380
for cat in categories:
375-
if cat not in current:
381+
if cat not in current or not isinstance(current[cat], dict):
376382
current[cat] = {}
377383
current = current[cat]
378384

385+
# 处理空分类占位符:只创建分类结构,不添加标签
386+
if tag_name == "__empty__" or tag_name == "__placeholder__":
387+
continue
388+
379389
# 添加标签
380390
current[tag_name] = tag_value
381391

382-
# self._log(f"成功加载CSV文件: {filename} (编码: {encoding})")
383392
return result
384393
except UnicodeDecodeError:
385394
continue
@@ -396,25 +405,57 @@ def save_tags_csv(self, filename: str, tags: dict) -> bool:
396405

397406
try:
398407
rows = []
408+
max_depth = 0
399409

400410
def extract_tags(obj, path: list):
411+
nonlocal max_depth
412+
# 确保 obj 是字典类型
413+
if not isinstance(obj, dict):
414+
return
415+
416+
# 如果是空分类(空字典),添加占位行
417+
if len(obj) == 0 and path:
418+
# 使用 __empty__ 作为占位符标记空分类
419+
rows.append(["__empty__", ""] + path)
420+
max_depth = max(max_depth, len(path))
421+
return
422+
401423
for key, value in obj.items():
402424
if isinstance(value, str):
403425
rows.append([key, value] + path)
426+
max_depth = max(max_depth, len(path))
404427
elif isinstance(value, dict):
405428
extract_tags(value, path + [key])
406429

407-
for level1_name, level1_content in tags.items():
408-
if isinstance(level1_content, dict):
409-
extract_tags(level1_content, [level1_name])
430+
# 提取所有标签
431+
extract_tags(tags, [])
432+
433+
if not rows:
434+
self._log(f"保存CSV标签: 数据为空")
435+
# 如果数据为空,写入只含表头的文件或保持现状?
436+
# 通常为了防止误删,如果 tags 为空暂不操作或清空文件。
437+
# 这里选择写入表头:
438+
with open(csv_path, "w", encoding="utf-8-sig", newline="") as f:
439+
writer = csv.writer(f)
440+
writer.writerow(["标签名", "标签值"])
441+
return True
442+
443+
# 动态构建表头
444+
header = ["标签名", "标签值"]
445+
for i in range(max_depth):
446+
num_zh = ["一", "二", "三", "四", "五", "六", "七", "八", "九", "十"]
447+
suffix = num_zh[i] if i < len(num_zh) else str(i + 1)
448+
header.append(f"{suffix}级分类")
410449

411450
with open(csv_path, "w", encoding="utf-8-sig", newline="") as f:
412451
writer = csv.writer(f)
413-
writer.writerow(["标签名", "标签值", "一级分类", "二级分类", "三级分类", "四级分类"])
452+
writer.writerow(header)
414453
for row in rows:
415-
while len(row) < 6:
454+
# 补齐长度以匹配表头
455+
while len(row) < len(header):
416456
row.append("")
417-
writer.writerow(row[:6])
457+
# 确保 row 长度不超过表头(防御性)
458+
writer.writerow(row[:len(header)])
418459

419460
return True
420461
except Exception as e:
@@ -732,7 +773,7 @@ def get_vision_config(self):
732773
"base_url": service.get('base_url', ''),
733774
"api_key": api_key,
734775
"temperature": target_model.get('temperature', 0.7),
735-
"max_tokens": target_model.get('max_tokens', 500),
776+
"max_tokens": target_model.get('max_tokens', 1024),
736777
"top_p": target_model.get('top_p', 0.9),
737778
"auto_unload": service.get('auto_unload', True) if service.get('type') == 'ollama' else None,
738779
"providers": {} # v2.0中不再使用此字段
@@ -746,7 +787,7 @@ def _get_empty_vision_config(self):
746787
"base_url": "",
747788
"api_key": "",
748789
"temperature": 0.7,
749-
"max_tokens": 500,
790+
"max_tokens": 1024,
750791
"top_p": 0.9,
751792
"providers": {}
752793
}
@@ -1558,7 +1599,7 @@ def set_current_service(self, service_type: str, service_id: str, model_name: st
15581599
# --- 模型管理方法 ---
15591600

15601601
def add_model_to_service(self, service_id: str, model_type: str, model_name: str,
1561-
temperature: float = 0.7, top_p: float = 0.9, max_tokens: int = 512):
1602+
temperature: float = 0.7, top_p: float = 0.9, max_tokens: int = 1024):
15621603
"""添加模型到服务商"""
15631604
try:
15641605
config = self.load_config()

js/css/assistant.css

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,4 +667,101 @@
667667
/* 指示器初始化 - 触发入场动画 */
668668
.assistant-indicator.indicator-init {
669669
animation: indicatorAppear 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
670+
}
671+
672+
/* ==========================================================================
673+
10. 流式输出浮层 (Streaming Overlay)
674+
========================================================================== */
675+
/* 流式输出显示浮层 */
676+
/* --- 节点内嵌流式显示逻辑 --- */
677+
678+
/* 文本容器:挂载在节点容器底部 */
679+
.node-streaming-text-container {
680+
position: absolute;
681+
bottom: 35px;
682+
/* 紧贴底部工具条上方 */
683+
left: 8px;
684+
right: 8px;
685+
z-index: 99;
686+
pointer-events: none;
687+
/* 不干扰节点操作 */
688+
display: flex;
689+
flex-direction: column;
690+
justify-content: flex-end;
691+
692+
/* 关键:调整遮罩范围,使其在红框高度内保持清晰,上方迅速渐隐 */
693+
-webkit-mask-image: linear-gradient(to top,
694+
rgba(0, 0, 0, 1) 0%,
695+
rgba(0, 0, 0, 1) 50%,
696+
rgba(0, 0, 0, 0) 100%);
697+
mask-image: linear-gradient(to top,
698+
rgba(0, 0, 0, 1) 0%,
699+
rgba(0, 0, 0, 1) 50%,
700+
rgba(0, 0, 0, 0) 100%);
701+
702+
/* 动画 */
703+
opacity: 0;
704+
transition: opacity 0.3s ease;
705+
height: 100px;
706+
/* 用户调整后的高度 */
707+
overflow: hidden;
708+
}
709+
710+
/* LiteGraph 模式下的高性能同步层 */
711+
.node-streaming-text-container.is-litegraph {
712+
position: fixed;
713+
z-index: 10001;
714+
pointer-events: none;
715+
background: transparent;
716+
transform-origin: top left;
717+
/* 重要:从计算点开始缩放 */
718+
/* 宽度、高度、坐标和 transform 将由 JS 实时注入 */
719+
}
720+
721+
.node-streaming-text-container.show {
722+
opacity: 1;
723+
}
724+
725+
/* 内部流式文本 */
726+
.node-streaming-text-content {
727+
color: color-mix(in srgb, var(--text-primary), transparent 50%);
728+
font-size: 10px;
729+
line-height: 1.6;
730+
/* text-shadow: 0 1px 4px rgba(0, 0, 0, 0.8), 0 0 2px rgba(0, 0, 0, 1); */
731+
white-space: pre-wrap;
732+
word-break: break-all;
733+
text-align: left;
734+
padding-bottom: 6px;
735+
/* 让内容始终保持在底部 */
736+
margin-top: auto;
737+
}
738+
739+
740+
/* 生成中的提示文本样式 */
741+
.image-assistant-streaming-overlay.placeholder {
742+
color: var(--fg-color, #888);
743+
font-style: italic;
744+
}
745+
746+
/* 自定义滚动条样式,防止破坏圆角 */
747+
.image-assistant-streaming-overlay::-webkit-scrollbar {
748+
width: 6px;
749+
height: 6px;
750+
}
751+
752+
.image-assistant-streaming-overlay::-webkit-scrollbar-track {
753+
background: transparent;
754+
border-radius: 10px;
755+
}
756+
757+
.image-assistant-streaming-overlay::-webkit-scrollbar-thumb {
758+
background: color-mix(in srgb, var(--p-panel-border-color), transparent 50%);
759+
border-radius: 10px;
760+
/* 增加透明边距,使滑块看起来“悬浮”且不贴边 */
761+
border: 1px solid transparent;
762+
background-clip: content-box;
763+
}
764+
765+
.image-assistant-streaming-overlay::-webkit-scrollbar-thumb:hover {
766+
background-color: var(--p-panel-border-color);
670767
}

js/css/common.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,10 @@
179179
/* 应用高亮动画 */
180180
.input-highlight {
181181
animation: inputHighlight 0.2s ease-out;
182+
background-color: transparent !important;
183+
/* 兜底:即使动画卡住,类名存在时也确保透明 */
184+
will-change: background-color;
185+
/* 优化合成层渲染 */
182186
}
183187

184188
/* ==========================================================================

js/css/popup.css

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1333,4 +1333,57 @@
13331333

13341334
.tag_popup .tag_item:active {
13351335
cursor: grabbing;
1336+
}
1337+
1338+
/* ---添加分类按钮样式--- */
1339+
1340+
/* Tab 栏中的添加分类按钮 */
1341+
.popup_container .popup_tab.add_category_tab {
1342+
padding: 4px 10px 8px 10px;
1343+
opacity: 0.6;
1344+
transition: all 0.2s ease;
1345+
min-width: 28px;
1346+
display: flex;
1347+
align-items: center;
1348+
justify-content: center;
1349+
}
1350+
1351+
.popup_container .popup_tab.add_category_tab:hover {
1352+
opacity: 1;
1353+
color: var(--p-primary-500);
1354+
}
1355+
1356+
.popup_container .popup_tab.add_category_tab .pi {
1357+
font-size: 10px;
1358+
}
1359+
1360+
/* 添加分类按钮不显示底部高亮条 */
1361+
.popup_container .popup_tab.add_category_tab::after {
1362+
display: none;
1363+
}
1364+
1365+
/* 手风琴列表末尾的添加子分类按钮 */
1366+
.add_subcategory_button {
1367+
display: flex;
1368+
align-items: center;
1369+
justify-content: center;
1370+
margin: 8px;
1371+
padding: 8px 16px;
1372+
border: 1px dashed transparent;
1373+
border-radius: 6px;
1374+
cursor: pointer;
1375+
transition: all 0.2s ease;
1376+
color: var(--p-text-muted-color);
1377+
opacity: 0.5;
1378+
}
1379+
1380+
.add_subcategory_button:hover {
1381+
opacity: 1;
1382+
border-color: var(--p-content-border-color);
1383+
color: var(--p-text-muted-color);
1384+
background-color: transparent;
1385+
}
1386+
1387+
.add_subcategory_button .pi {
1388+
font-size: 10px;
13361389
}

0 commit comments

Comments
 (0)