coze_lab 0.1.19 → 0.1.21

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/index.js CHANGED
@@ -9,6 +9,7 @@ const PPE_TT_ENV = 'ppe_cozelab';
9
9
  const PPE_USE_PPE = '1';
10
10
  const COZE_API = 'https://api.coze.cn';
11
11
  const CREDS_PATH = require('path').join(require('os').homedir(), '.cozeloop', 'credentials.json');
12
+ const PACKAGE_VERSION = require('./package.json').version;
12
13
  // Refresh when less than 10 minutes remain
13
14
  const REFRESH_THRESHOLD_MS = 10 * 60 * 1000;
14
15
 
@@ -16,7 +17,7 @@ const REFRESH_THRESHOLD_MS = 10 * 60 * 1000;
16
17
  // 云端(--cloud)模式:在 stdout 输出一行机器可读结果 COZE_LAB_RESULT={...},
17
18
  // 供管理后台解析判定(inject/verify/logid/message),不依赖中文文案。
18
19
  let CLOUD_MODE = false;
19
- const cloudResult = { inject: 'skip', verify: 'skip', logid: '', message: '' };
20
+ const cloudResult = { version: PACKAGE_VERSION, inject: 'skip', verify: 'skip', logid: '', message: '' };
20
21
 
21
22
  // errorBox 在云端模式下抛此异常(而非 process.exit),由 main 外层统一收尾。
22
23
  class CloudAbort extends Error {}
@@ -4669,15 +4670,38 @@ function normalizeTraceAgentIds(ids) {
4669
4670
  .filter(Boolean);
4670
4671
  }
4671
4672
 
4672
- function getOpenClawEndpoint(cloud) {
4673
- return (cloud && process.env.COZELOOP_API_BASE_URL)
4674
- ? process.env.COZELOOP_API_BASE_URL.replace(/\/+$/, '') + '/v1/loop/opentelemetry'
4675
- : 'https://api.coze.cn/v1/loop/opentelemetry';
4673
+ function getCloudCozeloopApiBaseUrl() {
4674
+ const raw = process.env.COZELOOP_API_BASE_URL || process.env.OTEL_ENDPOINT || '';
4675
+ const base = raw.trim().replace(/\/+$/, '');
4676
+ if (!base) return '';
4677
+ if (base.endsWith('/v1/loop/opentelemetry/v1/traces')) {
4678
+ return base.slice(0, -'/v1/loop/opentelemetry/v1/traces'.length).replace(/\/+$/, '');
4679
+ }
4680
+ if (base.endsWith('/api/v1/loop/opentelemetry/v1/traces')) {
4681
+ return base.slice(0, -'/v1/loop/opentelemetry/v1/traces'.length).replace(/\/+$/, '');
4682
+ }
4683
+ if (base.endsWith('/v1/loop/opentelemetry')) {
4684
+ return base.slice(0, -'/v1/loop/opentelemetry'.length).replace(/\/+$/, '');
4685
+ }
4686
+ if (base.endsWith('/api/v1/loop/opentelemetry')) {
4687
+ return base.slice(0, -'/loop/opentelemetry'.length).replace(/\/+$/, '');
4688
+ }
4689
+ if (base.endsWith('/api/v1')) {
4690
+ return base.slice(0, -'/v1'.length).replace(/\/+$/, '');
4691
+ }
4692
+ return base;
4693
+ }
4694
+
4695
+ function getCozeloopApiBaseUrl(cloud) {
4696
+ return cloud ? (getCloudCozeloopApiBaseUrl() || COZE_API) : COZE_API;
4697
+ }
4698
+
4699
+ function getOtelEndpointBase(cloud) {
4700
+ return `${getCozeloopApiBaseUrl(cloud).replace(/\/+$/, '')}/v1/loop/opentelemetry`;
4676
4701
  }
4677
4702
 
4678
- function getCloudCozeloopBaseUrl() {
4679
- const endpoint = process.env.COZELOOP_API_BASE_URL || process.env.OTEL_ENDPOINT || '';
4680
- return endpoint.replace(/\/v1\/loop\/opentelemetry\/?$/, '').replace(/\/+$/, '') || undefined;
4703
+ function getOtelTracesUrl(cloud) {
4704
+ return `${getOtelEndpointBase(cloud).replace(/\/+$/, '')}/v1/traces`;
4681
4705
  }
4682
4706
 
4683
4707
  function applyOpenClawPluginConfig(existing, token, workspaceId, agentId, cloud) {
@@ -4699,7 +4723,7 @@ function applyOpenClawPluginConfig(existing, token, workspaceId, agentId, cloud)
4699
4723
  if (!existing.plugins.entries[PLUGIN].config) existing.plugins.entries[PLUGIN].config = {};
4700
4724
  const pcfg = existing.plugins.entries[PLUGIN].config;
4701
4725
  pcfg.authorization = `Bearer ${token}`;
4702
- pcfg.endpoint = getOpenClawEndpoint(cloud);
4726
+ pcfg.endpoint = getOtelEndpointBase(cloud);
4703
4727
  pcfg.workspaceId = workspaceId;
4704
4728
  pcfg.debug = true;
4705
4729
  // per-agent trace 放行:把当前 agentId 并入 traceAgentIds(去重、归一为小写,
@@ -4855,7 +4879,7 @@ function httpsPost(url, body, extraHeaders) {
4855
4879
  // 只看 HTTP 状态码(2xx=通),不回查 trace 是否落库——回查由外部查询方完成。
4856
4880
  // pairCode 写进 span 的 pair_code attribute,供查询方按该字段过滤回查;缺省自动生成。
4857
4881
  // 不在函数内退出,退出行为交给调用方(主流程 Step 6 / 独立命令 --verify)。
4858
- async function verifyTraceReport(token, workspaceId, pairCode, baseUrl) {
4882
+ async function verifyTraceReport(token, workspaceId, pairCode, tracesUrl) {
4859
4883
  const traceId = crypto.randomBytes(16).toString('hex'); // 32 hex chars
4860
4884
  const spanId = crypto.randomBytes(8).toString('hex'); // 16 hex chars
4861
4885
  const nowNs = String(Date.now() * 1_000_000); // OTLP 要求纳秒 unix 时间(字符串)
@@ -4888,12 +4912,10 @@ async function verifyTraceReport(token, workspaceId, pairCode, baseUrl) {
4888
4912
  };
4889
4913
 
4890
4914
  let res;
4891
- // 云端:上报走 sandbox 注入的 COZELOOP_API_BASE_URL 代理(vefaas token 经它鉴权转换);
4892
- // 缺省回退到 api.coze.cn 直连。base 已去尾部斜杠。
4893
- const apiBase = (baseUrl || COZE_API).replace(/\/+$/, '');
4915
+ const url = tracesUrl || getOtelTracesUrl(false);
4894
4916
  try {
4895
4917
  res = await httpsPost(
4896
- `${apiBase}/v1/loop/opentelemetry/v1/traces`,
4918
+ url,
4897
4919
  otlpBody,
4898
4920
  { Authorization: `Bearer ${token}`, 'cozeloop-workspace-id': workspaceId },
4899
4921
  );
@@ -5180,7 +5202,7 @@ const NEXT_STEP = {
5180
5202
 
5181
5203
  async function main() {
5182
5204
  console.log('');
5183
- info('CozeLoop Onboard CLI starting...');
5205
+ info(`CozeLoop Onboard CLI starting... (coze_lab v${PACKAGE_VERSION})`);
5184
5206
  console.log('');
5185
5207
 
5186
5208
  const args = validateArgs(parseArgs());
@@ -5244,7 +5266,7 @@ async function main() {
5244
5266
  info('验证 trace 上报链路...');
5245
5267
  const token = await getValidToken(); // 无凭证会自动走登录/刷新
5246
5268
  console.log('');
5247
- const result = await verifyTraceReport(token, WORKSPACE_ID, args.pairCode, getCloudCozeloopBaseUrl());
5269
+ const result = await verifyTraceReport(token, WORKSPACE_ID, args.pairCode, getOtelTracesUrl(false));
5248
5270
  process.exit(result.success ? 0 : 1);
5249
5271
  }
5250
5272
 
@@ -5336,6 +5358,7 @@ async function main() {
5336
5358
 
5337
5359
  // Success summary(用实际写入路径,per-agent / 自定义 CODEX_HOME 时也准确)
5338
5360
  const summaryLines = [
5361
+ `Onboard: coze_lab v${PACKAGE_VERSION}`,
5339
5362
  `Agent: ${agent} v${version}`,
5340
5363
  ];
5341
5364
  if (args.agentId) summaryLines.push(`Agent ID: ${args.agentId}`);
@@ -5366,7 +5389,7 @@ async function main() {
5366
5389
 
5367
5390
  // Step 5: Verify trace reporting end-to-end
5368
5391
  info('Step 5/5: 验证 trace 上报链路...');
5369
- const verifyResult = await verifyTraceReport(token, WORKSPACE_ID, args.pairCode, args.cloud ? getCloudCozeloopBaseUrl() : undefined);
5392
+ const verifyResult = await verifyTraceReport(token, WORKSPACE_ID, args.pairCode, getOtelTracesUrl(args.cloud));
5370
5393
  if (verifyResult.success) {
5371
5394
  cloudResult.verify = 'ok';
5372
5395
  } else if (CLOUD_MODE) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coze_lab",
3
- "version": "0.1.19",
3
+ "version": "0.1.21",
4
4
  "description": "Configure local AI agents (Claude Code, Codex, OpenClaw) to report traces to CozeLoop",
5
5
  "keywords": [
6
6
  "cozeloop",
@@ -210,8 +210,16 @@ def _refresh_token(refresh_tok: str):
210
210
 
211
211
  def _normalize_api_base_url(url: str) -> str:
212
212
  base = (url or "").strip().rstrip("/")
213
+ if base.endswith(_OTEL_SUFFIX + "/v1/traces"):
214
+ return base[:-len(_OTEL_SUFFIX + "/v1/traces")].rstrip("/")
215
+ if base.endswith("/api/v1/loop/opentelemetry/v1/traces"):
216
+ return base[:-len("/v1/loop/opentelemetry/v1/traces")].rstrip("/")
213
217
  if base.endswith(_OTEL_SUFFIX):
214
218
  return base[:-len(_OTEL_SUFFIX)].rstrip("/")
219
+ if base.endswith("/api/v1/loop/opentelemetry"):
220
+ return base[:-len("/v1/loop/opentelemetry")].rstrip("/")
221
+ if base.endswith("/api/v1"):
222
+ return base[:-len("/v1")].rstrip("/")
215
223
  return base
216
224
 
217
225