chore(prep): shared groundwork for the Sprint-2 parallel batch

第二批(T6~T11)协调提交:
- 迁移 0005:kb 七表(entity/relation/rule/chunk vector1024+tsv 生成列/
  asset/color/gap),HNSW+GIN 索引,FK 级联
- ORM:七个 Kb* 模型(pgvector Vector/TSVECTOR/Computed)
- 配置:检索与 embedding、华为 JWKS、短信全参数组
- 错误码:40110/40111/42910/42911/61000
- 骨架路由:kb.py + auth_sms.py(已注册);依赖:tencentcloud-sdk-python-sms
  + spike extra(onnxruntime/opencv);gitignore:models/ 与 spike 输出
This commit is contained in:
xsl
2026-08-14 17:01:43 +08:00
parent ddec3973ad
commit d5f366fa4c
11 changed files with 656 additions and 4 deletions
+31
View File
@@ -112,3 +112,34 @@ COS_PRESIGN_EXPIRE_SECONDS=600
UPLOAD_MAX_BYTES=20971520 UPLOAD_MAX_BYTES=20971520
UPLOAD_ALLOWED_TYPES=image/jpeg,image/png,image/webp UPLOAD_ALLOWED_TYPES=image/jpeg,image/png,image/webp
UPLOAD_SCENES_JSON={"report_photo":{"bucket":"temp"},"avatar":{"bucket":"temp"}} UPLOAD_SCENES_JSON={"report_photo":{"bucket":"temp"},"avatar":{"bucket":"temp"}}
# ── 知识库与检索(架构 §8.3,TD-08)────────────────────────────────────────
# 当前 embedding 为确定性假实现(dev/test);真实 BGE-M3 ONNX 接入时只换这里。
KB_VECTOR_DIMENSIONS=1024
KB_EMBEDDING_MODEL=deterministic-v1
KB_EMBEDDING_DEVICE=cpu
RETRIEVAL_TOP_K=50
RETRIEVAL_RERANK_WEIGHTS_JSON={"vector":0.45,"keyword":0.2,"rule":0.25,"freshness":0.1}
# ── 华为账号登录(FR-ACC-01;真实联调待 AGC 配置,见《前置开通清单》§3)────
HUAWEI_JWKS_URL=https://oauth-login.cloud.huawei.com/oauth2/v3/certs
HUAWEI_AUDIENCE=
HUAWEI_ISSUER=https://accounts.huawei.com
HUAWEI_JWKS_CACHE_SECONDS=86400
# ── 手机号验证码登录(FR-ACC-04/14,TD-32)─────────────────────────────────
# fake = 验证码打日志(dev);tencent = 真实发送(签名审核通过后切换并填下方凭证)
SMS_PROVIDER=fake
TENCENT_SMS_SECRET_ID=
TENCENT_SMS_SECRET_KEY=
TENCENT_SMS_SDK_APP_ID=
TENCENT_SMS_SIGN_NAME=
TENCENT_SMS_TEMPLATE_ID=
SMS_CODE_TTL_SECONDS=300
SMS_CODE_LENGTH=6
SMS_VERIFY_MAX_ATTEMPTS=5
SMS_RESEND_COOLDOWN_SECONDS=60
SMS_HOURLY_LIMIT=5
SMS_DAILY_LIMIT=10
SMS_IP_DAILY_LIMIT=20
SMS_DEVICE_DAILY_LIMIT=10
+5
View File
@@ -31,3 +31,8 @@ htmlcov/
logs/ logs/
tmp/ tmp/
# 算法 SPIKE 的模型缓存与输出(模型文件绝不入库)
models/
scripts/spikes/out/
scripts/spikes/assets/
+11 -2
View File
@@ -12,7 +12,7 @@ from contextlib import asynccontextmanager
from fastapi import FastAPI from fastapi import FastAPI
from apps.api.deps import build_llm_gateway from apps.api.deps import build_llm_gateway
from apps.api.routers import agent, auth, events, health, quota, tasks, uploads from apps.api.routers import agent, auth, auth_sms, events, health, kb, quota, tasks, uploads
from packages.shared.config import Settings, get_settings from packages.shared.config import Settings, get_settings
from packages.shared.db import dispose_engine from packages.shared.db import dispose_engine
from packages.shared.handlers import install_exception_handlers from packages.shared.handlers import install_exception_handlers
@@ -69,7 +69,16 @@ def create_app(settings: Settings | None = None) -> FastAPI:
setup_tracing(app, cfg) setup_tracing(app, cfg)
app.include_router(health.router) app.include_router(health.router)
routers = (auth.router, agent.router, quota.router, tasks.router, events.router, uploads.router) routers = (
auth.router,
auth_sms.router,
agent.router,
quota.router,
tasks.router,
events.router,
uploads.router,
kb.router,
)
for router in routers: for router in routers:
app.include_router(router, prefix=cfg.api_prefix) app.include_router(router, prefix=cfg.api_prefix)
+12
View File
@@ -0,0 +1,12 @@
"""手机号验证码登录路由(骨架,T11 填充实现)。
POST /auth/sms/send、POST /auth/sms/verify;
实现契约见 docs/开发任务包/T11-短信登录代码先行.md。
与 auth.py(华为/dev-token/refresh)分文件以避免并行冲突。
"""
from __future__ import annotations
from fastapi import APIRouter
router = APIRouter(prefix="/auth", tags=["auth-sms"])
+10
View File
@@ -0,0 +1,10 @@
"""知识库实体路由(骨架,T6 填充实现)。
GET /kb/items 等;实现契约见 docs/开发任务包/T6-知识库实体与图谱.md。
"""
from __future__ import annotations
from fastapi import APIRouter
router = APIRouter(prefix="/kb", tags=["kb"])
+179
View File
@@ -0,0 +1,179 @@
"""Knowledge base tables for the Sprint-2 parallel batch (架构文档 §6.2 kb 域).
七张表一次落齐,任务批(T6/T7/T8)不再写迁移:
kb_entity / kb_relation / kb_rule → T6 实体图谱、T7 规则引擎
kb_chunk (vector 1024 + tsv) → T8 混合检索
kb_asset / kb_color → T6/T8
kb_gap → T8 无结果缺口埋点
索引决策:
- kb_chunk.embedding 用 HNSW(cosine)——万级数据下召回延迟远优于 IVFFlat,
且不需要先灌数据再训练聚类(IVFFlat 的 num_lists 依赖数据量)。
- tsv 用 GIN;tsvector 是生成列(PG12+),应用层不手工维护。
Reversible: 是。降级按依赖倒序 drop。
"""
from __future__ import annotations
from collections.abc import Sequence
import sqlalchemy as sa
from alembic import op
from pgvector.sqlalchemy import Vector
from sqlalchemy.dialects import postgresql
revision: str = "0005"
down_revision: str | None = "0004"
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None
def upgrade() -> None:
op.create_table(
"kb_entity",
sa.Column("entity_id", sa.BigInteger(), nullable=False),
sa.Column("entity_type", sa.String(length=32), nullable=False),
sa.Column("name", sa.String(length=128), nullable=False),
sa.Column("attrs", postgresql.JSONB(), nullable=False),
sa.Column("status", sa.String(length=16), nullable=False, server_default=sa.text("'draft'")),
sa.Column("version", sa.Integer(), nullable=False, server_default=sa.text("1")),
sa.Column("source", sa.String(length=255), nullable=True),
sa.Column("license", sa.String(length=64), nullable=True),
sa.Column("updated_by", sa.String(length=64), nullable=True),
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()),
sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()),
sa.PrimaryKeyConstraint("entity_id"),
sa.UniqueConstraint("entity_type", "name", name="uq_kb_entity_type_name"),
)
op.create_index("ix_kb_entity_type_status", "kb_entity", ["entity_type", "status"])
op.create_table(
"kb_relation",
sa.Column("relation_id", sa.BigInteger(), nullable=False),
sa.Column("from_id", sa.BigInteger(), nullable=False),
sa.Column("rel_type", sa.String(length=64), nullable=False),
sa.Column("to_id", sa.BigInteger(), nullable=False),
sa.Column("weight", sa.Numeric(4, 3), nullable=False, server_default=sa.text("1")),
sa.Column("confidence", sa.Numeric(4, 3), nullable=False, server_default=sa.text("1")),
sa.Column("evidence", sa.String(length=255), nullable=True),
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()),
sa.PrimaryKeyConstraint("relation_id"),
sa.UniqueConstraint("from_id", "rel_type", "to_id", name="uq_kb_relation_triple"),
sa.ForeignKeyConstraint(["from_id"], ["kb_entity.entity_id"], ondelete="CASCADE"),
sa.ForeignKeyConstraint(["to_id"], ["kb_entity.entity_id"], ondelete="CASCADE"),
)
op.create_index("ix_kb_relation_to", "kb_relation", ["to_id"])
op.create_table(
"kb_rule",
sa.Column("rule_id", sa.BigInteger(), nullable=False),
sa.Column("rule_key", sa.String(length=64), nullable=False),
sa.Column("category", sa.String(length=32), nullable=False),
sa.Column("version", sa.Integer(), nullable=False, server_default=sa.text("1")),
sa.Column("status", sa.String(length=16), nullable=False, server_default=sa.text("'draft'")),
sa.Column("priority", sa.Integer(), nullable=False, server_default=sa.text("60")),
sa.Column("conditions", postgresql.JSONB(), nullable=False),
sa.Column("effects", postgresql.JSONB(), nullable=False),
sa.Column("is_hard", sa.Boolean(), nullable=False, server_default=sa.text("false")),
sa.Column("confidence", sa.Numeric(4, 3), nullable=False, server_default=sa.text("0.9")),
sa.Column("evidence", sa.String(length=255), nullable=True),
sa.Column("author", sa.String(length=64), nullable=True),
sa.Column("reviewer", sa.String(length=64), nullable=True),
sa.Column("published_at", sa.DateTime(timezone=True), nullable=True),
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()),
sa.PrimaryKeyConstraint("rule_id"),
sa.UniqueConstraint("rule_key", name="uq_kb_rule_key"),
)
op.create_index("ix_kb_rule_status_priority", "kb_rule", ["status", "priority"])
op.create_table(
"kb_chunk",
sa.Column("chunk_id", sa.BigInteger(), nullable=False),
sa.Column("entity_id", sa.BigInteger(), nullable=False),
sa.Column("chunk_type", sa.String(length=32), nullable=False, server_default=sa.text("'text'")),
sa.Column("text", sa.Text(), nullable=False),
sa.Column("embedding", Vector(1024), nullable=False),
sa.Column("embedding_model", sa.String(length=64), nullable=False),
sa.Column("embedding_version", sa.String(length=16), nullable=False),
sa.Column(
"tsv",
postgresql.TSVECTOR(),
sa.Computed("to_tsvector('simple', text)", persisted=True),
nullable=False,
),
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()),
sa.PrimaryKeyConstraint("chunk_id"),
sa.ForeignKeyConstraint(["entity_id"], ["kb_entity.entity_id"], ondelete="CASCADE"),
)
op.create_index("ix_kb_chunk_entity", "kb_chunk", ["entity_id"])
op.execute(
"CREATE INDEX ix_kb_chunk_embedding_hnsw ON kb_chunk "
"USING hnsw (embedding vector_cosine_ops)"
)
op.execute("CREATE INDEX ix_kb_chunk_tsv_gin ON kb_chunk USING gin (tsv)")
op.create_table(
"kb_asset",
sa.Column("asset_id", sa.BigInteger(), nullable=False),
sa.Column("entity_id", sa.BigInteger(), nullable=False),
sa.Column("asset_type", sa.String(length=32), nullable=False),
sa.Column("cos_key", sa.String(length=255), nullable=False),
sa.Column("spec_check", postgresql.JSONB(), nullable=False),
sa.Column("tryon_ready", sa.Boolean(), nullable=False, server_default=sa.text("false")),
sa.Column("review_status", sa.String(length=16), nullable=False, server_default=sa.text("'pending'")),
sa.Column("license", sa.String(length=64), nullable=True),
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()),
sa.PrimaryKeyConstraint("asset_id"),
sa.ForeignKeyConstraint(["entity_id"], ["kb_entity.entity_id"], ondelete="CASCADE"),
)
op.create_index("ix_kb_asset_entity", "kb_asset", ["entity_id"])
op.execute(
"CREATE INDEX ix_kb_asset_tryon_ready ON kb_asset (tryon_ready) WHERE tryon_ready"
)
op.create_table(
"kb_color",
sa.Column("color_id", sa.BigInteger(), nullable=False),
sa.Column("season_code", sa.String(length=16), nullable=False),
sa.Column("role", sa.String(length=8), nullable=False),
sa.Column("lab_l", sa.Numeric(6, 2), nullable=False),
sa.Column("lab_a", sa.Numeric(6, 2), nullable=False),
sa.Column("lab_b", sa.Numeric(6, 2), nullable=False),
sa.Column("hex", sa.String(length=7), nullable=False),
sa.Column("name_cn", sa.String(length=64), nullable=False),
sa.PrimaryKeyConstraint("color_id"),
)
op.create_index("ix_kb_color_season", "kb_color", ["season_code"])
op.create_table(
"kb_gap",
sa.Column("gap_id", sa.BigInteger(), nullable=False),
sa.Column("query_text", sa.Text(), nullable=False),
sa.Column("filter_ctx", postgresql.JSONB(), nullable=False),
sa.Column("hit_count", sa.Integer(), nullable=False, server_default=sa.text("1")),
sa.Column("first_seen_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()),
sa.Column("last_seen_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()),
sa.PrimaryKeyConstraint("gap_id"),
)
op.create_index("ix_kb_gap_query", "kb_gap", ["query_text"])
def downgrade() -> None:
op.drop_index("ix_kb_gap_query", table_name="kb_gap")
op.drop_table("kb_gap")
op.drop_index("ix_kb_color_season", table_name="kb_color")
op.drop_table("kb_color")
op.execute("DROP INDEX IF EXISTS ix_kb_asset_tryon_ready")
op.drop_index("ix_kb_asset_entity", table_name="kb_asset")
op.drop_table("kb_asset")
op.execute("DROP INDEX IF EXISTS ix_kb_chunk_tsv_gin")
op.execute("DROP INDEX IF EXISTS ix_kb_chunk_embedding_hnsw")
op.drop_index("ix_kb_chunk_entity", table_name="kb_chunk")
op.drop_table("kb_chunk")
op.drop_index("ix_kb_rule_status_priority", table_name="kb_rule")
op.drop_table("kb_rule")
op.drop_index("ix_kb_relation_to", table_name="kb_relation")
op.drop_table("kb_relation")
op.drop_index("ix_kb_entity_type_status", table_name="kb_entity")
op.drop_table("kb_entity")
+36
View File
@@ -168,6 +168,41 @@ class Settings(BaseSettings):
alias="UPLOAD_SCENES_JSON", alias="UPLOAD_SCENES_JSON",
) )
# --- 知识库与检索(架构 §8.3,TD-08)--------------------------------------
kb_vector_dimensions: int = 1024
# 当前默认 = 确定性假实现;真实 BGE-M3 ONNX 是后续任务,届时只换这里。
kb_embedding_model: str = "deterministic-v1"
kb_embedding_device: str = "cpu"
retrieval_top_k: int = 50
# 重排权重(架构 §8.3 唯一口径):0.45 向量 + 0.2 关键词 + 0.25 规则 + 0.1 新鲜度。
retrieval_rerank_weights: dict[str, float] = Field(
default_factory=lambda: {"vector": 0.45, "keyword": 0.2, "rule": 0.25, "freshness": 0.1},
alias="RETRIEVAL_RERANK_WEIGHTS_JSON",
)
# --- 华为账号登录(FR-ACC-01;联调待 AGC 配置,见《前置开通清单》§3)------
huawei_jwks_url: str = "https://oauth-login.cloud.huawei.com/oauth2/v3/certs"
huawei_audience: str = "" # = AGC App ID;空配置时验签必须拒绝而不是跳过
huawei_issuer: str = "https://accounts.huawei.com"
huawei_jwks_cache_seconds: int = 86400
# --- 手机号验证码登录(FR-ACC-04/14,TD-32)--------------------------------
# fake = 验证码打日志(dev);tencent = 真实发送(待签名审核通过后切换)
sms_provider: str = "fake"
tencent_sms_secret_id: str = ""
tencent_sms_secret_key: str = ""
tencent_sms_sdk_app_id: str = ""
tencent_sms_sign_name: str = ""
tencent_sms_template_id: str = ""
sms_code_ttl_seconds: int = 300
sms_code_length: int = 6
sms_verify_max_attempts: int = 5
sms_resend_cooldown_seconds: int = 60
sms_hourly_limit: int = 5
sms_daily_limit: int = 10
sms_ip_daily_limit: int = 20
sms_device_daily_limit: int = 10
# --- Observability ----------------------------------------------------- # --- Observability -----------------------------------------------------
otel_enabled: bool = False otel_enabled: bool = False
otel_service_name: str = "meida-api" otel_service_name: str = "meida-api"
@@ -182,6 +217,7 @@ class Settings(BaseSettings):
"llm_budget_tiers", "llm_budget_tiers",
"task_bonus_rules", "task_bonus_rules",
"upload_scenes", "upload_scenes",
"retrieval_rerank_weights",
mode="before", mode="before",
) )
@classmethod @classmethod
+10
View File
@@ -32,6 +32,8 @@ class ErrorCode(IntEnum):
REFRESH_TOKEN_INVALID = 40103 REFRESH_TOKEN_INVALID = 40103
REFRESH_TOKEN_EXPIRED = 40104 REFRESH_TOKEN_EXPIRED = 40104
SESSION_REVOKED = 40105 SESSION_REVOKED = 40105
SMS_CODE_INVALID = 40110
SMS_CODE_EXPIRED = 40111
FORBIDDEN = 40300 FORBIDDEN = 40300
QUOTA_EXHAUSTED = 40301 QUOTA_EXHAUSTED = 40301
CONSENT_REQUIRED = 40302 CONSENT_REQUIRED = 40302
@@ -42,6 +44,8 @@ class ErrorCode(IntEnum):
STATE_CONFLICT = 40900 STATE_CONFLICT = 40900
TASK_BONUS_ALREADY_CLAIMED = 40910 TASK_BONUS_ALREADY_CLAIMED = 40910
RATE_LIMITED = 42900 RATE_LIMITED = 42900
SMS_SEND_TOO_FREQUENT = 42910
SMS_DAILY_LIMIT = 42911
# --- 5xxxx server ----------------------------------------------------- # --- 5xxxx server -----------------------------------------------------
INTERNAL_ERROR = 50000 INTERNAL_ERROR = 50000
@@ -58,6 +62,7 @@ class ErrorCode(IntEnum):
LLM_PROMPT_CACHE_VIOLATION = 60004 LLM_PROMPT_CACHE_VIOLATION = 60004
MODERATION_UNAVAILABLE = 60005 MODERATION_UNAVAILABLE = 60005
LLM_SCENE_DEGRADED = 60006 LLM_SCENE_DEGRADED = 60006
SMS_PROVIDER_FAILED = 61000
@dataclass(frozen=True, slots=True) @dataclass(frozen=True, slots=True)
@@ -84,6 +89,8 @@ ERROR_META: dict[ErrorCode, ErrorMeta] = {
ErrorCode.REFRESH_TOKEN_INVALID: ErrorMeta(401, "登录状态无效", "请重新登录"), ErrorCode.REFRESH_TOKEN_INVALID: ErrorMeta(401, "登录状态无效", "请重新登录"),
ErrorCode.REFRESH_TOKEN_EXPIRED: ErrorMeta(401, "登录状态已过期", "请重新登录"), ErrorCode.REFRESH_TOKEN_EXPIRED: ErrorMeta(401, "登录状态已过期", "请重新登录"),
ErrorCode.SESSION_REVOKED: ErrorMeta(401, "该会话已登出", "请重新登录"), ErrorCode.SESSION_REVOKED: ErrorMeta(401, "该会话已登出", "请重新登录"),
ErrorCode.SMS_CODE_INVALID: ErrorMeta(401, "验证码错误", "请检查后重试"),
ErrorCode.SMS_CODE_EXPIRED: ErrorMeta(401, "验证码已过期", "请重新获取"),
ErrorCode.FORBIDDEN: ErrorMeta(403, "没有访问权限"), ErrorCode.FORBIDDEN: ErrorMeta(403, "没有访问权限"),
ErrorCode.QUOTA_EXHAUSTED: ErrorMeta(403, "今日额度已用完", "明天恢复,或完成任务多换几次"), ErrorCode.QUOTA_EXHAUSTED: ErrorMeta(403, "今日额度已用完", "明天恢复,或完成任务多换几次"),
ErrorCode.CONSENT_REQUIRED: ErrorMeta(403, "需要先完成授权", "请阅读并同意后继续"), ErrorCode.CONSENT_REQUIRED: ErrorMeta(403, "需要先完成授权", "请阅读并同意后继续"),
@@ -98,6 +105,8 @@ ERROR_META: dict[ErrorCode, ErrorMeta] = {
409, "这个周期的任务奖励已领取", "下个周期再来" 409, "这个周期的任务奖励已领取", "下个周期再来"
), ),
ErrorCode.RATE_LIMITED: ErrorMeta(429, "操作太频繁了", "请稍后再试"), ErrorCode.RATE_LIMITED: ErrorMeta(429, "操作太频繁了", "请稍后再试"),
ErrorCode.SMS_SEND_TOO_FREQUENT: ErrorMeta(429, "发送太频繁了", "请稍后再试"),
ErrorCode.SMS_DAILY_LIMIT: ErrorMeta(429, "今日发送次数已达上限", "明天再试"),
ErrorCode.INTERNAL_ERROR: ErrorMeta(500, "服务开小差了", "请稍后重试"), ErrorCode.INTERNAL_ERROR: ErrorMeta(500, "服务开小差了", "请稍后重试"),
ErrorCode.DB_ERROR: ErrorMeta(500, "服务开小差了", "请稍后重试"), ErrorCode.DB_ERROR: ErrorMeta(500, "服务开小差了", "请稍后重试"),
ErrorCode.TASK_STATE_INVALID: ErrorMeta(500, "任务状态异常", "请到任务中心重试"), ErrorCode.TASK_STATE_INVALID: ErrorMeta(500, "任务状态异常", "请到任务中心重试"),
@@ -120,6 +129,7 @@ ERROR_META: dict[ErrorCode, ErrorMeta] = {
ErrorCode.LLM_SCENE_DEGRADED: ErrorMeta( ErrorCode.LLM_SCENE_DEGRADED: ErrorMeta(
503, "该功能今日暂时关闭", "AI 服务今日已达服务上限,明天恢复" 503, "该功能今日暂时关闭", "AI 服务今日已达服务上限,明天恢复"
), ),
ErrorCode.SMS_PROVIDER_FAILED: ErrorMeta(502, "短信服务暂时不可用", "请稍后重试"),
} }
+176 -1
View File
@@ -18,9 +18,11 @@ from datetime import datetime
from decimal import Decimal from decimal import Decimal
from typing import Any from typing import Any
from pgvector.sqlalchemy import Vector
from sqlalchemy import ( from sqlalchemy import (
BigInteger, BigInteger,
Boolean, Boolean,
Computed,
DateTime, DateTime,
Index, Index,
Integer, Integer,
@@ -31,8 +33,9 @@ from sqlalchemy import (
Text, Text,
UniqueConstraint, UniqueConstraint,
func, func,
text,
) )
from sqlalchemy.dialects.postgresql import JSONB from sqlalchemy.dialects.postgresql import JSONB, TSVECTOR
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
@@ -304,3 +307,175 @@ class ObEvent(Base):
Index("ix_ob_event_name_ts", "event_name", "server_ts"), Index("ix_ob_event_name_ts", "event_name", "server_ts"),
Index("ix_ob_event_user_ts", "user_id", "server_ts"), Index("ix_ob_event_user_ts", "user_id", "server_ts"),
) )
# ---------------------------------------------------------------------------
# kb 域(知识库,架构文档 §6.2)
# ---------------------------------------------------------------------------
class KbEntity(Base):
"""12 类实体统一表:attrs JSONB 承载类目差异化字段(架构 §6.2).
状态机 draft→reviewing→published→archived 由 service 层校验;
published 实体不可直接改(version 递增需回 draft 重走评审)。
"""
__tablename__ = "kb_entity"
entity_id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=False)
entity_type: Mapped[str] = mapped_column(String(32), nullable=False)
name: Mapped[str] = mapped_column(String(128), nullable=False)
attrs: Mapped[dict[str, Any]] = mapped_column(JSONB, nullable=False, default=dict)
status: Mapped[str] = mapped_column(String(16), nullable=False, default="draft")
version: Mapped[int] = mapped_column(Integer, nullable=False, default=1)
source: Mapped[str | None] = mapped_column(String(255))
license: Mapped[str | None] = mapped_column(String(64))
updated_by: Mapped[str | None] = mapped_column(String(64))
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), nullable=False, server_default=func.now()
)
updated_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), nullable=False, server_default=func.now()
)
__table_args__ = (
UniqueConstraint("entity_type", "name", name="uq_kb_entity_type_name"),
Index("ix_kb_entity_type_status", "entity_type", "status"),
)
class KbRelation(Base):
"""邻接表 + 递归 CTE 做 1~3 跳(TD-09:不上 Neo4j)."""
__tablename__ = "kb_relation"
relation_id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=False)
from_id: Mapped[int] = mapped_column(BigInteger, nullable=False)
rel_type: Mapped[str] = mapped_column(String(64), nullable=False)
to_id: Mapped[int] = mapped_column(BigInteger, nullable=False)
weight: Mapped[Decimal] = mapped_column(Numeric(4, 3), nullable=False, default=Decimal("1"))
confidence: Mapped[Decimal] = mapped_column(Numeric(4, 3), nullable=False, default=Decimal("1"))
evidence: Mapped[str | None] = mapped_column(String(255))
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), nullable=False, server_default=func.now()
)
__table_args__ = (
UniqueConstraint("from_id", "rel_type", "to_id", name="uq_kb_relation_triple"),
Index("ix_kb_relation_to", "to_id"),
)
class KbRule(Base):
"""决策表(TD-10 自研规则引擎)。conditions/effects 为 JSONB DSL."""
__tablename__ = "kb_rule"
rule_id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=False)
rule_key: Mapped[str] = mapped_column(String(64), nullable=False)
category: Mapped[str] = mapped_column(String(32), nullable=False)
version: Mapped[int] = mapped_column(Integer, nullable=False, default=1)
status: Mapped[str] = mapped_column(String(16), nullable=False, default="draft")
priority: Mapped[int] = mapped_column(Integer, nullable=False, default=60)
conditions: Mapped[dict[str, Any]] = mapped_column(JSONB, nullable=False)
effects: Mapped[dict[str, Any]] = mapped_column(JSONB, nullable=False)
is_hard: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
confidence: Mapped[Decimal] = mapped_column(
Numeric(4, 3), nullable=False, default=Decimal("0.9")
)
evidence: Mapped[str | None] = mapped_column(String(255))
author: Mapped[str | None] = mapped_column(String(64))
reviewer: Mapped[str | None] = mapped_column(String(64))
published_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), nullable=False, server_default=func.now()
)
__table_args__ = (
UniqueConstraint("rule_key", name="uq_kb_rule_key"),
Index("ix_kb_rule_status_priority", "status", "priority"),
)
class KbChunk(Base):
"""向量 + 全文双索引,支撑混合检索(架构 §8.3).
embedding_model/version 必填:没有版本号的向量不可重跑(T-P2-03)。
tsv 是生成列——写入时不要手工填。
"""
__tablename__ = "kb_chunk"
chunk_id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=False)
entity_id: Mapped[int] = mapped_column(BigInteger, nullable=False)
chunk_type: Mapped[str] = mapped_column(String(32), nullable=False, default="text")
text: Mapped[str] = mapped_column(Text, nullable=False)
embedding = mapped_column(Vector(1024), nullable=False)
embedding_model: Mapped[str] = mapped_column(String(64), nullable=False)
embedding_version: Mapped[str] = mapped_column(String(16), nullable=False)
tsv = mapped_column(
TSVECTOR, Computed("to_tsvector('simple', text)", persisted=True), nullable=False
)
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), nullable=False, server_default=func.now()
)
__table_args__ = (Index("ix_kb_chunk_entity", "entity_id"),)
class KbAsset(Base):
"""图像资产。tryon_ready 是换装闭环的关键标志位(架构 §6.2)."""
__tablename__ = "kb_asset"
asset_id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=False)
entity_id: Mapped[int] = mapped_column(BigInteger, nullable=False)
asset_type: Mapped[str] = mapped_column(String(32), nullable=False)
cos_key: Mapped[str] = mapped_column(String(255), nullable=False)
spec_check: Mapped[dict[str, Any]] = mapped_column(JSONB, nullable=False, default=dict)
tryon_ready: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
review_status: Mapped[str] = mapped_column(String(16), nullable=False, default="pending")
license: Mapped[str | None] = mapped_column(String(64))
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), nullable=False, server_default=func.now()
)
__table_args__ = (
Index("ix_kb_asset_entity", "entity_id"),
Index("ix_kb_asset_tryon_ready", "tryon_ready", postgresql_where=text("tryon_ready")),
)
class KbColor(Base):
"""自建色板(TD-18:规避「四季色彩/CMB」商标)。Lab 用于 ΔE 数值匹配."""
__tablename__ = "kb_color"
color_id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=False)
season_code: Mapped[str] = mapped_column(String(16), nullable=False)
role: Mapped[str] = mapped_column(String(8), nullable=False)
lab_l: Mapped[Decimal] = mapped_column(Numeric(6, 2), nullable=False)
lab_a: Mapped[Decimal] = mapped_column(Numeric(6, 2), nullable=False)
lab_b: Mapped[Decimal] = mapped_column(Numeric(6, 2), nullable=False)
hex: Mapped[str] = mapped_column(String(7), nullable=False)
name_cn: Mapped[str] = mapped_column(String(64), nullable=False)
__table_args__ = (Index("ix_kb_color_season", "season_code"),)
class KbGap(Base):
"""知识缺口埋点:无检索结果的查询,驱动内容生产(T-P2-06)."""
__tablename__ = "kb_gap"
gap_id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=False)
query_text: Mapped[str] = mapped_column(Text, nullable=False)
filter_ctx: Mapped[dict[str, Any]] = mapped_column(JSONB, nullable=False, default=dict)
hit_count: Mapped[int] = mapped_column(Integer, nullable=False, default=1)
first_seen_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), nullable=False, server_default=func.now()
)
last_seen_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), nullable=False, server_default=func.now()
)
__table_args__ = (Index("ix_kb_gap_query", "query_text"),)
+6
View File
@@ -21,9 +21,15 @@ dependencies = [
"orjson>=3.10", "orjson>=3.10",
"prometheus-client>=0.21", "prometheus-client>=0.21",
"cos-python-sdk-v5>=1.9.44", "cos-python-sdk-v5>=1.9.44",
"tencentcloud-sdk-python-sms>=3.1.153",
] ]
[project.optional-dependencies] [project.optional-dependencies]
spike = [
# 算法验证 SPIKE(T-P0-10/12/16)专用;模型文件在 models/(已 gitignore)
"onnxruntime>=1.20",
"opencv-python-headless>=4.10",
]
dev = [ dev = [
"pytest>=8.3", "pytest>=8.3",
"pytest-asyncio>=0.24", "pytest-asyncio>=0.24",
Generated
+180 -1
View File
@@ -706,6 +706,14 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/a7/8e/50f46a9c0ce8d2861a394c1347caae037ea0431d2f67d7feb151cbc4649a/filelock-3.32.3-py3-none-any.whl", hash = "sha256:7f0ca4bcc0e181c60dbbd8aa9ab5b120ebb99e4e064e83636340056f833a1f09", size = 98901, upload-time = "2026-08-13T16:00:03.974Z" }, { url = "https://files.pythonhosted.org/packages/a7/8e/50f46a9c0ce8d2861a394c1347caae037ea0431d2f67d7feb151cbc4649a/filelock-3.32.3-py3-none-any.whl", hash = "sha256:7f0ca4bcc0e181c60dbbd8aa9ab5b120ebb99e4e064e83636340056f833a1f09", size = 98901, upload-time = "2026-08-13T16:00:03.974Z" },
] ]
[[package]]
name = "flatbuffers"
version = "25.12.19"
source = { registry = "https://pypi.org/simple" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/e8/2d/d2a548598be01649e2d46231d151a6c56d10b964d94043a335ae56ea2d92/flatbuffers-25.12.19-py2.py3-none-any.whl", hash = "sha256:7634f50c427838bb021c2d66a3d1168e9d199b0607e6329399f04846d42e20b4", size = 26661, upload-time = "2025-12-19T23:16:13.622Z" },
]
[[package]] [[package]]
name = "greenlet" name = "greenlet"
version = "3.5.5" version = "3.5.5"
@@ -1185,6 +1193,7 @@ dependencies = [
{ name = "sqlalchemy", extra = ["asyncio"] }, { name = "sqlalchemy", extra = ["asyncio"] },
{ name = "structlog" }, { name = "structlog" },
{ name = "tenacity" }, { name = "tenacity" },
{ name = "tencentcloud-sdk-python-sms" },
{ name = "uvicorn", extra = ["standard"] }, { name = "uvicorn", extra = ["standard"] },
] ]
@@ -1200,6 +1209,10 @@ dev = [
{ name = "respx" }, { name = "respx" },
{ name = "ruff" }, { name = "ruff" },
] ]
spike = [
{ name = "onnxruntime" },
{ name = "opencv-python-headless" },
]
[package.metadata] [package.metadata]
requires-dist = [ requires-dist = [
@@ -1212,6 +1225,8 @@ requires-dist = [
{ name = "httpx", specifier = ">=0.28" }, { name = "httpx", specifier = ">=0.28" },
{ name = "import-linter", marker = "extra == 'dev'", specifier = ">=2.1" }, { name = "import-linter", marker = "extra == 'dev'", specifier = ">=2.1" },
{ name = "mypy", marker = "extra == 'dev'", specifier = ">=1.13" }, { name = "mypy", marker = "extra == 'dev'", specifier = ">=1.13" },
{ name = "onnxruntime", marker = "extra == 'spike'", specifier = ">=1.20" },
{ name = "opencv-python-headless", marker = "extra == 'spike'", specifier = ">=4.10" },
{ name = "orjson", specifier = ">=3.10" }, { name = "orjson", specifier = ">=3.10" },
{ name = "pgvector", specifier = ">=0.3.6" }, { name = "pgvector", specifier = ">=0.3.6" },
{ name = "pre-commit", marker = "extra == 'dev'", specifier = ">=4.0" }, { name = "pre-commit", marker = "extra == 'dev'", specifier = ">=4.0" },
@@ -1228,9 +1243,10 @@ requires-dist = [
{ name = "sqlalchemy", extras = ["asyncio"], specifier = ">=2.0.36" }, { name = "sqlalchemy", extras = ["asyncio"], specifier = ">=2.0.36" },
{ name = "structlog", specifier = ">=24.4" }, { name = "structlog", specifier = ">=24.4" },
{ name = "tenacity", specifier = ">=9.0" }, { name = "tenacity", specifier = ">=9.0" },
{ name = "tencentcloud-sdk-python-sms", specifier = ">=3.1.153" },
{ name = "uvicorn", extras = ["standard"], specifier = ">=0.32" }, { name = "uvicorn", extras = ["standard"], specifier = ">=0.32" },
] ]
provides-extras = ["dev"] provides-extras = ["spike", "dev"]
[[package]] [[package]]
name = "mypy" name = "mypy"
@@ -1295,6 +1311,130 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl", hash = "sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827", size = 23438, upload-time = "2025-12-20T14:08:52.782Z" }, { url = "https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl", hash = "sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827", size = 23438, upload-time = "2025-12-20T14:08:52.782Z" },
] ]
[[package]]
name = "numpy"
version = "2.5.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/9a/80/db0b4559e57ec36362bedbb05530a87fafbcb6067708c946967a41d449e7/numpy-2.5.2.tar.gz", hash = "sha256:d482d171c406ae88c5b19cad3b6a1c4c5209f886ab74bc44c2c865c23f52d860", size = 20773161, upload-time = "2026-08-09T13:48:27.962Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/69/72/dccb0aaf40972777283303919f613964227266d0c13adebb79ac124f1c3e/numpy-2.5.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:14e373cfc6387177e8409dac3c7159be8eb05cd77096cd7c950268b86f62831c", size = 16891693, upload-time = "2026-08-09T13:44:51.702Z" },
{ url = "https://files.pythonhosted.org/packages/60/2e/b5aee50a1f74ac815cf8331812cb8251e29024025de462e0c047641c614c/numpy-2.5.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4bbd96c833ecc8cc069ce518078fc8c60cb9cbfb0fea5b7a803ad65035596d03", size = 11903109, upload-time = "2026-08-09T13:44:55.501Z" },
{ url = "https://files.pythonhosted.org/packages/f3/f4/29e78102a80601cf034d4e9767022cffeca2c3b4c926e1754572ca95593d/numpy-2.5.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:6e8172ddfcf5cf74b811d372b570b83c60bd2de87a6fbfbebdadb4a9bd9c6cbb", size = 5350202, upload-time = "2026-08-09T13:44:58.401Z" },
{ url = "https://files.pythonhosted.org/packages/11/4b/dcd3b7eadaf4035d2c7a4289d232523a6964f602598ef7674e4bd7291f93/numpy-2.5.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:65f188481f1669e26f62b701e8205d19e460fa4a9b52a1414ba382330e4a3414", size = 6687736, upload-time = "2026-08-09T13:45:00.813Z" },
{ url = "https://files.pythonhosted.org/packages/e5/21/4947e0e9d6c9fc2e2ff15b8949049ee44f63adb9cacc729ab8793f97e712/numpy-2.5.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8ee9c4eeb8454b3660a8b53493563c3e121c2fc94fbd72b848ef814ed7b676a9", size = 15612696, upload-time = "2026-08-09T13:45:04.151Z" },
{ url = "https://files.pythonhosted.org/packages/3a/5f/62d28cf019460c7f1394105b4d49d9911a9c444cb77ab0bd95a204c5a6de/numpy-2.5.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3cdec01fa790a186d430433fdd4d4ffb70eed6f0eeb4bf05c8dbe2dce0a9bcb8", size = 16722264, upload-time = "2026-08-09T13:45:07.714Z" },
{ url = "https://files.pythonhosted.org/packages/14/25/3f0be4c1b9fdf5dd5e708a6806978564d7c46a055c000496309ff2a2f8af/numpy-2.5.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7999d4ddb0c4025018373fd787510d46e04c769467af22869707b3c1cfd459ab", size = 16974396, upload-time = "2026-08-09T13:45:11.316Z" },
{ url = "https://files.pythonhosted.org/packages/22/72/6262cbdeeb45da9d971e40715f579d791603ba8ec0b5e2db1ac55454421d/numpy-2.5.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c1f017dc0875c9209d219f97feceb7d54c2661bb243deb4114478e1295808af7", size = 18476044, upload-time = "2026-08-09T13:45:14.869Z" },
{ url = "https://files.pythonhosted.org/packages/36/33/29208b8b075bde62d26a81d14b358c42b0f69b6cabd98d4ff97f37f22b05/numpy-2.5.2-cp312-cp312-win32.whl", hash = "sha256:d6a48072864e3324e194a8fbb3c657bcc5b5c869dbc64c9537b1d5c862572c0a", size = 6072817, upload-time = "2026-08-09T13:45:17.867Z" },
{ url = "https://files.pythonhosted.org/packages/7f/b9/87fea2769fe1c47c1b5b01d8310772c9d1a85d485de7cf386ef7a3332b02/numpy-2.5.2-cp312-cp312-win_amd64.whl", hash = "sha256:28ac63476ec7651484215ee7fa15a1f78b57c14621f01e392afe17b9a1390ce4", size = 12464674, upload-time = "2026-08-09T13:45:20.734Z" },
{ url = "https://files.pythonhosted.org/packages/14/52/032b97e00461ab0809bbe4c588b035620e5a14b8cdee47ecddefc7b17d33/numpy-2.5.2-cp312-cp312-win_arm64.whl", hash = "sha256:27650bb0e7140fa3d37b9923b4803645e0b125d190f326eecfd3f4dad8e8ade1", size = 10397131, upload-time = "2026-08-09T13:45:23.73Z" },
{ url = "https://files.pythonhosted.org/packages/f5/d2/6b24738a0ef4557d189b150046cd07823c50e4273e8aebd651222e24306f/numpy-2.5.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8e4cb9a754c8a0c62eaa88273a5fba3391f4a610d1dee893c0755da31c083f15", size = 16886595, upload-time = "2026-08-09T13:45:27.323Z" },
{ url = "https://files.pythonhosted.org/packages/65/60/f2d208d366f263f39c6e69ed309290717aab41078b6d04c9be2a84fa2a07/numpy-2.5.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:52c808f96484f5571a5cc863775ce50247c17dfb3b0361f8ed6b4b0456f80080", size = 11896845, upload-time = "2026-08-09T13:45:31.638Z" },
{ url = "https://files.pythonhosted.org/packages/3c/79/81e0bf24f4d020a2b1d5cd297a9f60c3f24eeb116f9bba5870443f7b6a4a/numpy-2.5.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:29d81e97f668489cba8ebfd796b9bdd453525d35dd9e162e2daec94bf3fc7740", size = 5343880, upload-time = "2026-08-09T13:45:34.373Z" },
{ url = "https://files.pythonhosted.org/packages/ba/cc/e3141cf06d1a8a2c7e107543fe1269c1d1af760d4d683c0794a4ee1127c2/numpy-2.5.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:afb3f0632d6b2e3ba04dbce8d1e48d321b369138b73830b5ca371a0e8d479d56", size = 6682264, upload-time = "2026-08-09T13:45:36.7Z" },
{ url = "https://files.pythonhosted.org/packages/29/f1/2a64a307d92c5d98f5255a4014eb43bb6103ee477087b61ecae44a3aa9b9/numpy-2.5.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0aadf13b60048d501e05fa699efaf7734e2494f3498a4c2a5521d822640324f3", size = 15609566, upload-time = "2026-08-09T13:45:39.518Z" },
{ url = "https://files.pythonhosted.org/packages/7b/44/59a1eb68e773c4098d107ef34a0dbdeca501d72ffcfbff9a7707343921ce/numpy-2.5.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:29b86ff8a6cc556b47ec6b64b194815cc80e6bf5eedcc6cddfd65318cb0b4eee", size = 16709995, upload-time = "2026-08-09T13:45:43.661Z" },
{ url = "https://files.pythonhosted.org/packages/8a/4c/3e54d4ddbc359a1295f8b633e8106bcd4d7d4a206e82df051bdfb3058755/numpy-2.5.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6950c4b7dd562453090548ba7f5da7e59f57f85663f15d5dcc60e249192f7e59", size = 16972511, upload-time = "2026-08-09T13:45:47.094Z" },
{ url = "https://files.pythonhosted.org/packages/f2/9f/02e371638ebf19b66d46231e4be52999e87f32d1961b113bc45656608b22/numpy-2.5.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b9727f472d2f3888053b8a75ab0cb94745a9de224bb5846dbadc0092101bc71d", size = 18465609, upload-time = "2026-08-09T13:45:50.808Z" },
{ url = "https://files.pythonhosted.org/packages/eb/ae/ad6645abc7a3510fe48e8ea1ab4598166f500057ef4ebf38bfad4f1577de/numpy-2.5.2-cp313-cp313-win32.whl", hash = "sha256:4f9744f9fbdcea0bc552e8f19e1f141f811a3f9bc2be2cc6e86d982cab23e3f4", size = 6070204, upload-time = "2026-08-09T13:45:54.111Z" },
{ url = "https://files.pythonhosted.org/packages/15/20/f3489f86d81ea460b2bcdceaed094142ca6579f6be0ec527b781d39afe68/numpy-2.5.2-cp313-cp313-win_amd64.whl", hash = "sha256:85aaccb24182c25df891ad0ec333585967e115269d5f1b17f2c9ae005bc96657", size = 12460532, upload-time = "2026-08-09T13:45:57.167Z" },
{ url = "https://files.pythonhosted.org/packages/d5/21/35b31dde1b283b79de828b80f876afd8c94e28fe1e9c375f89e261cc4c0d/numpy-2.5.2-cp313-cp313-win_arm64.whl", hash = "sha256:bd68ece1553d2023c09a4226d9e41c586ad2d20594d1a456186c33513d2cb3f2", size = 10396725, upload-time = "2026-08-09T13:46:00.478Z" },
{ url = "https://files.pythonhosted.org/packages/ac/f8/c3b222bf075b50afd8e949a07a15c4b312a4a84bd8102a332bcd953cbbb4/numpy-2.5.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:d787cf769c3baeb5f6235e778edb52c08dfa923789b5958f28e6450f96107cb1", size = 16885180, upload-time = "2026-08-09T13:46:03.939Z" },
{ url = "https://files.pythonhosted.org/packages/17/e1/2c1d4b1987795a92b5bbf7c24fe249ab96aa2573ab0d7604802c189d7b86/numpy-2.5.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:24b9dc2e3d84aa58523798805194e23e736f3f6ce2d1a5b92583ae734e6dbda8", size = 11907878, upload-time = "2026-08-09T13:46:07.045Z" },
{ url = "https://files.pythonhosted.org/packages/b9/ee/d08226fc858044355983a6e5b94f08ff6f3969e0a2b160a4a89f0ddb3445/numpy-2.5.2-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:9e9413326d726c2545bfa65d2c0876871e8d8386e77f992c1d426e180bbd4323", size = 5354922, upload-time = "2026-08-09T13:46:10.04Z" },
{ url = "https://files.pythonhosted.org/packages/94/f0/6d3d933056440ebbc5e6bad92065fc6c26a48a84a36b1208580e94eea76c/numpy-2.5.2-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:60e902ac295855348a5ca2ea4c89108989a9f5fddfad3dfc0a8f36b10358567e", size = 6679168, upload-time = "2026-08-09T13:46:12.275Z" },
{ url = "https://files.pythonhosted.org/packages/c4/3b/ecd49dd90033cceb2704d88ca905d4d7d89b0e8c739608754ffd325fa820/numpy-2.5.2-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:50e500dc868e9313530ce12ba470fe50ff3afe3d62993ed6eff652dacd555b65", size = 15624501, upload-time = "2026-08-09T13:46:15.322Z" },
{ url = "https://files.pythonhosted.org/packages/c7/99/461bd36dbdfac6c1c53efa370bd55a83227542d0d118f1677dbf1a3dacd5/numpy-2.5.2-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:318b9a4c845dbea06708a29c84ee429cc3065048db34cdb799047643492050ee", size = 16713701, upload-time = "2026-08-09T13:46:18.949Z" },
{ url = "https://files.pythonhosted.org/packages/f9/9c/2b251df9e8a5d647b62b0cbc1b90a91850c1cf4859ecb532fd0b4eacff6c/numpy-2.5.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:34c319e2963be042673fb46570501b2f06c41924e17e3563d58646b4380dfb68", size = 16986065, upload-time = "2026-08-09T13:46:23.006Z" },
{ url = "https://files.pythonhosted.org/packages/8f/25/20de43f53ff1390534a124475055a19f01fe10c920a0fd11b8e18d6d6052/numpy-2.5.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f06571a052127dc1b4e8b83029b4d1b20daa2b64a31cdd181fc6bc774e9000eb", size = 18470031, upload-time = "2026-08-09T13:46:27.102Z" },
{ url = "https://files.pythonhosted.org/packages/56/5e/0c577ca308d6da5eb79b546ba10bbe5b60148192194e2da060913b1de4f1/numpy-2.5.2-cp314-cp314-win32.whl", hash = "sha256:2cc779226e476d1e1f08c74068c419e60f41a9e0e069c92f6671d31d5c985e98", size = 6121028, upload-time = "2026-08-09T13:46:30.046Z" },
{ url = "https://files.pythonhosted.org/packages/15/5c/7bcbd5b11f94199073320410cddcbb80cee62415bfeb540874b265c2d922/numpy-2.5.2-cp314-cp314-win_amd64.whl", hash = "sha256:7587f53dfbd5edc0f7b87c6217b4c6d2d1f2ef9c3da70bc1315e7db5f8d7ec9d", size = 12597627, upload-time = "2026-08-09T13:46:32.886Z" },
{ url = "https://files.pythonhosted.org/packages/87/bc/4d0b06fba0da90ccc75af62823cb9dcedb6c9ea0cffa058cb2c9ee773a77/numpy-2.5.2-cp314-cp314-win_arm64.whl", hash = "sha256:3e4c367352d3747784248a227fbec218e193b56f7e6692e3b64fc805478ecfdf", size = 10680414, upload-time = "2026-08-09T13:46:36.036Z" },
{ url = "https://files.pythonhosted.org/packages/cd/17/f429aac9dc08833a0d0f188eba38c532a751b1a1f2ca6018a37b455cb321/numpy-2.5.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b879fb674276e331513fb136b78dbc6bd3c848309e0d841cfd63be3896c4cfc1", size = 12026967, upload-time = "2026-08-09T13:46:39.084Z" },
{ url = "https://files.pythonhosted.org/packages/ca/9f/d0849de96a2a4ceaa16662f18ee13eaa9c0aa418269fdc8c4857c56b11da/numpy-2.5.2-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:fd0d703772bba096843785bd38371e31bb4a0c1151497ad5739d182114a73f7f", size = 5473874, upload-time = "2026-08-09T13:46:42.075Z" },
{ url = "https://files.pythonhosted.org/packages/89/3c/8df216d4a4a5422a3de045301cf7df8ea47286d76f5cb7160b0128ac26b7/numpy-2.5.2-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:3a2f061cebd9e3d23bdcfaaded5e2293a4c6a5b60fa42df85d410a725ce621bf", size = 6789276, upload-time = "2026-08-09T13:46:44.387Z" },
{ url = "https://files.pythonhosted.org/packages/e6/3a/20d7e9891c4ddfadd6ff8d95bf4b29f353d8e1770553de2099880551dfb9/numpy-2.5.2-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6df895598c0edcb41030126c89e0f353b07d93238116143b7405e937359736c4", size = 15659154, upload-time = "2026-08-09T13:46:47.538Z" },
{ url = "https://files.pythonhosted.org/packages/aa/d6/f3aa3d2688bf501b858835c6bd087ae9b51a56ae6fca8e2b0990abd177af/numpy-2.5.2-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1ab3d4a901f844ea836c3e80bf463c6a27d7f3c14e8e292fcf28d348b25b9bce", size = 16748909, upload-time = "2026-08-09T13:46:51.442Z" },
{ url = "https://files.pythonhosted.org/packages/7d/8f/1c5cae8d2baf86ab802ae97a00be55bc7e21ebc11b12bbc33376c5f05342/numpy-2.5.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:cebc2d6dbb605a7703d59751dea4bd6b0ab127a5a4338a6f432df1936fef8b26", size = 17027685, upload-time = "2026-08-09T13:46:55.095Z" },
{ url = "https://files.pythonhosted.org/packages/5c/27/71d3467404aedc1c24ce79610f91b52b0b0f466c43a701aa56fc75c145ab/numpy-2.5.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:eaca7ff36f0f52e2111ec71f169d8fd3e889e7ddc0d2592e0d703fd8d3ce8fac", size = 18501181, upload-time = "2026-08-09T13:46:59.09Z" },
{ url = "https://files.pythonhosted.org/packages/14/2f/42921d27c40aea7e077f4a423ae509fd9220b028cd787bafefd8ab2b3a5f/numpy-2.5.2-cp314-cp314t-win32.whl", hash = "sha256:ddf47472af2e4280d79bac82304f5e80150211f1b9e614b760061d5fdfbb6eba", size = 6271085, upload-time = "2026-08-09T13:47:01.903Z" },
{ url = "https://files.pythonhosted.org/packages/75/e6/bad5f5d56de9b1971bac959963dda276d35c40f1854475005434bbe08692/numpy-2.5.2-cp314-cp314t-win_amd64.whl", hash = "sha256:44ef9675d908e65f9953063837c3277730f3f4437615a4cdab67b366cabaf884", size = 12787971, upload-time = "2026-08-09T13:47:04.963Z" },
{ url = "https://files.pythonhosted.org/packages/df/05/f608795cb34391acd67e38d94a3c36abd8d8576293a3a80727d7595c372c/numpy-2.5.2-cp314-cp314t-win_arm64.whl", hash = "sha256:eaa088384c46f519dacb93b7ec483a6d6b19a4a2085ae4f25ab9b1c43d387d1e", size = 10750306, upload-time = "2026-08-09T13:47:07.976Z" },
{ url = "https://files.pythonhosted.org/packages/33/c6/28de0191c5f82b7d42a0a51390ba98587048aa93a39fafb05bdbe6e8d00c/numpy-2.5.2-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:078f9b027b478c9379b9677babbf0f8b8f1ecfada27636d7b9a93990c638739f", size = 16885274, upload-time = "2026-08-09T13:47:11.439Z" },
{ url = "https://files.pythonhosted.org/packages/dd/d1/973ca116000d244897e468ea1aff30b589e5022e3c8744b71706fe33bd57/numpy-2.5.2-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:50a68f4bacd8a2b33d8da3d2269d0d78500f86ea582e4786dc10f5ef2c2c6842", size = 11907846, upload-time = "2026-08-09T13:47:15.128Z" },
{ url = "https://files.pythonhosted.org/packages/78/d9/8c4b3937ef204cb2fd88d389ccd0f265a2ffb11f35a01d2064cf46714bd6/numpy-2.5.2-cp315-cp315-macosx_14_0_arm64.whl", hash = "sha256:e79aba74ffaf5f78a050d777c184cddf8fdffabab38acf5f3ef1fecbc17895d6", size = 5354892, upload-time = "2026-08-09T13:47:18.07Z" },
{ url = "https://files.pythonhosted.org/packages/74/9b/b6ee65ea2999fdb7023935e108e6fb776ee4082aa15f159acfa857e578c8/numpy-2.5.2-cp315-cp315-macosx_14_0_x86_64.whl", hash = "sha256:9a0731745a72a184490a582fb4af2533512bd071ace67785b5fdffc0ae58dce8", size = 6679309, upload-time = "2026-08-09T13:47:20.456Z" },
{ url = "https://files.pythonhosted.org/packages/43/f3/acb18d8b137a393c8e7803a8c994c9e64bde3930692a69d826993113a159/numpy-2.5.2-cp315-cp315-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4ec954036759bcee3aa484f8603bd9c14f3e776293b85578b8734c2d72777c69", size = 15625850, upload-time = "2026-08-09T13:47:24.365Z" },
{ url = "https://files.pythonhosted.org/packages/a9/bf/a8e9bb0db815a0e265b5744ebedd3af0bd5faad8604e5b50a1cd012f3c91/numpy-2.5.2-cp315-cp315-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dc649493697006bc90614a5f0bbc8cb3cb1866715c474e473694968d7e6b99ab", size = 16713664, upload-time = "2026-08-09T13:47:27.965Z" },
{ url = "https://files.pythonhosted.org/packages/0c/c3/6e913736b3dd6582344af32418b5fb9dab34282e8a8174ae1d54ceb0fc13/numpy-2.5.2-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:cf7de32f486e4ac9e2d93b810f9e9ac72a728dd46a32a0bb403222f27f653514", size = 16986749, upload-time = "2026-08-09T13:47:31.541Z" },
{ url = "https://files.pythonhosted.org/packages/80/09/7d3b23eff5c7428ef6c01e6f7052bb60d504c4d33e317b36b8959c24ad97/numpy-2.5.2-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:2ffa7bacab3e2ee1b19ed31766bb60bb380b68c23f051e199c5cc598afd68710", size = 18470495, upload-time = "2026-08-09T13:47:35.364Z" },
{ url = "https://files.pythonhosted.org/packages/a5/a4/68a321d825374f6eb677ffe8ef8c6b9a328304e6fd2e39d9530822776607/numpy-2.5.2-cp315-cp315-win32.whl", hash = "sha256:6b588cc8f902d6bff201c19fd00c43ab8545671e3554d014e12e14139e5e8617", size = 6120696, upload-time = "2026-08-09T13:47:38.561Z" },
{ url = "https://files.pythonhosted.org/packages/c8/23/deafbb1700f79fae9cd1e91220f133d124cc267de1b584da3fbf6db2f6cd/numpy-2.5.2-cp315-cp315-win_amd64.whl", hash = "sha256:07d4e89f3a9ab0a9ba24264ccdb642b3dd951b2281e8883a5481a4aa79cc31a7", size = 12597324, upload-time = "2026-08-09T13:47:41.401Z" },
{ url = "https://files.pythonhosted.org/packages/33/cd/3272ba105e3bbbdaeb11357eda31e7a6825ffe159e8171665660299a948f/numpy-2.5.2-cp315-cp315-win_arm64.whl", hash = "sha256:a610dc7e3c52edd39c2bc2375ff9c3fd59cb3ad00e4472d36f83bc1457145788", size = 10680466, upload-time = "2026-08-09T13:47:44.873Z" },
{ url = "https://files.pythonhosted.org/packages/0e/0e/58370637b1bb70a5c9ce2b43f4b521ccb224e36ccb76a6596b17ae4b447c/numpy-2.5.2-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:40f4d451aed46a8046a1aae41c4e55fb3612273df9c502480135e1501576a34b", size = 16993947, upload-time = "2026-08-09T13:47:48.97Z" },
{ url = "https://files.pythonhosted.org/packages/10/93/2abcb807712b289d6d60fe4cf30532f98974a8396d885650f3ba5a13026e/numpy-2.5.2-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:c081cbe16ba1ab53078e5ff29013621e33c509eedab055775d956427712c236e", size = 12025331, upload-time = "2026-08-09T13:47:52.646Z" },
{ url = "https://files.pythonhosted.org/packages/8b/3a/2898e003a5fbaf87e76c039b4ee1f5eb390471b4ffe74887c1f34c4e791e/numpy-2.5.2-cp315-cp315t-macosx_14_0_arm64.whl", hash = "sha256:0090ccdd57ec2703e9b49d0bf554767370581c1dd0a6b2bb2b2d9def317d042a", size = 5472336, upload-time = "2026-08-09T13:47:55.403Z" },
{ url = "https://files.pythonhosted.org/packages/61/a5/23f69d07c544597b29758b31b55c27dc9d541012a2c1496189fef702aec2/numpy-2.5.2-cp315-cp315t-macosx_14_0_x86_64.whl", hash = "sha256:6a9bb119fb8dd21ba30b3f0e555b7e2b081bd9883af21ec9c1c633d161cda3a8", size = 6788387, upload-time = "2026-08-09T13:47:58.192Z" },
{ url = "https://files.pythonhosted.org/packages/15/ea/c0dbdbcf22f43782510a3e492dd3da73c6112b69cac8929d16d127536fc4/numpy-2.5.2-cp315-cp315t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a839318485284a6fb31be4f8f2c91c8f2cb22f4543c4a8903f12b0671ffe07cc", size = 15667096, upload-time = "2026-08-09T13:48:01.562Z" },
{ url = "https://files.pythonhosted.org/packages/fc/5e/29c73c31748cdb0f7566642125ba17fd5b56780cddf891b085dab27e4466/numpy-2.5.2-cp315-cp315t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba0a474801b8dc67b66bf465548abc90e82b44d2611b5770f33008dcabffe8ec", size = 16751730, upload-time = "2026-08-09T13:48:05.706Z" },
{ url = "https://files.pythonhosted.org/packages/47/95/02501e8454796bb58dadf7a99d3181e0b464bf264e1003039572f9779fac/numpy-2.5.2-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:0a4035ae1129ff8777f08bfbd44f1e5d8e9c049ce0c2dd78fc0d92c13e7251c0", size = 17038686, upload-time = "2026-08-09T13:48:09.627Z" },
{ url = "https://files.pythonhosted.org/packages/0e/b5/53a681d91b5c82687067d8ea5035e02d917b5509d6f334cb06484a954714/numpy-2.5.2-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:77843ca236b777e67f8d6b3660ea116e499612703a0ecd7093f316201eb9d8e2", size = 18507727, upload-time = "2026-08-09T13:48:13.744Z" },
{ url = "https://files.pythonhosted.org/packages/42/06/6e11443f7b64ee376c860506091103bf68f92d2cab9e8d96d4501babf07c/numpy-2.5.2-cp315-cp315t-win32.whl", hash = "sha256:7354826bc6f8f69402e9b7fe28d15fcd34feebd74f856f111585c5b0c9fb0251", size = 6269775, upload-time = "2026-08-09T13:48:17.543Z" },
{ url = "https://files.pythonhosted.org/packages/f1/18/195d6b86cd72dbbc501edfa778005fa6b87afd34c153e46028cd3a0938f4/numpy-2.5.2-cp315-cp315t-win_amd64.whl", hash = "sha256:e5651f3f87add730ee6608d915009e19c911fba0cb000c7e3ea994b7d768eb12", size = 12782559, upload-time = "2026-08-09T13:48:21.023Z" },
{ url = "https://files.pythonhosted.org/packages/b4/07/458c344f0f0c178f4481dad5cca790626ffe4c34eabf9467069d06ee4999/numpy-2.5.2-cp315-cp315t-win_arm64.whl", hash = "sha256:5f8e00be2ec6f45f4e8a41a527f68d44a7d96fee92a650e4d8b1326f77f61e6e", size = 10748103, upload-time = "2026-08-09T13:48:24.21Z" },
]
[[package]]
name = "onnxruntime"
version = "1.28.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "flatbuffers" },
{ name = "numpy" },
{ name = "packaging" },
{ name = "protobuf" },
]
wheels = [
{ url = "https://files.pythonhosted.org/packages/98/f8/dcbe7700dca82fa540035abd3c868fe5ad0f86af00b9a3db7c2e27d15c7d/onnxruntime-1.28.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:26ff0fdd06efb6c155bae95387a09db1a2be89c7a03e4d0bffd5a171cc2826da", size = 19141362, upload-time = "2026-07-25T01:22:36.965Z" },
{ url = "https://files.pythonhosted.org/packages/28/5b/1d77e62097fdbe07e2dc827f389b1c4c0c275f6fab0369a8f46d2461af27/onnxruntime-1.28.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e81a23df16e7acb9d51b06d30cc098e49315ef9180f97bc2221d167b4b04d9c", size = 17050628, upload-time = "2026-07-25T01:21:40.481Z" },
{ url = "https://files.pythonhosted.org/packages/95/df/5486ab03e9be288d5268867054c8b04bebcf95bfd12e801c05cc67703dab/onnxruntime-1.28.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0a83bdb70d143cede762b677789bf2a7acca54b3fb82565601d5c30695aa933c", size = 19214257, upload-time = "2026-07-25T01:22:01.695Z" },
{ url = "https://files.pythonhosted.org/packages/3e/3b/986ca67c274932ba9ac5332fb10de56f643dfd433c74e33f8ae8f847cf24/onnxruntime-1.28.0-cp312-cp312-win_amd64.whl", hash = "sha256:c35064f9b3c43c81c5d5d282091401d0f1ff22796d93ccade4ea2ece5e137ab8", size = 13755036, upload-time = "2026-07-25T01:22:26.89Z" },
{ url = "https://files.pythonhosted.org/packages/1d/46/059dba81d46c6ba88e0c2d1c64321ac8098847d678423300a183d42ecbd6/onnxruntime-1.28.0-cp312-cp312-win_arm64.whl", hash = "sha256:e02feeb0165c5f13b4cc954738078d59b90128516ac12b671ee24a530242bf02", size = 13454462, upload-time = "2026-07-25T01:22:17.38Z" },
{ url = "https://files.pythonhosted.org/packages/9c/12/3807e2b17d9eb71d3cb78ed2ba76869b05c637c9b9d6112e636098b0c97a/onnxruntime-1.28.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:31410f544674f534c2f27348af52ef81682ca9c8719154bf4d48f0ef23823b1e", size = 19141759, upload-time = "2026-07-25T01:21:53.765Z" },
{ url = "https://files.pythonhosted.org/packages/c0/23/b46045c3bf67a9cf54c12f5df0f018a422c65fbb9d6072b10071bebfaae2/onnxruntime-1.28.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f649dd6f6452d12a8059888aa489fe519e062e18793dac72b9efa0f9fdb64135", size = 17049339, upload-time = "2026-07-25T01:21:43.005Z" },
{ url = "https://files.pythonhosted.org/packages/78/b6/8c5396e7894e77c5a7d1e026f3acb9dd39c4b5644e412e37a0055eaa3bc5/onnxruntime-1.28.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:54fa221d669282bd8f582708ce4c96010a7e9fb0661f9006b37fe2fedafb73fe", size = 19214329, upload-time = "2026-07-25T01:22:04.133Z" },
{ url = "https://files.pythonhosted.org/packages/56/f1/51225c202edba4dfc94e1ea03f3d78f1aaf307da75fd792c0ce1946b2514/onnxruntime-1.28.0-cp313-cp313-win_amd64.whl", hash = "sha256:1a1a19175464665c9b8d50bc916f216cc0b569110045b7bbca8f9f290b186f58", size = 13755033, upload-time = "2026-07-25T01:22:29.302Z" },
{ url = "https://files.pythonhosted.org/packages/f4/db/f59f715edfdd96a051f32b5ef0e680a20a8755d4ecd75f63090e960e347a/onnxruntime-1.28.0-cp313-cp313-win_arm64.whl", hash = "sha256:cfab507abe09d6ffeb817eee07944d452fdc0b00fdcef34cab4db10a45e378c7", size = 13454175, upload-time = "2026-07-25T01:22:19.912Z" },
{ url = "https://files.pythonhosted.org/packages/47/28/810314fa88647af9f4cdaf438a30ad1cfebebb53ded55499232d7a0094e6/onnxruntime-1.28.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ac301f53b1930402fc46c368e268acfed02f3207272aaff05070d7e09f96f031", size = 17057307, upload-time = "2026-07-25T01:21:45.492Z" },
{ url = "https://files.pythonhosted.org/packages/3d/cc/9e9f193cc0f29f263a8f09ec08487aed6c96ee856d5fd77da32a425c1949/onnxruntime-1.28.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f7f022a1103cae591c75fc4565589a515f2ddd14a6ac8e8a05812dfeda142e28", size = 19222954, upload-time = "2026-07-25T01:22:06.952Z" },
{ url = "https://files.pythonhosted.org/packages/4e/eb/952314c451d9463e5c9aed9978eec76cf32930d407d9ab8700dd0f4ea1ea/onnxruntime-1.28.0-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:8adff67a3f28257b37cfe945a7e952e4122666aa8c91a0380862e9fd4c2ed19f", size = 19143748, upload-time = "2026-07-25T01:21:56.297Z" },
{ url = "https://files.pythonhosted.org/packages/3f/e9/139180b4dd810329aaa42c238b4e6383c906202d98609ae29d66eb7c32b1/onnxruntime-1.28.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bc2565e487b4896fb988d6383577d875d958e071fc5f6c3550bd5d02ae98264b", size = 17051950, upload-time = "2026-07-25T01:21:48.606Z" },
{ url = "https://files.pythonhosted.org/packages/03/88/9432428273356ad3c8aa01f52c1b3e7f53c4c0192748f41ad983872b436b/onnxruntime-1.28.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6afdc83f1317c136e92fc29f5ee9f058de59d87c0b22cee3fdbfbaa0ccc2098a", size = 19214924, upload-time = "2026-07-25T01:22:09.727Z" },
{ url = "https://files.pythonhosted.org/packages/bb/e2/6feb3a43517aaf2b1bf7e46897ba5eb81a29717f7d7901420614d5ee4653/onnxruntime-1.28.0-cp314-cp314-win_amd64.whl", hash = "sha256:f2a3b9e30ce880d4ca54999cb313569e36da4f62eefe25f87be18f43e9a3a4d5", size = 14093738, upload-time = "2026-07-25T01:22:31.629Z" },
{ url = "https://files.pythonhosted.org/packages/fc/8f/83974a1e201dc2e58e5e7111bcaeb1ca2413e9c41f505d26419ee9e3dddf/onnxruntime-1.28.0-cp314-cp314-win_arm64.whl", hash = "sha256:07fb3cbe990d6bf0ab3c22bfbbfb0e314151266046ea6edb4a07f556b4258c5f", size = 13821117, upload-time = "2026-07-25T01:22:22.387Z" },
{ url = "https://files.pythonhosted.org/packages/0d/83/00e606bc25c756d76a267370c39b7516ad52f9cf134d7ff2bff8b6108bc4/onnxruntime-1.28.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e562d6e36a749f6764481c0ddb0f2af3d0b5a3c164291361d08803c557f369af", size = 17055518, upload-time = "2026-07-25T01:21:51.08Z" },
{ url = "https://files.pythonhosted.org/packages/94/a9/68707e1ce345cbdbcd4df65932ebc82a673e917d63eda0007ebcff948691/onnxruntime-1.28.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4f6e92367ddce1e4d33cf295024f40192be6c6171a09208f515ba169ced06c8e", size = 19222976, upload-time = "2026-07-25T01:22:12.474Z" },
]
[[package]]
name = "opencv-python-headless"
version = "5.0.0.93"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "numpy" },
]
sdist = { url = "https://files.pythonhosted.org/packages/1d/99/76b7c80252aa83c1af16393454aafd125a0287101afe8deb0a6821af0e30/opencv_python_headless-5.0.0.93.tar.gz", hash = "sha256:b82f9831daab90b725c7c1ee1b36cb5732c367096ac76d119e64e14eb70d5f3c", size = 81817738, upload-time = "2026-07-02T07:01:06.039Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/53/7c/8c8097891c509d98cd128493835c95631c80be6a8f37ed9d25716c2e16f1/opencv_python_headless-5.0.0.93-cp37-abi3-macosx_13_0_arm64.whl", hash = "sha256:030ca5e0837a2963ab36ef896baa9767eb8d2b83353fb28af5a521e40dd8756f", size = 48322581, upload-time = "2026-07-02T05:50:34.207Z" },
{ url = "https://files.pythonhosted.org/packages/90/8c/eab2ad388c3cbab2a350c10c2ef19ce6bd099240afc31789032c996bab52/opencv_python_headless-5.0.0.93-cp37-abi3-macosx_14_0_x86_64.whl", hash = "sha256:1e55af3abfb462eeeabe5c775f12bdb36216d8a93a3583d69e6bd6e1d6ba7d00", size = 34782894, upload-time = "2026-07-02T05:51:39.856Z" },
{ url = "https://files.pythonhosted.org/packages/ec/78/afca939f40ffe2b2380bfa86f812b2f7d4acc5a27b27dc41b49cad7ce7b4/opencv_python_headless-5.0.0.93-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:10818d91510e05c04568ae12b5cd120779c70c01bf897b001a6221fe430df80f", size = 36521085, upload-time = "2026-07-02T06:55:24.429Z" },
{ url = "https://files.pythonhosted.org/packages/2b/97/8170e9819764c47e436c130d3ff6cfb73b58f923eae9d3a03d8982b04aec/opencv_python_headless-5.0.0.93-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:09a872a157c1376ab922a69bbf22f9a95bcc7b658a9d8b436a60212b02b2eeb4", size = 56563598, upload-time = "2026-07-02T06:55:47.355Z" },
{ url = "https://files.pythonhosted.org/packages/3a/98/1a28a7101e31801042b3098871a74b76c61581d328ef40774ff4edb53a56/opencv_python_headless-5.0.0.93-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:840bd717c21e5c11cadadc022a823315ea417f961213d06b4df010e019eb16f4", size = 39648433, upload-time = "2026-07-02T06:56:04.255Z" },
{ url = "https://files.pythonhosted.org/packages/9b/21/f6ef335f6e65724aa78b8d792b48d40a48c381715f1e62f5a5049e09d07e/opencv_python_headless-5.0.0.93-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:ed709fdf9aa0bd1f2ed8549e71d19449b03a675bb581eb292285f6861953be37", size = 61204038, upload-time = "2026-07-02T06:56:41.823Z" },
{ url = "https://files.pythonhosted.org/packages/d0/8f/b8756467ea991449a293797f6b3fa80fcfdd29598a0a60d1cd5715b96e61/opencv_python_headless-5.0.0.93-cp37-abi3-win32.whl", hash = "sha256:c6bcd96b185975ea240d22cfdb15a1f6d080cc95264cfbe2621f21bb144d89b9", size = 35411237, upload-time = "2026-07-02T05:50:12.901Z" },
{ url = "https://files.pythonhosted.org/packages/b8/88/763b967f7efd7226b82c9fae16d560cba049b1f0c036647e65c610fd636e/opencv_python_headless-5.0.0.93-cp37-abi3-win_amd64.whl", hash = "sha256:829717b6a95554f273e49e357cee3b3a2a26b6f4842fbc1bed2b45bdd8f87e0e", size = 43825962, upload-time = "2026-07-02T05:50:09.627Z" },
]
[[package]] [[package]]
name = "orjson" name = "orjson"
version = "3.11.9" version = "3.11.9"
@@ -1430,6 +1570,21 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/54/6f/84908cad2d6aa5144abcf7b42709fe4fdb459bc640ec7ac5786e7693dabc/prompt_toolkit-3.0.53-py3-none-any.whl", hash = "sha256:01c0891d7f9237d5e339f7d3e42cdae80b7534abb1c7c0e3352efba6231492f2", size = 392288, upload-time = "2026-07-26T20:56:12.512Z" }, { url = "https://files.pythonhosted.org/packages/54/6f/84908cad2d6aa5144abcf7b42709fe4fdb459bc640ec7ac5786e7693dabc/prompt_toolkit-3.0.53-py3-none-any.whl", hash = "sha256:01c0891d7f9237d5e339f7d3e42cdae80b7534abb1c7c0e3352efba6231492f2", size = 392288, upload-time = "2026-07-26T20:56:12.512Z" },
] ]
[[package]]
name = "protobuf"
version = "7.35.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/da/01/9ef0afd7999eb9badb3a768b4aedd78c86d4c65cfaf1958ab276199e76b4/protobuf-7.35.1.tar.gz", hash = "sha256:ce115a26fe0c39a2c29973d914d327e516a6455464489fe3cd1e51a1b354f81a", size = 458717, upload-time = "2026-06-11T21:55:40.257Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/10/03/8aeeb7458d22546bf64b5250ca1daeb5ff757d900e8e4a7476c6f0db843e/protobuf-7.35.1-cp310-abi3-macosx_10_9_universal2.whl", hash = "sha256:24f857477359a85c0c235261b8ba905fd51b2562f4a64ca1df5473f29850cbf6", size = 433226, upload-time = "2026-06-11T21:55:31.719Z" },
{ url = "https://files.pythonhosted.org/packages/37/4b/dfb89eb0e652a1ff073c39a59fb5e3a83cfe9b57a2c83fa6d78270101767/protobuf-7.35.1-cp310-abi3-manylinux2014_aarch64.whl", hash = "sha256:11d6b0ec246892d85215b0a13ca6e0233cf5284b68f0ac02646427f4ff88a799", size = 328847, upload-time = "2026-06-11T21:55:34.035Z" },
{ url = "https://files.pythonhosted.org/packages/0f/58/dc12f2cd484951524af6e3382c785869b9b3fb5e52ee95ae23add53ee8f9/protobuf-7.35.1-cp310-abi3-manylinux2014_s390x.whl", hash = "sha256:b73f9489a4b8b1c9cb1f8ed951c736392592edb24b9d6819f36d2e10b171d5b4", size = 344030, upload-time = "2026-06-11T21:55:34.941Z" },
{ url = "https://files.pythonhosted.org/packages/e4/be/5b3cfe508bfab6761414ff944e3366eb13be4fd71efcd69450f89ba39f43/protobuf-7.35.1-cp310-abi3-manylinux2014_x86_64.whl", hash = "sha256:74758715c53d7158fb76caf4f0cfdacc5329a4b1bb994f865d6cf302d413a1c4", size = 327130, upload-time = "2026-06-11T21:55:35.921Z" },
{ url = "https://files.pythonhosted.org/packages/d8/bc/6d6c7ba8709c85f8f2c390b2b118d6fb08a783676a572271851bf45a7d22/protobuf-7.35.1-cp310-abi3-win32.whl", hash = "sha256:353652e4efd0bca5b5fc2656abf8307ef351f0cf938c9eba09f0e09c20a25c30", size = 428945, upload-time = "2026-06-11T21:55:37.034Z" },
{ url = "https://files.pythonhosted.org/packages/0a/19/8d0cb6f20a1ef7b18f1c8986ad5783f22f84cce39c6ce9a6e645ea55192e/protobuf-7.35.1-cp310-abi3-win_amd64.whl", hash = "sha256:230a75ddfc2de4806e56696ce9640c1cdfdb6543b7cfce98d42a4c0a0e7bdb87", size = 439996, upload-time = "2026-06-11T21:55:38.123Z" },
{ url = "https://files.pythonhosted.org/packages/19/c7/5f7c636ec43e0c545e28d1f1db71990108306f7bdcb89f069ba97e428e7f/protobuf-7.35.1-py3-none-any.whl", hash = "sha256:4bc97768d8fe4ad6743c8a19403e314511ed9f6d13205b687e52421c023ac1b9", size = 171659, upload-time = "2026-06-11T21:55:39.155Z" },
]
[[package]] [[package]]
name = "pycparser" name = "pycparser"
version = "3.0" version = "3.0"
@@ -1872,6 +2027,30 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/d7/c1/eb8f9debc45d3b7918a32ab756658a0904732f75e555402972246b0b8e71/tenacity-9.1.4-py3-none-any.whl", hash = "sha256:6095a360c919085f28c6527de529e76a06ad89b23659fa881ae0649b867a9d55", size = 28926, upload-time = "2026-02-07T10:45:32.24Z" }, { url = "https://files.pythonhosted.org/packages/d7/c1/eb8f9debc45d3b7918a32ab756658a0904732f75e555402972246b0b8e71/tenacity-9.1.4-py3-none-any.whl", hash = "sha256:6095a360c919085f28c6527de529e76a06ad89b23659fa881ae0649b867a9d55", size = 28926, upload-time = "2026-02-07T10:45:32.24Z" },
] ]
[[package]]
name = "tencentcloud-sdk-python-common"
version = "3.1.156"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "requests" },
]
sdist = { url = "https://files.pythonhosted.org/packages/f1/82/a69a3983e175bf80ec58615ea1daac159fc8086601423d87a54cfc505732/tencentcloud_sdk_python_common-3.1.156.tar.gz", hash = "sha256:7306bcaf3128ab3dbc96bc3117fe3562e303fb654e366bffa565d67cc85f4cd1", size = 22672, upload-time = "2026-08-13T07:15:59.396Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/a6/dd/47dba883bfa116bb75fc3344bd0a4df6f65894070e4c4ac3d81b60aa0110/tencentcloud_sdk_python_common-3.1.156-py2.py3-none-any.whl", hash = "sha256:94711a6c8130a1a3f1f24e708e71f646e5aa561fe4fefc3e0ac37389732b3339", size = 34275, upload-time = "2026-08-13T07:15:57.163Z" },
]
[[package]]
name = "tencentcloud-sdk-python-sms"
version = "3.1.153"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "tencentcloud-sdk-python-common" },
]
sdist = { url = "https://files.pythonhosted.org/packages/dc/21/f22f5e3c7ab0665de70da8f09d488e266fd9d264f224bf46ff1013b7fe52/tencentcloud_sdk_python_sms-3.1.153.tar.gz", hash = "sha256:3d00d97bb9210095d507dd2b7649c2782663b50d3f5bf3029fd3e385d0610495", size = 52292, upload-time = "2026-08-09T18:50:40.494Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/7a/ed/c7e77cc2c64d1b4270102c7cfdf6840c217e4c5f9e70d185ceaae6d2672e/tencentcloud_sdk_python_sms-3.1.153-py2.py3-none-any.whl", hash = "sha256:951dcdb0fb34ba6c2be4782ddfd87eb3b06820b9b6e8c6014429e4f6993ae631", size = 60246, upload-time = "2026-08-09T18:50:38.483Z" },
]
[[package]] [[package]]
name = "typing-extensions" name = "typing-extensions"
version = "4.16.0" version = "4.16.0"