Fix #1611: classifyTopic fails when summarizer uses Anthropic endpoint (Kimi Code)#2133
Conversation
…MemTensor#1611) `Summarizer.classifyTopic` and `Summarizer.arbitrateTopicSplit` always dispatched to the OpenAI implementation regardless of the summarizer's configured provider. When configured against an Anthropic-only endpoint (e.g. Kimi Code's `/coding/v1/messages`), every call returned 404 because the OpenAI helper appended `/chat/completions` to a URL that does not exist — wasting tokens, polluting logs, adding event-loop latency. Fix (Option A from the issue): - Add native classifyTopic{Anthropic,Gemini,Bedrock} and arbitrateTopicSplit{Anthropic,Gemini,Bedrock} in the three provider files, mirroring the shape of the existing judgeNewTopic* helpers. - Re-export TOPIC_CLASSIFIER_PROMPT / TOPIC_ARBITRATION_PROMPT from openai.ts so all providers share prompt strings and parseTopicClassifyResult remains the single JSON parser — no behavioral drift across providers. - Rewire callTopicClassifier / callTopicArbitration switch statements so the anthropic / gemini / bedrock arms route to their native implementations instead of falling through to the OpenAI helpers. - Bedrock helpers require cfg.endpoint (throws `Bedrock topic-classifier|arbitration requires 'endpoint'`) matching every other Bedrock helper in the file. - Mirror every edit into packages/memos-core/src/ingest/providers/ so the byte-similar sibling tree cannot silently regress the bug after the next sync. Tests: new tests/topic-classifier-dispatch.test.ts (8 cases) stubs globalThis.fetch and asserts each provider hits the correct URL + body shape; includes a regression case where an Anthropic 404 surfaces an `Anthropic topic-classifier failed` error rather than the old `OpenAI topic-classifier failed` — the exact string from issue MemTensor#1611. TDD baseline: 7/8 fail against buggy code. Post-fix: 8/8 pass. Existing tests/topic-judge-minimax-1315.test.ts (5/5) continues to pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
🤖 Open Code ReviewTarget: PR #2133 🔍 OpenCodeReview found 11 issue(s) in this PR. 1.
|
🔧 Open Code Review requested Agent fixOpen Code Review found 14 issue(s). I have resumed the development Agent to fix them.
The Agent will push a new commit to this PR branch. OCR will recheck after the commit is pushed. |
…eview Address code-review findings on the topic-classifier + arbitrator dispatch helpers added in MemTensor#2133 (issue MemTensor#1611). Applied to both apps/memos-local-openclaw and packages/memos-core (byte-similar mirrors). Correctness / security fixes: - anthropic: validate cfg.apiKey up front instead of silently sending ""; move cfg.headers spread BEFORE x-api-key + anthropic-version so a misconfigured header cannot silently overwrite the credential - anthropic: guard content parsing — treat missing/non-array json.content as [] to avoid TypeError on unexpected API payloads - anthropic: reduce arbitrateTopicSplit max_tokens from 60 to 10 to match arbitrateTopicSplitOpenAI (single-word NEW/SAME reply) - gemini: validate cfg.apiKey up front; construct URL via new URL() + URLSearchParams so a caller-supplied endpoint that already contains a query string ("?version=v1beta") does not produce malformed "…?version=v1beta?key=…" - bedrock: emit warn log when arbitrateTopicSplit sees empty or unexpected text so silent bias toward SAME becomes visible at normal log levels (production usually suppresses debug) Intentionally not applied (out-of-scope refactors that would touch pre-existing helpers not in this PR): DRY-extract shared low-level callers for anthropic/gemini/bedrock (findings MemTensor#4/MemTensor#7/MemTensor#10/MemTensor#14) and the DEFAULT_BEDROCK_MODEL constant (finding MemTensor#11). Existing tests unchanged: tests/topic-classifier-dispatch.test.ts (8/8) and tests/topic-judge-minimax-1315.test.ts (5/5) still pass. The new guards use apiKey values already provided by every test case, so no test edits were required. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
✅ Automated Test Results: PASSEDAll tests passed (17/17 executed). memos_local_openclaw/unit: 8/8, memos_local_plugin/unit: 9/9. Duration: 6s [advisory, non-gating] AI-generated tests on branch test/auto-gen-75ef940b99925b96-20260721122708: 84/86 passed, 2 failed — these do NOT affect the PR verdict; review the branch manually. Branch: |
🔧 Open Code Review requested Agent fixOpen Code Review found 12 issue(s). I have resumed the development Agent to fix them.
Repeated findings are prioritized because the previous repair did not converge. |
…fier providers Round 1 (commit 646c28a) did not fully converge OCR review. Round 2 targets the 2 repeated findings and 10 newly detected ones without expanding scope beyond the classifier/arbitration functions added by PR MemTensor#2133. Bedrock (packages/memos-core + apps/memos-local-openclaw): - Fix TRUE MISS from Round 1: `arbitrateTopicSplitBedrock` was still using `maxTokens: 60` while Anthropic's arbitrator was already lowered to 10. Aligned to `maxTokens: 10`. - Introduce `DEFAULT_BEDROCK_TOPIC_MODEL` constant scoped to the two new functions only (`classifyTopicBedrock`, `arbitrateTopicSplitBedrock`). Pre-existing helpers (`judgeDedupBedrock`, `summarizeBedrock`, etc.) keep their inline default to stay out of scope. - Extract `bedrockConverseTopic()` shared transport used by the two new functions to eliminate the DRY duplication OCR flagged. Gemini (packages/memos-core + apps/memos-local-openclaw): - Add empty/unexpected-response `log.warn` branches to `arbitrateTopicSplitGemini`, mirroring the Bedrock arbitrator's defensive handling (Round 1 covered Bedrock only). - Extract `callGeminiTopic()` shared transport used by the two new functions to eliminate the DRY duplication OCR flagged. - Rejected escalating the empty-response case to `throw`: throwing would cascade through `Summarizer.tryChain` and burn tokens on every fallback; warn+default-to-SAME is the safer choice for a boundary detector. Anthropic (packages/memos-core + apps/memos-local-openclaw): - Extract `callAnthropicMessagesTopic()` shared transport used by the two new functions to eliminate the DRY duplication OCR flagged. Header spread order is preserved verbatim: `...cfg.headers` comes BEFORE the credential and `anthropic-version` so user-supplied headers cannot override them (this was the Round 1 security fix — do not undo). Pre-existing helpers in each provider are intentionally untouched to keep the diff minimum-scoped to PR MemTensor#2133's classifier/arbitrator additions. Verification (executed in apps/memos-local-openclaw): - `./node_modules/.bin/vitest run tests/topic-classifier-dispatch.test.ts \\ tests/topic-judge-minimax-1315.test.ts` → 13/13 passed - `./node_modules/.bin/tsc --noEmit` on the 3 modified provider files → 0 errors - All 6 files (3 apps + 3 packages/memos-core mirrors) are byte-identical
|
Description
Fixed issue #1611:
Summarizer.classifyTopicandSummarizer.arbitrateTopicSplitin the memos-local-openclaw plugin used to unconditionally dispatch to the OpenAI implementation, so any summarizer configured against an Anthropic-only endpoint (e.g. Kimi Code's/coding/v1/messages) had every classification call return 404 — the OpenAI helper appended/chat/completionsto a URL that doesn't exist. The fix implements Option A from the issue: added six new native transport helpers (classifyTopic{Anthropic,Gemini,Bedrock}andarbitrateTopicSplit{Anthropic,Gemini,Bedrock}) mirroring the shape of the existingjudgeNewTopic*helpers, and rewired bothcallTopicClassifierandcallTopicArbitrationswitch statements so theanthropic/gemini/bedrockarms route to their native implementations instead of falling through to the OpenAI helpers.To prevent prompt drift across providers,
TOPIC_CLASSIFIER_PROMPT/TOPIC_ARBITRATION_PROMPTare exported fromopenai.tsand re-imported by the three provider files;parseTopicClassifyResultcontinues as the single JSON parser. The byte-similar duplicate atpackages/memos-core/src/ingest/providers/received identical edits so a future re-sync between the two trees cannot silently regress the bug. Bedrock helpers requirecfg.endpoint, matching every other Bedrock helper in the file.Tests: added
apps/memos-local-openclaw/tests/topic-classifier-dispatch.test.tswith 8 cases that stubglobalThis.fetchand assert each provider hits the correct URL + body shape. TDD baseline was 7/8 failing against the buggy code — the anthropic case surfaces the exactOpenAI topic-classifier failed (404)string from the issue. Post-fix: 8/8 pass. Existingtopic-judge-minimax-1315.test.ts(5/5) continues to pass, andtask-processor.test.tsregressions match baseline exactly.tsc --noEmiton the modified provider files is clean.Files: 5 modified + 1 new in
apps/memos-local-openclaw/, 5 mirrored inpackages/memos-core/. Total 11 files, 876 insertions, 14 deletions. Branch pushed toorigin/feature/autodev-1611-20260721033002951; scheduler will create the PR and add reviewers.Related Issue (Required): Fixes #1611
Type of change
Please delete options that are not relevant.
How Has This Been Tested?
Automated tests are pending.
Checklist
@whipser030, @hijzy please review this PR.
Reviewer Checklist