fix(kimi): keep monitor robust against K2.6 redesign noise
Desktop Client Build / Resolve Build Metadata (push) Has been cancelled
Desktop Client Build / Build Desktop Client (push) Has been cancelled
Desktop Client Build / Publish Client Artifacts to NAS (push) Has been cancelled
Frontend CI / Frontend (push) Successful in 6m6s

K2.6 introduced new UI surfaces that polluted the answer extraction and
the busy-signal probe, breaking monitor runs even though Kimi rendered a
correct answer:

- collectCandidates now drops elements that contain a chat composer child
  (<textarea>, non-hidden <input>, [contenteditable]). This filters
  wrapper containers like .chat-detail-content that the wide
  [class*="content"] fallback would otherwise pick, pulling editor
  placeholder text ("可快捷使用技能", "Kimi K2.6 已就位") into the answer.
- isAuxiliaryPanelElement skips elements with role="dialog" /
  "alertdialog", aria-modal="true", or the <dialog> tag, so the K2.6
  launch-announcement popover ("Kimi K2.6, 已就位 / 一键部署 OpenClaw")
  no longer counts as answer content.
- Drop the class-based loading-indicator probe entirely. The previous
  global [class*="loading"]/"stream"/"typing"/"spinner" sweep matched
  K2.6's always-on text-stream wrapper and held busy=true forever, which
  caused kimi_query_timeout even after the assistant turn had fully
  rendered. The textual busySignalsPattern (思考中/搜索中/生成中…) is
  the actual semantic signal and survives any UI rename.
- Surface a capacityNotice from the assistant turn when Kimi shows its
  short capacity-exhausted message ("算力不够 / 请稍后再试"). The top
  level falls back to it when answerText is empty so the SaaS pipeline
  records the user-visible message instead of an unknown row, with
  capacity_limited / capacity_notice flagged in raw_response_json.

All filters lean on HTML form / ARIA semantics and visible text rather
than Kimi-specific BEM classes, so they survive future redesigns.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-08 21:51:49 +08:00
parent 1e6ed77453
commit 0f3a9a977e
2 changed files with 166 additions and 19 deletions
@@ -5,6 +5,8 @@ import { __kimiTestUtils } from './kimi'
const {
buildSourceItem,
classifyKimiSources,
isKimiAnswerComplete,
isKimiPromotionalAnswerNoise,
mergeKimiSourceLinksIntoContentSnapshot,
normalizeUrl,
} = __kimiTestUtils
@@ -25,6 +27,7 @@ function buildSnapshot(
answerBlocks: ['答案'],
reasoningText: null,
reasoningBlocks: [],
capacityNotice: null,
questionMatched: true,
candidateAnswerCount: 1,
candidateReasoningCount: 0,
@@ -143,4 +146,25 @@ describe('kimi adapter helpers', () => {
expect(merged.searchResultLinks).toHaveLength(1)
expect(merged.searchResultLinks[0]?.url).toBe('https://example.com/a')
})
it('rejects Kimi K2.6 marketing copy as an answer', () => {
const promotionalText = [
'Kimi K2.6,已就位!',
'Coding、Agent 集群、Kimi Claw 同步升级',
'Agent 集群,升级了',
'多技能调用,多产物类型一次性交付',
'Kimi Claw 已就位!',
'一键部署 OpenClawKimi 24小时为你干活',
].join('\n')
expect(isKimiPromotionalAnswerNoise(promotionalText)).toBe(true)
expect(
isKimiAnswerComplete(
buildSnapshot({
answerText: promotionalText,
answerBlocks: [promotionalText],
}),
),
).toBe(false)
})
})