127 Commits

Author SHA1 Message Date
姚章浩 16ee1ddfbe fix(ci): 存量历史提交只告警不拦截,新增提交仍严格校验
build / build (push) Successful in 18s
把早已推送到其它远端分支的 lineage 合进 main 时,被带进来的提交不是本次新增,
它们标题不合规属既有事实。闸门先抓全部远端分支头,用 git branch -r --contains
取证:能证明已存在于其它远端分支的只告警放行;证不出来的照旧拦截(fail-closed)。
2026-11-11 16:42:15 +08:00
姚章浩 d24457d9d5 Merge remote-tracking branch 'origin/fix/weknora-timeout-nolimit' into HEAD
build / build (push) Failing after 4s
2026-11-11 15:18:47 +08:00
zheromiku 1b42ac7765 ci: 接入提交规范闸门与自动编译流水线(本机Runner+微信通知)
build / build (push) Has been cancelled
2026-09-28 18:38:36 +08:00
zheromiku 65490b1aaa ci: 接入提交规范闸门与自动编译流水线(本机Runner+微信通知)
build / build (push) Has been cancelled
2026-09-28 18:38:34 +08:00
zheromiku f803365a20 ci: 接入提交规范闸门与自动编译流水线(本机Runner+微信通知)
build / build (push) Has been cancelled
2026-09-28 18:38:33 +08:00
姚章浩 70b144f1e5 fix(weknora): drop 120s client total timeout so long agent streams are not cut
The weknora HTTP client used a hardcoded 120s total-duration timeout, which
kills any smart-reasoning agent stream that legitimately runs longer (22 tool
rounds measured in prod) and the failure branch then overwrote the already
streamed card with the error text. Pass 0 and keep Go's default (no timeout).
2026-09-22 16:10:07 +08:00
姚章浩 1bbaf2f07a fix(outboundtext): keep resource handles intact when normalizing formulas 2026-09-18 17:14:45 +08:00
姚章浩 48b741984f fix(reasoning): never cut a lead-in that carries an image 2026-09-18 16:49:16 +08:00
姚章浩 5ccaeb3b96 fix(outbound): keep single-run answers whole and show formulas
The DingTalk binding can point at the quick-answer agent, which publishes the
whole answer as one answer run plus tool_call/tool_result steps. The narration
boundary was rejected for that shape (start=0), so the text-only heuristic ran
and dropped the answer lead-in together with its image.

- answer_observation: a single answer run means there is no narration to cut.
- outboundtext: rewrite LaTeX formulas into plain Unicode text, because
  DingTalk cards render no math typesetting (r = sqrt(X^2 + Y^2) -> r = √(X² + Y²)).
- dingtalk handler: normalize formulas on both the partial and final card paths.
2026-09-18 16:21:42 +08:00
姚章浩 dfce8cb9f6 test(qa): pin the answer-run boundary used to trim narration
Adds the production CRA5 shape (narration run + tool steps + final answer run
that opens with a lead-in and an image) and a control case where the last
answer run is interrupted by a tool call and the heuristic still applies.
2026-09-18 15:58:14 +08:00
姚章浩 149e94b34b fix(reasoning): keep the answer body's lead-in and images when trimming narration
The DingTalk card dropped the answer's opening (and any image reference in
it) whenever the agent narrated its steps before answering: the text-only
boundary heuristic (reasoningmode.BodyStartOffset) treats everything before
the first structural line as narration, so a lead-in like "我已经找到了…"
plus the image that follows it disappeared, leaving the card to start at
the first heading.

The event stream already knows the boundary: every agent step publishes its
answer chunks under its own answer run id (data.event_id), and the final
body is the last run that no tool/thinking event interrupts. WeKnora
StreamEvent now carries the run id and run start offset; qa.Service tracks
the observation and prefers it over the heuristic, falling back to the
heuristic when the stream carries no run information.

Verified: production turn efae317e (给我CRA5的负载图) lost 131 chars —
lead-in + the load-curve image + separator — and now keeps them.
2026-09-18 15:53:43 +08:00
hermes dd229ec0ad feat(dingtalk): per-frame wide-table grouping (stream keeps tables flowing while streaming) 2026-09-18 11:55:45 +08:00
hermes 92324b4242 feat(dingtalk): make wide-table grouping switchable for wide-screen PC cards
DINGTALK_CARD_WIDE_TABLE_GROUP=off keeps over-wide answer tables as tables on the final frame (still replaces <br> inside cells) so the PC wide-screen card can lay them out itself.
2026-09-18 11:45:55 +08:00
agent 882ac62433 perf(dingtalk): compress outbound screenshots, reuse uploaded objects, raise rewrite budget
- outboundimage: re-encode large PNG/JPEG screenshots as downscaled JPEG (1600px long edge, q82, transparency flattened onto white) before upload; undecodable, small, GIF/WebP payloads are published untouched
- outboundimage: StableHashPublisher skips the upload when the content-addressed object already exists (ObjectStater); OSS store implements it via IsObjectExist
- cmd/dobotai: DOBOTAI_OUTBOUND_IMAGE_REWRITE_TIMEOUT default 60s -> 180s; DOBOTAI_OUTBOUND_IMAGE_COMPRESS (on by default, off restores raw bytes)
2026-09-18 11:14:13 +08:00
agent 8a9c1eaf82 perf(dingtalk): rewrite answer images concurrently and make the rewrite budget configurable
- outboundimage: fetch and publish up to 4 images in parallel, dedupe in document order, log per-image outcome plus a rewrite summary
- dingtalk handler: OutboundRewriteTimeout applies to the image rewrite stage only, falling back to finalDeliveryTimeout
- cmd/dobotai: DOBOTAI_OUTBOUND_IMAGE_REWRITE_TIMEOUT (default 60s, invalid values fall back)
2026-09-18 10:57:32 +08:00
agent 9de1ed66aa feat(dingtalk): make outbound image count configurable (DOBOTAI_OUTBOUND_IMAGE_MAX_COUNT, default 12) 2026-09-18 10:16:14 +08:00
姚章浩 cfe3271fa2 feat(dingtalk): fall back to the public image URL and report image ref shape
The loopback fetch now degrades to the public URL ...
2026-09-17 18:20:02 +08:00
姚章浩 dfc7c8dba9 feat(dingtalk): deliver card images through DingTalk media ids
AI card bodies render only DingTalk-hosted media, so published image URLs are
rewritten into media ids inside card content (streaming frames never block,
final frame waits briefly), while the markdown fallback keeps external URLs.
2026-09-17 18:14:03 +08:00
姚章浩 06d11135e1 deploy(prod): 生产切换脚本(门控字面量+回滚标签+env 0600 备份) 2026-09-17 14:25:30 +08:00
姚章浩 5f1206b545 fix(dingtalk): 推理正文边界支持「首行即正文」并补齐卡片结构诊断 + 流式分帧重放守卫 2026-09-17 14:16:40 +08:00
姚章浩 a1a2aabab4 fix(dingtalk): 推理正文边界支持「首行即正文」并补齐卡片结构诊断
- BodyStartOffset:内容首个非空行即结构行时正文从头开始,避免收尾裁剪
  把标题+首段一起删掉(118 条生产样本中 31 条、最多 526 字)
- 语料回归守卫:隐藏前缀不得含结构行、上限 600 字;单测补 suffix 断言
- 卡片诊断新增 body_ok/body_line/body_prefix_runes/banner_pos/first_heading_line
  (定位流式残留推理末句,只看结构不看文本)
2026-09-17 14:01:10 +08:00
姚章浩 fcca33050a test: 通用的测试服镜像切换脚本(先打回滚标签+env 0600 备份,读回校验) 2026-09-17 11:08:23 +08:00
姚章浩 cd3f92aaaa verify: 合并宽屏自适应与推理输出改造(测试服验证用) 2026-09-17 11:03:05 +08:00
姚章浩 15f2a11162 fix(dingtalk): 推理模式卡片隐藏推理并只留正文
- reasoningmode: 新增正文边界识别(结构行 + 前置空行)与流式 PartialFeed:
  分步叙述按行拼接显示,正文开始时只输出正文,卡片更新即刷新清掉推理区
- dingtalk: 事件流与流式回调统一改走 PartialFeed
- qa: 推理执行的最终答案在入库/投递前去掉步骤叙述(快速模式行为不变)

语料回归:生产 118 条内建智能推理答案中 106 条识别出正文边界(被隐藏的
均为 59-164 字过渡句),12 条无推理的问候类答案保持原样;go vet 与
go test ./... 全绿。
2026-09-17 10:58:59 +08:00
hermes-agent a096ba5f51 fix(dingtalk): 投放 AI 卡片时开启宽屏自适应布局
PC 端卡片宽度过窄:创建卡片(createAndDeliver)请求体从未请求宽屏布局。

修复落在创建卡片的 JSON 载荷层 —— cardData.cardParamMap 的钉钉保留系统
字段 sys_full_json_obj 内传 {"config":{"autoLayout":true}}。config 为
对象类型,钉钉规定复杂类型变量必须走该保留字段;放在 cardParamMap 兄弟
节点会因变量未赋值而静默失效(宽度不变、无报错)。

- 仅影响 PC 宽屏渲染;移动端保持自适应布局不变。
- 未改动富文本组件宽度/padding,也未改动模板内静态内容。
- 流式更新(streaming)请求体不带该字段,避免中途变更布局。

新增回归守卫测试:投放体(direct/group)必须含该字段且 autoLayout=true,
流式更新体必须不含;防止退化为静默失效写法。

验证:gofmt 干净、go vet ok、go test ./... 全绿;
A/B 探针(A 带字段 / B 对照)经 PC 端人工确认 A 卡片变宽。
2026-09-17 09:59:39 +08:00
zheromiku ba090d1705 Merge pull request 'feat: default smart reasoning and robust channel delivery' (#16) from feat/default-reasoning-mode into main 2026-09-15 17:13:32 +08:00
姚章浩 4e65028d1d fix(dingtalk): strip leaked internal source handles 2026-09-15 17:08:33 +08:00
姚章浩 c7d2629a77 fix(coverage): let references override partial no-answer wording 2026-09-15 16:53:12 +08:00
姚章浩 b49cb5eaf9 feat(dingtalk): normalize wide tables into grouped lists on final card 2026-09-15 16:09:43 +08:00
姚章浩 16aa981028 test(reasoning): cover default-mode routing, user pinning and 000022 contract 2026-09-15 14:01:00 +08:00
姚章浩 f800127461 feat(reasoning): support operator-configurable default mode via DOBOTAI_DEFAULT_MODE 2026-09-15 12:25:09 +08:00
姚章浩 d6a781ba5b fix(dingtalk): send answer language via Accept-Language header
WeKnora's system prompt hard-enforces 'ALWAYS respond in {{language}}',
fed by its Language middleware (WEKNORA_LANGUAGE env -> Accept-Language
header -> zh-CN fallback). The previous localizedQuery() prompt prefix
lost against that instruction, so a user-set 'en' preference still got
Chinese answers on English questions.

- AgentChatRequest.Locale is transmitted as the Accept-Language header
  (never in the JSON body); WeKnora maps it to the prompt language
- 'auto' detects the query script client-side (latin->en, Han->zh-CN,
  kana->ja, Hangul->ko); es is never auto-guessed
- unset/unknown locale sends no header, preserving prior server behavior
- drop localizedQuery prompt prefixes entirely
2026-09-14 16:58:52 +08:00
姚章浩 168e401bc0 docs(deploy): table the optional outbound-image OSS fields 2026-09-11 20:38:06 +08:00
zheromiku 58b37f1c24 Merge pull request 'fix(deploy): configure outbound image OSS as an optional group' (#15) from feat/docker-external-rds into main 2026-09-11 18:48:56 +08:00
姚章浩 6a3f505965 fix(deploy): configure outbound image OSS as an optional group 2026-09-11 18:48:15 +08:00
zheromiku a0f1fbf391 Merge pull request 'feat(deploy): external-RDS Docker deployment with fielded RDS config' (#14) from feat/docker-external-rds into main 2026-09-11 18:39:20 +08:00
姚章浩 49e0789fa5 feat(deploy): prompt RDS config as separate fields 2026-09-11 18:04:38 +08:00
姚章浩 d77fbd675b fix(deploy): honor configured Go module proxy 2026-09-11 17:27:20 +08:00
姚章浩 a615693bd0 fix(deploy): configure distinct quick and reasoning agents 2026-09-11 13:26:17 +08:00
姚章浩 febf99b549 fix(deploy): generate internal tenant key automatically 2026-09-11 13:20:44 +08:00
姚章浩 b4b61c0aa5 fix(deploy): explain missing RDS database to administrators 2026-09-11 12:25:31 +08:00
姚章浩 6153533b46 fix(deploy): isolate installer command directory 2026-09-11 12:10:08 +08:00
姚章浩 27d4d45af4 feat(deploy): run Docker application against external RDS 2026-09-11 12:09:29 +08:00
zheromiku a31156dc4e Merge pull request 'docs: 清理历史计划并说明仓库目录结构' (#13) from feat/cli-admin-bootstrap into main 2026-09-11 10:18:28 +08:00
姚章浩 f408096611 docs: document repository structure and remove stale plan 2026-09-11 10:17:03 +08:00
hermes-bot 218ab657d6 Merge pull request 'Feat/cli admin bootstrap' (#12) from feat/cli-admin-bootstrap into main
Reviewed-on: #12
2026-09-10 22:38:04 +08:00
姚章浩 5c5e4494cb test(migrations): cover non-knowledge response reason 2026-09-10 22:25:48 +08:00
姚章浩 e584b17929 docs(dobotai): add container deployment guide 2026-09-10 22:25:19 +08:00
姚章浩 8027635330 fix(coverage): skip alerts for non-knowledge text turns 2026-09-10 22:02:59 +08:00
姚章浩 563329320b docs(dobotai): guide container credential input 2026-09-10 18:31:55 +08:00