feat(observability): add request-level Discovery routing trace - #1351
Conversation
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthrough该变更引入有界流式 Discovery,包括配置、协议解析、候选竞速、版本化 session binding、Redis 租约与 CAS、routingTrace 持久化、outbox 回放、终态结算、管理界面展示及相应迁移和测试覆盖。 ChangesBounded Streaming Discovery 与路由追踪
Estimated code review effort: 5 (Critical) | ~120 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Code Review
This pull request introduces 'Bounded Streaming Discovery', an optional cold-start routing mode for streaming requests designed to reduce duplicate upstream costs while maintaining request reliability. The changes include database schema updates for new system settings, comprehensive configuration management for Discovery parameters, and a new observability routing trace system. Additionally, it implements a versioned session binding mechanism using Redis Lua scripts to ensure atomic updates and concurrency control. No review comments were provided for this pull request.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (1)
tests/unit/usage-ledger/trigger.test.ts (1)
41-44: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win建议收紧断言范围,避免贪婪正则误报。
/UPDATE OF[\s\S]*routing_trace[\s\S]*ON message_request/中的[\s\S]*会贪婪地跨越整个文件。只要routing_trace出现在第一处UPDATE OF与最后一处ON message_request之间的任意位置(例如trigger.sql里解释“为何排除 routing_trace”的注释),该否定断言就会误报失败,即便列白名单里并不含routing_trace。建议先截取触发器的列清单再断言:♻️ 建议的精确断言
it("does not run the accounting projection for routing-trace-only updates", () => { expect(sql).toContain("AFTER INSERT OR UPDATE OF"); - expect(sql).not.toMatch(/UPDATE OF[\s\S]*routing_trace[\s\S]*ON message_request/); + const triggerColumns = sql.match(/AFTER INSERT OR UPDATE OF([\s\S]*?)ON message_request/); + expect(triggerColumns).not.toBeNull(); + expect(triggerColumns?.[1]).not.toContain("routing_trace"); });🤖 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 `@tests/unit/usage-ledger/trigger.test.ts` around lines 41 - 44, 收紧测试中针对 routing_trace 的否定断言范围:在测试 “does not run the accounting projection for routing-trace-only updates” 中先提取对应触发器的 UPDATE OF 列清单,再仅对该列清单断言不包含 routing_trace,避免正则跨越整个 sql 文本匹配注释或其他内容;保留现有 AFTER INSERT OR UPDATE OF 的断言。
🤖 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/app/v1/_lib/proxy/discovery-validity.ts`:
- Around line 132-144: 在 openai-responses 的就绪判定中补充
response.reasoning_summary_text.delta 事件:当该事件的 object.delta 通过 hasContent 检查时返回
ready: true。保持现有
output_text.delta、function_call_arguments.delta、output_item.added 及终止事件的处理不变。
In `@src/app/v1/_lib/proxy/error-handler.ts`:
- Line 677: 在 error-handler.ts 的 session.closeLiveObservability() 调用处补充 Promise
拒绝处理:保留异步调用的非阻塞行为,并链式添加 catch,按本文件其他 void 调用的既有错误处理约定记录或处理错误,避免产生未处理的 Promise
拒绝。
In `@src/lib/redis/live-chain-store.ts`:
- Around line 33-45: Update the outcome selection in inferDiscoveryPhase to
prefer terminalEvent.outcome over trace.summary?.outcome, matching
getDiscoveryTerminal in provider-chain-popover.tsx. Preserve the existing phase
mapping while ensuring a request_finished failure overrides an earlier summary
success.
In `@src/lib/validation/discovery-settings.ts`:
- Around line 15-17: Update isDiscoverySettingField to replace the in-operator
check with an Object.prototype.hasOwnProperty.call check against
DISCOVERY_FIELD_LIMITS, so only explicitly defined fields are accepted while
preserving the existing string validation.
In `@tests/unit/lib/session-manager-binding-smart.test.ts`:
- Around line 176-184: Remove the duplicate findProviderById negative assertion
in the forceUpdate=true test, and add a positive assertion that the persistence
path, such as bindingMocks.mutateLegacySessionBindingSafely, is called with the
expected arguments.
---
Nitpick comments:
In `@tests/unit/usage-ledger/trigger.test.ts`:
- Around line 41-44: 收紧测试中针对 routing_trace 的否定断言范围:在测试 “does not run the
accounting projection for routing-trace-only updates” 中先提取对应触发器的 UPDATE OF
列清单,再仅对该列清单断言不包含 routing_trace,避免正则跨越整个 sql 文本匹配注释或其他内容;保留现有 AFTER INSERT OR
UPDATE OF 的断言。
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 1b25122d-77c6-467b-863e-4571789fcf8c
📒 Files selected for processing (106)
.env.exampledocs/streaming-discovery.mddrizzle/0110_daffy_rawhide_kid.sqldrizzle/0111_happy_mauler.sqldrizzle/meta/0110_snapshot.jsondrizzle/meta/0111_snapshot.jsondrizzle/meta/_journal.jsonmessages/en/dashboard.jsonmessages/en/settings/config.jsonmessages/ja/dashboard.jsonmessages/ja/settings/config.jsonmessages/ru/dashboard.jsonmessages/ru/settings/config.jsonmessages/zh-CN/dashboard.jsonmessages/zh-CN/settings/config.jsonmessages/zh-TW/dashboard.jsonmessages/zh-TW/settings/config.jsonpackage.jsonsrc/actions/system-config.tssrc/actions/usage-logs.tssrc/app/[locale]/dashboard/logs/_components/error-details-dialog.test.tsxsrc/app/[locale]/dashboard/logs/_components/error-details-dialog/components/DiscoveryTraceView.tsxsrc/app/[locale]/dashboard/logs/_components/error-details-dialog/components/LogicTraceTab.tsxsrc/app/[locale]/dashboard/logs/_components/error-details-dialog/components/index.tssrc/app/[locale]/dashboard/logs/_components/error-details-dialog/index.tsxsrc/app/[locale]/dashboard/logs/_components/error-details-dialog/types.tssrc/app/[locale]/dashboard/logs/_components/provider-chain-popover.test.tsxsrc/app/[locale]/dashboard/logs/_components/provider-chain-popover.tsxsrc/app/[locale]/dashboard/logs/_components/usage-logs-table.tsxsrc/app/[locale]/dashboard/logs/_components/virtualized-logs-table.tsxsrc/app/[locale]/settings/config/_components/system-settings-form.tsxsrc/app/[locale]/settings/config/page.tsxsrc/app/api/admin/system-config/route.tssrc/app/api/v1/resources/system/handlers.tssrc/app/api/v1/resources/system/router.tssrc/app/v1/_lib/proxy/discovery-coordinator.tssrc/app/v1/_lib/proxy/discovery-validity.tssrc/app/v1/_lib/proxy/error-handler.tssrc/app/v1/_lib/proxy/forwarder.tssrc/app/v1/_lib/proxy/provider-selector.tssrc/app/v1/_lib/proxy/response-handler.tssrc/app/v1/_lib/proxy/session.tssrc/app/v1/_lib/proxy/stream-finalization.tssrc/drizzle/schema.tssrc/lib/api-client/v1/openapi-types.gen.tssrc/lib/api/v1/_shared/error-envelope.tssrc/lib/api/v1/_shared/request-body.tssrc/lib/api/v1/schemas/system-config.tssrc/lib/config/env.schema.tssrc/lib/config/system-settings-cache.tssrc/lib/ledger-backfill/trigger.sqlsrc/lib/observability/discovery-metrics.tssrc/lib/redis/client.tssrc/lib/redis/live-chain-store.storage.test.tssrc/lib/redis/live-chain-store.test.tssrc/lib/redis/live-chain-store.tssrc/lib/redis/lua-scripts.tssrc/lib/redis/session-binding.tssrc/lib/session-manager.tssrc/lib/session-tracker.tssrc/lib/validation/discovery-settings.tssrc/lib/validation/schemas.tssrc/repository/_shared/transformers.tssrc/repository/message-write-buffer.tssrc/repository/message.tssrc/repository/system-config.tssrc/repository/usage-logs.tssrc/types/message.tssrc/types/routing-trace.tssrc/types/system-config.tstests/api/v1/system/system-config.test.tstests/configs/integration.config.tstests/configs/session-binding.config.tstests/integration/proxy-hedge-lifecycle.test.tstests/integration/session-binding-versioning-redis.test.tstests/unit/actions/system-config-save.test.tstests/unit/api/admin-system-config-route.test.tstests/unit/lib/redis/client.test.tstests/unit/lib/redis/session-binding.test.tstests/unit/lib/session-manager-binding-smart.test.tstests/unit/lib/session-manager-content-hash.test.tstests/unit/lib/session-manager-terminate-provider-sessions.test.tstests/unit/lib/session-manager-terminate-session.test.tstests/unit/lib/session-manager-versioned-binding.test.tstests/unit/lib/session-tracker-cleanup.test.tstests/unit/proxy/discovery-coordinator.test.tstests/unit/proxy/discovery-validity.test.tstests/unit/proxy/hedge-winner-dedup.test.tstests/unit/proxy/provider-selector-cross-type-model.test.tstests/unit/proxy/provider-selector-group-priority.test.tstests/unit/proxy/provider-selector-model-mismatch-binding.test.tstests/unit/proxy/proxy-forwarder-hedge-first-byte.test.tstests/unit/proxy/proxy-forwarder-provider-session-release.test.tstests/unit/proxy/response-handler-abort-listener-cleanup.test.tstests/unit/proxy/response-handler-client-abort-drain.test.tstests/unit/proxy/response-handler-endpoint-circuit-isolation.test.tstests/unit/proxy/response-handler-gemini-stream-passthrough-timeouts.test.tstests/unit/proxy/routing-trace.test.tstests/unit/proxy/terminal-outcome-contract.test.tstests/unit/repository/message-terminal-write-apis.test.tstests/unit/repository/message-write-buffer.test.tstests/unit/repository/system-config-degradation-ladder.test.tstests/unit/repository/system-config-update-missing-columns.test.tstests/unit/types/routing-trace.test.tstests/unit/usage-ledger/trigger.test.tstests/unit/validation/system-settings-discovery.test.ts
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/repository/message.ts (1)
622-627: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win归一化失败时静默丢弃 routingTrace,缺少任何日志。
当
normalizeRoutingTrace(routingTrace)返回空值时函数直接return,不记录任何日志;而重试耗尽路径(Line 649)却有告警日志。这会导致某个请求的 routingTrace 从未落库时,运维完全无法定位原因,与本 PR "版本化路由追踪观测性" 的目标相悖。🔧 建议增加归一化失败日志
export async function updateMessageRequestRoutingTrace( id: number, routingTrace: RoutingTraceV1 ): Promise<void> { const normalized = normalizeRoutingTrace(routingTrace); - if (!normalized) return; + if (!normalized) { + logger.warn("[MessageRequest] Skipped patching invalid routing trace", { requestId: id }); + return; + }🤖 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/repository/message.ts` around lines 622 - 627, 在 updateMessageRequestRoutingTrace 中处理 normalizeRoutingTrace 返回空值的分支时增加告警日志,记录消息标识和归一化失败的 routingTrace 上下文后再返回;保持成功路径及重试耗尽路径现有行为不变。
🤖 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/repository/message.ts`:
- Around line 622-627: 在 updateMessageRequestRoutingTrace 中处理
normalizeRoutingTrace 返回空值的分支时增加告警日志,记录消息标识和归一化失败的 routingTrace
上下文后再返回;保持成功路径及重试耗尽路径现有行为不变。
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 379461de-cb1c-473e-aadf-b11486390a14
📒 Files selected for processing (17)
src/app/v1/_lib/proxy/discovery-validity.tssrc/app/v1/_lib/proxy/error-handler.tssrc/app/v1/_lib/proxy/forwarder.tssrc/app/v1/_lib/proxy/response-handler.tssrc/app/v1/_lib/proxy/stream-finalization.tssrc/lib/redis/live-chain-store.tssrc/lib/validation/discovery-settings.tssrc/repository/message.tstests/unit/lib/redis/live-chain-store.test.tstests/unit/lib/session-manager-binding-smart.test.tstests/unit/proxy/discovery-validity.test.tstests/unit/proxy/error-handler-durable-persistence.test.tstests/unit/proxy/proxy-forwarder-hedge-first-byte.test.tstests/unit/proxy/response-handler-client-abort-drain.test.tstests/unit/proxy/response-handler-endpoint-circuit-isolation.test.tstests/unit/repository/message-terminal-write-apis.test.tstests/unit/validation/system-settings-discovery.test.ts
🚧 Files skipped from review as they are similar to previous changes (10)
- src/app/v1/_lib/proxy/error-handler.ts
- tests/unit/validation/system-settings-discovery.test.ts
- src/app/v1/_lib/proxy/stream-finalization.ts
- src/lib/validation/discovery-settings.ts
- src/app/v1/_lib/proxy/discovery-validity.ts
- tests/unit/lib/session-manager-binding-smart.test.ts
- src/app/v1/_lib/proxy/forwarder.ts
- tests/unit/proxy/response-handler-endpoint-circuit-isolation.test.ts
- tests/unit/proxy/proxy-forwarder-hedge-first-byte.test.ts
- src/app/v1/_lib/proxy/response-handler.ts
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/repository/message-write-buffer.ts (1)
329-342: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
normalizeRoutingTrace返回 null 时会写入 jsonb'null'而非 SQL NULL。当
value是已定义但结构非法的 routingTrace 时,normalizeRoutingTrace(value)返回null,JSON.stringify(null)得到字符串"null",最终以'null'::jsonb(JSON null)落库,而不是跳过或写入 SQLNULL。这条路径可经enqueueMessageRequestUpdate(id, { routingTrace })到达(该入口不做前置校验,见本仓库测试对原始 trace 的直接入队),导致列中出现 JSON null 的“脏值”。建议在归一化为 null 时写 SQL NULL。Proposed fix
if ( key === "providerChain" || key === "routingTrace" || key === "specialSettings" || key === "costBreakdown" ) { if (value === null) { cases.push(sql`WHEN ${update.id} THEN NULL`); continue; } - const json = JSON.stringify(key === "routingTrace" ? normalizeRoutingTrace(value) : value); - cases.push(sql`WHEN ${update.id} THEN ${json}::jsonb`); + if (key === "routingTrace") { + const normalized = normalizeRoutingTrace(value); + if (!normalized) { + cases.push(sql`WHEN ${update.id} THEN NULL`); + continue; + } + cases.push(sql`WHEN ${update.id} THEN ${JSON.stringify(normalized)}::jsonb`); + continue; + } + cases.push(sql`WHEN ${update.id} THEN ${JSON.stringify(value)}::jsonb`); continue; }🤖 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/repository/message-write-buffer.ts` around lines 329 - 342, Update the providerChain/routingTrace/specialSettings/costBreakdown handling so the normalized result of normalizeRoutingTrace is checked before JSON.stringify; when routingTrace normalization returns null, enqueue SQL NULL via the existing null branch instead of serializing JSON null. Preserve current JSONB serialization for valid routingTrace values and the other supported keys.
🤖 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/repository/message-write-buffer.ts`:
- Around line 329-342: Update the
providerChain/routingTrace/specialSettings/costBreakdown handling so the
normalized result of normalizeRoutingTrace is checked before JSON.stringify;
when routingTrace normalization returns null, enqueue SQL NULL via the existing
null branch instead of serializing JSON null. Preserve current JSONB
serialization for valid routingTrace values and the other supported keys.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: b25e0cdf-e1f9-477e-899a-609b1aa55116
📒 Files selected for processing (4)
src/repository/message-write-buffer.tssrc/repository/message.tstests/unit/repository/message-terminal-write-apis.test.tstests/unit/repository/message-write-buffer.test.ts
|
@coderabbitai Addressed the latest outside-diff finding in 01277fc: |
|
Tip For best results, initiate chat on the files or code changes.
If you found this review helpful, would you consider giving us a shout-out on X? Thank you for using CodeRabbit! |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
src/types/routing-trace.ts (1)
210-212: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value可选:避免对
sessionTtlSeconds重复调用finiteNumber。当前对
finiteNumber(config.sessionTtlSeconds)调用了两次,可先计算一次再复用,提高可读性。♻️ 建议改动
- ...(finiteNumber(config.sessionTtlSeconds) !== undefined - ? { sessionTtlSeconds: finiteNumber(config.sessionTtlSeconds) } - : {}), + ...(() => { + const sessionTtlSeconds = finiteNumber(config.sessionTtlSeconds); + return sessionTtlSeconds !== undefined ? { sessionTtlSeconds } : {}; + })(),🤖 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/types/routing-trace.ts` around lines 210 - 212, 在构建配置对象的逻辑中,更新 sessionTtlSeconds 处理以仅调用一次 finiteNumber(config.sessionTtlSeconds),保存计算结果后复用于条件判断和属性赋值,保持现有 undefined 时不添加该属性的行为不变。src/app/[locale]/dashboard/logs/_components/error-details-dialog/components/DiscoveryTraceView.tsx (1)
681-689: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value可选:将
knownCancellationKinds提升到模块作用域。该常量集合与组件状态无关,却在每次
AttemptCard渲染时重新构造。提升为模块级常量可避免重复分配。🤖 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/app/`[locale]/dashboard/logs/_components/error-details-dialog/components/DiscoveryTraceView.tsx around lines 681 - 689, 将 AttemptCard 中的 knownCancellationKinds 常量集合提升到模块作用域,保持其内容不变,并让组件直接复用该模块级集合,避免每次渲染重复创建。
🤖 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.
Nitpick comments:
In
`@src/app/`[locale]/dashboard/logs/_components/error-details-dialog/components/DiscoveryTraceView.tsx:
- Around line 681-689: 将 AttemptCard 中的 knownCancellationKinds
常量集合提升到模块作用域,保持其内容不变,并让组件直接复用该模块级集合,避免每次渲染重复创建。
In `@src/types/routing-trace.ts`:
- Around line 210-212: 在构建配置对象的逻辑中,更新 sessionTtlSeconds 处理以仅调用一次
finiteNumber(config.sessionTtlSeconds),保存计算结果后复用于条件判断和属性赋值,保持现有 undefined
时不添加该属性的行为不变。
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 6ae8cc5c-888d-4622-99ee-afacf65cdc6a
📒 Files selected for processing (19)
messages/en/dashboard.jsonmessages/en/settings/config.jsonmessages/ja/dashboard.jsonmessages/ja/settings/config.jsonmessages/ru/dashboard.jsonmessages/ru/settings/config.jsonmessages/zh-CN/dashboard.jsonmessages/zh-CN/settings/config.jsonmessages/zh-TW/dashboard.jsonmessages/zh-TW/settings/config.jsonsrc/app/[locale]/dashboard/logs/_components/error-details-dialog.test.tsxsrc/app/[locale]/dashboard/logs/_components/error-details-dialog/components/DiscoveryTraceView.tsxsrc/app/[locale]/dashboard/logs/_components/error-details-dialog/components/LogicTraceTab.tsxsrc/app/[locale]/dashboard/logs/_components/provider-chain-popover.test.tsxsrc/app/[locale]/dashboard/logs/_components/provider-chain-popover.tsxsrc/app/[locale]/settings/config/_components/system-settings-form.tsxsrc/app/[locale]/settings/config/page.tsxsrc/app/v1/_lib/proxy/forwarder.tssrc/types/routing-trace.ts
🚧 Files skipped from review as they are similar to previous changes (12)
- messages/zh-TW/settings/config.json
- messages/ru/settings/config.json
- messages/zh-CN/settings/config.json
- messages/ru/dashboard.json
- messages/ja/dashboard.json
- messages/zh-TW/dashboard.json
- messages/ja/settings/config.json
- messages/en/dashboard.json
- src/app/[locale]/dashboard/logs/_components/error-details-dialog/components/LogicTraceTab.tsx
- messages/zh-CN/dashboard.json
- src/app/[locale]/dashboard/logs/_components/provider-chain-popover.tsx
- src/app/v1/_lib/proxy/forwarder.ts
|
@coderabbitai Addressed both latest nitpicks in c7a1dc3: |
|
Tip For best results, initiate chat on the files or code changes.
🐇 ✅ |
|
Follow-up UI clarification pushed in
Validation:
@coderabbitai review |
|
✅ Action performedReview finished.
|
|
Follow-up UI routing summary pushed in
Validation:
@coderabbitai review |
|
✅ Action performedReview finished.
|
|
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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/utils/provider-chain-display.ts`:
- Around line 16-20: 在 shouldShowCostBadgeInCell 的多行参数声明中,为最后一个参数 routingTrace
添加尾逗号,使其符合 Biome 的 trailing comma 格式配置。
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 7a5eb930-90c6-417a-b524-d06dc4f83a33
📒 Files selected for processing (13)
messages/en/dashboard.jsonmessages/ja/dashboard.jsonmessages/ru/dashboard.jsonmessages/zh-CN/dashboard.jsonmessages/zh-TW/dashboard.jsonsrc/app/[locale]/dashboard/logs/_components/provider-chain-popover.test.tsxsrc/app/[locale]/dashboard/logs/_components/provider-chain-popover.tsxsrc/app/[locale]/dashboard/logs/_components/usage-logs-table.test.tsxsrc/app/[locale]/dashboard/logs/_components/usage-logs-table.tsxsrc/app/[locale]/dashboard/logs/_components/virtualized-logs-table.test.tsxsrc/app/[locale]/dashboard/logs/_components/virtualized-logs-table.tsxsrc/lib/utils/provider-chain-display.test.tssrc/lib/utils/provider-chain-display.ts
🚧 Files skipped from review as they are similar to previous changes (6)
- messages/ja/dashboard.json
- messages/ru/dashboard.json
- messages/zh-TW/dashboard.json
- messages/en/dashboard.json
- messages/zh-CN/dashboard.json
- src/app/[locale]/dashboard/logs/_components/provider-chain-popover.tsx
|
Follow-up compact route badge palette pushed in
Validation:
@coderabbitai review |
🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
git show --stat --oneline --decorate --no-renames f1ee7eea
printf '\n--- changed files ---\n'
git diff-tree --no-commit-id --name-only -r f1ee7eea
printf '\n--- component outline ---\n'
ast-grep outline 'src/app/[locale]/dashboard/logs/_components/provider-chain-popover.tsx' --items all --view expanded || true
printf '\n--- follow-up diff: component and tests ---\n'
git show --format=fuller --no-ext-diff --unified=80 f1ee7eea -- \
'src/app/[locale]/dashboard/logs/_components/provider-chain-popover.tsx' \
'src/app/[locale]/dashboard/logs/_components/provider-chain-popover.test.tsx'
printf '\n--- palette/accessibility references ---\n'
rg -n -C 5 -e 'Rediscovery|Cold start|Sticky|lease_conflict|aria-label|title=|badge|winnerOrigin|routeMode' \
'src/app/[locale]/dashboard/logs/_components/provider-chain-popover.tsx' \
'src/app/[locale]/dashboard/logs/_components/provider-chain-popover.test.tsx'Length of output: 129037
The badge mapping is trace-derived and correctly keeps winner-less/incomplete combinations neutral. The compact badge title and trigger ✅ Action performedReview finished.
|
…0723' into agent/discovery-1351-on-integration # Conflicts: # messages/en/dashboard.json # messages/ja/dashboard.json # messages/ru/dashboard.json # messages/zh-CN/dashboard.json # messages/zh-TW/dashboard.json # src/app/[locale]/dashboard/logs/_components/usage-logs-table.test.tsx # src/app/v1/_lib/proxy/forwarder.ts # tests/unit/proxy/response-handler-endpoint-circuit-isolation.test.ts
333ea75
into
ding113:integration/discovery-stack-20260723
Summary
This is the observability follow-up for the bounded streaming Discovery work in #1340. It is stacked on #1349 and depends on #1347 and #1348.
routing_tracealongside the existingprovider_chain.User impact
Administrators can now explain how a request was routed instead of inferring Discovery behavior from the legacy serial provider chain.
The trace distinguishes Discovery from legacy routing, Sticky/normal/fallback attempts, first-byte winner selection from the final stream result, late fake-200 or completion failures, and Sticky generation-CAS outcomes.
Legacy requests retain the existing decision chain and additionally show why Discovery was bypassed, including non-streaming, unsupported protocol, Redis capability, and lease conflicts.
Design boundaries
provider_chainremains the existing billing/retry contract.Migration
message_request.routing_traceJSONB; existing rows require no backfill.Durable final-trace recovery
cch:routing-trace-outbox:v1before the post-terminal database write. Entries do not expire automatically and are deleted only after an exact-payload database acknowledgement.recoverable: false; otherwise the staged snapshot remains recoverable across process restarts.Stack and issue
Validation
304/304tests passed.85/85tests passed.7339passed,13skipped,0failed (787files passed,2skipped).bun run typecheckbun run lintbun run format:checkbun run validate:migrationsbun run openapi:checkbun run openapi:lintbun run i18n:audit-messages-no-emoji:failbun run buildThe placeholder audit still reports pre-existing locale-equivalence findings outside the new routing trace keys.
Greptile Summary
This PR adds request-level Discovery routing traces from proxy execution through storage and dashboard display. The main changes are:
routing_tracedatabase field and accounting-trigger updates.Confidence Score: 5/5
This looks safe to merge.
Important Files Changed
Reviews (12): Last reviewed commit: "test(discovery): preserve nested Respons..." | Re-trigger Greptile