deerflow2/backend/packages/harness/deerflow/config/third_party_proxy_config.py

119 lines
4.6 KiB
Python

"""Configuration for the third-party API proxy with billing integration."""
from __future__ import annotations
from pydantic import BaseModel, Field
class SubmitRouteConfig(BaseModel):
"""Identifies a submit request — triggers billing reserve + task state tracking."""
method: str = Field(default="POST", description="HTTP method to match (case-insensitive)")
path_pattern: str = Field(
description="Glob-style path pattern. Use ** to match any sub-path, e.g. /openapi/v2/**"
)
exclude_path_pattern: str | None = Field(
default=None,
description="If set, paths matching this pattern are excluded from submit handling",
)
task_id_jsonpath: str = Field(
description="Dot-path into the *response* body to extract the provider task ID, e.g. taskId"
)
frozen_amount: float | None = Field(
default=None,
ge=0,
description="Optional route-level override for billing reserve payload frozenAmount",
)
frozen_type: int | None = Field(
default=None,
description="Optional route-level override for billing reserve payload frozenType",
)
frozen_token: int | None = Field(
default=None,
ge=0,
description="Optional route-level override for billing reserve payload estimatedInputTokens/estimatedOutputTokens when frozenType=1",
)
class QueryRouteConfig(BaseModel):
"""Identifies a query/poll request — checks for terminal status + triggers billing finalize."""
method: str = Field(default="POST", description="HTTP method to match (case-insensitive)")
path_pattern: str = Field(description="Glob-style path pattern for the query endpoint")
request_task_id_jsonpath: str = Field(
description="Dot-path into the *request* body to extract the task ID being queried"
)
status_jsonpath: str = Field(
description="Dot-path into the response body to read the task status value"
)
success_values: list[str] = Field(
default_factory=list,
description="Status string values that indicate successful terminal state, e.g. [\"SUCCESS\"]",
)
failure_values: list[str] = Field(
default_factory=list,
description="Status string values that indicate failed terminal state, e.g. [\"FAILED\", \"CANCELLED\"]",
)
usage_jsonpath: str | None = Field(
default=None,
description=(
"Dot-path into the response body for the actual monetary cost to pass to billing finalize. "
"E.g. usage.thirdPartyConsumeMoney"
),
)
usage_jsonpaths: list[str] = Field(
default_factory=list,
description=(
"Optional list of dot-paths into the response body to extract monetary costs and sum them. "
"When set, values from all valid paths are added together. "
"Example: [\"usage.thirdPartyConsumeMoney\", \"usage.consumeMoney\"]"
),
)
class ThirdPartyProviderConfig(BaseModel):
"""Configuration for a single third-party API platform."""
base_url: str = Field(description="Base URL of the provider, e.g. https://www.runninghub.cn")
api_key_env: str | None = Field(
default=None,
description="Name of the environment variable holding the API key",
)
timeout_seconds: float = Field(
default=30.0,
gt=0,
description="HTTP request timeout when forwarding to the provider",
)
frozen_amount: float = Field(
default=0.0,
ge=0,
description="Amount to reserve in billing reserve payload (frozenAmount)",
)
frozen_type: int | None = Field(
default=None,
description="Billing frozen type for this provider (frozenType). If omitted, falls back to billing.frozen_type",
)
frozen_token: int = Field(
default=0,
ge=0,
description="Estimated token amount used for reserve payload when frozenType=1",
)
submit_routes: list[SubmitRouteConfig] = Field(
default_factory=list,
description="Route patterns that identify submit (task-create) requests",
)
query_routes: list[QueryRouteConfig] = Field(
default_factory=list,
description="Route patterns that identify query/poll requests",
)
class ThirdPartyProxyConfig(BaseModel):
"""Top-level configuration for the third-party API proxy."""
enabled: bool = Field(default=False, description="Enable the proxy endpoint")
providers: dict[str, ThirdPartyProviderConfig] = Field(
default_factory=dict,
description="Keyed by provider name (used in the URL path /api/proxy/{provider}/...)",
)