Wyatt_K
7c01d29a0d
fix(agent): 创作引导 - 使用可点选项并控制工具描述预算 ( #607 )
2026-09-23 16:26:40 +08:00
itsWyatt-K
33baecde28
feat(agent): 技能用量 - 按用户运行日志统计检索与读取 ( #590 )
2026-09-23 16:22:44 +08:00
Wyatt_K
ec81a1b92b
feat(skills): 场景预设 - 提供公开只读目录并校验内置技能引用 ( #603 )
2026-09-23 16:01:27 +08:00
Wyatt_K
7ebdd06268
fix(skills): 技能门房 - 推荐商店真名并标注上架状态
2026-09-23 13:58:16 +08:00
Wyatt_K
c4879421c3
fix(skills): 技能种子 - 同步合规改造后的 judian-skills 指令
2026-09-23 13:53:39 +08:00
Wyatt_K
bca47a27bc
fix(agent): skill_search tokenizer keeps single CJK runes
...
cloudAgentSkillSearchTokens dropped any token shorter than 2 runes.
That filter was copied from English stop-word logic (a / I), but a single
Han rune such as the ones meaning hook, gag or twist is already a complete
semantic unit in Chinese. When the whole keyword consisted of such runes,
tokens came back empty and cloudAgentSearchSkills degraded to listing the
full index of enabled skills - the user thinks a search happened but gets
an unsorted dump.
Fix: keep a token when it is exactly one Han rune (unicode.Han); single
ASCII/digit runes and empty strings are still dropped as before.
Test: TestCloudAgentSkillSearchTokensKeepsSingleCJKRune fails on the old
logic (got [反转 钩子], want [反转 钩子 梗 钩]) and passes after the fix.
recall_lessons has an isomorphic copy of the same tokenizer, fixed
separately in #593 .
2026-09-22 16:30:07 +08:00
Wyatt_K
23b4b2adde
fix(agent): recall_lessons tokenizer keeps single CJK runes
...
cloudAgentLessonSearchTokens dropped any token shorter than 2 runes.
That filter was copied from English stop-word logic (a / I), but a single
Han rune such as the ones meaning hook, gag or twist is already a complete
semantic unit in Chinese. When the whole keyword consisted of such runes,
tokens came back empty and cloudAgentSearchLessons silently fell back to
"list the first N lessons" - the user thinks a search happened but gets an
arbitrary list.
Fix: keep a token when it is exactly one Han rune (unicode.Han); single
ASCII/digit runes and empty strings are still dropped as before.
Test: TestLessonSearchTokensKeepsSingleCJKRune fails on the old logic
(got [反转 钩子], want [反转 钩子 梗 钩]) and passes after the fix.
The isomorphic copy in skill_search (cloud_agent_tools.go) is fixed
separately on the #580 branch and deliberately not included here.
Gates: go build ./... and go vet EXIT=0; gofmt clean on LF content; the 3
go-sqlite3 cgo-stub failures in internal/app are pre-existing and unrelated.
2026-09-22 15:59:34 +08:00
Codex Audit
7737047a8d
perf(media): OSS 资源 - 通过签名地址直连下载并禁止浏览器代理媒体
2026-09-23 11:10:20 +08:00
Codex Audit
8436904316
fix(backend): Agent 任务 - 限制循环读取并收紧提交后的取消边界
2026-09-23 11:09:57 +08:00
ddCat
5f9b010932
feat(auth): 登录注册 - 添加短信通知与组合验证支持
2026-09-22 23:46:15 +08:00
ddCat
a66799b1f2
fix(media): 资源分发 - 统一 CDN 读取签名与源站降级边界
2026-09-22 23:26:28 +08:00
ddCat
b9c7439c2f
fix(media): 资源分发 - 补齐存储配置类型并修正后端构建
2026-09-22 22:25:05 +08:00
ddCat
487c34bfeb
refactor(media): 资源分发 - 统一资源访问策略与云存储重定向
2026-09-22 21:41:00 +08:00
ddCat
48a82ded74
feat(media): 作品保存恢复 - 按原任务重试交付并避免重复生成计费
2026-09-22 15:47:24 +08:00
ddCat
acbb354e97
fix(canvas): Agent 识图 - 交付真实图片字节并纠正视觉状态
2026-09-22 15:27:10 +08:00
ddCat
7c4495623f
fix(skills): 种子测试 - 跟随最新域包名称校验公开搜索
2026-09-22 13:13:26 +08:00
ddCat
ed5335ddcc
feat(skills): 技能种子 - 同步最新域包与展示媒体
2026-09-22 13:09:42 +08:00
ddCat
423291247a
fix(skills): 合并兼容 - 替换已删除种子回归夹具
2026-09-22 12:55:15 +08:00
ddCat
7fec0484e6
fix(integration): 批量整合 - 合入 13 个 PR 并保留安全边界
2026-09-22 12:46:20 +08:00
itsWyatt-K
3fb703dd2d
feat(skills): 为 34 个域包种子条目补演示媒体(信息卡片图)
...
官方 36 个技能里 33 个带 showcaseMedia,我们 0 —— 技能库列表页上,
有图和没图是两个点击率。本次给 34 个域包各配一张信息卡片图。
- 图片存放于 itsWyatt-K/judian-skills 的 showcase/ 目录,随仓库版本化,
URL 形如 https://raw.githubusercontent.com/itsWyatt-K/judian-skills/main/showcase/pack- <slug>.png
- 选信息卡片而非 AI 抽卡图的理由:卡片传递「这个技能能干什么」的真实信息
(名称/一句话能力/卡数/代表卡),AI 示例图与技能方法关联弱、只是装饰且风格杂乱;
示例成片待有真实使用案例后再补
- 门房 scene-recipe-concierge 是路由技能、无域包图,本轮不配图
校验:34 个条目填入,逐个通过 GitHub API 确认图片存在于仓库后才写 URL。
条目总数与 skill_id 未改动。
2026-09-22 12:34:00 +08:00
ddCat
40b9650b56
refactor(skills): 技能种子 - 修正作者归属时间并收敛文档口径
2026-09-22 12:09:03 +08:00
itsWyatt-K
b5b485d7d0
fix(skills): 修复种子条目重复——上一次同步把 35 条旧条目留下了
...
上一个提交 ce89c402 的替换逻辑有 bug:计算了剔除集合却没有使用,
导致 35 条旧英文 slug 条目与 35 条新中文名条目同时存在,
skills.json 条目数 68 → 103,skill_id 出现重复。
本次修正为「先剔除旧条目,再把新条目插到第一个旧条目原来的位置」:
- 条目总数回到 68(33 官方 + 35 域包)
- skill_id 全部唯一
- 我们的 35 条 tag 分布 drama 15 / creative 12 / ecommerce 5 / social 2 / others 1
- description 全部 <=500 且不含「蒸馏自《XX」」
教训:批量替换类操作必须在推送前校验「条目总数与 ID 唯一性」,
我上次只校验了新条目自身,没校验合并结果。
2026-09-22 12:06:12 +08:00
itsWyatt-K
ce89c40287
feat(skills): 种子条目同步 v2.0.0 改造成果(中文名 / tag 五分类 / 新话术)
...
v2.0.0 已把 34 个域包改造为中文名、tag 对齐影策五分类、description 首句改为
「我能帮你产出什么」并移除「蒸馏自《XX」」,但 skills.json 里的种子条目仍是
旧英文 slug 与旧话术,影策市场一条都没收到。本次把改造成果真正送进上游通道。
- 35 条种子条目 skill_name 全部中文化(含门房「选包门房」)
- tag 对齐影策五分类:drama 15 / creative 12 / ecommerce 5 / social 2 / others 1
- description 首句改「我能帮你产出什么」,全部 ≤500 字符且不含「蒸馏自《XX」」
- ID 区间 73-107 与上一版完全一致,未新增或改动任何编号
同步来源:itsWyatt-K/judian-skills seed-contribution/seed-addition-packs.json
2026-09-22 12:02:36 +08:00
ddCat
f4e5c73eb2
test(agent): 执行边界 - 覆盖环境超时范围校验
2026-09-22 11:59:14 +08:00
ddCat
2af633caec
feat(auth): 注册协议 - 合并同意校验并顺延迁移版本
2026-09-22 11:58:49 +08:00
ddCat
e40465a1c3
fix(agent): 工具协议 - 控制技能工具 schema 体积
2026-09-22 11:50:03 +08:00
ddCat
979705e38a
fix(agent): 执行边界 - 遵守策略上限并压缩工具协议
2026-09-22 11:43:42 +08:00
ddCat
9d9cec8e2e
fix(skills): 技能文件包 - 修复旧数据迁移回填元数据超限
2026-09-22 11:28:32 +08:00
ddCat
17377ce6e4
feat(agent): 技能检索 - 整合卡片索引并保留看图与布局工具
2026-09-22 11:27:42 +08:00
ddCat
76613edadc
fix(agent): 合并回归 - 保留当前输入提示与任务租约安全边界
2026-09-22 11:21:38 +08:00
ddCat
2cbe80369b
Merge remote-tracking branch 'origin/pr-589' into codex/pr-557-589-security-integration
...
# Conflicts:
# docs/content/docs/backend/http-api.mdx
2026-09-22 11:20:54 +08:00
ddCat
1d43d2d986
Merge remote-tracking branch 'origin/pr-588' into codex/pr-557-589-security-integration
2026-09-22 11:19:54 +08:00
ddCat
6a4180230e
Merge remote-tracking branch 'origin/pr-587' into codex/pr-557-589-security-integration
...
# Conflicts:
# backend/internal/app/cloud_agent_runtime.go
2026-09-22 11:19:54 +08:00
ddCat
f500bc3951
Merge remote-tracking branch 'origin/pr-586' into codex/pr-557-589-security-integration
2026-09-22 11:10:48 +08:00
ddCat
6f4bc29524
Merge remote-tracking branch 'origin/pr-585' into codex/pr-557-589-security-integration
2026-09-22 11:10:48 +08:00
ddCat
e8811ace34
Merge remote-tracking branch 'origin/pr-580' into codex/pr-557-589-security-integration
2026-09-22 11:05:37 +08:00
ddCat
e46f599dc2
Merge remote-tracking branch 'origin/pr-584' into codex/pr-557-589-security-integration
2026-09-22 11:05:08 +08:00
ddCat
4bea8cb7b6
Merge remote-tracking branch 'origin/pr-577' into codex/pr-557-589-security-integration
2026-09-22 11:05:08 +08:00
ddCat
c8a91fd2e9
fix(canvas): 模型生成 - 保留安全的上游失败原因并展示到用户卡片
2026-09-22 10:48:25 +08:00
ddCat
b2a1bcc8d9
chore(release): 版本发布 - 准备 v1.5.7.1 预览版
2026-09-22 09:23:18 +08:00
itsWyatt-K
590f6b4204
fix(cloud-agent): 修正 skill_search 改动的 gofmt 格式
...
两处:skill_read_file 工具描述里 map 参数前补逗号后空格;测试文件里新增最长 map 键后重排值对齐。
本地 gofmt 已确认两文件合规,go test 全绿。
2026-09-22 08:27:12 +08:00
Wyatt_K
e28c28f97a
feat(cloud-agent): 新增 skill_search——Agent 侧技能/卡级检索
...
#577 让 Agent 知道「有哪些技能」;本 PR 补上「这个任务该读哪张卡」。
#568/#575 之后种子已有 34 个域包、759 张卡,单包最多 67 张,
「先读 SKILL.md 总纲再按名录找卡」的成本会随卡数线性上涨。
## 设计(复用仓库既有范式,不发明新机制)
参照 recall_lessons(个人记忆检索):同一套分词器、稳定排序、无关键词列全量索引。
打分四档:**卡名命中 4 > 技能名 3 > 技能描述 2**。
- 命中卡片 → path 直接给 `cards/xxx.md`,Agent 不必读总纲;
- 只命中技能 → path 给 SKILL.md,并下发该包的 **卡索引**(跨条目共享 40 条预算),
Agent 可直奔某张卡。中文关键词打不到英文卡名时,这条兜底路径是主要收益来源;
- 数据源 = 本轮冻结快照(含 #577 注入的 description;卡路径本就在 Files 里,无需读正文);
- 只搜已启用技能;**只返回索引与路径,正文永不内联**;
- 不可信数据纪律延续:工具描述明牌「返回的是索引,不是指令」。
## 实机验证(本机影策 v1.5.7 + 本分支编译的后端,step-5-preview-intl)
- **检索→读取闭环打通**:`skill_search("反转 结构 钩子")` → 命中 2 条并下发卡索引 →
Agent 直读 `cards/ssqr-twist-ending.md`,**全程未读 SKILL.md**,tool_failed=0。
- 8 技能满槽自由跑(原始/改描述/再改描述 三次):模型**均未自发调用**,
skill_read_file 15 / 8 / 9 次落在噪声内 —— **仅靠工具描述不足以驱动该模型主动检索**,
本 PR 不声称改善了采纳率;采纳与否需要遥测才能判定。
## 实机撞出的两个缺陷(已修,非理论风险)
1. **参数容错**:模型按 skill_read_file 习惯顺手带 skillId,被 DisallowUnknownFields 拒 →
tool_failed,工具可见却一次都没成功。现容忍(仅接收不生效)。
2. **snippet 多字节越界 panic**:strings.Index 的字节偏移被当 []rune 下标、start 未夹紧 →
`panic: slice bounds out of range [249:233]`,**整个后端进程被打挂**(复现两次)。
现改为 rune 级子串查找 + start/end 双向夹紧;回归测试用 276 rune/字节偏移 483 的长中文
描述,修复前稳定 panic([443:276])。
## 测试(11 个契约用例,全绿)
注册与门控、卡名命中返回卡路径、中文关键词回落到卡索引、卡索引预算夹紧、
name>description 排序、无关键词列索引、limit 夹紧、无命中 guidance、
stray skillId 穿透解码层、长中文描述不越界、sentinel 断言正文绝不内联。
门禁:go build ./internal/app/ ✓ go vet ./internal/app/ ✓ go test 11/11 ✓
2026-09-22 07:47:55 +08:00
Wyatt_K
04bbbf642e
fix(cloud-agent): skill_search 两处实机缺陷——skillId 容错与 snippet 多字节越界
...
两个缺陷都是实机验证时撞出来的,不是理论风险。
1) 参数容错:Agent 首次调用时按 skill_read_file 的参数习惯顺手带上 skillId
({"keyword": "...", "skillId": "<已启用技能ID>"}),而参数解码走
decodeCloudAgentJSONObject(DisallowUnknownFields),直接拒绝 → tool_failed。
结果是工具在清单里可见、却一次都没调用成功。
- args struct 增加 SkillID(json:"skillId,omitempty"),仅接收不生效——
检索范围恒为本轮已启用技能;
- 工具描述补「不要传 skillId——本工具搜索全部已启用技能」,从源头减少误传;
- 回归测试走完整的工具分发路径(cloudAgentReadTool),真正穿透解码层,
并断言该字段不会缩小检索范围。
2) snippet 越界 panic(更严重):cloudAgentSkillSnippet 用 strings.Index 拿
**字节偏移**,却拿它去切 **[]rune**。中文描述里关键词越靠后、字节偏移越远
超 rune 数,start 没有夹紧到 len(runes),触发
panic: runtime error: slice bounds out of range [249:233],
**整个后端进程被打挂**(实测复现两次)。
- 改为 rune 级子串查找(cloudAgentSkillRuneIndex),不再混用字节与 rune 下标;
- start/end 双向夹紧,并补 start>end 兜底;
- 回归测试用 276 rune、命中词字节偏移 483 的长中文描述,
在修复前稳定 panic([443:276]),修复后通过。
3) 工具描述补充检索引导(提示文本,非行为改动):
- skill_search:明写「当本轮启用了多个技能、而你不确定该读哪一个时,先用本工具检索」;
- skill_read_file:补「若本轮启用了多个技能且不确定该读哪一个,先用 skill_search 检索再读」——
放在这里是因为模型一定会用到 read_file,提示的可达性高于只写在 search 自己的描述里。
实测:同一 8 技能满槽任务跑 3 次(原始描述 / 只改 search 描述 / 再改 read_file 描述),
step-5 **三次都没自发调用** skill_search,skill_read_file 次数 15 / 8 / 9(噪声内)。
即:**仅靠工具描述不足以驱动该模型自发检索**,需要系统提示层路由或遥测来验证采纳,
本 PR 不声称改善了采纳率。
门禁:go build ✓ go vet ✓ go test 8/8 ✓
2026-09-22 03:35:24 +08:00
AetherNo2332
1637bb9536
fix(cloud-agent): 布局工具参数错误按字段归类,审批卡补整理徽标
...
- canvas_arrange_nodes 的参数契约错误改用上游既有的 cloudAgentFieldError:
snapshotHash 缺失按 required、mode/align/gap/nodeIds/groups 非法按 invalid_value、
nodeIds/groups 超限按 item_count。原先一律 BadAuthRequest(*AppError),按上游运行期的
errors.As 顺序会走 failCloudAgentAdmission 把整轮判死,模型拿不到可纠正回执。
- 审批卡补 .canvas-agent-approval-operation-arrange_nodes 徽标配色(与新增/修改/连线同一组),
并补一条前端用例:arrange_nodes 预览项不得被 operation() 当成未知值丢掉。
2026-09-22 01:40:43 +08:00
AetherNo2332
6a216dddc2
perf(cloud-agent): 画布事件 - 整理类变更只下发几何增量
...
一次整理几十个节点时,canvas_updated 仍按整节点下发完整 before/after,单条事件会超过
validateCloudAgentRuntime 的 128KiB 单事件上限,整轮直接失败。
- 新增 cloudAgentShrinkChange:仅当 before/after 除 position/width/height/zIndex 之外
完全一致(且无键被删)时,只下发 id 与变化的几何字段;带内容或 metadata 变化的节点仍发
完整 before/after,不影响前端的三方合并与生成任务状态保护。
- 新增用例覆盖"几何变化只发增量"与"内容变化 / 键被删仍发完整对象"。
2026-09-22 01:32:32 +08:00
AetherNo2332
9d0bce6bb5
fix(cloud-agent): 续轮交接 - 用有界结构化事实帧替代跨轮散文收束
...
续轮(POST /agent/runs 带 parentId)过去只把「上一轮已结束(failed)。…已提交生成任务:
a, b」这段散文塞进下一轮历史:新轮看不到上一轮真实改过哪些节点,也无法可靠区分「这是
服务端交接」还是「用户自己写的一句话」。
- 与轮内既有事实帧(cloud_agent_context_frame.go 的 task_repository 帧)同构,把跨轮交接
也改成有界结构化帧:source=server、kind=run_handoff,带 parentRunId / status /
failureReason / submittedTaskIds / canvasChanges / omittedCanvasChanges / authority。
画布改动取自上一轮真实 canvas_updated 事件,最多 12 组(operation、去重后的
nodeId/title、actionCount),超出只记 omittedCanvasChanges,不静默丢。
- 身份改由 providerTextMessage.AgentContextSource 结构体字段承载,canonical 装配时原样
透出;isCloudAgentContinuationMessage 要求「来源元数据 + 【运行状态】前缀 + JSON
source=server/kind=run_handoff」三者同时成立,用户逐字复制帧 JSON 也拿不到该身份
(此前按内容前缀猜,用户自己写一句「上一轮已结束(…)」就会被认成交接)。
- 旧格式兼容:升级前落库的散文交接没有来源字段,改按「紧跟 assistant 回复 + 旧版文案
前缀」识别,只用于历史裁剪与轮次计数;canonical 身份仍只认结构体字段。
- cloudAgentLegacyHistory 重建时把落库的 agentContextSource 一起搬,身份不在重建口丢失。
- 帧按字节封顶:单个 nodeId 截 64 字符、整帧 8 KiB,超限按最近改动优先裁剪并累计
omittedCanvasChanges;失败原因过既有脱敏口径 cloudAgentSafeUserMessage。
- 不搬运 dev 专有内容:不引入事件读取上限常量(上游本就返回全量事件),硬闸口径按上游
的 64 KiB 注释,也不引入 `dropped := 0` / `_ = dropped` 这类死代码。
- docs/content/docs/backend/http-api.mdx 补帧字段与「非授权」口径。
帧只被 isCloudAgentContinuationMessage 用于「历史怎么裁、怎么数轮」;写入与收费闸门读的
是落库策略(审批闸、生成次数闸、视频秒数闸、工具授权),不读消息内容,因此帧不构成重放
写入、重复提交付费任务或扩大权限的授权依据。
2026-09-22 01:32:21 +08:00
AetherNo2332
56598108d4
feat(canvas): 云端 Agent 画布布局 - 新增 canvas_arrange_nodes 与新增节点自动落位
...
云端 Agent 此前只能新建节点与连线,既不会排版也不能移动已有节点:模型只能用几十个
update_node 手算坐标,或者让用户自己拖。
- 新增 backend/internal/canvas/layout:把前端既有的画布布局算法(web/src/lib/canvas/
canvas-layout.ts,本 PR 不改该文件)按同一套常量移植到服务端,提供 Kahn 拓扑分层 flow、
媒体泳道 byType、row/column/grid、对齐与等距、分组分带、AABB 重叠检测与空位搜索。
- 新增写工具 canvas_arrange_nodes:snapshotHash 必需,mode∈{auto,flow,byType,row,column,
grid},可传 nodeIds、groups(只做横向位置分带,不建容器、不改层级)、align、gap、dryRun。
只改坐标,不改内容、不建连线、不增删节点;一次最多 50 个节点 / 12 组。锁定节点、背板等
容器、隐藏批次子节点与已归属背板的子节点保持不动并在回执里说明;整批复用现有 mutation
记录与事件管线,审批与撤销走同一条路径。
- add_node 省略坐标时不再落到 (0,0):优先贴合本批连线的对端(输入在左、输出在右),否则
追加到同泳道同类节点之后,冲突则扫描空位;只给一个轴时保留该轴。agentCanvasOp.X/Y 改为
指针以区分"没给坐标"与"坐标 0"。
- update_node 的 patch 新增 x/y(PatchField.Limit 校验 ±1e6),供模型微调单个节点。
- 系统行为策略新增「布局与整理」一节并升版到 8;docs 补工具说明与工具全集;前端同步审批
预览联合类型、面板文案与徽标。
- 工具 schema 预算按实测从 24000 上调到 25000(21 个工具 24788 字节),并改正注释里
"上游约 23.4 KB"的说法(上游 20 个工具实测 22777 字节)。
2026-09-22 01:32:20 +08:00
AetherNo2332
080e4b901e
feat(cloud-agent): 看图工具 canvas_inspect_image 与同批多图工具结果配对
...
云端 Agent 过去只能凭标题或提示词猜画面:上游既有的 image_text_detect / image_annotation_render
是"组织 OCR 请求"和"渲染标注图当参考"两种不同能力,模型自己从不看像素。本 PR 新增只读工具
canvas_inspect_image,把画面本身交给模型。
- 交付走与生成任务参考图同一套短时签名链接(providerResourceURL),Agent 上下文只增长一个
URL,不内联 base64:一张 500 KB 的内联图片会同时顶穿请求体硬限与压缩阈值。
- 能力门控:仅当本轮渠道模型声明 text.references.maxImages > 0 时暴露该工具;VisionEnabled 在
建 run 时按渠道模型合同定格并持久化(工具授权每步从落库状态重建,客户端传入值被忽略)。
- 上下文治理:图片保留最近 3 个工具轮次,同一张图一轮内最多附图 2 次(之后只回执文字,确需
重看传 refresh=true),超出保留轮次换成逐图文字占位符并落 context_images_pruned 事件。
- 视觉锚点:模型看过后写进正文的一句观察记入 ReferenceAssets[].VisualNote 并跨轮继承,下一轮
不必重复看图,也不再对这张图声称"没有视觉识别证据"。
- 同批多图合并成一条 user 消息:图片只能挂 user 消息(tool 角色只接受字符串),逐张 append 会让
历史退化成 tool → user(图) → tool → user(图),被上游以"tool_calls 之后缺少对应 tool 消息"
拒绝。改为先缓冲到 PendingImageInspections,等整批 tool 结果入历史后合并成一条;两个 flush 点
共用同一个幂等助手,ask_user 提前结束路径单独 flush。缓冲必须进检查点:一次推进只执行一个
调用,整批跨越多次转移,每次转移都从 StateJSON 重新解码。
- 附带把上述 400 从"渠道余额不足"归类里拆出来(原文含 insufficient 会落进额度类目掩盖真因),
归为"会话里的工具调用与结果不匹配"。
- 文档补该能力口径与工具全集条目;前端零改动。
2026-09-22 01:32:07 +08:00
AetherNo2332
63c9e32259
feat(cloud-agent): 单步输出上限与秒级墙钟,超时/空输出可自恢复
...
画布 Agent 一轮要跑很多步模型调用,此前只有"按任务类型的分钟级超时":某一步卡住只能等
整轮判死;更根本的是每一步请求根本不带输出上限,不写 max_tokens 时上游按剩余上下文放行,
思考模型可以把单步拖到几分钟,且偶发把整个输出预算花在推理上、正文与工具调用皆空。
- 新增运行时策略 task.agentStepTimeoutSeconds 与 task.agentStepMaxOutputTokens:秒级墙钟
与单步输出上限,都支持环境变量给部署级默认值、管理端热更新;旧配置 JSON 缺字段按默认值
回填,无需数据迁移。
- 单步墙钟到点中止这一步时不再把整轮判死:以可识别标记记为该步失败,运行期关掉上游思考
重试同一步一次(model_failure_recovered / step_timeout_retried),重试仍超时才以可读原因
(model_step_timeout)结束本轮。
- 空输出催办用尽后新增一级升级:关思考 + 放大输出预算重试同一步
(model_failure_recovered / empty_output_escalated),而不是直接判死。放大档在原值上翻倍
并以 131072 封顶,策略值为 0 时用 32768 兜底,让重试仍然有界。
- 输出上限真正下发到上游:textOptions.maxOutputTokens 成为任务信封字段,Agent 的两条请求
路径(内置协议与声明式协议)组装请求体时写入 max_tokens / max_output_tokens,与既有的
input.MaxOutputTokens 取较小值,避免策略上限超过模型声明的物理上限。
- task_worker:执行时限改用带画布 Agent 分支的 taskExecutionTimeout;执行时限到点本身不再
被当成"租约丢失",否则任务会停在 running 等租约过期后被反复重跑(实测一次调用被重跑成
三次上游请求)。续租仍用上游已合入的"不继承父 context 取消"的独立 context。
2026-09-22 01:20:36 +08:00
AetherNo2332
4e2df72eeb
fix(cloud-agent): 工具失败归类与可行动字段
...
工具失败此前只有一句自然语言(tool_failed + text),无法区分"模型自己出的错"和真实的
权限/状态/上游问题:模型拿不到可自纠的反馈,排查时分不清该改提示词、改权限还是等上游。
- 新增 backend/internal/app/cloud_agent_tool_error_class.go:把失败归成
invalid_model_output(幻觉工具名;本轮契约之外、只被 contextScope 挡掉的调用)、
schema_error(缺必填字段/类型错/未知字段/非法 JSON)、state_conflict(画布在读取之后被改动)、
permission_violation(只读轮发起写入等真实授权边界)、upstream_failure(上游 4xx/5xx、
超时、媒体上游拒绝),其余归 tool_error。
- 每类附 retryable 与稳定的 requiredAction(fix_arguments / reread_canvas /
use_advertised_tools / ask_user / report_to_user),写进 tool_failed 的回执与载荷顶层。
只加标注:没有任何放行或拒绝逻辑读它。
- 缺必填字段的通用判定:各工具的校验点抛的多是普通 AppError,从错误类型看不出"模型漏了字段"。
现在用本轮实际暴露的 schema 的 required 与参数比对,命中即按参数契约错误处理(回传 schema 与
guidance 供模型自纠);只在业务侧确实按参数问题拒绝(400/422)时套用,已分类的参数错误不套壳。
- 幻觉工具名的拒绝文案更具体:过去一律"工具未获本轮权限授权",现在指向"不存在的工具 + 只使用
本轮工具表里列出的工具"。
- 前端工具卡失败时显示归类标签,比统一的"执行失败"更能说明下一步该做什么。
2026-09-22 00:53:32 +08:00