Skip to content

Commit 8eecfd5

Browse files
refactor(backend): group workflow repair and workspace services
1 parent d69672e commit 8eecfd5

11 files changed

Lines changed: 920 additions & 913 deletions

File tree

packages/backend/app/services/workflow_repair_state.py

Lines changed: 1 addition & 776 deletions
Large diffs are not rendered by default.
Lines changed: 1 addition & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -1,126 +1,3 @@
11
from __future__ import annotations
22

3-
from copy import deepcopy
4-
5-
from app.services.workflow_datasets import compact_value_for_transport, compact_workflow_result
6-
7-
8-
_SUMMARY_ARTIFACT_REFERENCE_KEYS = (
9-
"dashboard_url",
10-
"report_path",
11-
"video_url",
12-
"video_path",
13-
"task_id",
14-
"output_path",
15-
)
16-
17-
18-
def serialize_workspace_state(snapshot: dict) -> dict:
19-
turn = snapshot.get("turn")
20-
draft = snapshot.get("draft")
21-
run = snapshot.get("run")
22-
artifacts = snapshot.get("artifacts") or []
23-
return {
24-
"session_id": str(snapshot.get("session_id")) if snapshot.get("session_id") is not None else None,
25-
"turn": (
26-
{
27-
"id": str(turn.id),
28-
"status": turn.status,
29-
"input_text": turn.input_text,
30-
"error": turn.error,
31-
}
32-
if turn
33-
else None
34-
),
35-
"draft": (
36-
{
37-
"id": str(draft.id),
38-
"status": draft.status,
39-
"version": draft.version,
40-
"source": draft.source,
41-
}
42-
if draft
43-
else None
44-
),
45-
"run": (
46-
{
47-
"id": str(run.id),
48-
"status": run.status,
49-
"error": run.error,
50-
"result": compact_workflow_result(run.result, row_limit=10, text_limit=2500),
51-
}
52-
if run
53-
else None
54-
),
55-
"artifacts": [
56-
{
57-
"id": str(artifact.id),
58-
"kind": artifact.kind,
59-
"payload": compact_value_for_transport(artifact.payload, row_limit=10, text_limit=2500),
60-
}
61-
for artifact in artifacts
62-
],
63-
}
64-
65-
66-
def dedupe_summary_artifact_references(workspace_state: dict | None) -> dict:
67-
if not isinstance(workspace_state, dict):
68-
return {}
69-
70-
deduped = deepcopy(workspace_state)
71-
artifacts = deduped.get("artifacts")
72-
if not isinstance(artifacts, list):
73-
return deduped
74-
75-
seen_references: dict[str, set[str]] = {}
76-
for artifact in artifacts:
77-
if not isinstance(artifact, dict):
78-
continue
79-
payload = artifact.get("payload")
80-
if not isinstance(payload, dict):
81-
continue
82-
for key in _SUMMARY_ARTIFACT_REFERENCE_KEYS:
83-
value = payload.get(key)
84-
if isinstance(value, str) and value.strip():
85-
seen_references.setdefault(key, set()).add(value.strip())
86-
87-
run = deduped.get("run")
88-
if not isinstance(run, dict):
89-
return deduped
90-
result = run.get("result")
91-
if not isinstance(result, dict):
92-
return deduped
93-
outputs = result.get("outputs")
94-
if not isinstance(outputs, dict):
95-
return deduped
96-
97-
for node_output in outputs.values():
98-
if not isinstance(node_output, dict):
99-
continue
100-
for key, values in seen_references.items():
101-
value = node_output.get(key)
102-
if isinstance(value, str) and value.strip() in values:
103-
node_output.pop(key, None)
104-
105-
return deduped
106-
107-
108-
def extract_final_answer(workspace_state: dict | None) -> str | None:
109-
if not isinstance(workspace_state, dict):
110-
return None
111-
run = workspace_state.get("run")
112-
if not isinstance(run, dict):
113-
return None
114-
result = run.get("result")
115-
if not isinstance(result, dict):
116-
return None
117-
outputs = result.get("outputs")
118-
if not isinstance(outputs, dict):
119-
return None
120-
for node_output in outputs.values():
121-
if not isinstance(node_output, dict):
122-
continue
123-
answer = node_output.get("answer")
124-
if isinstance(answer, str) and answer.strip():
125-
return answer.strip()
126-
return None
3+
from app.workflow.services.workspace_state import * # noqa: F403

packages/backend/app/test/test_agent_orchestration.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
os.environ.setdefault("LLM_MODEL", "test-model")
1818

1919
from app.services.agent_prompts import build_supervisor_prompt
20-
from app.services.workflow_workspace_state import extract_final_answer
20+
from app.workflow.services.workspace_state import extract_final_answer
2121
from app.tasks.callbacks import MessageCollector, _workflow_tool_trace_summary
2222
from app.tools.workflow_tools import (
2323
_new_repair_state,

packages/backend/app/test/test_workflow_tracking_service.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
replace_workflow_artifacts,
2424
upsert_workflow_draft,
2525
)
26-
from app.services.workflow_workspace_state import dedupe_summary_artifact_references
26+
from app.workflow.services.workspace_state import dedupe_summary_artifact_references
2727

2828

2929
def _build_test_db():
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
from __future__ import annotations
22

3-
from app.services.workflow_repair_state import * # noqa: F403
3+
from app.workflow.repair.state import * # noqa: F403

packages/backend/app/tools/workflow/workspace_state.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from __future__ import annotations
22

3-
from app.services.workflow_workspace_state import (
3+
from app.workflow.services.workspace_state import (
44
dedupe_summary_artifact_references as _dedupe_summary_artifact_references,
55
extract_final_answer as _extract_final_answer,
66
serialize_workspace_state as _serialize_workspace_state,

packages/backend/app/tools/workflow_tools.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,7 @@
1919
run_agent_workflow_file,
2020
)
2121
from app.services.workflow_tracking_service import build_workspace_state, build_workspace_state_for_turn
22-
from app.services.workflow_workspace_state import (
23-
dedupe_summary_artifact_references,
24-
extract_final_answer,
25-
serialize_workspace_state,
26-
)
27-
from app.tools.workflow.payloads import _normalize_workflow_payload_shape
28-
from app.services.workflow_repair_state import (
22+
from app.workflow.repair.state import (
2923
_build_tool_failure,
3024
_guard_repair_limit,
3125
_mark_terminal_failure,
@@ -36,6 +30,12 @@
3630
_repair_limit_failure,
3731
_require_reuse_after_failure,
3832
)
33+
from app.workflow.services.workspace_state import (
34+
dedupe_summary_artifact_references,
35+
extract_final_answer,
36+
serialize_workspace_state,
37+
)
38+
from app.tools.workflow.payloads import _normalize_workflow_payload_shape
3939
from deepeye.agents import WorkflowAgent
4040
from deepeye.tools.base import tool
4141

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"""Workflow repair classification and state helpers."""

0 commit comments

Comments
 (0)