feat: 拆分 usage 记录的请求体/响应体为客户端侧与提供商侧

将 request_body/response_body 语义明确为客户端原始请求体和提供商原始响应体,
新增 provider_request_body(格式转换后发给提供商的请求体)和 client_response_body
(格式转换后返回给客户端的响应体),支持跨格式转换场景下分别查看两侧数据。

- 数据库新增 provider_request_body/client_response_body 及对应压缩字段
- 全链路(telemetry/recording/handler/stream_context)传递新字段
- 维护调度器同步支持新字段的压缩与清理
- 前端请求详情抽屉支持请求体/响应体/响应头的客户端/提供商视图切换
This commit is contained in:
fawney19
2026-02-21 01:56:28 +08:00
parent 4c5dac603f
commit 314e4a497d
23 changed files with 449 additions and 106 deletions

View File

@@ -0,0 +1,56 @@
"""Add provider_request_body and client_response_body columns to usage table
Revision ID: 7e8f9a0b1c2d
Revises: 6d7e8f9a0b1c
Create Date: 2026-02-20 18:00:00.000000
"""
from __future__ import annotations
from collections.abc import Sequence
import sqlalchemy as sa
from sqlalchemy import inspect
from alembic import op
# revision identifiers, used by Alembic.
revision: str = "7e8f9a0b1c2d"
down_revision: str | None = "6d7e8f9a0b1c"
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None
def upgrade() -> None:
conn = op.get_bind()
inspector = inspect(conn)
existing_columns = {col["name"] for col in inspector.get_columns("usage")}
if "provider_request_body" not in existing_columns:
op.add_column("usage", sa.Column("provider_request_body", sa.JSON(), nullable=True))
if "provider_request_body_compressed" not in existing_columns:
op.add_column(
"usage", sa.Column("provider_request_body_compressed", sa.LargeBinary(), nullable=True)
)
if "client_response_body" not in existing_columns:
op.add_column("usage", sa.Column("client_response_body", sa.JSON(), nullable=True))
if "client_response_body_compressed" not in existing_columns:
op.add_column(
"usage", sa.Column("client_response_body_compressed", sa.LargeBinary(), nullable=True)
)
def downgrade() -> None:
conn = op.get_bind()
inspector = inspect(conn)
existing_columns = {col["name"] for col in inspector.get_columns("usage")}
for col in (
"client_response_body_compressed",
"client_response_body",
"provider_request_body_compressed",
"provider_request_body",
):
if col in existing_columns:
op.drop_column("usage", col)