codebee 0.1.40 → 0.1.42
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 +12 -0
- package/README.md +8 -0
- package/app/core/dispatch.py +1 -0
- package/app/core/flows.py +6 -0
- package/app/core/pipeline.py +8 -0
- package/app/core/planner.py +98 -90
- package/app/ui/i18n.js +8 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,18 @@ README 元数据带回,供老版本在「发现新版本」时展示新版更
|
|
|
6
6
|
|
|
7
7
|
## 未发布
|
|
8
8
|
|
|
9
|
+
## v0.1.42(2026-09-22)
|
|
10
|
+
|
|
11
|
+
### ✨ 新功能
|
|
12
|
+
|
|
13
|
+
- 新任务类型「标书编制」:上传招标文件,AI 按评分标准逐条应答起草投标文件——五大评审维度(应答完整性/合规符合度/方案针对性/评分点覆盖/商务清晰度),资质业绩只引真实材料(缺失标注待补,绝不虚构),应答先结论后细节,并全文自查废标风险项(密封/签章/格式/有效期)。
|
|
14
|
+
|
|
15
|
+
## v0.1.41(2026-09-22)
|
|
16
|
+
|
|
17
|
+
### 🛠 问题修复
|
|
18
|
+
|
|
19
|
+
- 断点续跑/重跑更省钱:同一任务再次生成大纲或执行计划时直接命中上次结果的精确缓存(1 小时内有效),不再重复花一次全量规划调用;大纲首试成功但格式不合规时的重试仍会重新生成(保「换一次样本」语义,不会拿同一份坏文本空转)。
|
|
20
|
+
|
|
9
21
|
## v0.1.40(2026-09-21)
|
|
10
22
|
|
|
11
23
|
### 🛠 问题修复
|
package/README.md
CHANGED
|
@@ -21,8 +21,16 @@ Kimi Code、MiMo Code、Grok Build、Pi、DeepSeek Harness……),提供
|
|
|
21
21
|
不会把你的任务内容交给任何第三方。
|
|
22
22
|
|
|
23
23
|
<!-- relnotes:start -->
|
|
24
|
+
### ✨ 新功能 · New
|
|
25
|
+
|
|
26
|
+
- 新任务类型「标书编制」:上传招标文件,AI 按评分标准逐条应答起草投标文件;资质不虚构(缺失标注待补)、应答先结论、全文自查废标风险项。
|
|
27
|
+
- New "Bid Document" task type: upload the tender file and the AI drafts point-by-point responses against scoring criteria — no fabricated credentials, conclusion-first answers, and a full disqualification-risk sweep.
|
|
28
|
+
|
|
24
29
|
### 🛠 问题修复 · Fixes
|
|
25
30
|
|
|
31
|
+
- 断点续跑/重跑更省钱:同任务再次生成大纲或计划直接命中精确缓存(1 小时内),不重复花全量规划调用;格式不合规的重试仍重新生成。
|
|
32
|
+
- Resuming or re-running a task now hits an exact cache for outline/plan regeneration (within 1 hour), skipping a full planning call; format-failure retries still regenerate.
|
|
33
|
+
|
|
26
34
|
- 修复长任务上下文撑爆后重试仍失败:压缩摘要此前只写日志、没真正替换发往模型的上下文;现在重试用「压缩摘要+最近消息」重建请求并放弃膨胀的旧会话,超长任务能真正续跑。
|
|
27
35
|
- Fixed long-task overflow retries failing again: compaction summaries used to go only to logs. Retries now rebuild the request from the summary plus recent messages and drop the bloated old session.
|
|
28
36
|
|
package/app/core/dispatch.py
CHANGED
package/app/core/flows.py
CHANGED
|
@@ -113,6 +113,12 @@ BUILTIN_FLOWS = [
|
|
|
113
113
|
"threshold": 7.0, "rounds": 2,
|
|
114
114
|
"goal_hint": "目标岗位 + 个人经历(可贴旧简历附件),几年经验投什么职级",
|
|
115
115
|
"note": "简历优化/定制:起草 → 多维评审 → 修订循环 → 发布门禁"},
|
|
116
|
+
{"id": "bid_doc", "name": "标书编制", "icon": "i-file-search", "engine": "review", "builtin": True,
|
|
117
|
+
"manuscript": "bid.md",
|
|
118
|
+
"rubric": ["应答完整性", "合规符合度", "方案针对性", "评分点覆盖", "商务清晰度"],
|
|
119
|
+
"threshold": 7.5, "rounds": 2,
|
|
120
|
+
"goal_hint": "招标文件(可作附件)+ 标段/包件 + 我方资质与业绩亮点",
|
|
121
|
+
"note": "标书/投标文件:起草 → 多维评审 → 修订循环 → 发布门禁"},
|
|
116
122
|
]
|
|
117
123
|
|
|
118
124
|
_ID_RE = re.compile(r"^[a-z][a-z0-9_-]{0,31}$")
|
package/app/core/pipeline.py
CHANGED
|
@@ -1675,6 +1675,14 @@ CONTENT_DELIVERY_CONTRACTS = {
|
|
|
1675
1675
|
"围绕目标岗位提炼真实经历,用行动、结果和技能关键词表达岗位匹配度。",
|
|
1676
1676
|
"不得虚构经历、公司、学历、指标或技术栈;缺少量化数据时保留待补提示。",
|
|
1677
1677
|
]),
|
|
1678
|
+
"bid_doc": ("投标经理", [
|
|
1679
|
+
# BidCraft 标书匠灵感(2026-09-22):逐条对齐招标文件实质性要求与评分标准
|
|
1680
|
+
"逐条对齐招标文件的实质性要求和评分标准,每个评分点都有对应的应答段落。",
|
|
1681
|
+
"资质、业绩、人员证书只引用真实材料;缺失项明确标注「待补」并说明需要哪类材料。",
|
|
1682
|
+
# sepia 分场合规则(投标文体):先结论后展开;废标项零容忍
|
|
1683
|
+
"应答开门见山给结论(满足/优于/偏离),再给支撑细节,不写套话式开头。",
|
|
1684
|
+
"全文自查废标风险项(密封/签章/格式/有效期),任何疑似偏离必须显式列出。",
|
|
1685
|
+
]),
|
|
1678
1686
|
}
|
|
1679
1687
|
|
|
1680
1688
|
|
package/app/core/planner.py
CHANGED
|
@@ -114,13 +114,13 @@ def _log_usage(source, role, task, res, agent=None, tool="", model="", provider=
|
|
|
114
114
|
except Exception:
|
|
115
115
|
pass
|
|
116
116
|
|
|
117
|
-
CODE_PLAN_PROMPT = """你是技术负责人。请把下面的开发目标拆解为 __N__ 个以内、按顺序执行的子任务,
|
|
118
|
-
并判定任务难度和后续质量步骤。只输出一个 ```json 代码块,不要输出其他内容。JSON 结构:
|
|
119
|
-
{"difficulty": "easy 或 hard", "workflow": {"review_required": true, "max_repair_rounds": 0, "allow_switch": false}, "subtasks": [{"title": "简短标题", "detail": "具体要做什么,给执行工程师的直接指令", "files": ["涉及的文件路径"]}]}
|
|
120
|
-
难度判定:常规增删改查/小函数/格式调整 = easy;跨模块改动/架构调整/复杂算法/安全相关 = hard。
|
|
121
|
-
质量步骤判定:涉及安全、数据迁移、并发、权限、公共 API 或跨模块改动时必须评审;
|
|
122
|
-
有明确自动验收的低风险小改可不做模型评审。max_repair_rounds 取 0-2,只有复杂任务才建议换将。
|
|
123
|
-
子任务粒度要可独立验证;最后一个子任务必须包含整体联调/收尾。
|
|
117
|
+
CODE_PLAN_PROMPT = """你是技术负责人。请把下面的开发目标拆解为 __N__ 个以内、按顺序执行的子任务,
|
|
118
|
+
并判定任务难度和后续质量步骤。只输出一个 ```json 代码块,不要输出其他内容。JSON 结构:
|
|
119
|
+
{"difficulty": "easy 或 hard", "workflow": {"review_required": true, "max_repair_rounds": 0, "allow_switch": false}, "subtasks": [{"title": "简短标题", "detail": "具体要做什么,给执行工程师的直接指令", "files": ["涉及的文件路径"]}]}
|
|
120
|
+
难度判定:常规增删改查/小函数/格式调整 = easy;跨模块改动/架构调整/复杂算法/安全相关 = hard。
|
|
121
|
+
质量步骤判定:涉及安全、数据迁移、并发、权限、公共 API 或跨模块改动时必须评审;
|
|
122
|
+
有明确自动验收的低风险小改可不做模型评审。max_repair_rounds 取 0-2,只有复杂任务才建议换将。
|
|
123
|
+
子任务粒度要可独立验证;最后一个子任务必须包含整体联调/收尾。
|
|
124
124
|
|
|
125
125
|
## 先探索再计划(重要,借鉴 OpenSpec explore)
|
|
126
126
|
拆解之前先用你的读文件/搜索工具**实际查看工作目录**,找到目标相关的真实文件与函数,再据此拆解。
|
|
@@ -137,12 +137,12 @@ __CONTEXT__
|
|
|
137
137
|
## 验收命令(最终必须通过)
|
|
138
138
|
__VERIFY__"""
|
|
139
139
|
|
|
140
|
-
REVIEW_OUTLINE_PROMPT = """你是内容主编。请为下面的创作任务拟一份写作大纲(要点列表,3-8 条),
|
|
141
|
-
并按内容风险建议后续质量步骤。
|
|
142
|
-
只输出一个 ```json 代码块,不要输出其他内容。JSON 结构:
|
|
143
|
-
{"outline": ["要点1", "要点2", ...], "workflow": {"reviewers": 1, "review_rounds": 1}}
|
|
144
|
-
reviewers 取 1-2,review_rounds 取 1-3;研究报告、技术方案、长文和高发布门槛应增加,
|
|
145
|
-
普通邮件、短翻译、工作汇报等低风险短内容保持 1。
|
|
140
|
+
REVIEW_OUTLINE_PROMPT = """你是内容主编。请为下面的创作任务拟一份写作大纲(要点列表,3-8 条),
|
|
141
|
+
并按内容风险建议后续质量步骤。
|
|
142
|
+
只输出一个 ```json 代码块,不要输出其他内容。JSON 结构:
|
|
143
|
+
{"outline": ["要点1", "要点2", ...], "workflow": {"reviewers": 1, "review_rounds": 1}}
|
|
144
|
+
reviewers 取 1-2,review_rounds 取 1-3;研究报告、技术方案、长文和高发布门槛应增加,
|
|
145
|
+
普通邮件、短翻译、工作汇报等低风险短内容保持 1。
|
|
146
146
|
|
|
147
147
|
## 创作任务
|
|
148
148
|
__GOAL__
|
|
@@ -327,9 +327,14 @@ def make_serial_outline(task, author_agent=None, workdir=None, ev=None, log_path
|
|
|
327
327
|
# 否则 stop_reason=max_tokens、正文为空(实测 2048 全被思考吞掉)
|
|
328
328
|
# 流式回调把增量实时写进步骤日志,直连生成不再是一行标题的黑箱
|
|
329
329
|
cb = _log_streamer(log_path)
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
330
|
+
# §07 T2.2 幂等精确缓存(TTL 1h):断点续跑/重跑同任务时大纲
|
|
331
|
+
# prompt 逐字节相同,命中省一次全量规划调用。第 2 次尝试故意
|
|
332
|
+
# 旁路缓存——首试 ok 但 JSON 不合法时,重试要的是「再抽一次样
|
|
333
|
+
# 本」而不是同一份坏文本。
|
|
334
|
+
res = modelhub.chat(prov["id"], model, prompt,
|
|
335
|
+
max_tokens=16000, timeout=300, on_delta=cb,
|
|
336
|
+
reasoning_effort=_reasoning_effort(task),
|
|
337
|
+
cache_ttl=3600 if _attempt == 1 else 0)
|
|
333
338
|
cb.flush()
|
|
334
339
|
_log_usage("outline", "outline", task, res, model=model,
|
|
335
340
|
provider=prov.get("name", prov.get("id", "")),
|
|
@@ -409,56 +414,56 @@ def _norm_subtasks(data):
|
|
|
409
414
|
return steps or None
|
|
410
415
|
|
|
411
416
|
|
|
412
|
-
def _plan_difficulty(data):
|
|
417
|
+
def _plan_difficulty(data):
|
|
413
418
|
d = str((data or {}).get("difficulty") or "").lower()
|
|
414
|
-
return d if d in ("easy", "hard") else None
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
def _plan_workflow(data):
|
|
418
|
-
"""规范化规划器给出的后续步骤建议;最终安全下限由任务编译器裁决。"""
|
|
419
|
-
raw = (data or {}).get("workflow")
|
|
420
|
-
if not isinstance(raw, dict):
|
|
421
|
-
return None
|
|
422
|
-
out = {}
|
|
423
|
-
if isinstance(raw.get("review_required"), bool):
|
|
424
|
-
out["review_required"] = raw["review_required"]
|
|
425
|
-
try:
|
|
426
|
-
if "max_repair_rounds" in raw:
|
|
427
|
-
out["max_repair_rounds"] = max(0, min(2, int(raw["max_repair_rounds"])))
|
|
428
|
-
except (TypeError, ValueError):
|
|
429
|
-
pass
|
|
430
|
-
if isinstance(raw.get("allow_switch"), bool):
|
|
431
|
-
out["allow_switch"] = raw["allow_switch"]
|
|
432
|
-
return out or None
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
def _orchestrator():
|
|
436
|
-
"""编排者可用时返回 (provider, model),否则 None。"""
|
|
437
|
-
try:
|
|
438
|
-
return modelhub.resolve_orchestrator()
|
|
439
|
-
except Exception:
|
|
440
|
-
return None
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
def _reasoning_effort(task):
|
|
444
|
-
"""把任务级思考程度映射为直连编排者支持的 reasoning 参数。"""
|
|
445
|
-
task = task if isinstance(task, dict) else {}
|
|
446
|
-
selected = str(task.get("thinking") or "standard").strip().lower()
|
|
447
|
-
if selected in ("low", "standard", "high"):
|
|
448
|
-
return {"low": "low", "standard": "medium", "high": "high"}[selected]
|
|
449
|
-
mode = str(task.get("mode") or "auto").lower()
|
|
450
|
-
difficulty = str(task.get("difficulty") or "auto").lower()
|
|
451
|
-
ttype = str(task.get("type") or "").lower()
|
|
452
|
-
try:
|
|
453
|
-
threshold = float(task.get("threshold") or 7.0)
|
|
454
|
-
except (TypeError, ValueError):
|
|
455
|
-
threshold = 7.0
|
|
456
|
-
if mode == "fast" or difficulty == "easy" or threshold <= 6.0:
|
|
457
|
-
return "low"
|
|
458
|
-
if (mode == "expert" or difficulty == "hard" or threshold >= 8.5
|
|
459
|
-
or ttype in ("research", "tech_proposal", "serial_novel")):
|
|
460
|
-
return "high"
|
|
461
|
-
return "medium"
|
|
419
|
+
return d if d in ("easy", "hard") else None
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
def _plan_workflow(data):
|
|
423
|
+
"""规范化规划器给出的后续步骤建议;最终安全下限由任务编译器裁决。"""
|
|
424
|
+
raw = (data or {}).get("workflow")
|
|
425
|
+
if not isinstance(raw, dict):
|
|
426
|
+
return None
|
|
427
|
+
out = {}
|
|
428
|
+
if isinstance(raw.get("review_required"), bool):
|
|
429
|
+
out["review_required"] = raw["review_required"]
|
|
430
|
+
try:
|
|
431
|
+
if "max_repair_rounds" in raw:
|
|
432
|
+
out["max_repair_rounds"] = max(0, min(2, int(raw["max_repair_rounds"])))
|
|
433
|
+
except (TypeError, ValueError):
|
|
434
|
+
pass
|
|
435
|
+
if isinstance(raw.get("allow_switch"), bool):
|
|
436
|
+
out["allow_switch"] = raw["allow_switch"]
|
|
437
|
+
return out or None
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
def _orchestrator():
|
|
441
|
+
"""编排者可用时返回 (provider, model),否则 None。"""
|
|
442
|
+
try:
|
|
443
|
+
return modelhub.resolve_orchestrator()
|
|
444
|
+
except Exception:
|
|
445
|
+
return None
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
def _reasoning_effort(task):
|
|
449
|
+
"""把任务级思考程度映射为直连编排者支持的 reasoning 参数。"""
|
|
450
|
+
task = task if isinstance(task, dict) else {}
|
|
451
|
+
selected = str(task.get("thinking") or "standard").strip().lower()
|
|
452
|
+
if selected in ("low", "standard", "high"):
|
|
453
|
+
return {"low": "low", "standard": "medium", "high": "high"}[selected]
|
|
454
|
+
mode = str(task.get("mode") or "auto").lower()
|
|
455
|
+
difficulty = str(task.get("difficulty") or "auto").lower()
|
|
456
|
+
ttype = str(task.get("type") or "").lower()
|
|
457
|
+
try:
|
|
458
|
+
threshold = float(task.get("threshold") or 7.0)
|
|
459
|
+
except (TypeError, ValueError):
|
|
460
|
+
threshold = 7.0
|
|
461
|
+
if mode == "fast" or difficulty == "easy" or threshold <= 6.0:
|
|
462
|
+
return "low"
|
|
463
|
+
if (mode == "expert" or difficulty == "hard" or threshold >= 8.5
|
|
464
|
+
or ttype in ("research", "tech_proposal", "serial_novel")):
|
|
465
|
+
return "high"
|
|
466
|
+
return "medium"
|
|
462
467
|
|
|
463
468
|
|
|
464
469
|
def make_code_plan(task, planner_agent, workdir, ev=None, resume=None, log_path=None):
|
|
@@ -482,10 +487,10 @@ def make_code_plan(task, planner_agent, workdir, ev=None, resume=None, log_path=
|
|
|
482
487
|
_log_usage("plan", "plan", task, res, agent=planner_agent)
|
|
483
488
|
data = runner.extract_json(res.get("text") or "")
|
|
484
489
|
steps = _norm_subtasks(data)
|
|
485
|
-
if steps:
|
|
486
|
-
return {"source": "llm(%s)" % planner_agent["id"], "steps": steps,
|
|
487
|
-
"difficulty": _plan_difficulty(data),
|
|
488
|
-
"workflow": _plan_workflow(data)}
|
|
490
|
+
if steps:
|
|
491
|
+
return {"source": "llm(%s)" % planner_agent["id"], "steps": steps,
|
|
492
|
+
"difficulty": _plan_difficulty(data),
|
|
493
|
+
"workflow": _plan_workflow(data)}
|
|
489
494
|
return _fallback_code_plan(task, "LLM 计划解析失败,退化为单步模板")
|
|
490
495
|
|
|
491
496
|
|
|
@@ -496,13 +501,15 @@ def _fallback_code_plan(task, note):
|
|
|
496
501
|
|
|
497
502
|
def _orch_code_plan(task, prov, model, log_path=None):
|
|
498
503
|
cb = _log_streamer(log_path)
|
|
504
|
+
# §07 T2.2:代码计划同任务同 prompt(断点续跑/重试),TTL 1h 精确缓存
|
|
499
505
|
res = modelhub.chat(prov["id"], model,
|
|
500
506
|
(CODE_PLAN_PROMPT.replace("__N__", str(MAX_SUBTASKS))
|
|
501
507
|
.replace("__GOAL__", task["goal"])
|
|
502
508
|
.replace("__CONTEXT__", task.get("context") or "(无)")
|
|
503
509
|
.replace("__VERIFY__", task.get("verify_command") or "(未配置)")),
|
|
504
|
-
max_tokens=8000, timeout=300, on_delta=cb,
|
|
505
|
-
reasoning_effort=_reasoning_effort(task)
|
|
510
|
+
max_tokens=8000, timeout=300, on_delta=cb,
|
|
511
|
+
reasoning_effort=_reasoning_effort(task),
|
|
512
|
+
cache_ttl=3600)
|
|
506
513
|
cb.flush()
|
|
507
514
|
_log_usage("plan", "plan", task, res, model=model,
|
|
508
515
|
provider=prov.get("name", prov.get("id", "")))
|
|
@@ -515,9 +522,9 @@ def _orch_code_plan(task, prov, model, log_path=None):
|
|
|
515
522
|
if not steps:
|
|
516
523
|
_append_log(log_path, "编排者计划返回内容无法解析为子任务,回退 CLI")
|
|
517
524
|
return None
|
|
518
|
-
return {"source": "编排者(%s · %s)" % (prov.get("name", prov["id"]), model),
|
|
519
|
-
"steps": steps, "difficulty": _plan_difficulty(data),
|
|
520
|
-
"workflow": _plan_workflow(data)}
|
|
525
|
+
return {"source": "编排者(%s · %s)" % (prov.get("name", prov["id"]), model),
|
|
526
|
+
"steps": steps, "difficulty": _plan_difficulty(data),
|
|
527
|
+
"workflow": _plan_workflow(data)}
|
|
521
528
|
|
|
522
529
|
|
|
523
530
|
def make_review_outline(task):
|
|
@@ -530,8 +537,9 @@ def make_review_outline(task):
|
|
|
530
537
|
(REVIEW_OUTLINE_PROMPT
|
|
531
538
|
.replace("__GOAL__", task["goal"])
|
|
532
539
|
.replace("__CONTEXT__", task.get("context") or "(无)")),
|
|
533
|
-
max_tokens=8000, timeout=300,
|
|
534
|
-
reasoning_effort=_reasoning_effort(task)
|
|
540
|
+
max_tokens=8000, timeout=300,
|
|
541
|
+
reasoning_effort=_reasoning_effort(task),
|
|
542
|
+
cache_ttl=3600) # §07 T2.2:同任务重试幂等,TTL 1h
|
|
535
543
|
_log_usage("outline", "outline", task, res, model=model,
|
|
536
544
|
provider=prov.get("name", prov.get("id", "")))
|
|
537
545
|
if not res["ok"]:
|
|
@@ -541,20 +549,20 @@ def make_review_outline(task):
|
|
|
541
549
|
if not isinstance(outline, list):
|
|
542
550
|
return None
|
|
543
551
|
items = [str(x).strip()[:120] for x in outline if str(x).strip()][:8]
|
|
544
|
-
if not items:
|
|
545
|
-
return None
|
|
546
|
-
workflow = data.get("workflow") if isinstance(data.get("workflow"), dict) else {}
|
|
547
|
-
try:
|
|
548
|
-
reviewers = max(1, min(2, int(workflow.get("reviewers") or 1)))
|
|
549
|
-
except (TypeError, ValueError):
|
|
550
|
-
reviewers = 1
|
|
551
|
-
try:
|
|
552
|
-
review_rounds = max(1, min(3, int(workflow.get("review_rounds") or 1)))
|
|
553
|
-
except (TypeError, ValueError):
|
|
554
|
-
review_rounds = 1
|
|
555
|
-
return {"source": "编排者(%s · %s)" % (prov.get("name", prov["id"]), model),
|
|
556
|
-
"items": items,
|
|
557
|
-
"workflow": {"reviewers": reviewers, "review_rounds": review_rounds}}
|
|
552
|
+
if not items:
|
|
553
|
+
return None
|
|
554
|
+
workflow = data.get("workflow") if isinstance(data.get("workflow"), dict) else {}
|
|
555
|
+
try:
|
|
556
|
+
reviewers = max(1, min(2, int(workflow.get("reviewers") or 1)))
|
|
557
|
+
except (TypeError, ValueError):
|
|
558
|
+
reviewers = 1
|
|
559
|
+
try:
|
|
560
|
+
review_rounds = max(1, min(3, int(workflow.get("review_rounds") or 1)))
|
|
561
|
+
except (TypeError, ValueError):
|
|
562
|
+
review_rounds = 1
|
|
563
|
+
return {"source": "编排者(%s · %s)" % (prov.get("name", prov["id"]), model),
|
|
564
|
+
"items": items,
|
|
565
|
+
"workflow": {"reviewers": reviewers, "review_rounds": review_rounds}}
|
|
558
566
|
|
|
559
567
|
|
|
560
568
|
def make_novel_plan(task, author, critics):
|
package/app/ui/i18n.js
CHANGED
|
@@ -1576,6 +1576,14 @@
|
|
|
1576
1576
|
"商务邮件": "Business Email",
|
|
1577
1577
|
"技术方案": "Tech Proposal",
|
|
1578
1578
|
"简历": "Resume",
|
|
1579
|
+
"标书编制": "Bid Document",
|
|
1580
|
+
"标书/投标文件:起草 → 多维评审 → 修订循环 → 发布门禁": "Bid/tender documents: draft → multi-dim review → revision loop → publish gate",
|
|
1581
|
+
"招标文件(可作附件)+ 标段/包件 + 我方资质与业绩亮点": "Tender documents (attachable) + lot/package + our qualifications & track-record highlights",
|
|
1582
|
+
"应答完整性": "Response completeness",
|
|
1583
|
+
"合规符合度": "Compliance",
|
|
1584
|
+
"方案针对性": "Solution fit",
|
|
1585
|
+
"评分点覆盖": "Scoring coverage",
|
|
1586
|
+
"商务清晰度": "Commercial clarity",
|
|
1579
1587
|
"扫榜选材": "Rank Scan for Topics",
|
|
1580
1588
|
"抓取七猫排行榜公开数据 → AI 提炼热门题材/人设/差异化切入点(快档直出报告)": "Grabs public Qimao ranking data → AI distills hot genres / character archetypes / differentiation angles (fast lane, report straight out)",
|
|
1581
1589
|
"想写哪个方向(一句话,可留空默认分析总榜热门题材)": "Which direction to write (one sentence; leave empty to analyze the overall hot genres)",
|
package/package.json
CHANGED