service-forge 0.1.28__py3-none-any.whl → 0.1.39__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.
Potentially problematic release.
This version of service-forge might be problematic. Click here for more details.
- service_forge/__init__.py +0 -0
- service_forge/api/deprecated_websocket_api.py +91 -33
- service_forge/api/deprecated_websocket_manager.py +70 -53
- service_forge/api/http_api.py +127 -53
- service_forge/api/kafka_api.py +113 -25
- service_forge/api/routers/meta_api/meta_api_router.py +57 -0
- service_forge/api/routers/service/service_router.py +42 -6
- service_forge/api/routers/trace/trace_router.py +326 -0
- service_forge/api/routers/websocket/websocket_router.py +56 -1
- service_forge/api/service_studio.py +9 -0
- service_forge/execution_context.py +106 -0
- service_forge/frontend/static/assets/CreateNewNodeDialog-DkrEMxSH.js +1 -0
- service_forge/frontend/static/assets/CreateNewNodeDialog-DwFcBiGp.css +1 -0
- service_forge/frontend/static/assets/EditorSidePanel-BNVms9Fq.css +1 -0
- service_forge/frontend/static/assets/EditorSidePanel-DZbB3ILL.js +1 -0
- service_forge/frontend/static/assets/FeedbackPanel-CC8HX7Yo.js +1 -0
- service_forge/frontend/static/assets/FeedbackPanel-ClgniIVk.css +1 -0
- service_forge/frontend/static/assets/FormattedCodeViewer.vue_vue_type_script_setup_true_lang-BNuI1NCs.js +1 -0
- service_forge/frontend/static/assets/NodeDetailWrapper-BqFFM7-r.js +1 -0
- service_forge/frontend/static/assets/NodeDetailWrapper-pZBxv3J0.css +1 -0
- service_forge/frontend/static/assets/TestRunningDialog-D0GrCoYs.js +1 -0
- service_forge/frontend/static/assets/TestRunningDialog-dhXOsPgH.css +1 -0
- service_forge/frontend/static/assets/TracePanelWrapper-B9zvDSc_.js +1 -0
- service_forge/frontend/static/assets/TracePanelWrapper-BiednCrq.css +1 -0
- service_forge/frontend/static/assets/WorkflowEditor-CcaGGbko.js +3 -0
- service_forge/frontend/static/assets/WorkflowEditor-CmasOOYK.css +1 -0
- service_forge/frontend/static/assets/WorkflowList-Copuwi-a.css +1 -0
- service_forge/frontend/static/assets/WorkflowList-LrRJ7B7h.js +1 -0
- service_forge/frontend/static/assets/WorkflowStudio-CthjgII2.css +1 -0
- service_forge/frontend/static/assets/WorkflowStudio-FCyhGD4y.js +2 -0
- service_forge/frontend/static/assets/api-BDer3rj7.css +1 -0
- service_forge/frontend/static/assets/api-DyiqpKJK.js +1 -0
- service_forge/frontend/static/assets/code-editor-DBSql_sc.js +12 -0
- service_forge/frontend/static/assets/el-collapse-item-D4LG0FJ0.css +1 -0
- service_forge/frontend/static/assets/el-empty-D4ZqTl4F.css +1 -0
- service_forge/frontend/static/assets/el-form-item-BWkJzdQ_.css +1 -0
- service_forge/frontend/static/assets/el-input-D6B3r8CH.css +1 -0
- service_forge/frontend/static/assets/el-select-B0XIb2QK.css +1 -0
- service_forge/frontend/static/assets/el-tag-DljBBxJR.css +1 -0
- service_forge/frontend/static/assets/element-ui-D3x2y3TA.js +12 -0
- service_forge/frontend/static/assets/elkjs-Dm5QV7uy.js +24 -0
- service_forge/frontend/static/assets/highlightjs-D4ATuRwX.js +3 -0
- service_forge/frontend/static/assets/index-BMvodlwc.js +2 -0
- service_forge/frontend/static/assets/index-CjSe8i2q.css +1 -0
- service_forge/frontend/static/assets/js-yaml-yTPt38rv.js +32 -0
- service_forge/frontend/static/assets/time-DKCKV6Ug.js +1 -0
- service_forge/frontend/static/assets/ui-components-DQ7-U3pr.js +1 -0
- service_forge/frontend/static/assets/vue-core-DL-LgTX0.js +1 -0
- service_forge/frontend/static/assets/vue-flow-Dn7R8GPr.js +39 -0
- service_forge/frontend/static/index.html +16 -0
- service_forge/frontend/static/vite.svg +1 -0
- service_forge/model/meta_api/__init__.py +0 -0
- service_forge/model/meta_api/schema.py +29 -0
- service_forge/model/trace.py +82 -0
- service_forge/service.py +32 -11
- service_forge/service_config.py +14 -0
- service_forge/sft/config/injector.py +32 -2
- service_forge/sft/config/injector_default_files.py +12 -0
- service_forge/sft/config/sf_metadata.py +5 -0
- service_forge/sft/config/sft_config.py +18 -0
- service_forge/telemetry.py +66 -0
- service_forge/workflow/node.py +266 -27
- service_forge/workflow/triggers/fast_api_trigger.py +61 -28
- service_forge/workflow/triggers/websocket_api_trigger.py +31 -10
- service_forge/workflow/workflow.py +87 -10
- service_forge/workflow/workflow_callback.py +24 -2
- service_forge/workflow/workflow_factory.py +13 -0
- {service_forge-0.1.28.dist-info → service_forge-0.1.39.dist-info}/METADATA +4 -1
- service_forge-0.1.39.dist-info/RECORD +134 -0
- service_forge-0.1.28.dist-info/RECORD +0 -85
- {service_forge-0.1.28.dist-info → service_forge-0.1.39.dist-info}/WHEEL +0 -0
- {service_forge-0.1.28.dist-info → service_forge-0.1.39.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
from datetime import datetime, timezone
|
|
2
|
+
|
|
3
|
+
from fastapi import APIRouter, HTTPException
|
|
4
|
+
from httpx import AsyncClient, HTTPStatusError
|
|
5
|
+
from loguru import logger
|
|
6
|
+
|
|
7
|
+
from service_forge.current_service import get_service
|
|
8
|
+
from service_forge.model.trace import (
|
|
9
|
+
GetTraceListParams, GetTraceListResponse,
|
|
10
|
+
GetTraceDetailParams, GetTraceDetailResponse, TraceListItem, TraceDetail, Span, StatusCode, SpanKind
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
trace_router = APIRouter(prefix="/sdk/trace", tags=["trace"])
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _get_signoz_api_base():
|
|
17
|
+
_service = get_service()
|
|
18
|
+
if not _service:
|
|
19
|
+
return None
|
|
20
|
+
if not _service.config.signoz:
|
|
21
|
+
return None
|
|
22
|
+
return _service.config.signoz.api_url
|
|
23
|
+
|
|
24
|
+
def _get_signoz_api_key():
|
|
25
|
+
_service = get_service()
|
|
26
|
+
if not _service:
|
|
27
|
+
return None
|
|
28
|
+
if not _service.config.signoz:
|
|
29
|
+
return None
|
|
30
|
+
return _service.config.signoz.api_key
|
|
31
|
+
|
|
32
|
+
@trace_router.post("/list", response_model=GetTraceListResponse)
|
|
33
|
+
async def get_trace_list(params: GetTraceListParams):
|
|
34
|
+
"""
|
|
35
|
+
获取跟踪列表,调用外部SigNoz API
|
|
36
|
+
"""
|
|
37
|
+
_service = get_service()
|
|
38
|
+
internal_service_name = _service.name if _service else ""
|
|
39
|
+
|
|
40
|
+
# 构建SQL查询语句
|
|
41
|
+
where_clauses = []
|
|
42
|
+
|
|
43
|
+
# 添加服务名过滤
|
|
44
|
+
if params.service_name:
|
|
45
|
+
where_clauses.append(f"resource_string_service$$name = '{params.service_name}'")
|
|
46
|
+
elif internal_service_name:
|
|
47
|
+
where_clauses.append(f"resource_string_service$$name = '{internal_service_name}'")
|
|
48
|
+
|
|
49
|
+
# 添加工作流名过滤
|
|
50
|
+
if params.workflow_name:
|
|
51
|
+
where_clauses.append(f"attributes_string['workflow.name'] = '{params.workflow_name}'")
|
|
52
|
+
|
|
53
|
+
# 添加工作流任务ID过滤
|
|
54
|
+
if params.workflow_task_id:
|
|
55
|
+
where_clauses.append(f"attributes_string['workflow.task_id'] = '{params.workflow_task_id}'")
|
|
56
|
+
|
|
57
|
+
# 添加错误状态过滤
|
|
58
|
+
if params.has_error is not None:
|
|
59
|
+
where_clauses.append(f"has_error = {1 if params.has_error else 0}")
|
|
60
|
+
|
|
61
|
+
# 组合WHERE子句
|
|
62
|
+
where_part = ""
|
|
63
|
+
if where_clauses:
|
|
64
|
+
where_part = "WHERE " + " AND ".join(where_clauses)
|
|
65
|
+
|
|
66
|
+
# 构建完整的查询
|
|
67
|
+
# 注意:我们需要按trace_id分组,并计算每个trace的span_count
|
|
68
|
+
# 同时获取最新的span信息(最大timestamp)
|
|
69
|
+
query = f"""
|
|
70
|
+
SELECT
|
|
71
|
+
trace_id,
|
|
72
|
+
anyIf(resource_string_service$$name, resource_string_service$$name != '' AND resource_string_service$$name IS NOT NULL) as service_name,
|
|
73
|
+
anyIf(attributes_string['workflow.name'], attributes_string['workflow.name'] != '' AND attributes_string['workflow.name'] IS NOT NULL) as workflow_name,
|
|
74
|
+
anyIf(attributes_string['workflow.task_id'], attributes_string['workflow.task_id'] != '' AND attributes_string['workflow.task_id'] IS NOT NULL) as workflow_task_id,
|
|
75
|
+
max(timestamp) as timestamp,
|
|
76
|
+
sum(duration_nano) as duration_nano,
|
|
77
|
+
count() as span_count,
|
|
78
|
+
max(has_error) as has_error,
|
|
79
|
+
max(status_code) as status_code
|
|
80
|
+
FROM signoz_traces.distributed_signoz_index_v3
|
|
81
|
+
{where_part}
|
|
82
|
+
GROUP BY trace_id
|
|
83
|
+
ORDER BY timestamp DESC
|
|
84
|
+
LIMIT {params.limit or 100}
|
|
85
|
+
OFFSET {params.offset or 0}
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
# 同时计算总数
|
|
89
|
+
count_query = f"""
|
|
90
|
+
SELECT COUNT(DISTINCT trace_id) as total
|
|
91
|
+
FROM signoz_traces.distributed_signoz_index_v3
|
|
92
|
+
{where_part}
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
async with AsyncClient() as client:
|
|
96
|
+
try:
|
|
97
|
+
current_time = datetime.now(timezone.utc)
|
|
98
|
+
# 调用外部API
|
|
99
|
+
response = await client.post(
|
|
100
|
+
f"{_get_signoz_api_base()}/api/v5/query_range",
|
|
101
|
+
headers={
|
|
102
|
+
"SIGNOZ-API-KEY": _get_signoz_api_key()
|
|
103
|
+
},
|
|
104
|
+
json={
|
|
105
|
+
"start": int(params.start_time or 0),
|
|
106
|
+
"end": int(params.end_time or (current_time.timestamp() * 1000)),
|
|
107
|
+
"requestType": "raw",
|
|
108
|
+
"compositeQuery": {
|
|
109
|
+
"queries": [
|
|
110
|
+
{
|
|
111
|
+
"type": "clickhouse_sql",
|
|
112
|
+
"spec": {
|
|
113
|
+
"name": "query_1",
|
|
114
|
+
"query": query,
|
|
115
|
+
"disabled": False
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"type": "clickhouse_sql",
|
|
120
|
+
"spec": {
|
|
121
|
+
"name": "query_2",
|
|
122
|
+
"query": count_query,
|
|
123
|
+
"disabled": False
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
]
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
}
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
response.raise_for_status() # 检查HTTP状态码
|
|
133
|
+
|
|
134
|
+
# 假设外部API返回的数据格式与我们的响应模型一致
|
|
135
|
+
# 如果不一致,需要在这里进行数据转换
|
|
136
|
+
data = response.json()
|
|
137
|
+
|
|
138
|
+
query_results = data["data"]["data"]["results"]
|
|
139
|
+
query_1_result = None
|
|
140
|
+
query_2_result = None
|
|
141
|
+
for result in query_results:
|
|
142
|
+
if result["queryName"] == "query_1":
|
|
143
|
+
query_1_result = result
|
|
144
|
+
elif result["queryName"] == "query_2":
|
|
145
|
+
query_2_result = result
|
|
146
|
+
|
|
147
|
+
traces = [
|
|
148
|
+
TraceListItem(
|
|
149
|
+
trace_id=item["data"].get("trace_id", ""),
|
|
150
|
+
service_name=item["data"].get("service_name", params.service_name or internal_service_name),
|
|
151
|
+
workflow_name=item["data"].get("workflow_name", params.workflow_name or ""),
|
|
152
|
+
workflow_task_id=item["data"].get("workflow_task_id", params.workflow_task_id or ""),
|
|
153
|
+
timestamp=item["data"].get("timestamp", current_time.isoformat().replace("+00:00", "Z")),
|
|
154
|
+
duration_nano=item["data"].get("duration_nano", 0),
|
|
155
|
+
span_count=item["data"].get("span_count", 0),
|
|
156
|
+
has_error=item["data"].get("has_error", False),
|
|
157
|
+
status_code=item["data"].get("status_code", StatusCode.OK),
|
|
158
|
+
)
|
|
159
|
+
for item in query_1_result["rows"] or []
|
|
160
|
+
]
|
|
161
|
+
|
|
162
|
+
# 转换为内部响应模型并返回
|
|
163
|
+
return GetTraceListResponse(
|
|
164
|
+
traces=traces,
|
|
165
|
+
total=query_2_result["rows"][0]["data"].get("total", len(traces)),
|
|
166
|
+
limit=params.limit or 100,
|
|
167
|
+
offset=params.offset or 0,
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
except HTTPStatusError as e:
|
|
171
|
+
# 处理HTTP错误
|
|
172
|
+
raise HTTPException(status_code=e.response.status_code, detail=str(e))
|
|
173
|
+
except Exception as e:
|
|
174
|
+
# 处理其他错误
|
|
175
|
+
logger.error(e)
|
|
176
|
+
raise HTTPException(status_code=500, detail=f"API处理失败: {str(e)}")
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
@trace_router.post("/detail", response_model=GetTraceDetailResponse)
|
|
180
|
+
async def get_trace_detail(params: GetTraceDetailParams):
|
|
181
|
+
# 构建SQL查询语句
|
|
182
|
+
where_clauses = [f"trace_id = '{params.trace_id}'"]
|
|
183
|
+
|
|
184
|
+
# 添加服务名过滤
|
|
185
|
+
if params.service_name:
|
|
186
|
+
where_clauses.append(f"resource_string_service$$name = '{params.service_name}'")
|
|
187
|
+
|
|
188
|
+
# 组合WHERE子句
|
|
189
|
+
where_part = "WHERE " + " AND ".join(where_clauses)
|
|
190
|
+
|
|
191
|
+
# 构建完整的查询获取所有span信息
|
|
192
|
+
span_query = f"""
|
|
193
|
+
SELECT
|
|
194
|
+
trace_id,
|
|
195
|
+
span_id,
|
|
196
|
+
parent_span_id,
|
|
197
|
+
name,
|
|
198
|
+
kind,
|
|
199
|
+
timestamp,
|
|
200
|
+
duration_nano,
|
|
201
|
+
status_code,
|
|
202
|
+
has_error,
|
|
203
|
+
resource_string_service$$name as service_name,
|
|
204
|
+
attributes_string as attributes_string
|
|
205
|
+
FROM signoz_traces.distributed_signoz_index_v3
|
|
206
|
+
{where_part}
|
|
207
|
+
ORDER BY timestamp ASC
|
|
208
|
+
"""
|
|
209
|
+
|
|
210
|
+
count_query = f"""
|
|
211
|
+
SELECT
|
|
212
|
+
count(DISTINCT span_id) as total
|
|
213
|
+
FROM signoz_traces.distributed_signoz_index_v3
|
|
214
|
+
{where_part}
|
|
215
|
+
"""
|
|
216
|
+
|
|
217
|
+
async with AsyncClient() as client:
|
|
218
|
+
try:
|
|
219
|
+
current_time = datetime.now(timezone.utc)
|
|
220
|
+
# 调用外部API获取span数据
|
|
221
|
+
response = await client.post(
|
|
222
|
+
f"{_get_signoz_api_base()}/api/v5/query_range",
|
|
223
|
+
headers={
|
|
224
|
+
"SIGNOZ-API-KEY": _get_signoz_api_key()
|
|
225
|
+
},
|
|
226
|
+
json={
|
|
227
|
+
"start": 0, # 获取完整trace,不限制时间范围
|
|
228
|
+
"end": int(current_time.timestamp() * 1000),
|
|
229
|
+
"requestType": "raw",
|
|
230
|
+
"compositeQuery": {
|
|
231
|
+
"queries": [
|
|
232
|
+
{
|
|
233
|
+
"type": "clickhouse_sql",
|
|
234
|
+
"spec": {
|
|
235
|
+
"name": "query_1",
|
|
236
|
+
"query": span_query,
|
|
237
|
+
"disabled": False
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
"type": "clickhouse_sql",
|
|
242
|
+
"spec": {
|
|
243
|
+
"name": "query_2",
|
|
244
|
+
"query": count_query,
|
|
245
|
+
"disabled": False
|
|
246
|
+
}
|
|
247
|
+
},
|
|
248
|
+
]
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
)
|
|
252
|
+
response.raise_for_status() # 检查HTTP状态码
|
|
253
|
+
|
|
254
|
+
# 解析响应数据
|
|
255
|
+
data = response.json()
|
|
256
|
+
|
|
257
|
+
query_results = data["data"]["data"]["results"]
|
|
258
|
+
query_1_result = None
|
|
259
|
+
query_2_result = None
|
|
260
|
+
for result in query_results:
|
|
261
|
+
if result["queryName"] == "query_1":
|
|
262
|
+
query_1_result = result
|
|
263
|
+
elif result["queryName"] == "query_2":
|
|
264
|
+
query_2_result = result
|
|
265
|
+
|
|
266
|
+
_service = get_service()
|
|
267
|
+
internal_service_name = _service.name if _service else ""
|
|
268
|
+
|
|
269
|
+
spans = [
|
|
270
|
+
Span(
|
|
271
|
+
span_id=item["data"].get("span_id", ""),
|
|
272
|
+
parent_span_id=item["data"].get("parent_span_id", ""),
|
|
273
|
+
name=item["data"].get("name", ""),
|
|
274
|
+
kind=item["data"].get("kind", SpanKind.UNKNOWN),
|
|
275
|
+
timestamp=item["data"].get("timestamp", current_time.isoformat().replace("+00:00", "Z")),
|
|
276
|
+
duration_nano=item["data"].get("duration_nano", 0),
|
|
277
|
+
status_code=item["data"].get("status_code", StatusCode.OK),
|
|
278
|
+
service_name=item["data"].get("attributes_string", {}).get("service.name", params.service_name or internal_service_name),
|
|
279
|
+
workflow_name=item["data"].get("attributes_string", {}).get("workflow.name", ""),
|
|
280
|
+
workflow_task_id=item["data"].get("attributes_string", {}).get("workflow.task_id", ""),
|
|
281
|
+
node_name=item["data"].get("attributes_string", {}).get("node.name", ""),
|
|
282
|
+
attributes=item["data"].get("attributes_string", {}),
|
|
283
|
+
)
|
|
284
|
+
for item in query_1_result["rows"] or []
|
|
285
|
+
]
|
|
286
|
+
|
|
287
|
+
has_error = False
|
|
288
|
+
for row in (query_1_result["rows"] or []):
|
|
289
|
+
if row["data"].get("has_error", False):
|
|
290
|
+
has_error = True
|
|
291
|
+
break
|
|
292
|
+
|
|
293
|
+
workflow_name = ""
|
|
294
|
+
for span in spans:
|
|
295
|
+
if span.workflow_name:
|
|
296
|
+
workflow_name = span.workflow_name
|
|
297
|
+
break
|
|
298
|
+
|
|
299
|
+
workflow_task_id = ""
|
|
300
|
+
for span in spans:
|
|
301
|
+
if span.workflow_task_id:
|
|
302
|
+
workflow_task_id = span.workflow_task_id
|
|
303
|
+
break
|
|
304
|
+
|
|
305
|
+
return GetTraceDetailResponse(
|
|
306
|
+
trace=TraceDetail(
|
|
307
|
+
trace_id=params.trace_id,
|
|
308
|
+
service_name=params.service_name or "", # 注入当前服务名
|
|
309
|
+
spans=spans,
|
|
310
|
+
start_time=spans[0].timestamp if spans else None,
|
|
311
|
+
end_time=spans[-1].timestamp if spans else None,
|
|
312
|
+
span_count=query_2_result["rows"][0]["data"].get("total", len(spans)),
|
|
313
|
+
has_error=has_error,
|
|
314
|
+
workflow_name=workflow_name,
|
|
315
|
+
workflow_task_id=workflow_task_id,
|
|
316
|
+
)
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
except HTTPStatusError as e:
|
|
322
|
+
# 处理HTTP错误
|
|
323
|
+
raise HTTPException(status_code=e.response.status_code, detail=str(e))
|
|
324
|
+
except Exception as e:
|
|
325
|
+
# 处理其他错误
|
|
326
|
+
raise HTTPException(status_code=500, detail=f"API处理失败: {str(e)}")
|
|
@@ -1,8 +1,14 @@
|
|
|
1
|
-
from
|
|
1
|
+
from http.client import HTTPException
|
|
2
|
+
|
|
3
|
+
from fastapi import WebSocket, WebSocketDisconnect, Form
|
|
2
4
|
from fastapi.routing import APIRouter
|
|
3
5
|
from loguru import logger
|
|
4
6
|
import json
|
|
5
7
|
import uuid
|
|
8
|
+
|
|
9
|
+
from omegaconf import OmegaConf
|
|
10
|
+
|
|
11
|
+
from service_forge.current_service import get_service
|
|
6
12
|
from .websocket_manager import websocket_manager
|
|
7
13
|
|
|
8
14
|
websocket_router = APIRouter()
|
|
@@ -74,6 +80,10 @@ async def sdk_websocket_endpoint(websocket: WebSocket):
|
|
|
74
80
|
await websocket.send_text(
|
|
75
81
|
json.dumps({"error": "Invalid task_id format"})
|
|
76
82
|
)
|
|
83
|
+
# TODO: 支持调试模式下取消订阅后删除debug版本
|
|
84
|
+
# 调式模式下订阅(客户端无需实现提供task_id,而是提供工作流配置,并由服务端创建debug版本、触发debug版本、登记订阅并返回task_id和workflow_id)
|
|
85
|
+
elif message_type == "subscribe_debug":
|
|
86
|
+
await handle_subscribe_debug_message(websocket, message)
|
|
77
87
|
else:
|
|
78
88
|
await websocket.send_text(
|
|
79
89
|
json.dumps({"error": f"Unknown message type: {message_type}"})
|
|
@@ -89,3 +99,48 @@ async def sdk_websocket_endpoint(websocket: WebSocket):
|
|
|
89
99
|
logger.error(f"SDK WebSocket连接处理异常: {e}")
|
|
90
100
|
await websocket_manager.disconnect(websocket)
|
|
91
101
|
|
|
102
|
+
|
|
103
|
+
async def handle_subscribe_debug_message(websocket: WebSocket, message: dict):
|
|
104
|
+
# 解析debug版本的工作流配置
|
|
105
|
+
try:
|
|
106
|
+
workflow_config_str = message.get("workflow_config")
|
|
107
|
+
config = OmegaConf.to_object(OmegaConf.create(workflow_config_str))
|
|
108
|
+
except Exception as e:
|
|
109
|
+
await websocket.send_text(
|
|
110
|
+
json.dumps({"error": f"Failed to parse workflow config: {str(e)}"})
|
|
111
|
+
)
|
|
112
|
+
return
|
|
113
|
+
|
|
114
|
+
# 加载debug版本的工作流
|
|
115
|
+
try:
|
|
116
|
+
service = get_service()
|
|
117
|
+
workflow_id = await service.load_workflow_from_config(config=config, debug_version=True)
|
|
118
|
+
except Exception as e:
|
|
119
|
+
await websocket.send_text(
|
|
120
|
+
json.dumps({"error": f"Failed to load workflow of the debug version: {str(e)}"})
|
|
121
|
+
)
|
|
122
|
+
return
|
|
123
|
+
|
|
124
|
+
# 先指定task_id并订阅
|
|
125
|
+
task_id = uuid.uuid4()
|
|
126
|
+
try:
|
|
127
|
+
success = await websocket_manager.subscribe(websocket, task_id)
|
|
128
|
+
response = {"success": success, "type": "subscribe_response", "task_id": str(task_id), "workflow_id": str(workflow_id)}
|
|
129
|
+
await websocket.send_text(json.dumps(response))
|
|
130
|
+
except Exception as e:
|
|
131
|
+
await websocket.send_text(
|
|
132
|
+
json.dumps({"error": f"Failed to subscribe the debug task: {str(e)}"})
|
|
133
|
+
)
|
|
134
|
+
return
|
|
135
|
+
|
|
136
|
+
# 触发debug版本的工作流
|
|
137
|
+
try:
|
|
138
|
+
trigger_args = message.get("trigger_args", {})
|
|
139
|
+
task_id = service.trigger_workflow_by_id(str(workflow_id), "", assigned_task_id=task_id, **trigger_args)
|
|
140
|
+
response = {"success": True, "type": "trigger_response", "task_id": str(task_id), "workflow_id": str(workflow_id)}
|
|
141
|
+
await websocket.send_text(json.dumps(response))
|
|
142
|
+
except Exception as e:
|
|
143
|
+
await websocket.send_text(
|
|
144
|
+
json.dumps({"error": f"Failed to trigger workflow of the debug version: {str(e)}"})
|
|
145
|
+
)
|
|
146
|
+
return
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
from starlette.staticfiles import StaticFiles
|
|
4
|
+
|
|
5
|
+
def get_studio_static_files() -> StaticFiles:
|
|
6
|
+
frontend_dist_path = Path(__file__).parent.parent / "frontend" / "static"
|
|
7
|
+
return StaticFiles(directory=str(frontend_dist_path), html=True)
|
|
8
|
+
|
|
9
|
+
studio_static_files = get_studio_static_files()
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from contextlib import contextmanager
|
|
5
|
+
from contextvars import ContextVar, Token
|
|
6
|
+
from dataclasses import dataclass, field, replace
|
|
7
|
+
from typing import Any, Iterator, Mapping
|
|
8
|
+
|
|
9
|
+
from loguru import logger
|
|
10
|
+
from opentelemetry.context import Context as OtelContext
|
|
11
|
+
from opentelemetry.trace import Span
|
|
12
|
+
|
|
13
|
+
"""
|
|
14
|
+
ExecutionContext helper for tracing/logging/state propagation.
|
|
15
|
+
|
|
16
|
+
Usage constraints (async-aware):
|
|
17
|
+
- Entrypoints must call set_current_context/use_execution_context so spawned coroutines inherit the context; create tasks after setting it.
|
|
18
|
+
- ContextVar does not flow into run_in_executor/thread pools; set_current_context manually in threads if needed.
|
|
19
|
+
- Use with_state to copy + mutate state; instances are immutable to avoid concurrent writes.
|
|
20
|
+
- Logger/span are shared references; set a new ExecutionContext when switching spans to prevent cross-task leakage.
|
|
21
|
+
- State payload is masked for sensitive keys and capped at ~4KB after JSON serialization; oversize payload raises ValueError.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
STATE_SIZE_LIMIT_BYTES = 4096
|
|
25
|
+
SENSITIVE_KEYS = (
|
|
26
|
+
"password",
|
|
27
|
+
"passwd",
|
|
28
|
+
"secret",
|
|
29
|
+
"token",
|
|
30
|
+
"api_key",
|
|
31
|
+
"apikey",
|
|
32
|
+
"authorization",
|
|
33
|
+
"auth",
|
|
34
|
+
"credential",
|
|
35
|
+
"cookie",
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _mask_sensitive_value(key: str, value: Any) -> Any:
|
|
40
|
+
lower_key = key.lower()
|
|
41
|
+
if any(sensitive in lower_key for sensitive in SENSITIVE_KEYS):
|
|
42
|
+
return "***"
|
|
43
|
+
return value
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _validate_state_payload(state: Mapping[str, Any]) -> None:
|
|
47
|
+
try:
|
|
48
|
+
payload = json.dumps(state, default=str)
|
|
49
|
+
except Exception:
|
|
50
|
+
payload = str(state)
|
|
51
|
+
if len(payload.encode("utf-8")) > STATE_SIZE_LIMIT_BYTES:
|
|
52
|
+
raise ValueError(
|
|
53
|
+
f"ExecutionContext state exceeds {STATE_SIZE_LIMIT_BYTES} bytes after serialization; "
|
|
54
|
+
"store a compact summary instead of raw payloads."
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@dataclass(frozen=True)
|
|
59
|
+
class ExecutionContext:
|
|
60
|
+
"""Shared execution-scoped data passed across API, workflow, and node layers."""
|
|
61
|
+
|
|
62
|
+
trace_context: OtelContext | None = None
|
|
63
|
+
span: Span | None = None
|
|
64
|
+
logger = logger
|
|
65
|
+
state: Mapping[str, Any] = field(default_factory=dict)
|
|
66
|
+
metadata: Mapping[str, Any] = field(default_factory=dict)
|
|
67
|
+
|
|
68
|
+
def with_state(self, **updates: Any) -> ExecutionContext:
|
|
69
|
+
merged_state = {
|
|
70
|
+
key: _mask_sensitive_value(key, value)
|
|
71
|
+
for key, value in {**self.state, **updates}.items()
|
|
72
|
+
}
|
|
73
|
+
_validate_state_payload(merged_state)
|
|
74
|
+
return replace(self, state=merged_state)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
current_context: ContextVar[ExecutionContext | None] = ContextVar(
|
|
78
|
+
"current_execution_context",
|
|
79
|
+
default=None,
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def get_current_context(
|
|
84
|
+
default: ExecutionContext | None = None,
|
|
85
|
+
) -> ExecutionContext | None:
|
|
86
|
+
context = current_context.get()
|
|
87
|
+
if context is None:
|
|
88
|
+
return default
|
|
89
|
+
return context
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def set_current_context(context: ExecutionContext | None) -> Token:
|
|
93
|
+
return current_context.set(context)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def reset_current_context(token: Token) -> None:
|
|
97
|
+
current_context.reset(token)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
@contextmanager
|
|
101
|
+
def use_execution_context(context: ExecutionContext) -> Iterator[ExecutionContext]:
|
|
102
|
+
token = set_current_context(context)
|
|
103
|
+
try:
|
|
104
|
+
yield context
|
|
105
|
+
finally:
|
|
106
|
+
reset_current_context(token)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./api-DyiqpKJK.js";import{u as S,W as x}from"./WorkflowStudio-FCyhGD4y.js";/* empty css *//* empty css */import{u as B}from"./vue-flow-Dn7R8GPr.js";import{u as O}from"./WorkflowEditor-CcaGGbko.js";import{e as T,C as D,D as F,F as j,G as U,t as W}from"./element-ui-D3x2y3TA.js";import{v as h,i as G,c as f,r as K,w as M,J as v,y as r,K as s,U as a,a2 as _,B as p,x as R,H as A,a9 as H,k as I,u as J}from"./vue-core-DL-LgTX0.js";import{_ as L}from"./index-BMvodlwc.js";import"./ui-components-DQ7-U3pr.js";import"./js-yaml-yTPt38rv.js";import"./elkjs-Dm5QV7uy.js";import"./code-editor-DBSql_sc.js";const P={class:"type-info"},q=h({__name:"CreateNewNodeDialog",props:{pos:{}},setup(b){const y=b,l=G(x.CREATE_NEW_NODE_OPEN),d=S().nodeSchemaMap,N=B(),{addNewNode:E}=O(N),n=f(()=>[...d.values()]),t=K(n.value[0]?.name??"");M(n,()=>{n.value[0]&&(t.value=t.value||n.value[0]?.name)});const i=f(()=>d.get(t.value)),w=()=>{l&&(l.value=!1)},V=()=>{t.value&&(E(t.value,y.pos),l&&(l.value=!1))};return(z,e)=>{const C=F,g=D,u=U,m=j,c=T,k=W;return r(),v(k,{modelValue:J(l),"onUpdate:modelValue":e[1]||(e[1]=o=>I(l)?l.value=o:null),title:"新建节点 · 选择节点类型","align-center":""},{default:s(()=>[a(g,{modelValue:t.value,"onUpdate:modelValue":e[0]||(e[0]=o=>t.value=o),placeholder:n.value[0]?.name},{default:s(()=>[(r(!0),R(A,null,H(n.value,o=>(r(),v(C,{key:o.name,label:o.name,value:o.name},null,8,["label","value"]))),128))]),_:1},8,["modelValue","placeholder"]),p("div",P,[p("div",null,[e[2]||(e[2]=p("p",{class:"type-info-entry-title"},"输入",-1)),a(m,{data:Object.values(i.value?.inputs||{})},{default:s(()=>[a(u,{prop:"name",label:"端口名",width:"140"}),a(u,{prop:"type",label:"数据类型"}),a(u,{prop:"default_value",label:"默认值"})]),_:1},8,["data"])]),p("div",null,[e[3]||(e[3]=p("p",{class:"type-info-entry-title"},"输出",-1)),a(m,{data:Object.values(i.value?.outputs||{})},{default:s(()=>[a(u,{prop:"name",label:"端口名",width:"140"}),a(u,{prop:"type",label:"数据类型"})]),_:1},8,["data"])])])]),footer:s(()=>[a(c,{onClick:w},{default:s(()=>[...e[4]||(e[4]=[_("取消",-1)])]),_:1}),a(c,{type:"primary",onClick:V,disabled:!t.value},{default:s(()=>[...e[5]||(e[5]=[_(" 新建 ",-1)])]),_:1},8,["disabled"])]),_:1},8,["modelValue"])}}}),pe=L(q,[["__scopeId","data-v-ce5c662a"]]);export{pe as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{--el-popup-modal-bg-color:var(--el-color-black);--el-popup-modal-opacity:.5}.v-modal-enter{animation:v-modal-in var(--el-transition-duration-fast) ease}.v-modal-leave{animation:v-modal-out var(--el-transition-duration-fast) ease forwards}@keyframes v-modal-in{0%{opacity:0}}@keyframes v-modal-out{to{opacity:0}}.v-modal{background:var(--el-popup-modal-bg-color);height:100%;left:0;opacity:var(--el-popup-modal-opacity);position:fixed;top:0;width:100%}.el-popup-parent--hidden{overflow:hidden}.el-dialog{--el-dialog-width:50%;--el-dialog-margin-top:15vh;--el-dialog-bg-color:var(--el-bg-color);--el-dialog-box-shadow:var(--el-box-shadow);--el-dialog-title-font-size:var(--el-font-size-large);--el-dialog-content-font-size:14px;--el-dialog-font-line-height:var(--el-font-line-height-primary);--el-dialog-padding-primary:16px;--el-dialog-border-radius:var(--el-border-radius-base);background:var(--el-dialog-bg-color);border-radius:var(--el-dialog-border-radius);box-shadow:var(--el-dialog-box-shadow);box-sizing:border-box;margin:var(--el-dialog-margin-top,15vh) auto 50px;overflow-wrap:break-word;padding:var(--el-dialog-padding-primary);position:relative;width:var(--el-dialog-width,50%)}.el-dialog:focus{outline:none!important}.el-dialog.is-align-center{margin:auto}.el-dialog.is-fullscreen{--el-dialog-width:100%;--el-dialog-margin-top:0;border-radius:0;height:100%;margin-bottom:0;overflow:auto}.el-dialog__wrapper{inset:0;margin:0;overflow:auto;position:fixed}.el-dialog.is-draggable .el-dialog__header{cursor:move;-webkit-user-select:none;-moz-user-select:none;user-select:none}.el-dialog__header{padding-bottom:var(--el-dialog-padding-primary)}.el-dialog__header.show-close{padding-right:calc(var(--el-dialog-padding-primary) + var(--el-message-close-size, 16px))}.el-dialog__headerbtn{background:transparent;border:none;cursor:pointer;font-size:var(--el-message-close-size,16px);height:48px;outline:none;padding:0;position:absolute;right:0;top:0;width:48px}.el-dialog__headerbtn .el-dialog__close{color:var(--el-color-info);font-size:inherit}.el-dialog__headerbtn:focus .el-dialog__close,.el-dialog__headerbtn:hover .el-dialog__close{color:var(--el-color-primary)}.el-dialog__title{color:var(--el-text-color-primary);font-size:var(--el-dialog-title-font-size);line-height:var(--el-dialog-font-line-height)}.el-dialog__body{color:var(--el-text-color-regular);font-size:var(--el-dialog-content-font-size)}.el-dialog__footer{box-sizing:border-box;padding-top:var(--el-dialog-padding-primary);text-align:right}.el-dialog--center{text-align:center}.el-dialog--center .el-dialog__body{text-align:initial}.el-dialog--center .el-dialog__footer{text-align:inherit}.el-modal-dialog.is-penetrable{pointer-events:none}.el-modal-dialog.is-penetrable .el-dialog{pointer-events:auto}.el-overlay-dialog{inset:0;overflow:auto;position:fixed}.dialog-fade-enter-active{animation:modal-fade-in var(--el-transition-duration)}.dialog-fade-enter-active .el-overlay-dialog{animation:dialog-fade-in var(--el-transition-duration)}.dialog-fade-leave-active{animation:modal-fade-out var(--el-transition-duration)}.dialog-fade-leave-active .el-overlay-dialog{animation:dialog-fade-out var(--el-transition-duration)}@keyframes dialog-fade-in{0%{opacity:0;transform:translate3d(0,-20px,0)}to{opacity:1;transform:translateZ(0)}}@keyframes dialog-fade-out{0%{opacity:1;transform:translateZ(0)}to{opacity:0;transform:translate3d(0,-20px,0)}}@keyframes modal-fade-in{0%{opacity:0}to{opacity:1}}@keyframes modal-fade-out{0%{opacity:1}to{opacity:0}}.el-overlay{background-color:var(--el-overlay-color-lighter);height:100%;inset:0;overflow:auto;position:fixed;z-index:2000}.el-overlay .el-overlay-root{height:0}.el-table{--el-table-border-color:var(--el-border-color-lighter);--el-table-border:1px solid var(--el-table-border-color);--el-table-text-color:var(--el-text-color-regular);--el-table-header-text-color:var(--el-text-color-secondary);--el-table-row-hover-bg-color:var(--el-fill-color-light);--el-table-current-row-bg-color:var(--el-color-primary-light-9);--el-table-header-bg-color:var(--el-bg-color);--el-table-fixed-box-shadow:var(--el-box-shadow-light);--el-table-bg-color:var(--el-fill-color-blank);--el-table-tr-bg-color:var(--el-bg-color);--el-table-expanded-cell-bg-color:var(--el-fill-color-blank);--el-table-fixed-left-column:inset 10px 0 10px -10px rgba(0,0,0,.15);--el-table-fixed-right-column:inset -10px 0 10px -10px rgba(0,0,0,.15);--el-table-index:var(--el-index-normal);background-color:var(--el-table-bg-color);box-sizing:border-box;color:var(--el-table-text-color);font-size:var(--el-font-size-base);height:-moz-fit-content;height:fit-content;max-width:100%;overflow:hidden;position:relative;width:100%}.el-table__inner-wrapper{display:flex;flex-direction:column;height:100%;position:relative}.el-table__inner-wrapper:before{bottom:0;height:1px;left:0}.el-table tbody:focus-visible{outline:none}.el-table.has-footer.el-table--fluid-height tr:last-child td.el-table__cell,.el-table.has-footer.el-table--scrollable-y tr:last-child td.el-table__cell{border-bottom-color:transparent}.el-table__empty-block{align-items:center;display:flex;justify-content:center;left:0;min-height:60px;position:sticky;text-align:center;width:100%}.el-table__empty-text{color:var(--el-text-color-secondary);line-height:60px;width:50%}.el-table__expand-column .cell{padding:0;text-align:center;-webkit-user-select:none;-moz-user-select:none;user-select:none}.el-table__expand-icon{color:var(--el-text-color-regular);cursor:pointer;font-size:12px;height:20px;position:relative;transition:transform var(--el-transition-duration-fast) ease-in-out}.el-table__expand-icon--expanded{transform:rotate(90deg)}.el-table__expand-icon>.el-icon{font-size:12px}.el-table__expanded-cell{background-color:var(--el-table-expanded-cell-bg-color)}.el-table__expanded-cell[class*=cell]{padding:20px 50px}.el-table__expanded-cell:hover{background-color:transparent!important}.el-table__placeholder{display:inline-block;width:20px}.el-table__append-wrapper{overflow:hidden}.el-table--fit{border-bottom:0;border-right:0}.el-table--fit .el-table__cell.gutter{border-right-width:1px}.el-table--fit .el-table__inner-wrapper:before{width:100%}.el-table thead{color:var(--el-table-header-text-color)}.el-table thead th{font-weight:600}.el-table thead.is-group th.el-table__cell{background:var(--el-fill-color-light)}.el-table .el-table__cell{box-sizing:border-box;min-width:0;padding:8px 0;position:relative;text-align:left;text-overflow:ellipsis;vertical-align:middle;z-index:var(--el-table-index)}.el-table .el-table__cell.is-center{text-align:center}.el-table .el-table__cell.is-right{text-align:right}.el-table .el-table__cell.gutter{border-bottom-width:0;border-right-width:0;padding:0;width:15px}.el-table .el-table__cell.is-hidden>*{visibility:hidden}.el-table .cell{box-sizing:border-box;line-height:23px;overflow:hidden;overflow-wrap:break-word;padding:0 12px;text-overflow:ellipsis;white-space:normal}.el-table .cell.el-tooltip{min-width:50px;white-space:nowrap}.el-table--large{font-size:var(--el-font-size-base)}.el-table--large .el-table__cell{padding:12px 0}.el-table--large .cell{padding:0 16px}.el-table--default{font-size:var(--el-font-size-base)}.el-table--default .el-table__cell{padding:8px 0}.el-table--default .cell{padding:0 12px}.el-table--small{font-size:var(--el-font-size-extra-small)}.el-table--small .el-table__cell{padding:4px 0}.el-table--small .cell{padding:0 8px}.el-table tr{background-color:var(--el-table-tr-bg-color)}.el-table tr input[type=checkbox]{margin:0}.el-table td.el-table__cell,.el-table th.el-table__cell.is-leaf{border-bottom:var(--el-table-border)}.el-table th.el-table__cell.is-sortable{cursor:pointer}.el-table th.el-table__cell{background-color:var(--el-table-header-bg-color)}.el-table th.el-table__cell>.cell.highlight{color:var(--el-color-primary)}.el-table th.el-table__cell.required>div:before{background:#ff4d51;border-radius:50%;content:"";display:inline-block;height:8px;margin-right:5px;vertical-align:middle;width:8px}.el-table td.el-table__cell div{box-sizing:border-box}.el-table td.el-table__cell.gutter{width:0}.el-table--border .el-table__inner-wrapper:after,.el-table--border:after,.el-table--border:before,.el-table__inner-wrapper:before{background-color:var(--el-table-border-color);content:"";position:absolute;z-index:calc(var(--el-table-index) + 2)}.el-table--border .el-table__inner-wrapper:after{height:1px;left:0;top:0;width:100%;z-index:calc(var(--el-table-index) + 2)}.el-table--border:before{height:100%;left:0;top:-1px;width:1px}.el-table--border:after{height:100%;right:0;top:-1px;width:1px}.el-table--border .el-table__inner-wrapper{border-bottom:none;border-right:none}.el-table--border .el-table__footer-wrapper{flex-shrink:0;position:relative}.el-table--border .el-table__cell{border-right:var(--el-table-border)}.el-table--border th.el-table__cell.gutter:last-of-type{border-bottom:var(--el-table-border);border-bottom-width:1px}.el-table--border th.el-table__cell{border-bottom:var(--el-table-border)}.el-table--hidden{visibility:hidden}.el-table__body-wrapper,.el-table__footer-wrapper,.el-table__header-wrapper{width:100%}.el-table__body-wrapper tr td.el-table-fixed-column--left,.el-table__body-wrapper tr td.el-table-fixed-column--right,.el-table__body-wrapper tr th.el-table-fixed-column--left,.el-table__body-wrapper tr th.el-table-fixed-column--right,.el-table__footer-wrapper tr td.el-table-fixed-column--left,.el-table__footer-wrapper tr td.el-table-fixed-column--right,.el-table__footer-wrapper tr th.el-table-fixed-column--left,.el-table__footer-wrapper tr th.el-table-fixed-column--right,.el-table__header-wrapper tr td.el-table-fixed-column--left,.el-table__header-wrapper tr td.el-table-fixed-column--right,.el-table__header-wrapper tr th.el-table-fixed-column--left,.el-table__header-wrapper tr th.el-table-fixed-column--right{background:inherit;position:sticky!important;z-index:calc(var(--el-table-index) + 1)}.el-table__body-wrapper tr td.el-table-fixed-column--left.is-first-column:before,.el-table__body-wrapper tr td.el-table-fixed-column--left.is-last-column:before,.el-table__body-wrapper tr td.el-table-fixed-column--right.is-first-column:before,.el-table__body-wrapper tr td.el-table-fixed-column--right.is-last-column:before,.el-table__body-wrapper tr th.el-table-fixed-column--left.is-first-column:before,.el-table__body-wrapper tr th.el-table-fixed-column--left.is-last-column:before,.el-table__body-wrapper tr th.el-table-fixed-column--right.is-first-column:before,.el-table__body-wrapper tr th.el-table-fixed-column--right.is-last-column:before,.el-table__footer-wrapper tr td.el-table-fixed-column--left.is-first-column:before,.el-table__footer-wrapper tr td.el-table-fixed-column--left.is-last-column:before,.el-table__footer-wrapper tr td.el-table-fixed-column--right.is-first-column:before,.el-table__footer-wrapper tr td.el-table-fixed-column--right.is-last-column:before,.el-table__footer-wrapper tr th.el-table-fixed-column--left.is-first-column:before,.el-table__footer-wrapper tr th.el-table-fixed-column--left.is-last-column:before,.el-table__footer-wrapper tr th.el-table-fixed-column--right.is-first-column:before,.el-table__footer-wrapper tr th.el-table-fixed-column--right.is-last-column:before,.el-table__header-wrapper tr td.el-table-fixed-column--left.is-first-column:before,.el-table__header-wrapper tr td.el-table-fixed-column--left.is-last-column:before,.el-table__header-wrapper tr td.el-table-fixed-column--right.is-first-column:before,.el-table__header-wrapper tr td.el-table-fixed-column--right.is-last-column:before,.el-table__header-wrapper tr th.el-table-fixed-column--left.is-first-column:before,.el-table__header-wrapper tr th.el-table-fixed-column--left.is-last-column:before,.el-table__header-wrapper tr th.el-table-fixed-column--right.is-first-column:before,.el-table__header-wrapper tr th.el-table-fixed-column--right.is-last-column:before{bottom:-1px;box-shadow:none;content:"";overflow-x:hidden;overflow-y:hidden;pointer-events:none;position:absolute;top:0;touch-action:none;width:10px}.el-table__body-wrapper tr td.el-table-fixed-column--left.is-first-column:before,.el-table__body-wrapper tr td.el-table-fixed-column--right.is-first-column:before,.el-table__body-wrapper tr th.el-table-fixed-column--left.is-first-column:before,.el-table__body-wrapper tr th.el-table-fixed-column--right.is-first-column:before,.el-table__footer-wrapper tr td.el-table-fixed-column--left.is-first-column:before,.el-table__footer-wrapper tr td.el-table-fixed-column--right.is-first-column:before,.el-table__footer-wrapper tr th.el-table-fixed-column--left.is-first-column:before,.el-table__footer-wrapper tr th.el-table-fixed-column--right.is-first-column:before,.el-table__header-wrapper tr td.el-table-fixed-column--left.is-first-column:before,.el-table__header-wrapper tr td.el-table-fixed-column--right.is-first-column:before,.el-table__header-wrapper tr th.el-table-fixed-column--left.is-first-column:before,.el-table__header-wrapper tr th.el-table-fixed-column--right.is-first-column:before{left:-10px}.el-table__body-wrapper tr td.el-table-fixed-column--left.is-last-column:before,.el-table__body-wrapper tr td.el-table-fixed-column--right.is-last-column:before,.el-table__body-wrapper tr th.el-table-fixed-column--left.is-last-column:before,.el-table__body-wrapper tr th.el-table-fixed-column--right.is-last-column:before,.el-table__footer-wrapper tr td.el-table-fixed-column--left.is-last-column:before,.el-table__footer-wrapper tr td.el-table-fixed-column--right.is-last-column:before,.el-table__footer-wrapper tr th.el-table-fixed-column--left.is-last-column:before,.el-table__footer-wrapper tr th.el-table-fixed-column--right.is-last-column:before,.el-table__header-wrapper tr td.el-table-fixed-column--left.is-last-column:before,.el-table__header-wrapper tr td.el-table-fixed-column--right.is-last-column:before,.el-table__header-wrapper tr th.el-table-fixed-column--left.is-last-column:before,.el-table__header-wrapper tr th.el-table-fixed-column--right.is-last-column:before{right:-10px}.el-table__body-wrapper tr td.el-table__fixed-right-patch,.el-table__body-wrapper tr th.el-table__fixed-right-patch,.el-table__footer-wrapper tr td.el-table__fixed-right-patch,.el-table__footer-wrapper tr th.el-table__fixed-right-patch,.el-table__header-wrapper tr td.el-table__fixed-right-patch,.el-table__header-wrapper tr th.el-table__fixed-right-patch{background:#fff;position:sticky!important;right:0;z-index:calc(var(--el-table-index) + 1)}.el-table__header-wrapper{flex-shrink:0}.el-table__header-wrapper tr th.el-table-fixed-column--left,.el-table__header-wrapper tr th.el-table-fixed-column--right{background-color:var(--el-table-header-bg-color)}.el-table__body,.el-table__footer,.el-table__header{border-collapse:separate;table-layout:fixed}.el-table__header-wrapper{overflow:hidden}.el-table__header-wrapper tbody td.el-table__cell{background-color:var(--el-table-row-hover-bg-color);color:var(--el-table-text-color)}.el-table__footer-wrapper{flex-shrink:0;overflow:hidden}.el-table__footer-wrapper tfoot td.el-table__cell{background-color:var(--el-table-row-hover-bg-color);color:var(--el-table-text-color)}.el-table__body-wrapper .el-table-column--selection>.cell,.el-table__header-wrapper .el-table-column--selection>.cell{align-items:center;display:inline-flex;height:23px}.el-table__body-wrapper .el-table-column--selection .el-checkbox,.el-table__header-wrapper .el-table-column--selection .el-checkbox{height:unset}.el-table.is-scrolling-left .el-table-fixed-column--right.is-first-column:before{box-shadow:var(--el-table-fixed-right-column)}.el-table.is-scrolling-left.el-table--border .el-table-fixed-column--left.is-last-column.el-table__cell{border-right:var(--el-table-border)}.el-table.is-scrolling-left th.el-table-fixed-column--left{background-color:var(--el-table-header-bg-color)}.el-table.is-scrolling-right .el-table-fixed-column--left.is-last-column:before{box-shadow:var(--el-table-fixed-left-column)}.el-table.is-scrolling-right .el-table-fixed-column--left.is-last-column.el-table__cell{border-right:none}.el-table.is-scrolling-right th.el-table-fixed-column--right{background-color:var(--el-table-header-bg-color)}.el-table.is-scrolling-middle .el-table-fixed-column--left.is-last-column.el-table__cell{border-right:none}.el-table.is-scrolling-middle .el-table-fixed-column--right.is-first-column:before{box-shadow:var(--el-table-fixed-right-column)}.el-table.is-scrolling-middle .el-table-fixed-column--left.is-last-column:before{box-shadow:var(--el-table-fixed-left-column)}.el-table.is-scrolling-none .el-table-fixed-column--left.is-first-column:before,.el-table.is-scrolling-none .el-table-fixed-column--left.is-last-column:before,.el-table.is-scrolling-none .el-table-fixed-column--right.is-first-column:before,.el-table.is-scrolling-none .el-table-fixed-column--right.is-last-column:before{box-shadow:none}.el-table.is-scrolling-none th.el-table-fixed-column--left,.el-table.is-scrolling-none th.el-table-fixed-column--right{background-color:var(--el-table-header-bg-color)}.el-table__body-wrapper{flex:1;overflow:hidden;position:relative}.el-table__body-wrapper .el-scrollbar__bar{z-index:calc(var(--el-table-index) + 2)}.el-table .caret-wrapper{align-items:center;cursor:pointer;display:inline-flex;flex-direction:column;height:14px;overflow:initial;position:relative;vertical-align:middle;width:24px}.el-table .sort-caret{border:5px solid transparent;height:0;left:7px;position:absolute;width:0}.el-table .sort-caret.ascending{border-bottom-color:var(--el-text-color-placeholder);top:-5px}.el-table .sort-caret.descending{border-top-color:var(--el-text-color-placeholder);bottom:-3px}.el-table .ascending .sort-caret.ascending{border-bottom-color:var(--el-color-primary)}.el-table .descending .sort-caret.descending{border-top-color:var(--el-color-primary)}.el-table .hidden-columns{position:absolute;visibility:hidden;z-index:-1}.el-table--striped .el-table__body tr.el-table__row--striped td.el-table__cell{background:var(--el-fill-color-lighter)}.el-table--striped .el-table__body tr.el-table__row--striped.current-row td.el-table__cell{background-color:var(--el-table-current-row-bg-color)}.el-table__body tr.hover-row.current-row>td.el-table__cell,.el-table__body tr.hover-row.el-table__row--striped.current-row>td.el-table__cell,.el-table__body tr.hover-row.el-table__row--striped>td.el-table__cell,.el-table__body tr.hover-row>td.el-table__cell{background-color:var(--el-table-row-hover-bg-color)}.el-table__body tr>td.hover-cell{background-color:var(--el-table-row-hover-bg-color)}.el-table__body tr.current-row>td.el-table__cell{background-color:var(--el-table-current-row-bg-color)}.el-table.el-table--scrollable-y .el-table__body-header{position:sticky;top:0;z-index:calc(var(--el-table-index) + 2)}.el-table.el-table--scrollable-y .el-table__body-footer{bottom:0;position:sticky;z-index:calc(var(--el-table-index) + 2)}.el-table__column-resize-proxy{border-left:var(--el-table-border);bottom:0;left:200px;position:absolute;top:0;width:0;z-index:calc(var(--el-table-index) + 9)}.el-table__column-filter-trigger{cursor:pointer;display:inline-block}.el-table__column-filter-trigger i{color:var(--el-color-info);font-size:14px;vertical-align:middle}.el-table__border-left-patch{height:100%;top:0;width:1px}.el-table__border-bottom-patch,.el-table__border-left-patch{background-color:var(--el-table-border-color);left:0;position:absolute;z-index:calc(var(--el-table-index) + 2)}.el-table__border-bottom-patch{height:1px}.el-table__border-right-patch{background-color:var(--el-table-border-color);height:100%;position:absolute;top:0;width:1px;z-index:calc(var(--el-table-index) + 2)}.el-table--enable-row-transition .el-table__body td.el-table__cell{transition:background-color .25s ease}.el-table--enable-row-hover .el-table__body tr:hover>td.el-table__cell{background-color:var(--el-table-row-hover-bg-color)}.el-table [class*=el-table__row--level] .el-table__expand-icon{display:inline-block;height:12px;line-height:12px;margin-right:8px;text-align:center;width:12px}.el-table .el-table.el-table--border .el-table__cell{border-right:var(--el-table-border)}.el-table:not(.el-table--border) .el-table__cell{border-right:none}.el-table:not(.el-table--border)>.el-table__inner-wrapper:after{content:none}.el-checkbox{--el-checkbox-font-size:14px;--el-checkbox-font-weight:var(--el-font-weight-primary);--el-checkbox-text-color:var(--el-text-color-regular);--el-checkbox-input-height:14px;--el-checkbox-input-width:14px;--el-checkbox-border-radius:var(--el-border-radius-small);--el-checkbox-bg-color:var(--el-fill-color-blank);--el-checkbox-input-border:var(--el-border);--el-checkbox-disabled-border-color:var(--el-border-color);--el-checkbox-disabled-input-fill:var(--el-fill-color-light);--el-checkbox-disabled-icon-color:var(--el-text-color-placeholder);--el-checkbox-disabled-checked-input-fill:var(--el-border-color-extra-light);--el-checkbox-disabled-checked-input-border-color:var(--el-border-color);--el-checkbox-disabled-checked-icon-color:var(--el-text-color-placeholder);--el-checkbox-checked-text-color:var(--el-color-primary);--el-checkbox-checked-input-border-color:var(--el-color-primary);--el-checkbox-checked-bg-color:var(--el-color-primary);--el-checkbox-checked-icon-color:var(--el-color-white);--el-checkbox-input-border-color-hover:var(--el-color-primary);align-items:center;color:var(--el-checkbox-text-color);cursor:pointer;display:inline-flex;font-size:var(--el-font-size-base);font-weight:var(--el-checkbox-font-weight);height:var(--el-checkbox-height,32px);margin-right:30px;position:relative;-webkit-user-select:none;-moz-user-select:none;user-select:none;white-space:nowrap}.el-checkbox.is-disabled{cursor:not-allowed}.el-checkbox.is-bordered{border:var(--el-border);border-radius:var(--el-border-radius-base);box-sizing:border-box;padding:0 15px 0 9px}.el-checkbox.is-bordered.is-checked{border-color:var(--el-color-primary)}.el-checkbox.is-bordered.is-disabled{border-color:var(--el-border-color-lighter)}.el-checkbox.is-bordered.el-checkbox--large{border-radius:var(--el-border-radius-base);padding:0 19px 0 11px}.el-checkbox.is-bordered.el-checkbox--large .el-checkbox__label{font-size:var(--el-font-size-base)}.el-checkbox.is-bordered.el-checkbox--large .el-checkbox__inner{height:14px;width:14px}.el-checkbox.is-bordered.el-checkbox--small{border-radius:calc(var(--el-border-radius-base) - 1px);padding:0 11px 0 7px}.el-checkbox.is-bordered.el-checkbox--small .el-checkbox__label{font-size:12px}.el-checkbox.is-bordered.el-checkbox--small .el-checkbox__inner{height:12px;width:12px}.el-checkbox.is-bordered.el-checkbox--small .el-checkbox__inner:after{height:6px;width:2px}.el-checkbox input:focus-visible+.el-checkbox__inner{border-radius:var(--el-checkbox-border-radius);outline:2px solid var(--el-checkbox-input-border-color-hover);outline-offset:1px}.el-checkbox__input{cursor:pointer;display:inline-flex;outline:none;position:relative;white-space:nowrap}.el-checkbox__input.is-disabled .el-checkbox__inner{background-color:var(--el-checkbox-disabled-input-fill);border-color:var(--el-checkbox-disabled-border-color);cursor:not-allowed}.el-checkbox__input.is-disabled .el-checkbox__inner:after{border-color:var(--el-checkbox-disabled-icon-color);cursor:not-allowed}.el-checkbox__input.is-disabled.is-checked .el-checkbox__inner{background-color:var(--el-checkbox-disabled-checked-input-fill);border-color:var(--el-checkbox-disabled-checked-input-border-color)}.el-checkbox__input.is-disabled.is-checked .el-checkbox__inner:after{border-color:var(--el-checkbox-disabled-checked-icon-color)}.el-checkbox__input.is-disabled.is-indeterminate .el-checkbox__inner{background-color:var(--el-checkbox-disabled-checked-input-fill);border-color:var(--el-checkbox-disabled-checked-input-border-color)}.el-checkbox__input.is-disabled.is-indeterminate .el-checkbox__inner:before{background-color:var(--el-checkbox-disabled-checked-icon-color);border-color:var(--el-checkbox-disabled-checked-icon-color)}.el-checkbox__input.is-disabled+span.el-checkbox__label{color:var(--el-disabled-text-color);cursor:not-allowed}.el-checkbox__input.is-checked .el-checkbox__inner{background-color:var(--el-checkbox-checked-bg-color);border-color:var(--el-checkbox-checked-input-border-color)}.el-checkbox__input.is-checked .el-checkbox__inner:after{border-color:var(--el-checkbox-checked-icon-color);transform:translate(-45%,-60%) rotate(45deg) scaleY(1)}.el-checkbox__input.is-checked+.el-checkbox__label{color:var(--el-checkbox-checked-text-color)}.el-checkbox__input.is-focus:not(.is-checked) .el-checkbox__original:not(:focus-visible){border-color:var(--el-checkbox-input-border-color-hover)}.el-checkbox__input.is-indeterminate .el-checkbox__inner{background-color:var(--el-checkbox-checked-bg-color);border-color:var(--el-checkbox-checked-input-border-color)}.el-checkbox__input.is-indeterminate .el-checkbox__inner:before{background-color:var(--el-checkbox-checked-icon-color);content:"";display:block;height:2px;left:0;position:absolute;right:0;top:5px;transform:scale(.5)}.el-checkbox__input.is-indeterminate .el-checkbox__inner:after{display:none}.el-checkbox__inner{background-color:var(--el-checkbox-bg-color);border:var(--el-checkbox-input-border);border-radius:var(--el-checkbox-border-radius);box-sizing:border-box;display:inline-block;height:var(--el-checkbox-input-height);position:relative;transition:border-color .25s cubic-bezier(.71,-.46,.29,1.46),background-color .25s cubic-bezier(.71,-.46,.29,1.46),outline .25s cubic-bezier(.71,-.46,.29,1.46);width:var(--el-checkbox-input-width);z-index:var(--el-index-normal)}.el-checkbox__inner:hover{border-color:var(--el-checkbox-input-border-color-hover)}.el-checkbox__inner:after{border:1px solid transparent;border-left:0;border-top:0;box-sizing:content-box;content:"";height:7px;left:50%;position:absolute;top:50%;transform:translate(-45%,-60%) rotate(45deg) scaleY(0);transform-origin:center;transition:transform .15s ease-in .05s;width:3px}.el-checkbox__original{height:0;margin:0;opacity:0;outline:none;position:absolute;width:0;z-index:-1}.el-checkbox__label{display:inline-block;font-size:var(--el-checkbox-font-size);line-height:1;padding-left:8px}.el-checkbox.el-checkbox--large{height:40px}.el-checkbox.el-checkbox--large .el-checkbox__label{font-size:14px}.el-checkbox.el-checkbox--large .el-checkbox__inner{height:14px;width:14px}.el-checkbox.el-checkbox--small{height:24px}.el-checkbox.el-checkbox--small .el-checkbox__label{font-size:12px}.el-checkbox.el-checkbox--small .el-checkbox__inner{height:12px;width:12px}.el-checkbox.el-checkbox--small .el-checkbox__input.is-indeterminate .el-checkbox__inner:before{top:4px}.el-checkbox.el-checkbox--small .el-checkbox__inner:after{height:6px;width:2px}.el-checkbox:last-of-type{margin-right:0}.el-table-column--selection .cell{padding-left:14px;padding-right:14px}.el-table-filter{background-color:#fff;border:1px solid var(--el-border-color-lighter);border-radius:2px;box-shadow:var(--el-box-shadow-light);box-sizing:border-box}.el-table-filter__list{list-style:none;margin:0;min-width:100px;padding:5px 0}.el-table-filter__list-item{cursor:pointer;font-size:var(--el-font-size-base);line-height:36px;padding:0 10px}.el-table-filter__list-item:hover{background-color:var(--el-color-primary-light-9);color:var(--el-color-primary)}.el-table-filter__list-item.is-active{background-color:var(--el-color-primary);color:#fff}.el-table-filter__content{min-width:100px}.el-table-filter__bottom{border-top:1px solid var(--el-border-color-lighter);padding:8px}.el-table-filter__bottom button{background:transparent;border:none;color:var(--el-text-color-regular);cursor:pointer;font-size:var(--el-font-size-small);padding:0 3px}.el-table-filter__bottom button:hover{color:var(--el-color-primary)}.el-table-filter__bottom button:focus{outline:none}.el-table-filter__bottom button.is-disabled{color:var(--el-disabled-text-color);cursor:not-allowed}.el-table-filter__wrap{max-height:280px}.el-table-filter__checkbox-group{padding:10px}.el-table-filter__checkbox-group label.el-checkbox{align-items:center;display:flex;height:unset;margin-bottom:12px;margin-left:5px;margin-right:5px}.el-table-filter__checkbox-group .el-checkbox:last-child{margin-bottom:0}.type-info[data-v-ce5c662a]{display:flex;flex-direction:column;gap:20px;margin-top:24px}.type-info-entry-title[data-v-ce5c662a]{font-size:1.25rem;font-weight:500;padding-left:12px}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.editor-side-panel[data-v-202d287c]{display:flex;flex-direction:column;height:100%;overflow:hidden;background:var(--color-card-bg)}.panel-header[data-v-202d287c]{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:8px 12px;border-bottom:1px solid var(--color-border)}.panel-header-icon[data-v-202d287c]{width:16px;height:16px}.panel-header-text[data-v-202d287c]{flex:1;font-size:16px;font-weight:600;color:var(--color-text-1);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./api-DyiqpKJK.js";import"./WorkflowEditor-CcaGGbko.js";import{u as l}from"./ui-components-DQ7-U3pr.js";import{e as c,o as p}from"./element-ui-D3x2y3TA.js";import{v as d,J as e,G as m,y as n,K as _,B as t,z as C,U as u,L as f,O as h,u as v}from"./vue-core-DL-LgTX0.js";import{_ as L}from"./index-BMvodlwc.js";import"./vue-flow-Dn7R8GPr.js";import"./js-yaml-yTPt38rv.js";import"./WorkflowStudio-FCyhGD4y.js";import"./elkjs-Dm5QV7uy.js";import"./code-editor-DBSql_sc.js";/* empty css */const B=l({tag:"svg",attr:{viewBox:"0 0 24 24",fill:"none"},child:[{tag:"path",attr:{d:"M6.2253 4.81108C5.83477 4.42056 5.20161 4.42056 4.81108 4.81108C4.42056 5.20161 4.42056 5.83477 4.81108 6.2253L10.5858 12L4.81114 17.7747C4.42062 18.1652 4.42062 18.7984 4.81114 19.1889C5.20167 19.5794 5.83483 19.5794 6.22535 19.1889L12 13.4142L17.7747 19.1889C18.1652 19.5794 18.7984 19.5794 19.1889 19.1889C19.5794 18.7984 19.5794 18.1652 19.1889 17.7747L13.4142 12L19.189 6.2253C19.5795 5.83477 19.5795 5.20161 19.189 4.81108C18.7985 4.42056 18.1653 4.42056 17.7748 4.81108L12 10.5858L6.2253 4.81108Z",fill:"currentColor"},child:[]}]}),x={class:"editor-side-panel"},y={class:"panel-header"},g={class:"panel-header-text"},k=d({__name:"EditorSidePanel",props:{show:{type:Boolean},icon:{},title:{},onClose:{type:Function}},setup(s){const o=s;return(a,S)=>{const i=c,r=p;return o.show??!0?(n(),e(r,{key:0,min:"20%",size:"25%"},{default:_(()=>[t("div",x,[t("div",y,[(n(),e(f(o.icon),{class:"panel-header-icon"})),t("div",g,h(o.title),1),u(i,{icon:v(B),color:"",text:"",onClick:o.onClose},null,8,["icon","onClick"])]),C(a.$slots,"default",{},void 0,!0)])]),_:3})):m("",!0)}}}),K=L(k,[["__scopeId","data-v-202d287c"]]);export{K as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as V,e as D}from"./api-DyiqpKJK.js";/* empty css */import{W as I}from"./WorkflowStudio-FCyhGD4y.js";import{v as g,c as w,x as o,y as a,B as n,J as d,G as m,O as i,u as N,U as u,r as v,aC as O,i as R,w as W,R as $,H as b,a9 as j,K as y,a2 as A}from"./vue-core-DL-LgTX0.js";import{_ as K}from"./FormattedCodeViewer.vue_vue_type_script_setup_true_lang-BNuI1NCs.js";import{f as L}from"./time-DKCKV6Ug.js";import{u as T,v as U,w as P,e as z,b as G,a as H}from"./element-ui-D3x2y3TA.js";import{_ as x}from"./index-BMvodlwc.js";import"./ui-components-DQ7-U3pr.js";import"./js-yaml-yTPt38rv.js";import"./elkjs-Dm5QV7uy.js";import"./highlightjs-D4ATuRwX.js";const J={class:"feedback-item-card"},M={class:"feedback-time"},S={key:1,class:"feedback-comment"},q={class:"feedback-comment-text full-comment"},Q={class:"feedback-comment-text collapsed-comment"},X={key:2,class:"feedback-meta"},Y=g({__name:"FeedbackItemCard",props:{feedback:{}},setup(_){const l=_,e=w(()=>l.feedback);return(p,t)=>{const c=T;return a(),o("div",J,[n("p",M,i(N(L)(e.value.created_at)),1),e.value.rating!==void 0&&e.value.rating!==null?(a(),d(c,{key:0,modelValue:e.value.rating,"onUpdate:modelValue":t[0]||(t[0]=r=>e.value.rating=r),max:5,"show-text":!1,size:"small",disabled:""},null,8,["modelValue"])):m("",!0),e.value.comment?(a(),o("details",S,[t[1]||(t[1]=n("summary",{class:"detail-item-title"},"评论",-1)),n("p",q,i(e.value.comment),1)])):m("",!0),n("p",Q,i(e.value.comment),1),e.value.metadata&&Object.keys(e.value.metadata).length>0?(a(),o("details",X,[t[2]||(t[2]=n("summary",{class:"detail-item-title"},"元数据",-1)),u(K,{class:"feedback-meta-content",content:e.value.metadata,lang:"json"},null,8,["content"])])):m("",!0)])}}}),Z=x(Y,[["__scopeId","data-v-a25b1194"]]),ee={class:"trace-list-area"},ae={key:0,class:"trace-list"},te=g({__name:"FeedbackPanel",setup(_){const l=v(!1),e=v([]),p=O(),t=w(()=>p.params.id),c=R(I.WORKFLOW_DATA),r=async()=>{if(t.value){l.value=!0;try{const s=await V.get("/",{base:D(),params:c?.value?.name?{workflow_name:c?.value?.name}:void 0});e.value=s.feedbacks}catch(s){H.error(s?.message||"加载反馈失败"),console.error("Failed to load feedbacks:",s)}finally{l.value=!1}}};return W(t,s=>{s&&r()},{immediate:!0}),(s,f)=>{const h=P,F=z,E=G,B=U;return $((a(),o("div",ee,[e.value.length>0?(a(),o("div",ae,[(a(!0),o(b,null,j(e.value,(k,C)=>(a(),o(b,{key:k.feedback_id},[u(Z,{feedback:k},null,8,["feedback"]),C<e.value.length-1?(a(),d(h,{key:0,class:"trace-item-divider"})):m("",!0)],64))),128))])):(a(),d(E,{key:1,class:"empty-state"},{default:y(()=>[u(F,{type:"primary",onClick:r},{default:y(()=>[...f[0]||(f[0]=[A("重新加载",-1)])]),_:1})]),_:1}))])),[[B,l.value]])}}}),fe=x(te,[["__scopeId","data-v-4fb29a7e"]]);export{fe as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.el-rate{--el-rate-height:20px;--el-rate-font-size:var(--el-font-size-base);--el-rate-icon-size:18px;--el-rate-icon-margin:6px;--el-rate-void-color:var(--el-border-color-darker);--el-rate-fill-color:#f7ba2a;--el-rate-disabled-void-color:var(--el-fill-color);--el-rate-text-color:var(--el-text-color-primary);--el-rate-outline-color:var(--el-color-primary-light-5);align-items:center;display:inline-flex;height:32px}.el-rate:active,.el-rate:focus{outline:none}.el-rate:focus-visible .el-rate__item .el-rate__icon.is-focus-visible{outline:2px solid var(--el-rate-outline-color);transition:outline-offset 0s,outline 0s}.el-rate__item{color:var(--el-rate-void-color);cursor:pointer;display:inline-block;font-size:0;line-height:normal;position:relative;vertical-align:middle}.el-rate .el-rate__icon{display:inline-block;font-size:var(--el-rate-icon-size);margin-right:var(--el-rate-icon-margin);position:relative;transition:var(--el-transition-duration)}.el-rate .el-rate__icon.hover{transform:scale(1.15)}.el-rate .el-rate__icon .path2{left:0;position:absolute;top:0}.el-rate .el-rate__icon.is-active{color:var(--el-rate-fill-color)}.el-rate__decimal{color:var(--el-rate-fill-color);display:inline-block;overflow:hidden}.el-rate__decimal,.el-rate__decimal--box{left:0;position:absolute;top:0}.el-rate__text{color:var(--el-rate-text-color);font-size:var(--el-rate-font-size);vertical-align:middle}.el-rate--large{height:40px}.el-rate--small{height:24px}.el-rate--small .el-rate__icon{font-size:14px}.el-rate.is-disabled .el-rate__item{color:var(--el-rate-disabled-void-color);cursor:auto}.feedback-item-card[data-v-a25b1194]{display:flex;flex-direction:column;gap:4px;border-radius:var(--radius-m);transition:all .2s}.feedback-time[data-v-a25b1194]{font-size:.75rem;color:var(--color-text-4);flex-shrink:0}.feedback-comment .full-comment[data-v-a25b1194]{margin-top:4px}.feedback-comment:open~.collapsed-comment[data-v-a25b1194]{display:none}.collapsed-comment[data-v-a25b1194]{display:-webkit-box;line-clamp:2;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis}.feedback-meta[data-v-a25b1194]{margin-top:8px}.detail-item-title[data-v-a25b1194]{font-size:.75rem;cursor:pointer;color:var(--color-text-3)}.feedback-meta-content[data-v-a25b1194]{font-size:.875rem;padding:8px;margin-top:4px;border-radius:var(--radius-m);background:var(--color-card-bg-dark)}.trace-list-area[data-v-4fb29a7e]{width:100%;flex:1;overflow-y:auto}.trace-list[data-v-4fb29a7e]{display:flex;flex-direction:column;padding:12px 16px}.empty-state[data-v-4fb29a7e]{width:100%;align-self:center}.trace-item-divider[data-v-4fb29a7e]{margin:16px 0}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as u}from"./js-yaml-yTPt38rv.js";import{f as b}from"./element-ui-D3x2y3TA.js";import{r as T}from"./highlightjs-D4ATuRwX.js";import{v as R,c as d,x as p,y as A,B as O}from"./vue-core-DL-LgTX0.js";var C=T();const i=b(C);function S(e){const n={className:"attr",begin:/"(\\.|[^\\"\r\n])*"(?=\s*:)/,relevance:1.01},t={match:/[{}[\],:]/,className:"punctuation",relevance:0},a=["true","false","null"],s={scope:"literal",beginKeywords:a.join(" ")};return{name:"JSON",aliases:["jsonc"],keywords:{literal:a},contains:[n,t,e.QUOTE_STRING_MODE,s,e.C_NUMBER_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE],illegal:"\\S"}}function v(e){const n="true false yes no null",t="[\\w#;/?:@&=+$,.~*'()[\\]]+",a={className:"attr",variants:[{begin:/[\w*@][\w*@ :()\./-]*:(?=[ \t]|$)/},{begin:/"[\w*@][\w*@ :()\./-]*":(?=[ \t]|$)/},{begin:/'[\w*@][\w*@ :()\./-]*':(?=[ \t]|$)/}]},s={className:"template-variable",variants:[{begin:/\{\{/,end:/\}\}/},{begin:/%\{/,end:/\}/}]},E={className:"string",relevance:0,begin:/'/,end:/'/,contains:[{match:/''/,scope:"char.escape",relevance:0}]},o={className:"string",relevance:0,variants:[{begin:/"/,end:/"/},{begin:/\S+/}],contains:[e.BACKSLASH_ESCAPE,s]},g=e.inherit(o,{variants:[{begin:/'/,end:/'/,contains:[{begin:/''/,relevance:0}]},{begin:/"/,end:/"/},{begin:/[^\s,{}[\]]+/}]}),m={className:"number",begin:"\\b"+"[0-9]{4}(-[0-9][0-9]){0,2}"+"([Tt \\t][0-9][0-9]?(:[0-9][0-9]){2})?"+"(\\.[0-9]*)?"+"([ \\t])*(Z|[-+][0-9][0-9]?(:[0-9][0-9])?)?"+"\\b"},c={end:",",endsWithParent:!0,excludeEnd:!0,keywords:n,relevance:0},_={begin:/\{/,end:/\}/,contains:[c],illegal:"\\n",relevance:0},N={begin:"\\[",end:"\\]",contains:[c],illegal:"\\n",relevance:0},l=[a,{className:"meta",begin:"^---\\s*$",relevance:10},{className:"string",begin:"[\\|>]([1-9]?[+-])?[ ]*\\n( +)[^ ][^\\n]*\\n(\\2[^\\n]+\\n?)*"},{begin:"<%[%=-]?",end:"[%-]?%>",subLanguage:"ruby",excludeBegin:!0,excludeEnd:!0,relevance:0},{className:"type",begin:"!\\w+!"+t},{className:"type",begin:"!<"+t+">"},{className:"type",begin:"!"+t},{className:"type",begin:"!!"+t},{className:"meta",begin:"&"+e.UNDERSCORE_IDENT_RE+"$"},{className:"meta",begin:"\\*"+e.UNDERSCORE_IDENT_RE+"$"},{className:"bullet",begin:"-(?=[ ]|$)",relevance:0},e.HASH_COMMENT_MODE,{beginKeywords:n,keywords:{literal:n}},m,{className:"number",begin:e.C_NUMBER_RE+"\\b",relevance:0},_,N,E,o],r=[...l];return r.pop(),r.push(g),c.contains=r,{name:"YAML",case_insensitive:!0,aliases:["yml"],contains:l}}i.registerLanguage("json",S);i.registerLanguage("yaml",v);const M={class:"code-viewer"},I=["lang","innerHTML"],$=R({__name:"FormattedCodeViewer",props:{lang:{},content:{}},setup(e){const n=e,t=d(()=>{let a="";try{return n.lang==="yaml"?a=u.dump(n.content,{indent:2}):a=JSON.stringify(n.content,null,2),i.highlight(a,{language:n.lang||"json"}).value}catch{return a}});return(a,s)=>(A(),p("pre",M,[O("code",{lang:n.lang||"json",innerHTML:t.value},null,8,I)]))}});export{$ as _};
|