coze_lab 0.1.13 → 0.1.14
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 +93 -44
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -4622,19 +4622,107 @@ function writeCodexHook(token, workspaceId, pythonCmd, codexHome, cloud) {
|
|
|
4622
4622
|
// agentId 非空时并入 plugins.entries[...].config.traceAgentIds allowlist —— 插件运行时
|
|
4623
4623
|
// 用 resolveAgentIdFromHookCtx 取当前 agentId,仅 allowlist 内的 agent 才上报 trace。
|
|
4624
4624
|
// allowlist 为空(本地全局模式)= 全部放行,向后兼容。
|
|
4625
|
+
// resolveHomeDir 解析 home 目录。云端 SandboxShellExec 执行环境的 $HOME 可能缺失/不一致,
|
|
4626
|
+
// 导致 os.homedir() 解析不到真实 home(如 /root)。云端模式下做兜底探测。
|
|
4627
|
+
function resolveHomeDir(cloud) {
|
|
4628
|
+
const h = os.homedir();
|
|
4629
|
+
if (!cloud) return h;
|
|
4630
|
+
// 优先 $HOME,其次 os.homedir(),再回退云端常见 root home。
|
|
4631
|
+
const candidates = [process.env.HOME, h, '/root'].filter(Boolean);
|
|
4632
|
+
for (const c of candidates) {
|
|
4633
|
+
try {
|
|
4634
|
+
if (fs.existsSync(path.join(c, '.coze')) || fs.existsSync(path.join(c, '.openclaw'))) {
|
|
4635
|
+
return c;
|
|
4636
|
+
}
|
|
4637
|
+
} catch { /* ignore */ }
|
|
4638
|
+
}
|
|
4639
|
+
return h || '/root';
|
|
4640
|
+
}
|
|
4641
|
+
|
|
4642
|
+
function normalizeTraceAgentIds(ids) {
|
|
4643
|
+
return (Array.isArray(ids) ? ids : [])
|
|
4644
|
+
.map((s) => String(s).trim().toLowerCase())
|
|
4645
|
+
.filter(Boolean);
|
|
4646
|
+
}
|
|
4647
|
+
|
|
4648
|
+
function getOpenClawEndpoint(cloud) {
|
|
4649
|
+
return (cloud && process.env.COZELOOP_API_BASE_URL)
|
|
4650
|
+
? process.env.COZELOOP_API_BASE_URL.replace(/\/+$/, '') + '/v1/loop/opentelemetry'
|
|
4651
|
+
: 'https://api.coze.cn/v1/loop/opentelemetry';
|
|
4652
|
+
}
|
|
4653
|
+
|
|
4654
|
+
function applyOpenClawPluginConfig(existing, token, workspaceId, agentId, cloud) {
|
|
4655
|
+
if (!existing.plugins) existing.plugins = {};
|
|
4656
|
+
if (!existing.plugins.allow) existing.plugins.allow = [];
|
|
4657
|
+
if (!existing.plugins.entries) existing.plugins.entries = {};
|
|
4658
|
+
|
|
4659
|
+
const PLUGIN = 'openclaw-cozeloop-trace';
|
|
4660
|
+
if (!existing.plugins.allow.includes(PLUGIN)) {
|
|
4661
|
+
existing.plugins.allow.push(PLUGIN);
|
|
4662
|
+
}
|
|
4663
|
+
// Preserve existing entry structure, only update config.
|
|
4664
|
+
if (!existing.plugins.entries[PLUGIN]) {
|
|
4665
|
+
existing.plugins.entries[PLUGIN] = { enabled: true };
|
|
4666
|
+
}
|
|
4667
|
+
existing.plugins.entries[PLUGIN].enabled = true;
|
|
4668
|
+
// hooks.allowConversationAccess required for 2026.5+ to access session content.
|
|
4669
|
+
existing.plugins.entries[PLUGIN].hooks = { allowConversationAccess: true };
|
|
4670
|
+
if (!existing.plugins.entries[PLUGIN].config) existing.plugins.entries[PLUGIN].config = {};
|
|
4671
|
+
const pcfg = existing.plugins.entries[PLUGIN].config;
|
|
4672
|
+
pcfg.authorization = `Bearer ${token}`;
|
|
4673
|
+
pcfg.endpoint = getOpenClawEndpoint(cloud);
|
|
4674
|
+
pcfg.workspaceId = workspaceId;
|
|
4675
|
+
pcfg.debug = true;
|
|
4676
|
+
// per-agent trace 放行:把当前 agentId 并入 traceAgentIds(去重、归一为小写,
|
|
4677
|
+
// 与插件侧 resolveAgentIdFromHookCtx 的归一一致)。无 agentId(全局模式)则不动
|
|
4678
|
+
// allowlist —— 空 allowlist 表示全部放行。
|
|
4679
|
+
if (agentId) {
|
|
4680
|
+
const norm = String(agentId).trim().toLowerCase();
|
|
4681
|
+
const list = normalizeTraceAgentIds(pcfg.traceAgentIds);
|
|
4682
|
+
if (norm && !list.includes(norm)) list.push(norm);
|
|
4683
|
+
pcfg.traceAgentIds = list;
|
|
4684
|
+
}
|
|
4685
|
+
return existing;
|
|
4686
|
+
}
|
|
4687
|
+
|
|
4688
|
+
function isOpenClawAlreadyInjected(configPath, pluginDir, token, workspaceId, agentId, cloud) {
|
|
4689
|
+
if (!fs.existsSync(pluginDir)) return false;
|
|
4690
|
+
let existing;
|
|
4691
|
+
try {
|
|
4692
|
+
existing = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
4693
|
+
} catch {
|
|
4694
|
+
return false;
|
|
4695
|
+
}
|
|
4696
|
+
const desired = applyOpenClawPluginConfig(
|
|
4697
|
+
JSON.parse(JSON.stringify(existing)),
|
|
4698
|
+
token,
|
|
4699
|
+
workspaceId,
|
|
4700
|
+
agentId,
|
|
4701
|
+
cloud,
|
|
4702
|
+
);
|
|
4703
|
+
return JSON.stringify(existing) === JSON.stringify(desired);
|
|
4704
|
+
}
|
|
4705
|
+
|
|
4625
4706
|
function writeOpenClawHook(token, workspaceId, agentId, cloud) {
|
|
4626
|
-
const
|
|
4627
|
-
const
|
|
4707
|
+
const home = resolveHomeDir(cloud);
|
|
4708
|
+
const configPath = path.join(home, '.openclaw', 'openclaw.json');
|
|
4709
|
+
const pluginDir = path.join(home, '.cozeloop', 'openclaw-plugin');
|
|
4628
4710
|
|
|
4629
4711
|
if (!fs.existsSync(configPath)) {
|
|
4630
4712
|
errorBox([
|
|
4631
|
-
|
|
4713
|
+
`ERROR: openclaw.json not found at ${configPath}`,
|
|
4632
4714
|
'',
|
|
4633
4715
|
'Make sure OpenClaw is installed and has been run at least once.',
|
|
4634
|
-
|
|
4716
|
+
`(home=${home}, $HOME=${process.env.HOME || 'unset'})`,
|
|
4635
4717
|
]);
|
|
4636
4718
|
}
|
|
4637
4719
|
|
|
4720
|
+
if (isOpenClawAlreadyInjected(configPath, pluginDir, token, workspaceId, agentId, cloud)) {
|
|
4721
|
+
ok(`OpenClaw plugin already configured in ${configPath}`);
|
|
4722
|
+
info('OpenClaw gateway restart skipped (configuration unchanged).');
|
|
4723
|
+
return { configPath, pluginDir, unchanged: true };
|
|
4724
|
+
}
|
|
4725
|
+
|
|
4638
4726
|
// 1. Write plugin files to ~/.cozeloop/openclaw-plugin/
|
|
4639
4727
|
ensureDir(pluginDir);
|
|
4640
4728
|
ensureDir(path.join(pluginDir, 'dist'));
|
|
@@ -4685,46 +4773,7 @@ function writeOpenClawHook(token, workspaceId, agentId, cloud) {
|
|
|
4685
4773
|
|
|
4686
4774
|
// 4. Update openclaw.json with token and workspace
|
|
4687
4775
|
const config = mergeJson(configPath, (existing) => {
|
|
4688
|
-
|
|
4689
|
-
if (!existing.plugins.allow) existing.plugins.allow = [];
|
|
4690
|
-
if (!existing.plugins.entries) existing.plugins.entries = {};
|
|
4691
|
-
|
|
4692
|
-
const PLUGIN = 'openclaw-cozeloop-trace';
|
|
4693
|
-
if (!existing.plugins.allow.includes(PLUGIN)) {
|
|
4694
|
-
existing.plugins.allow.push(PLUGIN);
|
|
4695
|
-
}
|
|
4696
|
-
// Preserve existing entry structure, only update config
|
|
4697
|
-
if (!existing.plugins.entries[PLUGIN]) {
|
|
4698
|
-
existing.plugins.entries[PLUGIN] = { enabled: true };
|
|
4699
|
-
}
|
|
4700
|
-
existing.plugins.entries[PLUGIN].enabled = true;
|
|
4701
|
-
// hooks.allowConversationAccess required for 2026.5+ to access session content
|
|
4702
|
-
existing.plugins.entries[PLUGIN].hooks = { allowConversationAccess: true };
|
|
4703
|
-
if (!existing.plugins.entries[PLUGIN].config) existing.plugins.entries[PLUGIN].config = {};
|
|
4704
|
-
const pcfg = existing.plugins.entries[PLUGIN].config;
|
|
4705
|
-
pcfg.authorization = `Bearer ${token}`;
|
|
4706
|
-
// 云端:endpoint 走 sandbox 注入的 COZELOOP_API_BASE_URL 代理(token 经它鉴权);
|
|
4707
|
-
// 缺省回退 api.coze.cn 直连。插件 exporter 会在此基础上拼 /v1/traces。
|
|
4708
|
-
const ocBase = (cloud && process.env.COZELOOP_API_BASE_URL)
|
|
4709
|
-
? process.env.COZELOOP_API_BASE_URL.replace(/\/+$/, '') + '/v1/loop/opentelemetry'
|
|
4710
|
-
: 'https://api.coze.cn/v1/loop/opentelemetry';
|
|
4711
|
-
pcfg.endpoint = ocBase;
|
|
4712
|
-
pcfg.workspaceId = workspaceId;
|
|
4713
|
-
pcfg.debug = true;
|
|
4714
|
-
// per-agent trace 放行:把当前 agentId 并入 traceAgentIds(去重、归一为小写,
|
|
4715
|
-
// 与插件侧 resolveAgentIdFromHookCtx 的归一一致)。无 agentId(全局模式)则不动
|
|
4716
|
-
// allowlist —— 空 allowlist 表示全部放行。
|
|
4717
|
-
if (agentId) {
|
|
4718
|
-
const norm = String(agentId).trim().toLowerCase();
|
|
4719
|
-
// 读 existing 时一并归一(小写、去空),与插件侧 resolveAgentIdFromHookCtx 一致,
|
|
4720
|
-
// 防手工编辑混入大写条目导致去重失效。
|
|
4721
|
-
const list = (Array.isArray(pcfg.traceAgentIds) ? pcfg.traceAgentIds : [])
|
|
4722
|
-
.map((s) => String(s).trim().toLowerCase())
|
|
4723
|
-
.filter(Boolean);
|
|
4724
|
-
if (norm && !list.includes(norm)) list.push(norm);
|
|
4725
|
-
pcfg.traceAgentIds = list;
|
|
4726
|
-
}
|
|
4727
|
-
return existing;
|
|
4776
|
+
return applyOpenClawPluginConfig(existing, token, workspaceId, agentId, cloud);
|
|
4728
4777
|
});
|
|
4729
4778
|
|
|
4730
4779
|
try {
|