64 lines
2.4 KiB
Python
64 lines
2.4 KiB
Python
"""Fast taskId + goPath history lookup for single-agent deep-link workspaces.
|
|
|
|
Messages and execution state remain canonical LangGraph threads. This API
|
|
reads only the dedicated ``task_deeplink_threads`` cards and never joins or
|
|
scans the generic ``threads_meta`` catalogue.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from fastapi import APIRouter, HTTPException, Query, Request
|
|
from pydantic import BaseModel
|
|
|
|
from app.gateway.deps import get_task_deeplink_thread_store
|
|
from app.gateway.routers.threads import ThreadResponse
|
|
from deerflow.persistence.task_deeplink_threads.base import is_valid_task_deeplink_go_path
|
|
from deerflow.utils.time import coerce_iso
|
|
|
|
router = APIRouter(
|
|
prefix="/api/task-deeplink-threads",
|
|
tags=["task-deeplink-threads"],
|
|
)
|
|
|
|
|
|
class TaskDeeplinkThreadListResponse(BaseModel):
|
|
threads: list[ThreadResponse]
|
|
|
|
|
|
@router.get("", response_model=TaskDeeplinkThreadListResponse)
|
|
async def list_task_deeplink_threads(
|
|
request: Request,
|
|
task_id: str = Query(min_length=1, max_length=128),
|
|
go_path: str = Query(min_length=1, max_length=32),
|
|
limit: int = Query(default=100, ge=1, le=500),
|
|
# b5-1 ?type= partition. Provided (even empty) → only that sub-type;
|
|
# omitted → every sub-type of the task/goPath partition (legacy callers).
|
|
sub_type: str | None = Query(default=None, max_length=64),
|
|
) -> TaskDeeplinkThreadListResponse:
|
|
"""Return one shared deep-link history partition, newest first."""
|
|
|
|
normalized_go_path = go_path.strip().lower()
|
|
if not is_valid_task_deeplink_go_path(normalized_go_path):
|
|
raise HTTPException(status_code=422, detail="Invalid task deep-link goPath")
|
|
store = get_task_deeplink_thread_store(request)
|
|
rows = await store.list_threads(
|
|
task_id.strip(),
|
|
normalized_go_path,
|
|
limit=limit,
|
|
sub_type=sub_type.strip() if sub_type is not None else None,
|
|
)
|
|
return TaskDeeplinkThreadListResponse(
|
|
threads=[
|
|
ThreadResponse(
|
|
thread_id=row["thread_id"],
|
|
status=row.get("status", "idle"),
|
|
created_at=coerce_iso(row.get("created_at", "")),
|
|
updated_at=coerce_iso(row.get("updated_at", "")),
|
|
metadata=row.get("metadata", {}),
|
|
values=row.get("values", {}),
|
|
interrupts=row.get("interrupts", {}),
|
|
)
|
|
for row in rows
|
|
]
|
|
)
|