autoglm-gui 1.1.0__py3-none-any.whl → 1.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- AutoGLM_GUI/adb_plus/__init__.py +5 -1
- AutoGLM_GUI/adb_plus/serial.py +61 -2
- AutoGLM_GUI/adb_plus/version.py +81 -0
- AutoGLM_GUI/api/__init__.py +8 -1
- AutoGLM_GUI/api/agents.py +329 -94
- AutoGLM_GUI/api/devices.py +145 -164
- AutoGLM_GUI/api/workflows.py +70 -0
- AutoGLM_GUI/device_manager.py +760 -0
- AutoGLM_GUI/exceptions.py +18 -0
- AutoGLM_GUI/phone_agent_manager.py +549 -0
- AutoGLM_GUI/phone_agent_patches.py +146 -0
- AutoGLM_GUI/schemas.py +310 -2
- AutoGLM_GUI/state.py +21 -0
- AutoGLM_GUI/static/assets/{about-Crpy4Xue.js → about-BtBH1xKN.js} +1 -1
- AutoGLM_GUI/static/assets/chat-DPzFNNGu.js +124 -0
- AutoGLM_GUI/static/assets/dialog-Dwuk2Hgl.js +45 -0
- AutoGLM_GUI/static/assets/index-B_AaKuOT.js +1 -0
- AutoGLM_GUI/static/assets/index-BjYIY--m.css +1 -0
- AutoGLM_GUI/static/assets/index-CvQkCi2d.js +11 -0
- AutoGLM_GUI/static/assets/logo-Cyfm06Ym.png +0 -0
- AutoGLM_GUI/static/assets/workflows-xX_QH-wI.js +1 -0
- AutoGLM_GUI/static/favicon.ico +0 -0
- AutoGLM_GUI/static/index.html +9 -2
- AutoGLM_GUI/static/logo-192.png +0 -0
- AutoGLM_GUI/static/logo-512.png +0 -0
- AutoGLM_GUI/workflow_manager.py +181 -0
- {autoglm_gui-1.1.0.dist-info → autoglm_gui-1.2.1.dist-info}/METADATA +51 -6
- {autoglm_gui-1.1.0.dist-info → autoglm_gui-1.2.1.dist-info}/RECORD +31 -19
- AutoGLM_GUI/static/assets/chat-DGFuSj6_.js +0 -149
- AutoGLM_GUI/static/assets/index-C1k5Ch1V.js +0 -10
- AutoGLM_GUI/static/assets/index-COYnSjzf.js +0 -1
- AutoGLM_GUI/static/assets/index-QX6oy21q.css +0 -1
- {autoglm_gui-1.1.0.dist-info → autoglm_gui-1.2.1.dist-info}/WHEEL +0 -0
- {autoglm_gui-1.1.0.dist-info → autoglm_gui-1.2.1.dist-info}/entry_points.txt +0 -0
- {autoglm_gui-1.1.0.dist-info → autoglm_gui-1.2.1.dist-info}/licenses/LICENSE +0 -0
AutoGLM_GUI/api/devices.py
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
"""Device discovery routes."""
|
|
2
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
6
|
+
|
|
3
7
|
from fastapi import APIRouter
|
|
4
8
|
|
|
5
|
-
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from AutoGLM_GUI.device_manager import ManagedDevice
|
|
11
|
+
from AutoGLM_GUI.phone_agent_manager import PhoneAgentManager
|
|
12
|
+
|
|
6
13
|
from AutoGLM_GUI.adb_plus.qr_pair import qr_pairing_manager
|
|
14
|
+
from AutoGLM_GUI.logger import logger
|
|
7
15
|
|
|
8
16
|
from AutoGLM_GUI.schemas import (
|
|
9
17
|
DeviceListResponse,
|
|
@@ -21,111 +29,126 @@ from AutoGLM_GUI.schemas import (
|
|
|
21
29
|
QRPairStatusResponse,
|
|
22
30
|
QRPairCancelResponse,
|
|
23
31
|
)
|
|
24
|
-
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _build_device_response_with_agent(
|
|
35
|
+
device: ManagedDevice, agent_manager: PhoneAgentManager
|
|
36
|
+
) -> dict:
|
|
37
|
+
"""组合设备信息和 Agent 状态(API 层职责)。
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
device: ManagedDevice 实例
|
|
41
|
+
agent_manager: PhoneAgentManager 实例
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
dict: 完整的设备响应,匹配 DeviceResponse schema
|
|
45
|
+
"""
|
|
46
|
+
# 获取纯设备信息
|
|
47
|
+
response = device.to_dict()
|
|
48
|
+
|
|
49
|
+
# 通过 serial 查找 Agent(支持连接切换)
|
|
50
|
+
agent_device_id = agent_manager.find_agent_by_serial(device.serial)
|
|
51
|
+
|
|
52
|
+
if agent_device_id:
|
|
53
|
+
metadata = agent_manager.get_metadata(agent_device_id)
|
|
54
|
+
|
|
55
|
+
if metadata:
|
|
56
|
+
response["agent"] = {
|
|
57
|
+
"state": metadata.state.value,
|
|
58
|
+
"created_at": metadata.created_at,
|
|
59
|
+
"last_used": metadata.last_used,
|
|
60
|
+
"error_message": metadata.error_message,
|
|
61
|
+
"model_name": metadata.model_config.model_name,
|
|
62
|
+
}
|
|
63
|
+
else:
|
|
64
|
+
response["agent"] = None
|
|
65
|
+
else:
|
|
66
|
+
response["agent"] = None
|
|
67
|
+
|
|
68
|
+
return response
|
|
69
|
+
|
|
25
70
|
|
|
26
71
|
router = APIRouter()
|
|
27
72
|
|
|
28
73
|
|
|
29
74
|
@router.get("/api/devices", response_model=DeviceListResponse)
|
|
30
75
|
def list_devices() -> DeviceListResponse:
|
|
31
|
-
"""列出所有 ADB
|
|
32
|
-
from
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
"serial": serial, # 真实序列号
|
|
50
|
-
}
|
|
51
|
-
)
|
|
76
|
+
"""列出所有 ADB 设备及 Agent 状态."""
|
|
77
|
+
from AutoGLM_GUI.device_manager import DeviceManager
|
|
78
|
+
from AutoGLM_GUI.phone_agent_manager import PhoneAgentManager
|
|
79
|
+
|
|
80
|
+
device_manager = DeviceManager.get_instance()
|
|
81
|
+
agent_manager = PhoneAgentManager.get_instance()
|
|
82
|
+
|
|
83
|
+
# Fallback: 如果轮询未启动,执行同步获取
|
|
84
|
+
if not device_manager._poll_thread or not device_manager._poll_thread.is_alive():
|
|
85
|
+
logger.warning("Polling not started, performing synchronous device fetch")
|
|
86
|
+
device_manager.force_refresh()
|
|
87
|
+
|
|
88
|
+
managed_devices = device_manager.get_devices()
|
|
89
|
+
|
|
90
|
+
# API 层负责聚合设备信息和 Agent 状态
|
|
91
|
+
devices_with_agents = [
|
|
92
|
+
_build_device_response_with_agent(d, agent_manager) for d in managed_devices
|
|
93
|
+
]
|
|
52
94
|
|
|
53
|
-
return DeviceListResponse(devices=
|
|
95
|
+
return DeviceListResponse(devices=devices_with_agents)
|
|
54
96
|
|
|
55
97
|
|
|
56
98
|
@router.post("/api/devices/connect_wifi", response_model=WiFiConnectResponse)
|
|
57
99
|
def connect_wifi(request: WiFiConnectRequest) -> WiFiConnectResponse:
|
|
58
100
|
"""从 USB 启用 TCP/IP 并连接到 WiFi。"""
|
|
59
|
-
from
|
|
101
|
+
from AutoGLM_GUI.device_manager import DeviceManager
|
|
60
102
|
|
|
61
|
-
|
|
103
|
+
device_manager = DeviceManager.get_instance()
|
|
104
|
+
success, message, wifi_id = device_manager.connect_wifi(
|
|
105
|
+
device_id=request.device_id,
|
|
106
|
+
port=request.port,
|
|
107
|
+
)
|
|
62
108
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
return WiFiConnectResponse(
|
|
67
|
-
success=False,
|
|
68
|
-
message="No connected device found",
|
|
69
|
-
error="device_not_found",
|
|
70
|
-
)
|
|
109
|
+
if success:
|
|
110
|
+
# Immediately refresh device list to show new WiFi device
|
|
111
|
+
device_manager.force_refresh()
|
|
71
112
|
|
|
72
|
-
# 已经是 WiFi 连接则直接返回
|
|
73
|
-
if device_info.connection_type == ConnectionType.REMOTE:
|
|
74
|
-
address = device_info.device_id
|
|
75
113
|
return WiFiConnectResponse(
|
|
76
114
|
success=True,
|
|
77
|
-
message=
|
|
78
|
-
device_id=
|
|
79
|
-
address=
|
|
80
|
-
)
|
|
81
|
-
|
|
82
|
-
# 1) 启用 tcpip
|
|
83
|
-
ok, msg = conn.enable_tcpip(port=request.port, device_id=device_info.device_id)
|
|
84
|
-
if not ok:
|
|
85
|
-
return WiFiConnectResponse(
|
|
86
|
-
success=False, message=msg or "Failed to enable tcpip", error="tcpip"
|
|
87
|
-
)
|
|
88
|
-
|
|
89
|
-
# 2) 读取设备 IP:先用本地 adb_plus 的 WiFi 优先逻辑,失败再回退上游接口
|
|
90
|
-
ip = get_wifi_ip(conn.adb_path, device_info.device_id) or conn.get_device_ip(
|
|
91
|
-
device_info.device_id
|
|
92
|
-
)
|
|
93
|
-
if not ip:
|
|
94
|
-
return WiFiConnectResponse(
|
|
95
|
-
success=False, message="Failed to get device IP", error="ip"
|
|
115
|
+
message=message,
|
|
116
|
+
device_id=wifi_id,
|
|
117
|
+
address=wifi_id,
|
|
96
118
|
)
|
|
119
|
+
else:
|
|
120
|
+
# Determine error type from message
|
|
121
|
+
error_type = "connect"
|
|
122
|
+
if "not found" in message.lower():
|
|
123
|
+
error_type = "device_not_found"
|
|
124
|
+
elif "tcpip" in message.lower():
|
|
125
|
+
error_type = "tcpip"
|
|
126
|
+
elif "ip" in message.lower():
|
|
127
|
+
error_type = "ip"
|
|
97
128
|
|
|
98
|
-
address = f"{ip}:{request.port}"
|
|
99
|
-
|
|
100
|
-
# 3) 连接 WiFi
|
|
101
|
-
ok, msg = conn.connect(address)
|
|
102
|
-
if not ok:
|
|
103
129
|
return WiFiConnectResponse(
|
|
104
130
|
success=False,
|
|
105
|
-
message=
|
|
106
|
-
error=
|
|
131
|
+
message=message,
|
|
132
|
+
error=error_type,
|
|
107
133
|
)
|
|
108
134
|
|
|
109
|
-
return WiFiConnectResponse(
|
|
110
|
-
success=True,
|
|
111
|
-
message="Switched to WiFi successfully",
|
|
112
|
-
device_id=address,
|
|
113
|
-
address=address,
|
|
114
|
-
)
|
|
115
|
-
|
|
116
135
|
|
|
117
136
|
@router.post("/api/devices/disconnect_wifi", response_model=WiFiDisconnectResponse)
|
|
118
137
|
def disconnect_wifi(request: WiFiDisconnectRequest) -> WiFiDisconnectResponse:
|
|
119
138
|
"""断开 WiFi 连接。"""
|
|
120
|
-
from
|
|
139
|
+
from AutoGLM_GUI.device_manager import DeviceManager
|
|
121
140
|
|
|
122
|
-
|
|
123
|
-
|
|
141
|
+
device_manager = DeviceManager.get_instance()
|
|
142
|
+
success, message = device_manager.disconnect_wifi(request.device_id)
|
|
143
|
+
|
|
144
|
+
if success:
|
|
145
|
+
# Refresh device list to update status
|
|
146
|
+
device_manager.force_refresh()
|
|
124
147
|
|
|
125
148
|
return WiFiDisconnectResponse(
|
|
126
|
-
success=
|
|
127
|
-
message=
|
|
128
|
-
error=None if
|
|
149
|
+
success=success,
|
|
150
|
+
message=message,
|
|
151
|
+
error=None if success else "disconnect_failed",
|
|
129
152
|
)
|
|
130
153
|
|
|
131
154
|
|
|
@@ -136,120 +159,78 @@ def connect_wifi_manual(
|
|
|
136
159
|
request: WiFiManualConnectRequest,
|
|
137
160
|
) -> WiFiManualConnectResponse:
|
|
138
161
|
"""手动连接到 WiFi 设备 (直接连接,无需 USB)."""
|
|
139
|
-
import
|
|
162
|
+
from AutoGLM_GUI.device_manager import DeviceManager
|
|
140
163
|
|
|
141
|
-
|
|
164
|
+
device_manager = DeviceManager.get_instance()
|
|
165
|
+
success, message, device_id = device_manager.connect_wifi_manual(
|
|
166
|
+
ip=request.ip,
|
|
167
|
+
port=request.port,
|
|
168
|
+
)
|
|
142
169
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
return WiFiManualConnectResponse(
|
|
147
|
-
success=False,
|
|
148
|
-
message="Invalid IP address format",
|
|
149
|
-
error="invalid_ip",
|
|
150
|
-
)
|
|
170
|
+
if success:
|
|
171
|
+
# Refresh device list to show new device
|
|
172
|
+
device_manager.force_refresh()
|
|
151
173
|
|
|
152
|
-
# 端口范围验证
|
|
153
|
-
if not (1 <= request.port <= 65535):
|
|
154
174
|
return WiFiManualConnectResponse(
|
|
155
|
-
success=
|
|
156
|
-
message=
|
|
157
|
-
|
|
175
|
+
success=True,
|
|
176
|
+
message=message,
|
|
177
|
+
device_id=device_id,
|
|
158
178
|
)
|
|
179
|
+
else:
|
|
180
|
+
# Determine error type from message
|
|
181
|
+
error_type = "connect_failed"
|
|
182
|
+
if "Invalid IP" in message:
|
|
183
|
+
error_type = "invalid_ip"
|
|
184
|
+
elif "Port must be" in message:
|
|
185
|
+
error_type = "invalid_port"
|
|
159
186
|
|
|
160
|
-
conn = ADBConnection()
|
|
161
|
-
address = f"{request.ip}:{request.port}"
|
|
162
|
-
|
|
163
|
-
# 直接连接
|
|
164
|
-
ok, msg = conn.connect(address)
|
|
165
|
-
if not ok:
|
|
166
187
|
return WiFiManualConnectResponse(
|
|
167
188
|
success=False,
|
|
168
|
-
message=
|
|
169
|
-
error=
|
|
189
|
+
message=message,
|
|
190
|
+
error=error_type,
|
|
170
191
|
)
|
|
171
192
|
|
|
172
|
-
return WiFiManualConnectResponse(
|
|
173
|
-
success=True,
|
|
174
|
-
message=f"Successfully connected to {address}",
|
|
175
|
-
device_id=address,
|
|
176
|
-
)
|
|
177
|
-
|
|
178
193
|
|
|
179
194
|
@router.post("/api/devices/pair_wifi", response_model=WiFiPairResponse)
|
|
180
195
|
def pair_wifi(request: WiFiPairRequest) -> WiFiPairResponse:
|
|
181
196
|
"""使用无线调试配对并连接到 WiFi 设备 (Android 11+)."""
|
|
182
|
-
import
|
|
183
|
-
|
|
184
|
-
from phone_agent.adb import ADBConnection
|
|
185
|
-
|
|
186
|
-
# IP 格式验证
|
|
187
|
-
ip_pattern = r"^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$"
|
|
188
|
-
if not re.match(ip_pattern, request.ip):
|
|
189
|
-
return WiFiPairResponse(
|
|
190
|
-
success=False,
|
|
191
|
-
message="Invalid IP address format",
|
|
192
|
-
error="invalid_ip",
|
|
193
|
-
)
|
|
197
|
+
from AutoGLM_GUI.device_manager import DeviceManager
|
|
194
198
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
return WiFiPairResponse(
|
|
198
|
-
success=False,
|
|
199
|
-
message="Pairing port must be between 1 and 65535",
|
|
200
|
-
error="invalid_port",
|
|
201
|
-
)
|
|
202
|
-
|
|
203
|
-
# 连接端口验证
|
|
204
|
-
if not (1 <= request.connection_port <= 65535):
|
|
205
|
-
return WiFiPairResponse(
|
|
206
|
-
success=False,
|
|
207
|
-
message="Connection port must be between 1 and 65535",
|
|
208
|
-
error="invalid_port",
|
|
209
|
-
)
|
|
210
|
-
|
|
211
|
-
# 配对码验证 (6 位数字)
|
|
212
|
-
if not request.pairing_code.isdigit() or len(request.pairing_code) != 6:
|
|
213
|
-
return WiFiPairResponse(
|
|
214
|
-
success=False,
|
|
215
|
-
message="Pairing code must be 6 digits",
|
|
216
|
-
error="invalid_pairing_code",
|
|
217
|
-
)
|
|
218
|
-
|
|
219
|
-
conn = ADBConnection()
|
|
220
|
-
|
|
221
|
-
# 步骤 1: 配对设备
|
|
222
|
-
ok, msg = pair_device(
|
|
199
|
+
device_manager = DeviceManager.get_instance()
|
|
200
|
+
success, message, device_id = device_manager.pair_wifi(
|
|
223
201
|
ip=request.ip,
|
|
224
|
-
|
|
202
|
+
pairing_port=request.pairing_port,
|
|
225
203
|
pairing_code=request.pairing_code,
|
|
226
|
-
|
|
204
|
+
connection_port=request.connection_port,
|
|
227
205
|
)
|
|
228
206
|
|
|
229
|
-
if
|
|
207
|
+
if success:
|
|
208
|
+
# Refresh device list to show newly paired device
|
|
209
|
+
device_manager.force_refresh()
|
|
210
|
+
|
|
230
211
|
return WiFiPairResponse(
|
|
231
|
-
success=
|
|
232
|
-
message=
|
|
233
|
-
|
|
212
|
+
success=True,
|
|
213
|
+
message=message,
|
|
214
|
+
device_id=device_id,
|
|
234
215
|
)
|
|
216
|
+
else:
|
|
217
|
+
# Determine error type from message
|
|
218
|
+
error_type = "connect_failed"
|
|
219
|
+
if "Invalid IP" in message:
|
|
220
|
+
error_type = "invalid_ip"
|
|
221
|
+
elif "port must be" in message.lower():
|
|
222
|
+
error_type = "invalid_port"
|
|
223
|
+
elif "Pairing code must be" in message:
|
|
224
|
+
error_type = "invalid_pairing_code"
|
|
225
|
+
elif "connection failed" not in message.lower():
|
|
226
|
+
error_type = "pair_failed"
|
|
235
227
|
|
|
236
|
-
# 步骤 2: 使用标准 ADB 端口连接到设备
|
|
237
|
-
connection_address = f"{request.ip}:{request.connection_port}"
|
|
238
|
-
ok, connect_msg = conn.connect(connection_address)
|
|
239
|
-
|
|
240
|
-
if not ok:
|
|
241
228
|
return WiFiPairResponse(
|
|
242
229
|
success=False,
|
|
243
|
-
message=
|
|
244
|
-
error=
|
|
230
|
+
message=message,
|
|
231
|
+
error=error_type,
|
|
245
232
|
)
|
|
246
233
|
|
|
247
|
-
return WiFiPairResponse(
|
|
248
|
-
success=True,
|
|
249
|
-
message=f"Successfully paired and connected to {connection_address}",
|
|
250
|
-
device_id=connection_address,
|
|
251
|
-
)
|
|
252
|
-
|
|
253
234
|
|
|
254
235
|
@router.get("/api/devices/discover_mdns", response_model=MdnsDiscoverResponse)
|
|
255
236
|
def discover_mdns() -> MdnsDiscoverResponse:
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"""Workflow API 路由."""
|
|
2
|
+
|
|
3
|
+
from fastapi import APIRouter, HTTPException
|
|
4
|
+
|
|
5
|
+
from AutoGLM_GUI.schemas import (
|
|
6
|
+
WorkflowCreate,
|
|
7
|
+
WorkflowListResponse,
|
|
8
|
+
WorkflowResponse,
|
|
9
|
+
WorkflowUpdate,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
router = APIRouter()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@router.get("/api/workflows", response_model=WorkflowListResponse)
|
|
16
|
+
def list_workflows() -> WorkflowListResponse:
|
|
17
|
+
"""获取所有 workflows."""
|
|
18
|
+
from AutoGLM_GUI.workflow_manager import workflow_manager
|
|
19
|
+
|
|
20
|
+
workflows = workflow_manager.list_workflows()
|
|
21
|
+
return WorkflowListResponse(workflows=workflows)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@router.get("/api/workflows/{workflow_uuid}", response_model=WorkflowResponse)
|
|
25
|
+
def get_workflow(workflow_uuid: str) -> WorkflowResponse:
|
|
26
|
+
"""获取单个 workflow."""
|
|
27
|
+
from AutoGLM_GUI.workflow_manager import workflow_manager
|
|
28
|
+
|
|
29
|
+
workflow = workflow_manager.get_workflow(workflow_uuid)
|
|
30
|
+
if not workflow:
|
|
31
|
+
raise HTTPException(status_code=404, detail="Workflow not found")
|
|
32
|
+
return WorkflowResponse(**workflow)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@router.post("/api/workflows", response_model=WorkflowResponse)
|
|
36
|
+
def create_workflow(request: WorkflowCreate) -> WorkflowResponse:
|
|
37
|
+
"""创建新 workflow."""
|
|
38
|
+
from AutoGLM_GUI.workflow_manager import workflow_manager
|
|
39
|
+
|
|
40
|
+
try:
|
|
41
|
+
workflow = workflow_manager.create_workflow(
|
|
42
|
+
name=request.name, text=request.text
|
|
43
|
+
)
|
|
44
|
+
return WorkflowResponse(**workflow)
|
|
45
|
+
except Exception as e:
|
|
46
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@router.put("/api/workflows/{workflow_uuid}", response_model=WorkflowResponse)
|
|
50
|
+
def update_workflow(workflow_uuid: str, request: WorkflowUpdate) -> WorkflowResponse:
|
|
51
|
+
"""更新 workflow."""
|
|
52
|
+
from AutoGLM_GUI.workflow_manager import workflow_manager
|
|
53
|
+
|
|
54
|
+
workflow = workflow_manager.update_workflow(
|
|
55
|
+
uuid=workflow_uuid, name=request.name, text=request.text
|
|
56
|
+
)
|
|
57
|
+
if not workflow:
|
|
58
|
+
raise HTTPException(status_code=404, detail="Workflow not found")
|
|
59
|
+
return WorkflowResponse(**workflow)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@router.delete("/api/workflows/{workflow_uuid}")
|
|
63
|
+
def delete_workflow(workflow_uuid: str) -> dict:
|
|
64
|
+
"""删除 workflow."""
|
|
65
|
+
from AutoGLM_GUI.workflow_manager import workflow_manager
|
|
66
|
+
|
|
67
|
+
success = workflow_manager.delete_workflow(workflow_uuid)
|
|
68
|
+
if not success:
|
|
69
|
+
raise HTTPException(status_code=404, detail="Workflow not found")
|
|
70
|
+
return {"success": True, "message": "Workflow deleted"}
|