Add external resource registration

This commit is contained in:
2026-06-22 13:19:18 +08:00
parent e5cd87789f
commit 12c767cd68
4 changed files with 496 additions and 11 deletions

View File

@ -7,6 +7,7 @@ from datetime import datetime, timezone
from typing import Any, Literal
from urllib.parse import parse_qsl, quote, urlsplit, urlunsplit
import httpx
from fastapi import APIRouter, FastAPI, File, Form, HTTPException, Request, UploadFile
from pydantic import BaseModel, Field, field_validator
from starlette.responses import Response
@ -86,6 +87,22 @@ class FlushMemoryRequest(BaseModel):
project_id: str = "default"
class ExternalResourceRequest(BaseModel):
user_id: str = Field(min_length=1)
user_key: str = Field(min_length=1)
app_id: str = "default"
project_id: str = "default"
filename: str = Field(min_length=1)
mime_type: str | None = None
content_type: str | None = None
size_bytes: int | None = Field(default=None, ge=0)
sha256: str | None = None
source_uri: str = Field(min_length=1)
ingest_uri: str | None = None
title: str | None = None
description: str | None = None
class MemoryOverrideRequest(BaseModel):
user_id: str = Field(min_length=1)
user_key: str = Field(min_length=1)
@ -196,6 +213,13 @@ def _body_for_log(body: bytes, content_type: str | None) -> Any:
return {"content_type": content_type, "size_bytes": len(body)}
def _backend_http_error_detail(exc: httpx.HTTPStatusError) -> Any:
try:
return exc.response.json()
except ValueError:
return exc.response.text
def create_app(
*,
config: GatewayConfig | None = None,
@ -366,6 +390,26 @@ def create_app(
return {"resources": []}
return {"resources": [resource]}
@router.post("/resources/external")
async def register_external_resource(
request: ExternalResourceRequest,
) -> dict[str, Any]:
require_user(request.user_id, request.user_key)
return await service.register_external_resource(
user_id=request.user_id,
app_id=request.app_id,
project_id=request.project_id,
filename=request.filename,
mime_type=request.mime_type,
content_type=request.content_type,
size_bytes=request.size_bytes,
sha256=request.sha256,
source_uri=request.source_uri,
ingest_uri=request.ingest_uri,
title=request.title,
description=request.description,
)
@router.delete("/resources/{resource_id}")
async def delete_resource(
resource_id: str,
@ -412,6 +456,11 @@ def create_app(
project_id=request.project_id,
messages=[message.model_dump() for message in request.messages],
)
except httpx.HTTPStatusError as exc:
raise HTTPException(
status_code=exc.response.status_code,
detail=_backend_http_error_detail(exc),
) from exc
except UploadTooLarge as exc:
raise HTTPException(status_code=413, detail=str(exc)) from exc
except InvalidAttachment as exc: