coze_lab 0.1.18 → 0.1.19

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
@@ -4464,6 +4464,10 @@ function mergeJson(filepath, mergeFn) {
4464
4464
  return mergeFn(existing);
4465
4465
  }
4466
4466
 
4467
+ function shellEnvLine(key, value) {
4468
+ return `${key}='${String(value).replace(/'/g, `'\\''`)}'`;
4469
+ }
4470
+
4467
4471
  // writeClaudeCodeHook 配置 Claude Code 的 hook。
4468
4472
  // configBaseDir 缺省 process.cwd()(全局/项目级);传入 agent 的 workspace 则 per-agent:
4469
4473
  // settings.json + 凭证写进 <configBaseDir>/.claude,仅该 agent(以此为 cwd 启动)生效。
@@ -4565,24 +4569,29 @@ function writeCodexHook(token, workspaceId, pythonCmd, codexHome, cloud) {
4565
4569
  writeHookScript(refreshScript, readScript('shared/cozeloop_refresh.py'));
4566
4570
 
4567
4571
  // 2. Write env file with chmod 600
4568
- // 云端(cloud):不落明文 token,hook 运行时从环境变量 COZE_API_TOKEN 读取。
4569
4572
  const envLines = [
4570
- `COZELOOP_WORKSPACE_ID=${workspaceId}`,
4573
+ shellEnvLine('COZELOOP_WORKSPACE_ID', workspaceId),
4571
4574
  ];
4572
- if (!cloud) {
4573
- envLines.push(`COZELOOP_API_TOKEN=${token}`);
4575
+ if (cloud) {
4576
+ if (process.env.COZELOOP_API_TOKEN) {
4577
+ envLines.push(shellEnvLine('COZELOOP_API_TOKEN', process.env.COZELOOP_API_TOKEN));
4578
+ } else if (process.env.COZE_API_TOKEN) {
4579
+ envLines.push(shellEnvLine('COZE_API_TOKEN', process.env.COZE_API_TOKEN));
4580
+ }
4581
+ } else {
4582
+ envLines.push(shellEnvLine('COZELOOP_API_TOKEN', token));
4574
4583
  }
4575
- envLines.push(`CODEX_HOME=${home}`);
4576
- envLines.push(`COZELOOP_HOOK_LOG=${logFile}`);
4584
+ envLines.push(shellEnvLine('CODEX_HOME', home));
4585
+ envLines.push(shellEnvLine('COZELOOP_HOOK_LOG', logFile));
4577
4586
  envLines.push('TRACE_TO_COZELOOP=true');
4578
4587
  if (process.env.COZELOOP_API_BASE_URL) {
4579
- envLines.push(`COZELOOP_API_BASE_URL=${process.env.COZELOOP_API_BASE_URL}`);
4588
+ envLines.push(shellEnvLine('COZELOOP_API_BASE_URL', process.env.COZELOOP_API_BASE_URL));
4580
4589
  } else if (process.env.OTEL_ENDPOINT) {
4581
- envLines.push(`OTEL_ENDPOINT=${process.env.OTEL_ENDPOINT}`);
4590
+ envLines.push(shellEnvLine('OTEL_ENDPOINT', process.env.OTEL_ENDPOINT));
4582
4591
  }
4583
4592
  // PPE 泳道:cozeloop SDK 读这两个环境变量,自动注入 x-tt-env / x-use-ppe header
4584
- envLines.push(`x_tt_env=${PPE_TT_ENV}`);
4585
- envLines.push(`x_use_ppe=${PPE_USE_PPE}`);
4593
+ envLines.push(shellEnvLine('x_tt_env', PPE_TT_ENV));
4594
+ envLines.push(shellEnvLine('x_use_ppe', PPE_USE_PPE));
4586
4595
  const envContent = envLines.join('\n') + '\n';
4587
4596
  try {
4588
4597
  fs.writeFileSync(envFile, envContent, { mode: 0o600 });
@@ -4666,6 +4675,11 @@ function getOpenClawEndpoint(cloud) {
4666
4675
  : 'https://api.coze.cn/v1/loop/opentelemetry';
4667
4676
  }
4668
4677
 
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;
4681
+ }
4682
+
4669
4683
  function applyOpenClawPluginConfig(existing, token, workspaceId, agentId, cloud) {
4670
4684
  if (!existing.plugins) existing.plugins = {};
4671
4685
  if (!existing.plugins.allow) existing.plugins.allow = [];
@@ -4820,7 +4834,7 @@ function httpsPost(url, body, extraHeaders) {
4820
4834
  const data = JSON.stringify(body);
4821
4835
  const u = new URL(url);
4822
4836
  const req = https.request(
4823
- { hostname: u.hostname, path: u.pathname + u.search, method: 'POST',
4837
+ { hostname: u.hostname, port: u.port || undefined, path: u.pathname + u.search, method: 'POST',
4824
4838
  headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(data),
4825
4839
  'x-tt-env': PPE_TT_ENV, 'x-use-ppe': PPE_USE_PPE,
4826
4840
  ...(extraHeaders || {}) } },
@@ -5230,7 +5244,7 @@ async function main() {
5230
5244
  info('验证 trace 上报链路...');
5231
5245
  const token = await getValidToken(); // 无凭证会自动走登录/刷新
5232
5246
  console.log('');
5233
- const result = await verifyTraceReport(token, WORKSPACE_ID, args.pairCode, process.env.COZELOOP_API_BASE_URL || undefined);
5247
+ const result = await verifyTraceReport(token, WORKSPACE_ID, args.pairCode, getCloudCozeloopBaseUrl());
5234
5248
  process.exit(result.success ? 0 : 1);
5235
5249
  }
5236
5250
 
@@ -5352,7 +5366,7 @@ async function main() {
5352
5366
 
5353
5367
  // Step 5: Verify trace reporting end-to-end
5354
5368
  info('Step 5/5: 验证 trace 上报链路...');
5355
- const verifyResult = await verifyTraceReport(token, WORKSPACE_ID, args.pairCode, args.cloud ? process.env.COZELOOP_API_BASE_URL : undefined);
5369
+ const verifyResult = await verifyTraceReport(token, WORKSPACE_ID, args.pairCode, args.cloud ? getCloudCozeloopBaseUrl() : undefined);
5356
5370
  if (verifyResult.success) {
5357
5371
  cloudResult.verify = 'ok';
5358
5372
  } else if (CLOUD_MODE) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coze_lab",
3
- "version": "0.1.18",
3
+ "version": "0.1.19",
4
4
  "description": "Configure local AI agents (Claude Code, Codex, OpenClaw) to report traces to CozeLoop",
5
5
  "keywords": [
6
6
  "cozeloop",
@@ -850,7 +850,12 @@ def send_turns_to_cozeloop(turns: List[Dict[str, Any]], session_id: str, model_n
850
850
  hook_log(f"token resolved prefix={token[:12]}...")
851
851
  print(f"[CozeLoop] Token 获取成功 ({token[:12]}...)", file=sys.stderr)
852
852
  else:
853
- hook_log("token missing")
853
+ hook_log(
854
+ "token missing "
855
+ f"has_cozeloop_token={bool(os.environ.get('COZELOOP_API_TOKEN'))} "
856
+ f"has_coze_token={bool(os.environ.get('COZE_API_TOKEN'))} "
857
+ f"api_base_url={bool(get_api_base_url())}"
858
+ )
854
859
  print("[CozeLoop] 警告: 未找到有效 Token,上报可能失败", file=sys.stderr)
855
860
  creds = _load_credentials()
856
861
  workspace_id = (creds or {}).get("workspace_id") or os.environ.get("COZELOOP_WORKSPACE_ID", "") or _DEFAULT_WORKSPACE_ID