codebee 0.1.102 → 0.1.104
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/CHANGELOG.md +9 -0
- package/README.md +3 -8
- package/app/core/dispatch.py +1 -1
- package/app/core/novel_quality.py +104 -0
- package/app/core/pipeline.py +57 -5
- package/app/core/planner.py +7 -0
- package/app/ui/app.js +2 -3
- package/app/ui/i18n.js +0 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,15 @@ CodeBee 的用户可感知变更记录。发布新版时:最上面加一节,
|
|
|
4
4
|
`<!-- relnotes:start -->…<!-- relnotes:end -->` 段(那段会被 `npm view` 的
|
|
5
5
|
README 元数据带回,供老版本在「发现新版本」时展示新版更新内容)。
|
|
6
6
|
|
|
7
|
+
## v0.1.104(2026-10-11)
|
|
8
|
+
|
|
9
|
+
- **连载「一直重写不达标」根因防线(马甲指纹三道防线)**:「落笔入册」「整段连排」类跨章复用此前只能靠评审判死,而重写用的是同一作者模型、长出来的还是同族指纹——循环烧钱永不达标。现把防线前移到生成侧:①**章稿落盘确定性查重闸**:整段(≥40 字)/整句(≥12 字)/完整对白(≥6 字)逐字重复检测,阈值按真实事故章校准,白描短句复沓不误伤;带重复的章稿直接打回,同作者重试与换将的提示词自动追加消重指令(同提示重跑只会长出同族事故);②**起草负样例注入**:近 4 章实际开笔/收束摘录随提示词下发(`__REUSE_GUARD__`),跨章句式同款从评审判据前移成起草约束;③**大纲轮换纪律**:开笔方式与收束形态批内硬性轮换。查重证据自动进评审面可见。生效范围:发版后的新批连载
|
|
10
|
+
|
|
11
|
+
## v0.1.103(2026-10-11)
|
|
12
|
+
|
|
13
|
+
- **设置页「模型评测」子页顶栏标题修复**:标题表漏 `evalbench` 键,点入「模型评测」子页后顶栏回退显示「设置」;现正确显示「模型评测」(英文界面 Model Bench),并补静态断言回归防回流
|
|
14
|
+
- **同族死项与过时词条清理**:删除零引用死常量 `SET_TABS` 与 i18n 孤儿词条「单智能体直达…」;direct 引擎/扫榜四平台/缺陷复盘类型等注释勘误对齐实际行为(全部零逻辑改动)
|
|
15
|
+
|
|
7
16
|
## v0.1.102(2026-10-10)
|
|
8
17
|
|
|
9
18
|
- **蜂巢 3D 蜜蜂办公室全面重建(程序化 WebGL 场景)**:3D 场景从参考贴图升级为全程序化 WebGL 实时渲染——办公室/工位/灯光/蜜蜂形态全部由代码建模并大幅精修(关节手打字、椭圆半透明翅膀、腹部金环纹、人体工学椅、双层光源与接触阴影),静态几何 GPU 批处理+按需渲染更流畅,轨道/平移/复位手感修正,实时遥测投到工位屏幕玻璃上,场景 overlay 支持读屏与键盘;新增**全屏工作台**:参考图/WebGL/2D 三种视图皆可一键全屏(保留画面比例),全屏冒烟测试常驻护航
|
package/README.md
CHANGED
|
@@ -25,14 +25,9 @@ Trae Agent、OpenClaw……),提供
|
|
|
25
25
|
---
|
|
26
26
|
|
|
27
27
|
<!-- relnotes:start -->
|
|
28
|
-
### 最新版更新内容(v0.1.
|
|
29
|
-
|
|
30
|
-
-
|
|
31
|
-
- 发布台存草稿四修:假成功真凶(submit 被人工闸吞掉)根治,保存反馈当凭据+对账剔除+瞬断重试+跨批互斥
|
|
32
|
-
- 连载书稿涨破 1MB 快照上限不再全灭:超限前态改存 git 对象库,恢复链路全适配
|
|
33
|
-
- 大屏实时流对 CLI 步骤回退读日志,全 CLI 连载流程不再永远「等待实时输出」
|
|
34
|
-
- 运行详情窄主列自动折行,缩放/窄窗不再出横向滚动条
|
|
35
|
-
- 命令执行后端可选 Docker 容器(内置命令工具专属)
|
|
28
|
+
### 最新版更新内容(v0.1.104)
|
|
29
|
+
|
|
30
|
+
- 连载新防线:跨章复用「马甲指纹」从评审判死前移到起草拦截——落盘查重闸(段落/整句/对白逐字重复直接打回)+ 近章开笔摘录作负样例注入 + 大纲开笔收束批内轮换,重写不再空转
|
|
36
31
|
<!-- relnotes:end -->
|
|
37
32
|
|
|
38
33
|
|
package/app/core/dispatch.py
CHANGED
|
@@ -25,6 +25,77 @@ _SENTENCE_RE = re.compile(r"[^。!?!?;;\n]+[。!?!?;;]?")
|
|
|
25
25
|
_DIALOGUE_RE = re.compile(r"[“‘\"「『](.*?)[”’\"」』]", re.S)
|
|
26
26
|
_EMOTION_RE = re.compile(r"哭|泪|笑|怒|怕|颤|抖|咬|攥|握紧|心跳|呼吸|喉咙|指甲|沉默")
|
|
27
27
|
|
|
28
|
+
# 逐字重复检测阈值(2026-10-11 连载实案校准):整段 ≥40 字重复两遍是 113/118 章
|
|
29
|
+
# 实际事故形态;完整对白复现(≥6 字)同理——有意复诵必有动作/归属铺垫,评审员
|
|
30
|
+
# 对 113 章「这杆子歪着」的判词就是「若有意让角色复诵咀嚼,缺少铺垫」。叙述性
|
|
31
|
+
# 短句复沓(「早上探,往里。」5 字)是白描节奏手段,落在阈值之下不误伤。
|
|
32
|
+
_DUP_MIN_PARA_CHARS = 40
|
|
33
|
+
_DUP_MIN_SENT_CHARS = 12
|
|
34
|
+
_DUP_MIN_DIALOGUE_CHARS = 6
|
|
35
|
+
_DUP_MAX_NOTES = 4
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def duplicate_notes(text):
|
|
39
|
+
"""章内逐字重复检测(确定性,成稿事故级)。
|
|
40
|
+
|
|
41
|
+
抓三类:整段逐字重复、整句(≥12 字去空白)逐字重复、完整对白(≥6 字去空白)
|
|
42
|
+
逐字重复。返回结构化证据列表 [{kind, count, quote}],供落盘验收打回重起草与
|
|
43
|
+
评审提示词引用;短句复沓等有意的节奏手段不在阈值之内,不构成证据。
|
|
44
|
+
"""
|
|
45
|
+
text = str(text or "").replace("\r\n", "\n").strip()
|
|
46
|
+
if not text:
|
|
47
|
+
return []
|
|
48
|
+
notes = []
|
|
49
|
+
# ① 整段逐字重复(去空白比对;间隔段落/连排都算)
|
|
50
|
+
para_counts = {}
|
|
51
|
+
for p in re.split(r"\n\s*\n", text):
|
|
52
|
+
p = re.sub(r"\s+", "", p)
|
|
53
|
+
if len(p) >= _DUP_MIN_PARA_CHARS:
|
|
54
|
+
para_counts[p] = para_counts.get(p, 0) + 1
|
|
55
|
+
dup_paras = [p for p, c in sorted(para_counts.items(), key=lambda kv: -kv[1])
|
|
56
|
+
if c >= 2]
|
|
57
|
+
for p in dup_paras[:2]:
|
|
58
|
+
notes.append({"kind": "整段重复", "count": para_counts[p], "quote": p[:40]})
|
|
59
|
+
# ② 整句逐字重复(已被整段重复覆盖的句子不再单列,避免一条事故报一串)
|
|
60
|
+
sent_counts = {}
|
|
61
|
+
for s in _SENTENCE_RE.findall(text):
|
|
62
|
+
s = re.sub(r"\s+", "", s)
|
|
63
|
+
if len(s) >= _DUP_MIN_SENT_CHARS:
|
|
64
|
+
sent_counts[s] = sent_counts.get(s, 0) + 1
|
|
65
|
+
for s, c in sorted(sent_counts.items(), key=lambda kv: -kv[1]):
|
|
66
|
+
if c < 2 or len(notes) >= _DUP_MAX_NOTES:
|
|
67
|
+
continue
|
|
68
|
+
if any(s in p for p in dup_paras):
|
|
69
|
+
continue
|
|
70
|
+
notes.append({"kind": "整句重复", "count": c, "quote": s[:40]})
|
|
71
|
+
# ③ 完整对白逐字重复(阈值更低:成稿事故最常以「对白整句连排两遍」出现)
|
|
72
|
+
seen_dialogue = {n["quote"] for n in notes}
|
|
73
|
+
dial_counts = {}
|
|
74
|
+
for d in _DIALOGUE_RE.findall(text):
|
|
75
|
+
d = re.sub(r"\s+", "", d)
|
|
76
|
+
if len(d) >= _DUP_MIN_DIALOGUE_CHARS:
|
|
77
|
+
dial_counts[d] = dial_counts.get(d, 0) + 1
|
|
78
|
+
for d, c in sorted(dial_counts.items(), key=lambda kv: -kv[1]):
|
|
79
|
+
if c < 2 or len(notes) >= _DUP_MAX_NOTES:
|
|
80
|
+
continue
|
|
81
|
+
if any(d in q for q in seen_dialogue):
|
|
82
|
+
continue
|
|
83
|
+
notes.append({"kind": "对白重复", "count": c, "quote": d[:40]})
|
|
84
|
+
return notes
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def format_duplicate_notes(notes):
|
|
88
|
+
"""Render duplicate_notes evidence as human-readable lines."""
|
|
89
|
+
lines = []
|
|
90
|
+
for n in notes if isinstance(notes, list) else []:
|
|
91
|
+
try:
|
|
92
|
+
lines.append("%s %d 处:「%s」" % (n.get("kind", "重复"),
|
|
93
|
+
int(n.get("count") or 0),
|
|
94
|
+
str(n.get("quote") or "")[:40]))
|
|
95
|
+
except (TypeError, ValueError):
|
|
96
|
+
continue
|
|
97
|
+
return lines
|
|
98
|
+
|
|
28
99
|
|
|
29
100
|
def rubric_for(task):
|
|
30
101
|
"""Return the configured rubric, or the signing rubric for serial novels."""
|
|
@@ -71,6 +142,10 @@ def signal_summary(text, chapter=None):
|
|
|
71
142
|
hints.append("存在偏长句,复查长定语、重复说明与动作拆分")
|
|
72
143
|
if len(paragraphs) >= 4 and chars / len(paragraphs) > 220:
|
|
73
144
|
hints.append("段落偏长,复查手机阅读下的节奏与信息密度")
|
|
145
|
+
# 逐字重复(整段/整句/完整对白)是成稿事故而非文风选择,直接点名证据;
|
|
146
|
+
# 起草验收闸(pipeline._chapter_state)用同一判定打回,评审面据此复核
|
|
147
|
+
for line in format_duplicate_notes(duplicate_notes(text)):
|
|
148
|
+
hints.append("逐字重复(成稿事故,须删并保留信息量最高的一处):" + line)
|
|
74
149
|
# Dialogue/emotion-action counts are descriptive signals only. Their absence
|
|
75
150
|
# is not a quality defect: narrative voice, genre, and scene purpose vary.
|
|
76
151
|
return {
|
|
@@ -111,6 +186,35 @@ def style_anchor_block(anchor):
|
|
|
111
186
|
"与其冲突处以本锚为准)\n%s\n" % anchor[:400])
|
|
112
187
|
|
|
113
188
|
|
|
189
|
+
def reuse_guard_block(samples):
|
|
190
|
+
"""Render prior chapters' opening/closing excerpts as a negative-example block.
|
|
191
|
+
|
|
192
|
+
samples: [{"chapter": int, "head": str, "tail": str}] — 起草面据此避开同款
|
|
193
|
+
开笔句式与同型收束(跨章复用红线:同一动作句式至多两次,第二次必须换载体
|
|
194
|
+
或升级信息量)。无样例(首批第 1 章等)返回空串,不占提示词字节。
|
|
195
|
+
"""
|
|
196
|
+
rows = []
|
|
197
|
+
for s in samples if isinstance(samples, list) else []:
|
|
198
|
+
if not isinstance(s, dict):
|
|
199
|
+
continue
|
|
200
|
+
try:
|
|
201
|
+
ch = int(s.get("chapter"))
|
|
202
|
+
except (TypeError, ValueError):
|
|
203
|
+
continue
|
|
204
|
+
head = str(s.get("head") or "").strip()
|
|
205
|
+
tail = str(s.get("tail") or "").strip()
|
|
206
|
+
if head:
|
|
207
|
+
rows.append("- 第 %d 章开笔:「%s」" % (ch, head[:60]))
|
|
208
|
+
if tail:
|
|
209
|
+
rows.append("- 第 %d 章收束:「…%s」" % (ch, tail[-70:]))
|
|
210
|
+
if not rows:
|
|
211
|
+
return ""
|
|
212
|
+
return ("## 跨章复用红线(起草前必读)\n"
|
|
213
|
+
"此前各章已用的开笔/收束形态如下——本章不得再以同款句式开笔或同型"
|
|
214
|
+
"句式收束;同一动作句式全书至多两次,第二次必须换载体或升级信息量,"
|
|
215
|
+
"连读时章尾节奏不得趋同:\n" + "\n".join(rows) + "\n")
|
|
216
|
+
|
|
217
|
+
|
|
114
218
|
def fingerprint(summary):
|
|
115
219
|
"""Normalize a signal_summary into per-1000-char style metrics."""
|
|
116
220
|
if not isinstance(summary, dict):
|
package/app/core/pipeline.py
CHANGED
|
@@ -2311,8 +2311,8 @@ def _run_direct(run, task, agents, ev, stats, mode):
|
|
|
2311
2311
|
if first:
|
|
2312
2312
|
prompt = ""
|
|
2313
2313
|
if task.get("type") == "rank_scan" and bi is not None:
|
|
2314
|
-
# 扫榜选材(借鉴 oh-story
|
|
2315
|
-
# AI 做选题洞察;抓取失败回落普通直连提示词
|
|
2314
|
+
# 扫榜选材(借鉴 oh-story 扫榜):抓七猫/番茄/起点/纵横四平台排行榜
|
|
2315
|
+
# 公开数据注入,AI 做选题洞察;抓取失败回落普通直连提示词
|
|
2316
2316
|
prompt = paihang.rank_scan_prompt(task.get("goal") or "") or ""
|
|
2317
2317
|
if task.get("type") == "defect_retro" and bi is not None:
|
|
2318
2318
|
# 缺陷复盘(借鉴 test-defect-retrospective):三视角分析框架
|
|
@@ -2919,6 +2919,7 @@ __VOLUME__
|
|
|
2919
2919
|
__LOCKED_CH__
|
|
2920
2920
|
__STALE_NOTE__
|
|
2921
2921
|
__REDO_ISSUES__
|
|
2922
|
+
__REUSE_GUARD__
|
|
2922
2923
|
- 正文约 __WORDS__ 字,中文,直接开写正文(可含本章标题行)。
|
|
2923
2924
|
|
|
2924
2925
|
## 前情提要(此前各章结尾摘录,衔接用)
|
|
@@ -3085,6 +3086,33 @@ def _wc(text):
|
|
|
3085
3086
|
return len(re.sub(r"\s", "", text or ""))
|
|
3086
3087
|
|
|
3087
3088
|
|
|
3089
|
+
def _reuse_guard_samples(workdir, upto, window=4, min_words=200):
|
|
3090
|
+
"""收集此前各章的开笔/收束摘录(起草负样例,防跨章句式同款——105-112 批
|
|
3091
|
+
「落笔入册」收束 8 章用 4 次被判 major 的根治手段之一:评审事后抓 → 起草
|
|
3092
|
+
事前给反面样例)。只看近 window 章(更早的句式影响衰减);过短/读不到的
|
|
3093
|
+
章静默跳过。"""
|
|
3094
|
+
samples = []
|
|
3095
|
+
for j in range(max(1, int(upto) - int(window)), int(upto)):
|
|
3096
|
+
t = _read_chapter(workdir, j)
|
|
3097
|
+
if not t or _wc(t) < int(min_words):
|
|
3098
|
+
continue
|
|
3099
|
+
body = re.sub(r"\s+", " ", t.strip())
|
|
3100
|
+
samples.append({"chapter": j, "head": body[:80], "tail": body[-100:]})
|
|
3101
|
+
return samples
|
|
3102
|
+
|
|
3103
|
+
|
|
3104
|
+
def _dup_reject_note(notes):
|
|
3105
|
+
"""查重打回后的重写指令块:把上一稿被拦截的重复证据逐条下发。"""
|
|
3106
|
+
lines = novel_quality.format_duplicate_notes(notes)
|
|
3107
|
+
if not lines:
|
|
3108
|
+
return ""
|
|
3109
|
+
return ("\n\n## 确定性查重拦截(必读)\n"
|
|
3110
|
+
"上一稿因整段/整句逐字重复未通过落盘验收,已被打回重写。重写时必须"
|
|
3111
|
+
"消除以下重复——删并重复内容、保留信息量最高的一处;若为有意的复诵"
|
|
3112
|
+
"或复沓,必须有动作/归属铺垫并改写措辞,不得逐字再现:\n- "
|
|
3113
|
+
+ "\n- ".join(lines) + "\n")
|
|
3114
|
+
|
|
3115
|
+
|
|
3088
3116
|
_ANCHOR_EDGE_PUNCT = "。!?,、;:…—·,.!?;:\"'“”‘’()()[]【】《》<>*#-"
|
|
3089
3117
|
|
|
3090
3118
|
|
|
@@ -3901,6 +3929,11 @@ def _run_serial_review(run, task, agents, ev, stats, mode, critics, impl, route,
|
|
|
3901
3929
|
redo_lines += _major_lines(book_lvl)
|
|
3902
3930
|
redo_note = ("## 上一轮评审未达标原因(必读)\n" + "\n".join(redo_lines) + "\n"
|
|
3903
3931
|
) if redo_lines else ""
|
|
3932
|
+
# 跨章复用红线负样例:此前各章实际的开笔/收束摘录随起草下发,把
|
|
3933
|
+
# 「评审事后抓句式同款」前移成「起草事前看反面样例」(105-112 批
|
|
3934
|
+
# 章末收束句式 4 连用被判 major 的根治;首批第 1 章无样例为空块)
|
|
3935
|
+
reuse_guard = novel_quality.reuse_guard_block(
|
|
3936
|
+
_reuse_guard_samples(workdir, i))
|
|
3904
3937
|
# stable_order:同一任务 8 个章节的技能块必须字节级一致(§07 T1.2' 前缀缓存)
|
|
3905
3938
|
# 三块分开留底:起草重试的分层降级(_serial_shrunk_block)要按
|
|
3906
3939
|
# 「经验库/圣经」各自的身份收缩,折成一整块就只剩 4K 硬截一层了
|
|
@@ -3940,6 +3973,7 @@ def _run_serial_review(run, task, agents, ev, stats, mode, critics, impl, route,
|
|
|
3940
3973
|
.replace("__LOCKED_CH__", serial_locked_chapter_block(workdir, i))
|
|
3941
3974
|
.replace("__STALE_NOTE__", stale_note)
|
|
3942
3975
|
.replace("__REDO_ISSUES__", redo_note)
|
|
3976
|
+
.replace("__REUSE_GUARD__", reuse_guard)
|
|
3943
3977
|
.replace("__REVIEW_RUBRIC__", rubric_block)
|
|
3944
3978
|
.replace("__HIGHLIGHT__", ch.get("highlight") or "按剧情要点自然铺设一处小冲突/小反转")
|
|
3945
3979
|
.replace("__STYLE__", style_tpl)
|
|
@@ -3956,9 +3990,14 @@ def _run_serial_review(run, task, agents, ev, stats, mode, critics, impl, route,
|
|
|
3956
3990
|
# ——2026-09-17 七猫连载实测:多 run 并行推进时后位章节必撞限流,
|
|
3957
3991
|
# 一章失败即整 run 作废,太贵。
|
|
3958
3992
|
def _chapter_state():
|
|
3959
|
-
"""
|
|
3993
|
+
"""草稿验收:成品是章稿文件本身,不是退出码——文件够长且无
|
|
3994
|
+
逐字重复才算好。整段/整句/完整对白逐字重复是成稿事故(113/
|
|
3995
|
+
118 章实案两处整段连排、对白复现,评审 major 一票否决+白烧
|
|
3996
|
+
一轮评审),落盘时确定性拦截打回,省下评审再抓的往返。"""
|
|
3960
3997
|
txt = _read_chapter(workdir, i)
|
|
3961
|
-
|
|
3998
|
+
if not txt or _wc(txt) < int(wpc * 0.6):
|
|
3999
|
+
return False, (txt or "")
|
|
4000
|
+
return not novel_quality.duplicate_notes(txt), txt
|
|
3962
4001
|
|
|
3963
4002
|
res = None
|
|
3964
4003
|
good = False
|
|
@@ -3971,6 +4010,7 @@ def _run_serial_review(run, task, agents, ev, stats, mode, critics, impl, route,
|
|
|
3971
4010
|
prev_prompt = None # 上一次实际下发的提示词
|
|
3972
4011
|
prev_timed_out = False # 上一次是否「超时/停滞」收场
|
|
3973
4012
|
shrink_note = "" # 本次重试的分层降级说明(进 step note 供对账)
|
|
4013
|
+
dup_fix_note = "" # 查重打回后的消重指令(重试/换将随提示词下发)
|
|
3974
4014
|
for draft_attempt in range(3):
|
|
3975
4015
|
if draft_attempt:
|
|
3976
4016
|
# 30s / 60s 退避;ev.wait 睡等可被取消即刻唤醒
|
|
@@ -3986,7 +4026,11 @@ def _run_serial_review(run, task, agents, ev, stats, mode, critics, impl, route,
|
|
|
3986
4026
|
# 30KB 对讯飞必挂)
|
|
3987
4027
|
shrunk_block, shrink_note = _serial_shrunk_block(
|
|
3988
4028
|
sk_lessons, bible, kb_block)
|
|
3989
|
-
use_prompt = prompt.replace(sk_block, shrunk_block)
|
|
4029
|
+
use_prompt = prompt.replace(sk_block, shrunk_block) + dup_fix_note
|
|
4030
|
+
elif draft_attempt and dup_fix_note:
|
|
4031
|
+
# 同作者重试带上一稿的重复证据(消重指令)——同提示重跑
|
|
4032
|
+
# 只会长出同族事故,新变量才值得烧(同 2026-09-22 超时教训)
|
|
4033
|
+
use_prompt = prompt + dup_fix_note
|
|
3990
4034
|
# 超时重试必须有新变量才值得做(2026-09-22):提示词与上次逐字节
|
|
3991
4035
|
# 相同、上次又是超时/停滞收场时,重试只是把同一个超时再烧一遍
|
|
3992
4036
|
# (2400s × N)。此时直接跳出交替换将——换 CLI/模型才是新机会。
|
|
@@ -4014,6 +4058,10 @@ def _run_serial_review(run, task, agents, ev, stats, mode, critics, impl, route,
|
|
|
4014
4058
|
good, txt = _chapter_state()
|
|
4015
4059
|
if good:
|
|
4016
4060
|
break
|
|
4061
|
+
if txt:
|
|
4062
|
+
_dups = novel_quality.duplicate_notes(txt)
|
|
4063
|
+
if _dups:
|
|
4064
|
+
dup_fix_note = _dup_reject_note(_dups)
|
|
4017
4065
|
if res["ok"] and _wc(res.get("text") or "") >= int(wpc * 0.6):
|
|
4018
4066
|
# 回复正文就是完整章稿(kimi 35B 实测:正文当消息回而不
|
|
4019
4067
|
# 落盘)→ 代为落盘救回成品
|
|
@@ -4024,6 +4072,10 @@ def _run_serial_review(run, task, agents, ev, stats, mode, critics, impl, route,
|
|
|
4024
4072
|
pass
|
|
4025
4073
|
if good:
|
|
4026
4074
|
break
|
|
4075
|
+
if txt:
|
|
4076
|
+
_dups = novel_quality.duplicate_notes(txt)
|
|
4077
|
+
if _dups:
|
|
4078
|
+
dup_fix_note = _dup_reject_note(_dups)
|
|
4027
4079
|
if ev is not None and ev.is_set():
|
|
4028
4080
|
break
|
|
4029
4081
|
# 同作者重试穷尽 → 起草换将:按路由分序逐个试备选(最多 2 个,
|
package/app/core/planner.py
CHANGED
|
@@ -266,6 +266,10 @@ __SKILLS__
|
|
|
266
266
|
不强制每章都打脸、反转或以悬念断章;
|
|
267
267
|
- 章末可自然收束或留白;大纲中的 highlight 描述主要戏剧/情绪变化或回报,无显著爆点时写清叙事功能,不要强造爆点。
|
|
268
268
|
- 大纲中的情感转折必须给出触发事件和人物选择,不能只写“误会加深/感情升温”;
|
|
269
|
+
- 开笔方式与收束形态批内轮换:相邻章不得用同型句子开笔(如连续多章以「第X日/
|
|
270
|
+
清晨」时间戳起笔),收束形态(落笔定格、悬置问句、场景切换、对话收拍、动作
|
|
271
|
+
停顿等)同一形态全批至多两次,第二次必须换载体或升级信息量——章尾节奏趋同
|
|
272
|
+
是批量生成最易露馅的指纹;
|
|
269
273
|
- style_anchor 是全书唯一的文风锚,每章起草/修订/评审都会注入:必须写明视角人称与句长基调等可执行约束,不要空话;
|
|
270
274
|
- highlight 是本章主要情绪/戏剧变化或读者回报,可为爽、暖、痛、惊、趣味、亲密、发现、安定等;
|
|
271
275
|
平静或过渡章节可承担必要功能,不为填字段伪造高潮;
|
|
@@ -293,6 +297,9 @@ __SKILLS__
|
|
|
293
297
|
- 在关键章节写清人物选择、阻碍与后果;不要求每章都有完整冲突闭环或悬念钩子,避免无功能重复;
|
|
294
298
|
- 复杂情感必须落到触发事件、动作/生理反应和潜台词,不能用一句概括代替;
|
|
295
299
|
- 延续既定叙述视角和语言锚点(见下方既定文风锚),删掉重复复述,避免节奏变慢;
|
|
300
|
+
- 开笔方式与收束形态批内轮换:相邻章不得用同型句子开笔(如连续多章以「第X日/
|
|
301
|
+
清晨」时间戳起笔),收束形态同一形态全批至多两次,第二次必须换载体或升级
|
|
302
|
+
信息量——章尾节奏趋同是批量生成最易露馅的指纹;
|
|
296
303
|
- 题材健康,无违规内容,符合平台签约调性。
|
|
297
304
|
__VOLUMES__
|
|
298
305
|
|
package/app/ui/app.js
CHANGED
|
@@ -451,7 +451,7 @@ function renderTypeOptions() {
|
|
|
451
451
|
if (prev && flowById(prev) && (S.typeTouched || prev !== "direct")) sel.value = prev;
|
|
452
452
|
// 偏好记忆:上次创建用的类型优先于出厂默认「直接执行」(老数据/已删流程回落)
|
|
453
453
|
else if (S.lastPrefs && S.lastPrefs.type && flowById(S.lastPrefs.type)) sel.value = S.lastPrefs.type;
|
|
454
|
-
//
|
|
454
|
+
// 首屏默认落在「直接执行」(快档位:直连模型 API,无拆解/评审);
|
|
455
455
|
// 老数据或该流程被删时保持首项,不硬造一个不存在的值
|
|
456
456
|
else if (flowById("direct")) sel.value = "direct";
|
|
457
457
|
applyTaskPreferenceDefaults();
|
|
@@ -14699,8 +14699,7 @@ async function suStartupCheck() {
|
|
|
14699
14699
|
}
|
|
14700
14700
|
|
|
14701
14701
|
/* ---------------------------------------------------------- 页签 & 初始化 */
|
|
14702
|
-
const TAB_TITLES = { overview: "概览", tasks: "任务", runs: "运行记录", automation: "自动化", browser: "浏览器", zentao: "禅道 Bug 自动修复", __wxdigest: "群摘要", usage: "用量统计", agents: "本机智能体", models: "模型接入", bindings: "模型调度(可选)", skills: "经验库", knowledge: "知识库", market: "插件市场", orch: "编排设置", data: "数据与备份", appearance: "皮肤", about: "关于与更新" };
|
|
14703
|
-
const SET_TABS = new Set(Object.keys(TAB_TITLES)); // 全部设置子页(__phone 是弹框,不算)
|
|
14702
|
+
const TAB_TITLES = { overview: "概览", tasks: "任务", runs: "运行记录", automation: "自动化", browser: "浏览器", zentao: "禅道 Bug 自动修复", __wxdigest: "群摘要", usage: "用量统计", agents: "本机智能体", models: "模型接入", bindings: "模型调度(可选)", skills: "经验库", knowledge: "知识库", market: "插件市场", orch: "编排设置", evalbench: "模型评测", data: "数据与备份", appearance: "皮肤", about: "关于与更新" };
|
|
14704
14703
|
|
|
14705
14704
|
function tabTitle(name) {
|
|
14706
14705
|
return t(TAB_TITLES[name]) || t("设置");
|
package/app/ui/i18n.js
CHANGED
|
@@ -1409,7 +1409,6 @@
|
|
|
1409
1409
|
"直连引擎(单智能体直达,无拆解/评审,快)": "Direct engine (single-agent straight through — no decomposition/review, fast)",
|
|
1410
1410
|
"直接执行": "Direct run",
|
|
1411
1411
|
"让 AI 直接做什么(一句话,可带附件)": "What should the AI just do? (one sentence, attachments welcome)",
|
|
1412
|
-
"单智能体直达:目标+附件交给一个 CLI 跑完即止,无拆解/评审(快)": "Single-agent straight through: goal + attachments go to one CLI and that's it — no decomposition or review (fast)",
|
|
1413
1412
|
"发现新版本,点击前往更新": "New version found — click to update",
|
|
1414
1413
|
"已忽略该版本提醒,可随时在「关于与更新」里升级": "This version's reminder is dismissed — upgrade anytime in \"About & Updates\"",
|
|
1415
1414
|
"已是最新版": "Already the latest version",
|
package/package.json
CHANGED