Skip to content

fix(anthropic): Curator/Tara reliability across the OAuth proxy, provider, and processors - #1117

Merged
murdore merged 1 commit into
releasefrom
fix/curator-tara-neurolink-suite
Jun 27, 2026
Merged

murdore merged 1 commit into
releasefrom
fix/curator-tara-neurolink-suite

Conversation

@murdore

@murdore murdore commented Jun 26, 2026 •

Copy link
Copy Markdown
Contributor

Consolidated single-commit PR with all the neurolink-side fixes that make Curator/Tara work reliably on the Anthropic surface — the native provider, the multi-account OAuth proxy, and the file processors — plus the tracing/test improvements found while debugging them.

Supersedes #1116 (structured-output/temperature/vision/exceljs/mammoth, approved) and folds in the previously-unraised proxy fixes (relocation + tracing). All #1116 review comments are addressed here (see below). The keep-alive feature (#1101) is intentionally not included.

OAuth proxy

  • Relocate non-CC system into the message stream. The subscription/OAuth path rejects any unrecognised system with a header-less rate_limit_error: "Error". Keeping a custom client's prompt in system[] made every Curator request fail, and the proxy misread it as a rate limit → all accounts burned over 44 retries. Now system carries only the recognised billing+agent blocks; the client prompt is wrapped in <system_instructions>…</system_instructions> as a leading user block (cache_control preserved). Genuine Claude Code traffic is detected and left untouched.
  • Fail fast on the anti-abuse 429 (no rate-limit headers, body "Error") instead of rotating every account.
  • Full request/response tracing: gen_ai.request.tool_names, gen_ai.response.model/finish_reason/tool_calls (non-streaming and streaming), proxy.account, token usage + cost, and redacted request/response body events.

Native Anthropic provider

  • Disable structured output when tools are present (native Anthropic Messages API + Bedrock) — experimental_output + tools silently drops tool calls.
  • Restore vision: AI-SDK file parts → Anthropic image/document blocks with sniffed media type; omit unsupported image/* hints (svg, bmp) instead of relabeling as PNG; runtime-validate file-part shape.
  • Omit temperature proactively for models that deprecate it; retry without it on the deprecation error (now with usage/cost telemetry on the retry span).

Processors

  • ExcelProcessor: fix exceljs CJS/ESM interop (Workbook under .default).
  • WordProcessor: patch mammoth for @xmldom/xmldom >= 0.9 (mimeType now required, errorHandler → onError) so .docx extraction works with the security-pinned xmldom.

Addressing #1116 review comments

Comment Resolution
anthropicImageBlocks.ts — skip unsupported image/* instead of relabeling as PNG (Major) Route to toAnthropicImageBlock only for the 4 supported types; unsupported image/* falls through to magic-byte salvage (omitted if not a real supported image).
structuredOutputPolicy — add native-Anthropic + Bedrock test assertions (Major) Added isToolsSchemaExclusionInForce('anthropic',…)===true and ('bedrock',…)===true to the policy suite (9/9 pass).
GenerationHandler.ts:585 — temperature-retry drops usage/cost telemetry Mirrored gen_ai.usage.input_tokens/output_tokens + neurolink.cost onto the retry span.
anthropic.ts:449 — file-part type-assertion safety Added a runtime shape/mediaType guard before the assertion; malformed parts skip gracefully.
Test files not registered in package.json Registered test:anthropic-tools-policy, test:anthropic-multimodal, test:excel-interop and added them to test:unit.

Verification

  • tsc --noEmit -p tsconfig.cli.json: 0 errors in changed files.
  • Test suites pass: anthropic-tools-policy (9/9), anthropic-multimodal, excel-interop.
  • Proxy relocation + tracing validated end-to-end against the live Anthropic OAuth path (curator opus turns 200, model/tool-calls visible in OpenObserve); docx/xlsx/vision validated through Tara.

Summary by CodeRabbit

  • New Features
    • Improved multimodal support for native file inputs (images and PDFs).
    • Enhanced tracing with caller tool-name context and richer response finish/tool metadata.
  • Bug Fixes
    • Improved handling of deprecated/unsupported temperature by retrying without it when appropriate.
    • Corrected request shaping for Claude Code vs other clients, including more reliable system/message placement.
  • Tests
    • Added continuous suites for Anthropic tools/temperature policy, Anthropic multimodal conversion, and Excel interop; expanded CI unit tier to run them.

@vercel

vercel Bot commented Jun 26, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
neurolink Ready Ready Preview, Comment Jun 26, 2026 8:58pm

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Jun 26, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: eb679a72-02af-46bd-ac73-0be4d6468781

📥 Commits

Reviewing files that changed from the base of the PR and between ffb9a7e and 2324803.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (15)
  • package.json
  • patches/mammoth@1.12.0.patch
  • src/lib/core/modules/GenerationHandler.ts
  • src/lib/core/modules/structuredOutputPolicy.ts
  • src/lib/processors/document/ExcelProcessor.ts
  • src/lib/providers/anthropic.ts
  • src/lib/providers/anthropicImageBlocks.ts
  • src/lib/proxy/oauthFetch.ts
  • src/lib/proxy/proxyTracer.ts
  • src/lib/proxy/systemRelocation.ts
  • src/lib/server/routes/claudeProxyRoutes.ts
  • src/lib/types/proxy.ts
  • test/continuous-test-suite-anthropic-multimodal.ts
  • test/continuous-test-suite-anthropic-tools-policy.ts
  • test/continuous-test-suite-excel-interop.ts
🚧 Files skipped from review as they are similar to previous changes (15)
  • test/continuous-test-suite-excel-interop.ts
  • src/lib/types/proxy.ts
  • patches/mammoth@1.12.0.patch
  • src/lib/proxy/proxyTracer.ts
  • src/lib/processors/document/ExcelProcessor.ts
  • src/lib/proxy/systemRelocation.ts
  • src/lib/core/modules/structuredOutputPolicy.ts
  • test/continuous-test-suite-anthropic-tools-policy.ts
  • src/lib/core/modules/GenerationHandler.ts
  • src/lib/providers/anthropicImageBlocks.ts
  • package.json
  • src/lib/proxy/oauthFetch.ts
  • src/lib/providers/anthropic.ts
  • test/continuous-test-suite-anthropic-multimodal.ts
  • src/lib/server/routes/claudeProxyRoutes.ts

📝 Walkthrough

Walkthrough

Adds Anthropic policy, multimodal, tracing, and request-normalization changes, plus ExcelJS interop fixes, new test scripts, and a local mammoth parser patch.

Changes

Anthropic runtime updates

Layer / File(s) Summary
Tools and temperature policy
src/lib/core/modules/structuredOutputPolicy.ts, src/lib/core/modules/GenerationHandler.ts, src/lib/providers/anthropic.ts, test/continuous-test-suite-anthropic-tools-policy.ts
structuredOutputPolicy adds native Anthropic/Bedrock tools gating and temperature helpers; GenerationHandler retries once without temperature; Anthropic request generation omits temperature for deprecated models.
Multimodal block conversion
src/lib/providers/anthropicImageBlocks.ts, src/lib/providers/anthropic.ts, test/continuous-test-suite-anthropic-multimodal.ts
Adds Anthropic image and document block helpers for byte arrays, URLs, data URLs, and file parts, with multimodal test coverage.
Proxy system and tracing
src/lib/proxy/oauthFetch.ts, src/lib/types/proxy.ts, src/lib/proxy/proxyTracer.ts, src/lib/server/routes/claudeProxyRoutes.ts
Request contexts carry tool names, response metadata is parsed into tracing, non-Claude-Code system content is relocated into messages, and deceptive 429 responses return upstream errors directly.

File processing compatibility

Layer / File(s) Summary
ExcelJS interop and test wiring
package.json, src/lib/processors/document/ExcelProcessor.ts, test/continuous-test-suite-excel-interop.ts
Adds the Excel interop test script and unit wiring, resolves exceljs Workbook from namespace or default export, and exercises .xlsx ingestion in the new suite.
mammoth XML parser patch
package.json, patches/mammoth@1.12.0.patch
Registers a local mammoth@1.12.0 patch that switches DOMParser to onError, filters non-fatal warnings, and passes text/xml to parseFromString.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • juspay/neurolink#1080 — Also updates structuredOutputPolicy and GenerationHandler fallback/retry behavior.

Suggested reviewers

  • Tara-ag
  • punyamsingh
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 55.56% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main Anthropic reliability changes across the proxy, provider, and processor layers.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/curator-tara-neurolink-suite

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

src/lib/core/modules/GenerationHandler.ts

Parsing error: Unable to parse the specified 'tsconfig' file. Ensure it's correct and has valid syntax.

error TS5012: Cannot read file '/.svelte-kit/tsconfig.json': ENOENT: no such file or directory, open '/.svelte-kit/tsconfig.json'.

src/lib/core/modules/structuredOutputPolicy.ts

Parsing error: Unable to parse the specified 'tsconfig' file. Ensure it's correct and has valid syntax.

error TS5012: Cannot read file '/.svelte-kit/tsconfig.json': ENOENT: no such file or directory, open '/.svelte-kit/tsconfig.json'.

src/lib/processors/document/ExcelProcessor.ts

Parsing error: Unable to parse the specified 'tsconfig' file. Ensure it's correct and has valid syntax.

error TS5012: Cannot read file '/.svelte-kit/tsconfig.json': ENOENT: no such file or directory, open '/.svelte-kit/tsconfig.json'.

  • 7 others

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/lib/proxy/oauthFetch.ts (1)

181-219: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract the duplicated system-relocation helper.

This helper is duplicated with src/lib/server/routes/claudeProxyRoutes.ts Line 589-Line 627. Since it encodes the OAuth anti-abuse workaround, keeping one shared implementation avoids future drift between proxy paths.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/proxy/oauthFetch.ts` around lines 181 - 219, The
relocateClientSystemIntoMessages helper is duplicated between oauthFetch and the
Claude proxy route, so the OAuth anti-abuse workaround can drift over time.
Extract this logic into a shared helper and have both call sites reuse it,
keeping the relocation behavior centralized while preserving the existing
relocateClientSystemIntoMessages behavior and message-wrapping semantics.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lib/server/routes/claudeProxyRoutes.ts`:
- Around line 4224-4248: The anti-abuse 429 check in `claudeProxyRoutes` is only
applied in the initial fetch path, but `handleAnthropicAuthRetry` still treats
matching retry 429s as real rate limits and rotates accounts. Reuse the same
`isAntiAbuseConstruction429(errRespHeaders, String(lastError))` guard inside
`handleAnthropicAuthRetry`, and when it matches, return the upstream error
response directly instead of advancing the primary account or continuing
rotation. Keep the behavior aligned with the existing construction-rejection
branch by preserving the passthrough response, logging, and tracer/error
handling.

---

Nitpick comments:
In `@src/lib/proxy/oauthFetch.ts`:
- Around line 181-219: The relocateClientSystemIntoMessages helper is duplicated
between oauthFetch and the Claude proxy route, so the OAuth anti-abuse
workaround can drift over time. Extract this logic into a shared helper and have
both call sites reuse it, keeping the relocation behavior centralized while
preserving the existing relocateClientSystemIntoMessages behavior and
message-wrapping semantics.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d2f5ae2e-c114-44b8-a206-95e584d10e59

📥 Commits

Reviewing files that changed from the base of the PR and between 8f0fda3 and 6055ed9.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (14)
  • package.json
  • patches/mammoth@1.12.0.patch
  • src/lib/core/modules/GenerationHandler.ts
  • src/lib/core/modules/structuredOutputPolicy.ts
  • src/lib/processors/document/ExcelProcessor.ts
  • src/lib/providers/anthropic.ts
  • src/lib/providers/anthropicImageBlocks.ts
  • src/lib/proxy/oauthFetch.ts
  • src/lib/proxy/proxyTracer.ts
  • src/lib/server/routes/claudeProxyRoutes.ts
  • src/lib/types/proxy.ts
  • test/continuous-test-suite-anthropic-multimodal.ts
  • test/continuous-test-suite-anthropic-tools-policy.ts
  • test/continuous-test-suite-excel-interop.ts

Comment thread src/lib/server/routes/claudeProxyRoutes.ts
@murdore
murdore force-pushed the fix/curator-tara-neurolink-suite branch from 6055ed9 to 92bb53b Compare June 26, 2026 13:51
@github-actions

github-actions Bot commented Jun 26, 2026 •

Copy link
Copy Markdown
Contributor

✅ Single Commit Policy - COMPLIANT

Status: Policy requirements met • 1 commit • Valid format • Ready for merge

📊 View validation details

📝 Commit Details

  • Hash: 2324803d33f21467850a297acb669f771d85d285
  • Message: fix(anthropic): Curator/Tara reliability across the OAuth proxy, provider, and processors
  • Author: Sachin Sharma

✅ Validation Results

  • Single commit requirement met
  • No merge commits in branch
  • Semantic commit message format verified
  • Ready for squash merge to release branch

🤖 Automated validation by NeuroLink Single Commit Enforcement

@github-actions

Copy link
Copy Markdown
Contributor

🤖 AI Review & Build Compliance ✅

Status: AI analysis complete • Build rules validated • Ready for review

📊 View detailed analysis results

🛡️ Analysis Complete

  • ✅ Security scan (vulnerabilities, API keys)
  • ✅ TypeScript safety & code quality
  • ✅ Error handling & best practices
  • ✅ Build rule enforcement validated
  • ✅ Commit format & compliance checks

📋 Ready for Merge When

  • All CI checks passing
  • Manual review approved
  • Any AI-flagged issues resolved

🤖 AI analysis complete - check individual code comments for specific feedback

@github-actions

Copy link
Copy Markdown
Contributor

🤖 AI Review & Build Compliance ✅

Status: AI analysis complete • Build rules validated • Ready for review

📊 View detailed analysis results

🛡️ Analysis Complete

  • ✅ Security scan (vulnerabilities, API keys)
  • ✅ TypeScript safety & code quality
  • ✅ Error handling & best practices
  • ✅ Build rule enforcement validated
  • ✅ Commit format & compliance checks

📋 Ready for Merge When

  • All CI checks passing
  • Manual review approved
  • Any AI-flagged issues resolved

🤖 AI analysis complete - check individual code comments for specific feedback

@Tara-ag

Tara-ag commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

I've analyzed this PR which consolidates fixes for Curator/Tara reliability on the Anthropic surface. Overall, this is a well-structured PR addressing real production issues. Here are my findings:

🔒 Security: No blocking issues found

  • No hardcoded secrets, API keys, or credentials
  • No unsafe eval/innerHTML/dynamic require patterns
  • Proper input validation on file parts before processing

⚠️ MAJOR Issues (2 found)

  1. JSDoc Duplication in claudeProxyRoutes.ts - There's a duplicated JSDoc comment block for relocateClientSystemIntoMessages that needs cleanup.

  2. Magic Byte Sniffing Edge Case - In anthropicImageBlocks.ts, the sniffBase64 function slices only 32 characters from the base64 string, which may not provide enough bytes for reliable WebP detection (requires 12 bytes = ~16 base64 chars, but PNG needs 8 bytes = ~11 chars). While this works for most cases, very short base64 payloads might fail detection.

💡 MINOR Issues (1 found)

  1. Test Coverage Gap - The modelDeprecatesTemperature regex in structuredOutputPolicy.ts matches opus-4-8 through opus-4-9, opus-4-10, etc., but the test doesn't verify the boundary condition at opus-4-7 (should be false).

✅ Positive Observations

  1. Excellent test coverage - Three new comprehensive test suites added
  2. Proper telemetry - Usage/cost correctly mirrored onto retry spans per fix(structured-output): disable structured output with tools on native anthropic provider #1116 review comment
  3. Anti-abuse 429 handling - Correctly addresses the "Error" body issue that was burning accounts
  4. CJS/ESM interop fix - ExcelProcessor properly normalizes the module shape
  5. CLAUDE.md Rule 3 compliance - Native Anthropic + tools correctly excludes structured output

📋 Recommendations

  1. Clean up the duplicated JSDoc in claudeProxyRoutes.ts
  2. Consider adding a test for modelDeprecatesTemperature("claude-opus-4-7") → false boundary case
  3. The PR description mentions this supersedes fix(structured-output): disable structured output with tools on native anthropic provider #1116 - ensure all review comments from that PR are addressed (appears to be done based on the table)

Verdict: Approve with minor cleanup requested. The architectural changes are sound and the fixes address real production pain points.

@murdore

murdore commented Jun 26, 2026

Copy link
Copy Markdown
Contributor Author

Review comments addressed — pushed in ffb9a7e (still a single commit)

Thanks @coderabbitai and @Tara-ag. All findings verified against the code and addressed:

1. Duplicated relocateClientSystemIntoMessages helper + orphaned JSDoc — fixed

CodeRabbit nitpick (oauthFetch.ts 181–219) + Tara-ag MAJOR #1 (JSDoc duplication)

The helper was byte-for-byte identical in src/lib/proxy/oauthFetch.ts and src/lib/server/routes/claudeProxyRoutes.ts, and the consolidation had also left an orphaned JSDoc block sitting above extractResponseInfo in claudeProxyRoutes.ts.

  • Extracted the single implementation into a new shared module src/lib/proxy/systemRelocation.ts (one JSDoc, exported relocateClientSystemIntoMessages).
  • Both proxy entry points now import it — the OAuth anti-abuse workaround can no longer drift between paths.
  • Removed both local definitions and the orphaned JSDoc.
  • Net −103 / +70 lines.

I kept it as a plain shared function rather than wiring it into src/lib/proxy/cloaking/ — that pipeline is plugin-based and not yet integrated into the request flow, so adapting a synchronous body-shaping call into it would be a behavior-changing refactor out of scope for this PR.

2. sniffBase64 magic-byte slice — clarified + made self-documenting

Tara-ag MAJOR #2 (32 chars may be too few for WebP)

The arithmetic actually shows the slice was already sufficient: WebP (RIFF…WEBP) is the longest signature and lives in the first 12 bytes; base64 packs 3 bytes / 4 chars, so 16 chars already cover it, and the existing slice of 32 chars decodes to 24 bytes — 2× the margin WebP needs (Buffer.from("A".repeat(32),"base64").length === 24). So this was not a correctness gap.

To close the underlying maintainability concern (a bare 32 whose relationship to the signatures wasn't obvious), I replaced it with a documented SNIFF_BASE64_CHARS constant explaining the derivation.

3. modelDeprecatesTemperature boundary test — added

Tara-ag MINOR (no opus-4-7 boundary case)

Added modelDeprecatesTemperature("claude-opus-4-7") → false to test/continuous-test-suite-anthropic-tools-policy.ts, pinning the boundary one step below the 4-8 cutoff.


Verification: tsc --project tsconfig.cli.json → 0 errors · ESLint → 0 errors · anthropic-tools-policy (9/9) and anthropic-multimodal (10/10) suites pass · single-commit policy preserved (amended, not added).

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

@murdore Thanks for the thorough follow-up — this all sounds good.

The shared extraction into src/lib/proxy/systemRelocation.ts, the self-documenting SNIFF_BASE64_CHARS constant, and the added claude-opus-4-7 boundary test directly address the concerns I raised. Appreciate the clear rationale and the verification details as well.

🐇✨


✏️ Learnings added
Learnt from: murdore
URL: https://github.com/juspay/neurolink/pull/1117

Timestamp: 2026-06-26T19:37:50.446Z
Learning: In the Neurolink proxy codebase, `src/lib/proxy/cloaking/` is a plugin-based pipeline that is not yet integrated into the current request flow, so synchronous request body shaping such as `relocateClientSystemIntoMessages` should stay as a plain shared function unless a broader behavior-changing refactor is intended.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

@github-actions

Copy link
Copy Markdown
Contributor

🤖 AI Review & Build Compliance ✅

Status: AI analysis complete • Build rules validated • Ready for review

📊 View detailed analysis results

🛡️ Analysis Complete

  • ✅ Security scan (vulnerabilities, API keys)
  • ✅ TypeScript safety & code quality
  • ✅ Error handling & best practices
  • ✅ Build rule enforcement validated
  • ✅ Commit format & compliance checks

📋 Ready for Merge When

  • All CI checks passing
  • Manual review approved
  • Any AI-flagged issues resolved

🤖 AI analysis complete - check individual code comments for specific feedback

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/proxy/oauthFetch.ts (1)

246-267: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Tighten agent-block detection before stripping system content.

includes("Claude Agent SDK") can match ordinary custom instructions, causing the request to be treated as Claude Code, skipping relocation, and stripping user-provided system text. Also dedupe removal indices so one block matching both predicates is not spliced twice.

Proposed fix
-      const agentIdx = parsed.system.findIndex(
-        (b: { text?: string }) =>
-          typeof b.text === "string" && b.text.includes("Claude Agent SDK"),
-      );
+      const agentIdx = parsed.system.findIndex(
+        (b: { text?: string }) =>
+          typeof b.text === "string" && b.text.trim() === agentBlock.text,
+      );
...
-      const indicesToRemove = [billingIdx, agentIdx]
-        .filter((i) => i >= 0)
-        .sort((a, b) => b - a);
+      const indicesToRemove = [...new Set([billingIdx, agentIdx])]
+        .filter((i) => i >= 0)
+        .sort((a, b) => b - a);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/proxy/oauthFetch.ts` around lines 246 - 267, The agent-detection in
oauthFetch currently uses a broad text match that can incorrectly classify
custom instructions as a Claude Code client. Tighten the predicate in the
parsed.system scan so only the real agent identity block is recognized, and keep
the relocation path for ordinary system text. Also update the removal logic in
the same function to deduplicate indices before splicing so a block matching
both billing and agent criteria is removed only once.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/lib/proxy/oauthFetch.ts`:
- Around line 246-267: The agent-detection in oauthFetch currently uses a broad
text match that can incorrectly classify custom instructions as a Claude Code
client. Tighten the predicate in the parsed.system scan so only the real agent
identity block is recognized, and keep the relocation path for ordinary system
text. Also update the removal logic in the same function to deduplicate indices
before splicing so a block matching both billing and agent criteria is removed
only once.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5a720bfa-3241-4321-88cb-009fff2b5f26

📥 Commits

Reviewing files that changed from the base of the PR and between 6055ed9 and ffb9a7e.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (15)
  • package.json
  • patches/mammoth@1.12.0.patch
  • src/lib/core/modules/GenerationHandler.ts
  • src/lib/core/modules/structuredOutputPolicy.ts
  • src/lib/processors/document/ExcelProcessor.ts
  • src/lib/providers/anthropic.ts
  • src/lib/providers/anthropicImageBlocks.ts
  • src/lib/proxy/oauthFetch.ts
  • src/lib/proxy/proxyTracer.ts
  • src/lib/proxy/systemRelocation.ts
  • src/lib/server/routes/claudeProxyRoutes.ts
  • src/lib/types/proxy.ts
  • test/continuous-test-suite-anthropic-multimodal.ts
  • test/continuous-test-suite-anthropic-tools-policy.ts
  • test/continuous-test-suite-excel-interop.ts
🚧 Files skipped from review as they are similar to previous changes (13)
  • patches/mammoth@1.12.0.patch
  • src/lib/types/proxy.ts
  • test/continuous-test-suite-excel-interop.ts
  • src/lib/core/modules/GenerationHandler.ts
  • src/lib/processors/document/ExcelProcessor.ts
  • test/continuous-test-suite-anthropic-multimodal.ts
  • src/lib/proxy/proxyTracer.ts
  • src/lib/core/modules/structuredOutputPolicy.ts
  • package.json
  • test/continuous-test-suite-anthropic-tools-policy.ts
  • src/lib/providers/anthropic.ts
  • src/lib/providers/anthropicImageBlocks.ts
  • src/lib/server/routes/claudeProxyRoutes.ts

…ider, and processors

Consolidated fixes that make Curator/Tara work reliably on the Anthropic
surface (native provider, the multi-account OAuth proxy, and file processors),
plus the static-analysis/tracing improvements found while debugging them.

OAuth proxy (claudeProxyRoutes, oauthFetch, proxyTracer, types/proxy):
- Relocate a non-Claude-Code client's `system` prompt into the message stream
  for the subscription/OAuth path. Anthropic rejects any unrecognised `system`
  with a header-less `rate_limit_error: "Error"`; keeping a custom client's
  system in `system[]` made every Curator request fail and the proxy misread it
  as a rate limit, burning all accounts over 44 retries. Now only the recognised
  billing+agent blocks go in `system`; the client prompt is wrapped in
  `<system_instructions>…</system_instructions>` as a leading user block
  (cache_control preserved). Genuine Claude Code traffic is detected and left
  untouched.
- Fail fast on the anti-abuse / construction 429 (no rate-limit headers, body
  "Error") instead of rotating every account.
- Trace request tool names and response model/finish_reason/tool_calls
  (gen_ai.* attributes) for both non-streaming and streaming paths, and record
  token usage + cost on the temperature-retry span.

Native Anthropic provider (anthropic.ts, anthropicImageBlocks.ts,
structuredOutputPolicy.ts, GenerationHandler.ts):
- Disable structured output when tools are present on the native Anthropic
  Messages API (and Bedrock) — experimental_output + tools silently drops tool
  calls. Covered by tests for anthropic + bedrock.
- Restore vision on the native surface: convert AI-SDK file parts to Anthropic
  image/document blocks with the correctly sniffed media type; omit unsupported
  image/* hints (svg, bmp) instead of relabelling them as PNG; runtime-validate
  file-part shape before use.
- Omit temperature proactively for models that deprecate it, and retry without
  temperature on the deprecation error.

Processors:
- ExcelProcessor: fix exceljs CJS/ESM interop (Workbook under .default).
- WordProcessor: patch mammoth for @xmldom/xmldom >= 0.9 (mimeType now
  required, errorHandler replaced by onError) so .docx extraction works with
  the security-pinned xmldom.

Tests: register the new continuous suites (anthropic-tools-policy,
anthropic-multimodal, excel-interop) in package.json and test:unit.
@github-actions

Copy link
Copy Markdown
Contributor

🤖 AI Review & Build Compliance ✅

Status: AI analysis complete • Build rules validated • Ready for review

📊 View detailed analysis results

🛡️ Analysis Complete

  • ✅ Security scan (vulnerabilities, API keys)
  • ✅ TypeScript safety & code quality
  • ✅ Error handling & best practices
  • ✅ Build rule enforcement validated
  • ✅ Commit format & compliance checks

📋 Ready for Merge When

  • All CI checks passing
  • Manual review approved
  • Any AI-flagged issues resolved

🤖 AI analysis complete - check individual code comments for specific feedback

@Tara-ag Tara-ag left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

I've reviewed the consolidated PR for Curator/Tara reliability fixes. This is a well-structured PR that addresses critical issues with the Anthropic OAuth proxy, native provider, and file processors.

Files Reviewed (16 total)

  • package.json: New test scripts properly registered
  • patches/mammoth@1.12.0.patch: xmldom compatibility fix
  • src/lib/core/modules/GenerationHandler.ts: Temperature retry with telemetry
  • src/lib/core/modules/structuredOutputPolicy.ts: Native Anthropic + Bedrock exclusion
  • src/lib/processors/document/ExcelProcessor.ts: CJS/ESM interop fix
  • src/lib/providers/anthropic.ts: Vision restoration, temperature handling
  • src/lib/providers/anthropicImageBlocks.ts: New multimodal conversion module
  • src/lib/proxy/oauthFetch.ts: System relocation for OAuth anti-abuse
  • src/lib/proxy/proxyTracer.ts: Enhanced tracing (tool_names, response info)
  • src/lib/proxy/systemRelocation.ts: Shared system relocation helper
  • src/lib/server/routes/claudeProxyRoutes.ts: Proxy routing with anti-abuse 429 handling
  • src/lib/types/proxy.ts: New ResponseInfoContext type
  • test/: Three new comprehensive test suites

Verification

  • ✅ CLAUDE.md Critical Rules followed (dynamic imports, type naming, barrel exports)
  • ✅ No hardcoded secrets or security vulnerabilities
  • ✅ Backward compatibility maintained
  • ✅ Comprehensive test coverage added
  • ✅ Existing review comments addressed (anti-abuse 429 in auth-retry, shared helper extraction)

Approval

This PR is ready for merge. The fixes are critical for Curator/Tara reliability and the implementation is solid.

@murdore
murdore merged commit 0228bf0 into release Jun 27, 2026
17 checks passed
@murdore
murdore deleted the fix/curator-tara-neurolink-suite branch June 27, 2026 04:57
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 9.79.2 🎉

The release is available on:

Your semantic-release bot 📦🚀

This branch was successfully deployed

1 active deployment
Preview — 2324803d Deployed Jun 26, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants