coze_lab 0.1.46 → 0.1.48
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.
package/package.json
CHANGED
|
@@ -107,6 +107,36 @@ _OTEL_SUFFIX = "/v1/loop/opentelemetry"
|
|
|
107
107
|
_DEFAULT_WORKSPACE_ID = "7649231955045072915" # hardcoded spaceID fallback
|
|
108
108
|
|
|
109
109
|
|
|
110
|
+
def _normalize_api_base_url(raw: str) -> str:
|
|
111
|
+
"""Normalize CozeLoop API/OTLP endpoint env vars to the SDK api_base_url."""
|
|
112
|
+
base = (raw or "").strip().rstrip("/")
|
|
113
|
+
if not base:
|
|
114
|
+
return ""
|
|
115
|
+
suffixes = [
|
|
116
|
+
"/api/v1/loop/traces/ingest",
|
|
117
|
+
"/v1/loop/traces/ingest",
|
|
118
|
+
"/api/v1/loop/opentelemetry/v1/traces",
|
|
119
|
+
"/v1/loop/opentelemetry/v1/traces",
|
|
120
|
+
"/api/v1/loop/opentelemetry",
|
|
121
|
+
"/v1/loop/opentelemetry",
|
|
122
|
+
"/api/v1",
|
|
123
|
+
"/v1",
|
|
124
|
+
]
|
|
125
|
+
for suffix in suffixes:
|
|
126
|
+
if base.endswith(suffix):
|
|
127
|
+
return base[:-len(suffix)].rstrip("/")
|
|
128
|
+
return base
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def get_api_base_url() -> str:
|
|
132
|
+
"""Return optional CozeLoop SDK api_base_url from onboard-injected env."""
|
|
133
|
+
return _normalize_api_base_url(
|
|
134
|
+
os.environ.get("COZELOOP_API_BASE_URL")
|
|
135
|
+
or os.environ.get("OTEL_ENDPOINT")
|
|
136
|
+
or ""
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
|
|
110
140
|
# --- coze-context parsing -------------------------------------------------
|
|
111
141
|
# User messages may embed a block like:
|
|
112
142
|
# <coze-context>
|
|
@@ -1442,7 +1472,12 @@ def send_steps_realtime(turns, session_id, history_turns, state, coze_tags_overr
|
|
|
1442
1472
|
if token:
|
|
1443
1473
|
os.environ["COZELOOP_API_TOKEN"] = token
|
|
1444
1474
|
workspace_id = os.environ.get("COZELOOP_WORKSPACE_ID", "") or _DEFAULT_WORKSPACE_ID
|
|
1445
|
-
|
|
1475
|
+
upload_events: List[str] = []
|
|
1476
|
+
client_kwargs = {
|
|
1477
|
+
"ultra_large_report": True,
|
|
1478
|
+
"upload_timeout": 120,
|
|
1479
|
+
"trace_finish_event_processor": _make_finish_event_processor(upload_events),
|
|
1480
|
+
}
|
|
1446
1481
|
if workspace_id:
|
|
1447
1482
|
client_kwargs["workspace_id"] = workspace_id
|
|
1448
1483
|
if token:
|
|
@@ -1509,6 +1544,9 @@ def send_steps_realtime(turns, session_id, history_turns, state, coze_tags_overr
|
|
|
1509
1544
|
# 实测:root finish 后,子 span 仍可用其 header 挂到同一 trace_id 下,不影响后续增量。
|
|
1510
1545
|
root_span.finish()
|
|
1511
1546
|
client.flush()
|
|
1547
|
+
if upload_events:
|
|
1548
|
+
debug_log(f"[rt] upload failed after root flush: {upload_events[-1][:500]}")
|
|
1549
|
+
return None
|
|
1512
1550
|
debug_log(f"[rt] root created+finished trace_id={getattr(root_ctx,'trace_id','?')}")
|
|
1513
1551
|
|
|
1514
1552
|
# ---- 发新完成的 step ----
|
|
@@ -1592,6 +1630,9 @@ def send_steps_realtime(turns, session_id, history_turns, state, coze_tags_overr
|
|
|
1592
1630
|
sent += 1
|
|
1593
1631
|
# 每个 step 立即 flush —— 这是“结束即可见”的关键。
|
|
1594
1632
|
client.flush()
|
|
1633
|
+
if upload_events:
|
|
1634
|
+
debug_log(f"[rt] upload failed after step flush: {upload_events[-1][:500]}")
|
|
1635
|
+
return None
|
|
1595
1636
|
|
|
1596
1637
|
new_last = last_global + sent
|
|
1597
1638
|
state["rt_last_global_step"] = new_last
|
|
@@ -1620,8 +1661,15 @@ def send_steps_realtime(turns, session_id, history_turns, state, coze_tags_overr
|
|
|
1620
1661
|
fin.set_output(last_output)
|
|
1621
1662
|
fin.finish()
|
|
1622
1663
|
client.flush()
|
|
1664
|
+
if upload_events:
|
|
1665
|
+
debug_log(f"[rt] upload failed after final flush: {upload_events[-1][:500]}")
|
|
1666
|
+
return None
|
|
1623
1667
|
debug_log(f"[rt] finalized, total sent steps={new_last}")
|
|
1624
1668
|
|
|
1669
|
+
if upload_events:
|
|
1670
|
+
debug_log(f"[rt] upload failed, state not advanced. Last failure: {upload_events[-1][:500]}")
|
|
1671
|
+
return None
|
|
1672
|
+
|
|
1625
1673
|
debug_log(f"[rt] sent {sent} new step(s), last_global={new_last}/{total_steps}, terminal={is_terminal}")
|
|
1626
1674
|
return True
|
|
1627
1675
|
except Exception as e:
|
|
@@ -133,6 +133,36 @@ else:
|
|
|
133
133
|
DEBUG = os.environ.get("CC_COZELOOP_DEBUG", "").lower() == "true"
|
|
134
134
|
|
|
135
135
|
|
|
136
|
+
def _normalize_api_base_url(raw: str) -> str:
|
|
137
|
+
"""Normalize CozeLoop API/OTLP endpoint env vars to the SDK api_base_url."""
|
|
138
|
+
base = (raw or "").strip().rstrip("/")
|
|
139
|
+
if not base:
|
|
140
|
+
return ""
|
|
141
|
+
suffixes = [
|
|
142
|
+
"/api/v1/loop/traces/ingest",
|
|
143
|
+
"/v1/loop/traces/ingest",
|
|
144
|
+
"/api/v1/loop/opentelemetry/v1/traces",
|
|
145
|
+
"/v1/loop/opentelemetry/v1/traces",
|
|
146
|
+
"/api/v1/loop/opentelemetry",
|
|
147
|
+
"/v1/loop/opentelemetry",
|
|
148
|
+
"/api/v1",
|
|
149
|
+
"/v1",
|
|
150
|
+
]
|
|
151
|
+
for suffix in suffixes:
|
|
152
|
+
if base.endswith(suffix):
|
|
153
|
+
return base[:-len(suffix)].rstrip("/")
|
|
154
|
+
return base
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def get_api_base_url() -> str:
|
|
158
|
+
"""Return optional CozeLoop SDK api_base_url from onboard-injected env."""
|
|
159
|
+
return _normalize_api_base_url(
|
|
160
|
+
os.environ.get("COZELOOP_API_BASE_URL")
|
|
161
|
+
or os.environ.get("OTEL_ENDPOINT")
|
|
162
|
+
or ""
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
|
|
136
166
|
def _log_file_path() -> str:
|
|
137
167
|
return os.environ.get("COZELOOP_HOOK_LOG", "").strip()
|
|
138
168
|
|
|
@@ -1221,7 +1251,12 @@ def send_steps_realtime(turns, session_id, state, model_name="codex", coze_tags_
|
|
|
1221
1251
|
if token:
|
|
1222
1252
|
os.environ["COZELOOP_API_TOKEN"] = token
|
|
1223
1253
|
workspace_id = os.environ.get("COZELOOP_WORKSPACE_ID", "") or _DEFAULT_WORKSPACE_ID
|
|
1224
|
-
|
|
1254
|
+
upload_events: List[str] = []
|
|
1255
|
+
client_kwargs = {
|
|
1256
|
+
"ultra_large_report": True,
|
|
1257
|
+
"upload_timeout": 120,
|
|
1258
|
+
"trace_finish_event_processor": _make_finish_event_processor(upload_events),
|
|
1259
|
+
}
|
|
1225
1260
|
if workspace_id:
|
|
1226
1261
|
client_kwargs["workspace_id"] = workspace_id
|
|
1227
1262
|
if token:
|
|
@@ -1277,6 +1312,9 @@ def send_steps_realtime(turns, session_id, state, model_name="codex", coze_tags_
|
|
|
1277
1312
|
root_ctx = client.get_span_from_header(state["rt_root_header"])
|
|
1278
1313
|
root_span.finish() # 立即 finish 落库(后端按 root_span 查),子 span 仍可挂同 trace
|
|
1279
1314
|
client.flush()
|
|
1315
|
+
if upload_events:
|
|
1316
|
+
hook_log(f"[rt] upload failed after root flush detail={upload_events[-1][:500]}")
|
|
1317
|
+
return None
|
|
1280
1318
|
hook_log(f"[rt] root created trace_id={getattr(root_ctx,'trace_id','?')}")
|
|
1281
1319
|
|
|
1282
1320
|
# 线性展开所有 tool_call(带 result 的才算完成),按全局序增量发
|
|
@@ -1331,6 +1369,9 @@ def send_steps_realtime(turns, session_id, state, model_name="codex", coze_tags_
|
|
|
1331
1369
|
tspan.finish()
|
|
1332
1370
|
sent += 1
|
|
1333
1371
|
client.flush() # 每个 tool_call 立即 flush → 结束即可见
|
|
1372
|
+
if upload_events:
|
|
1373
|
+
hook_log(f"[rt] upload failed after tool flush detail={upload_events[-1][:500]}")
|
|
1374
|
+
return None
|
|
1334
1375
|
|
|
1335
1376
|
state["rt_last_tool"] = last_tool + sent
|
|
1336
1377
|
if sent > 0:
|
|
@@ -1352,8 +1393,15 @@ def send_steps_realtime(turns, session_id, state, model_name="codex", coze_tags_
|
|
|
1352
1393
|
fin.set_output(truncate_text(last_out))
|
|
1353
1394
|
fin.finish()
|
|
1354
1395
|
client.flush()
|
|
1396
|
+
if upload_events:
|
|
1397
|
+
hook_log(f"[rt] upload failed after final flush detail={upload_events[-1][:500]}")
|
|
1398
|
+
return None
|
|
1355
1399
|
hook_log(f"[rt] finalized total_tools={state['rt_last_tool']}")
|
|
1356
1400
|
|
|
1401
|
+
if upload_events:
|
|
1402
|
+
hook_log(f"[rt] upload failed state not advanced detail={upload_events[-1][:500]}")
|
|
1403
|
+
return None
|
|
1404
|
+
|
|
1357
1405
|
hook_log(f"[rt] sent {sent} tool span(s), last_tool={state['rt_last_tool']}, terminal={is_terminal}")
|
|
1358
1406
|
return True
|
|
1359
1407
|
except Exception as e:
|