refactor(agent): replace workspace inspector with sandbox API (#37349)

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
盐粒 Yanli
2026-06-12 02:46:31 +00:00
committed by GitHub
co-authored by autofix-ci[bot]
parent 09bb87d089
commit 92df792e4a
46 changed files with 3838 additions and 2905 deletions
@@ -20,8 +20,8 @@ from clients.agent_backend import (
AgentBackendStreamInternalEvent,
AgentBackendTransportError,
AgentBackendValidationError,
CleanupLayerSpec,
extract_cleanup_layer_specs,
RuntimeLayerSpec,
extract_runtime_layer_specs,
)
from core.app.entities.app_invoke_entities import DIFY_RUN_CONTEXT_KEY, DifyRunContext
from core.workflow.system_variables import SystemVariableKey, get_system_text
@@ -255,7 +255,7 @@ class DifyAgentNode(Node[DifyAgentNodeData]):
session_scope=session_scope,
backend_run_id=terminal_event.run_id,
snapshot=terminal_event.session_snapshot,
composition_layer_specs=extract_cleanup_layer_specs(runtime_request.request.composition),
runtime_layer_specs=extract_runtime_layer_specs(runtime_request.request.composition),
metadata=metadata,
)
yield PauseRequestedEvent(
@@ -293,7 +293,7 @@ class DifyAgentNode(Node[DifyAgentNodeData]):
session_scope=session_scope,
backend_run_id=terminal_event.run_id,
snapshot=terminal_event.session_snapshot,
composition_layer_specs=extract_cleanup_layer_specs(runtime_request.request.composition),
runtime_layer_specs=extract_runtime_layer_specs(runtime_request.request.composition),
metadata=metadata,
)
@@ -454,7 +454,7 @@ class DifyAgentNode(Node[DifyAgentNodeData]):
session_scope: WorkflowAgentSessionScope,
backend_run_id: str,
snapshot: CompositorSessionSnapshot | None,
composition_layer_specs: list[CleanupLayerSpec],
runtime_layer_specs: list[RuntimeLayerSpec],
metadata: dict[str, Any],
) -> None:
if self._session_store is None:
@@ -464,7 +464,7 @@ class DifyAgentNode(Node[DifyAgentNodeData]):
scope=session_scope,
backend_run_id=backend_run_id,
snapshot=snapshot,
composition_layer_specs=composition_layer_specs,
runtime_layer_specs=runtime_layer_specs,
)
agent_backend = dict(metadata.get("agent_backend") or {})
agent_backend["session_snapshot_persisted"] = snapshot is not None
@@ -40,7 +40,7 @@ class WorkflowAgentSessionCleanupLayer(GraphEngineLayer):
the composition, the run fails asynchronously with ``run_failed`` — but
the initial ``POST /runs`` already returned 202, so the API side has no
visibility of the failure unless it waits for terminal status. The
``composition_layer_specs`` persistence in A.1–A.4 plus the
``runtime_layer_specs`` persistence in A.1–A.4 plus the
``_filter_snapshot_to_specs`` shape in ``build_cleanup_request`` keeps
the two name lists in sync.
@@ -144,13 +144,13 @@ class WorkflowAgentSessionCleanupLayer(GraphEngineLayer):
)
return
if not stored_session.composition_layer_specs:
if not stored_session.runtime_layer_specs:
# Sessions persisted before A.1 landed do not carry the spec list,
# so we cannot replay a valid cleanup composition. Leave the row
# ACTIVE and warn so the absence shows up in observability rather
# than being silently swallowed by a doomed cleanup run.
logger.warning(
"Skipping Agent backend cleanup: no composition_layer_specs persisted. "
"Skipping Agent backend cleanup: no runtime_layer_specs persisted. "
"workflow_run_id=%s node_id=%s agent_id=%s",
scope.workflow_run_id,
scope.node_id,
@@ -160,7 +160,7 @@ class WorkflowAgentSessionCleanupLayer(GraphEngineLayer):
request = self._request_builder.build_cleanup_request(
session_snapshot=stored_session.session_snapshot,
composition_layer_specs=stored_session.composition_layer_specs,
runtime_layer_specs=stored_session.runtime_layer_specs,
idempotency_key=f"{scope.workflow_run_id}:{scope.node_id}:{scope.binding_id}:agent-session-cleanup",
metadata={
"tenant_id": scope.tenant_id,
@@ -3,10 +3,10 @@ from __future__ import annotations
from dataclasses import dataclass, field
from agenton.compositor import CompositorSessionSnapshot
from dify_agent.protocol import RuntimeLayerSpec
from pydantic import TypeAdapter
from sqlalchemy import select
from clients.agent_backend.request_builder import CleanupLayerSpec
from core.db.session_factory import session_factory
from libs.datetime_utils import naive_utc_now
from models.agent import (
@@ -15,14 +15,14 @@ from models.agent import (
WorkflowAgentRuntimeSessionStatus,
)
_SPECS_ADAPTER: TypeAdapter[list[CleanupLayerSpec]] = TypeAdapter(list[CleanupLayerSpec])
_SPECS_ADAPTER: TypeAdapter[list[RuntimeLayerSpec]] = TypeAdapter(list[RuntimeLayerSpec])
def _serialize_specs(specs: list[CleanupLayerSpec]) -> str:
def _serialize_specs(specs: list[RuntimeLayerSpec]) -> str:
return _SPECS_ADAPTER.dump_json(specs).decode()
def _deserialize_specs(value: str | None) -> list[CleanupLayerSpec]:
def _deserialize_specs(value: str | None) -> list[RuntimeLayerSpec]:
if not value:
return []
return _SPECS_ADAPTER.validate_json(value)
@@ -46,7 +46,7 @@ class StoredWorkflowAgentSession:
scope: WorkflowAgentSessionScope
session_snapshot: CompositorSessionSnapshot
backend_run_id: str | None
composition_layer_specs: list[CleanupLayerSpec] = field(default_factory=list)
runtime_layer_specs: list[RuntimeLayerSpec] = field(default_factory=list)
class WorkflowAgentRuntimeSessionStore:
@@ -97,7 +97,7 @@ class WorkflowAgentRuntimeSessionStore:
),
session_snapshot=CompositorSessionSnapshot.model_validate_json(row.session_snapshot),
backend_run_id=row.backend_run_id,
composition_layer_specs=_deserialize_specs(row.composition_layer_specs),
runtime_layer_specs=_deserialize_specs(row.composition_layer_specs),
)
for row in rows
]
@@ -108,13 +108,13 @@ class WorkflowAgentRuntimeSessionStore:
scope: WorkflowAgentSessionScope,
backend_run_id: str,
snapshot: CompositorSessionSnapshot | None,
composition_layer_specs: list[CleanupLayerSpec],
runtime_layer_specs: list[RuntimeLayerSpec],
) -> None:
if scope.workflow_run_id is None or snapshot is None:
return
snapshot_json = snapshot.model_dump_json()
specs_json = _serialize_specs(composition_layer_specs)
specs_json = _serialize_specs(runtime_layer_specs)
with session_factory.create_session() as session:
row = session.scalar(
select(WorkflowAgentRuntimeSession).where(