mirror of
https://github.com/langgenius/dify.git
synced 2026-07-15 01:17:04 +08:00
101 lines
3.9 KiB
Python
101 lines
3.9 KiB
Python
"""Shared API-side helper for Agent backend lifecycle-only session cleanup.
|
|
|
|
Product code owns local row retirement and background-task dispatch. This module
|
|
only adapts persisted cleanup inputs into the public ``dify-agent`` run
|
|
protocol, performs the synchronous ``create_run + wait_run`` loop used by Celery
|
|
workers, and reports whether the backend cleanup succeeded, was skipped, or
|
|
failed.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from typing import ClassVar, Literal
|
|
|
|
from agenton.compositor import CompositorSessionSnapshot
|
|
from dify_agent.protocol import RuntimeLayerSpec
|
|
from pydantic import BaseModel, ConfigDict, Field, JsonValue
|
|
|
|
from clients.agent_backend.client import AgentBackendRunClient
|
|
from clients.agent_backend.errors import AgentBackendError
|
|
from clients.agent_backend.request_builder import AgentBackendRunRequestBuilder
|
|
|
|
|
|
class AgentBackendSessionCleanupPayload(BaseModel):
|
|
"""Serialized cleanup inputs preserved across API and Celery boundaries."""
|
|
|
|
session_snapshot: CompositorSessionSnapshot | None = None
|
|
runtime_layer_specs: list[RuntimeLayerSpec] = Field(default_factory=list)
|
|
idempotency_key: str | None = None
|
|
metadata: dict[str, JsonValue] = Field(default_factory=dict)
|
|
timeout_seconds: float = 30.0
|
|
|
|
model_config: ClassVar[ConfigDict] = ConfigDict(extra="forbid")
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class AgentBackendSessionCleanupResult:
|
|
"""Terminal outcome of one backend cleanup attempt."""
|
|
|
|
status: Literal["succeeded", "skipped", "failed"]
|
|
reason: str | None = None
|
|
cleanup_run_id: str | None = None
|
|
|
|
@classmethod
|
|
def succeeded(cls, cleanup_run_id: str) -> AgentBackendSessionCleanupResult:
|
|
return cls(status="succeeded", cleanup_run_id=cleanup_run_id)
|
|
|
|
@classmethod
|
|
def skipped(cls, reason: str) -> AgentBackendSessionCleanupResult:
|
|
return cls(status="skipped", reason=reason)
|
|
|
|
@classmethod
|
|
def failed(cls, reason: str, cleanup_run_id: str | None = None) -> AgentBackendSessionCleanupResult:
|
|
return cls(status="failed", reason=reason, cleanup_run_id=cleanup_run_id)
|
|
|
|
|
|
def cleanup_agent_backend_session(
|
|
*,
|
|
payload: AgentBackendSessionCleanupPayload,
|
|
client: AgentBackendRunClient | None,
|
|
request_builder: AgentBackendRunRequestBuilder | None = None,
|
|
) -> AgentBackendSessionCleanupResult:
|
|
"""Run lifecycle-only cleanup against the Agent backend and report status."""
|
|
if client is None:
|
|
return AgentBackendSessionCleanupResult.skipped("no_agent_backend_client")
|
|
if payload.session_snapshot is None:
|
|
return AgentBackendSessionCleanupResult.skipped("missing_session_snapshot")
|
|
if not payload.runtime_layer_specs:
|
|
return AgentBackendSessionCleanupResult.skipped("missing_runtime_layer_specs")
|
|
|
|
builder = request_builder or AgentBackendRunRequestBuilder()
|
|
request = builder.build_cleanup_request(
|
|
session_snapshot=payload.session_snapshot,
|
|
runtime_layer_specs=payload.runtime_layer_specs,
|
|
idempotency_key=payload.idempotency_key,
|
|
metadata=payload.metadata,
|
|
)
|
|
|
|
try:
|
|
response = client.create_run(request)
|
|
except AgentBackendError as exc:
|
|
return AgentBackendSessionCleanupResult.failed(str(exc))
|
|
|
|
try:
|
|
status_response = client.wait_run(response.run_id, timeout_seconds=payload.timeout_seconds)
|
|
except AgentBackendError as exc:
|
|
return AgentBackendSessionCleanupResult.failed(str(exc), cleanup_run_id=response.run_id)
|
|
|
|
if status_response.status != "succeeded":
|
|
reason = status_response.error or f"cleanup run ended with status {status_response.status}"
|
|
return AgentBackendSessionCleanupResult.failed(reason, cleanup_run_id=response.run_id)
|
|
|
|
return AgentBackendSessionCleanupResult.succeeded(response.run_id)
|
|
|
|
|
|
__all__ = [
|
|
"AgentBackendSessionCleanupPayload",
|
|
"AgentBackendSessionCleanupResult",
|
|
"cleanup_agent_backend_session",
|
|
]
|