coze_lab 0.1.14 → 0.1.15

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/README.md CHANGED
@@ -8,6 +8,9 @@ Configure local AI agents (Claude Code, Codex, OpenClaw) to report traces to Coz
8
8
  # First-time setup — triggers browser OAuth authorization
9
9
  npx coze_lab --agent=<type>
10
10
 
11
+ # Cloud setup for a managed agent
12
+ npx coze_lab --cloud --agent-id=<agentId>
13
+
11
14
  # Auth-only commands (no agent configuration)
12
15
  npx coze_lab --login # Device Code login only
13
16
  npx coze_lab --status # Show current authorization status
@@ -20,6 +23,9 @@ npx coze_lab --logout # Clear cached credentials
20
23
  | Parameter | Required | Values / Effect |
21
24
  |-----------|----------|-----------------|
22
25
  | `--agent` | ✓ (for setup) | `claude-code`, `codex`, `openclaw` |
26
+ | `--agent-id` | — | Resolve `~/.coze/agents/<agentId>/config.json` and write per-agent config |
27
+ | `--cloud` | — | Cloud mode: read token from env and emit `COZE_LAB_RESULT=...` |
28
+ | `--codex-home` | — | Override Codex config home for non-cloud/custom runs |
23
29
  | `--login` | — | Run the Device Code login flow only |
24
30
  | `--status` | — | Print local token status (valid / expiring / expired) |
25
31
  | `--refresh` | — | Force-refresh the access token via `refresh_token` |
@@ -50,6 +56,11 @@ npx coze_lab --logout # Clear cached credentials
50
56
  | `codex` | `~/.codex/hooks/cozeloop_hook.py` | `~/.codex/hooks.json` | `~/.codex/hooks/cozeloop.env` |
51
57
  | `openclaw` | — (Node.js plugin) | `~/.openclaw/openclaw.json` | inline in config |
52
58
 
59
+ For cloud Codex with `--cloud --agent-id=<agentId>`, Codex hooks are written to
60
+ `~/.coze/agents/<agentId>/codex-home` by default. The directory is created if it
61
+ does not already exist, so callers do not need to pass `--codex-home` for the
62
+ standard coze-bridge layout.
63
+
53
64
  ## Token lifecycle
54
65
 
55
66
  OAuth tokens are stored in `~/.cozeloop/credentials.json` (mode 600).
package/index.js CHANGED
@@ -4618,6 +4618,13 @@ function writeCodexHook(token, workspaceId, pythonCmd, codexHome, cloud) {
4618
4618
  return { hookScript, envFile, hooksJson };
4619
4619
  }
4620
4620
 
4621
+ function resolveCodexHome(args) {
4622
+ if (args.cloud && args.agentId) {
4623
+ return path.join(os.homedir(), '.coze', 'agents', args.agentId, 'codex-home');
4624
+ }
4625
+ return args['codex-home'] || process.env.CODEX_HOME || undefined;
4626
+ }
4627
+
4621
4628
  // writeOpenClawHook 配置 OpenClaw 的 cozeloop-trace 插件(全局装在 ~/.openclaw)。
4622
4629
  // agentId 非空时并入 plugins.entries[...].config.traceAgentIds allowlist —— 插件运行时
4623
4630
  // 用 resolveAgentIdFromHookCtx 取当前 agentId,仅 allowlist 内的 agent 才上报 trace。
@@ -5290,8 +5297,11 @@ async function main() {
5290
5297
  }
5291
5298
  written = writeClaudeCodeHook(token, WORKSPACE_ID, pythonCmd, args.agentId ? agentWorkspace : undefined, args.cloud);
5292
5299
  } else if (agent === 'codex') {
5293
- // CODEX_HOME 来源优先级:--codex-home= > 环境变量 CODEX_HOME > ~/.codex(缺省)。
5294
- const codexHome = args['codex-home'] || process.env.CODEX_HOME || undefined;
5300
+ const codexHome = resolveCodexHome(args);
5301
+ if (args.cloud && args.agentId && codexHome && !fs.existsSync(codexHome)) {
5302
+ ensureDir(codexHome);
5303
+ info(`已创建云端 Codex 配置目录: ${codexHome}`);
5304
+ }
5295
5305
  if (codexHome) info(`Codex 配置目录: ${codexHome}`);
5296
5306
  written = writeCodexHook(token, WORKSPACE_ID, pythonCmd, codexHome, args.cloud);
5297
5307
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coze_lab",
3
- "version": "0.1.14",
3
+ "version": "0.1.15",
4
4
  "description": "Configure local AI agents (Claude Code, Codex, OpenClaw) to report traces to CozeLoop",
5
5
  "keywords": [
6
6
  "cozeloop",
@@ -16,7 +16,12 @@
16
16
  },
17
17
  "files": [
18
18
  "index.js",
19
- "scripts/"
19
+ "scripts/claude-code/cozeloop_hook.py",
20
+ "scripts/codex/cozeloop_hook.py",
21
+ "scripts/shared/cozeloop_refresh.py",
22
+ "scripts/openclaw/dist/",
23
+ "scripts/openclaw/openclaw.plugin.json",
24
+ "scripts/openclaw/package.json"
20
25
  ],
21
26
  "engines": {
22
27
  "node": ">=18"
@@ -29,15 +29,53 @@ from pathlib import Path
29
29
  from typing import Optional, List, Dict, Any
30
30
 
31
31
  # --- SDK Import ---
32
- try:
32
+ def _ensure_cozeloop_sdk():
33
+ try:
34
+ import cozeloop # noqa: F401
35
+ return True
36
+ except ImportError:
37
+ pass
38
+ import subprocess
39
+ import importlib
40
+ import site
41
+ attempts = (
42
+ ["--quiet", "--disable-pip-version-check", "cozeloop"],
43
+ ["--quiet", "--disable-pip-version-check", "--break-system-packages", "cozeloop"],
44
+ ["--quiet", "--disable-pip-version-check", "--break-system-packages", "--user", "cozeloop"],
45
+ )
46
+ for extra in attempts:
47
+ try:
48
+ subprocess.run(
49
+ [sys.executable, "-m", "pip", "install", *extra],
50
+ timeout=180, check=True,
51
+ stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
52
+ )
53
+ except Exception:
54
+ continue
55
+ try:
56
+ importlib.reload(site)
57
+ user_site = site.getusersitepackages()
58
+ for p in ([user_site] if isinstance(user_site, str) else list(user_site)):
59
+ if p and p not in sys.path:
60
+ sys.path.insert(0, p)
61
+ importlib.invalidate_caches()
62
+ import cozeloop # noqa: F401
63
+ print("[CozeLoop] cozeloop SDK auto-installed at runtime.", file=sys.stderr)
64
+ return True
65
+ except ImportError:
66
+ continue
67
+ return False
68
+
69
+
70
+ if _ensure_cozeloop_sdk():
33
71
  import cozeloop
34
72
  from cozeloop.spec.tracespec import (
35
73
  Runtime, ModelInput, ModelMessage, ModelToolChoice,
36
74
  ModelOutput, ModelChoice, ModelToolCall, ModelToolCallFunction,
37
75
  ModelMessagePart, ModelMessagePartType
38
76
  )
39
- except ImportError:
40
- print("Error: cozeloop SDK not found. Please install it with: pip install cozeloop", file=sys.stderr)
77
+ else:
78
+ print("Error: cozeloop SDK not found and auto-install failed. Try: pip install cozeloop", file=sys.stderr)
41
79
  sys.exit(1)
42
80
 
43
81
  # --- Configuration ---
@@ -1412,4 +1450,3 @@ if __name__ == "__main__":
1412
1450
  main()
1413
1451
 
1414
1452
 
1415
-
@@ -202,15 +202,53 @@ def get_fresh_token():
202
202
  # -------------------------------------------------------------------------
203
203
 
204
204
  # --- SDK Import ---
205
- try:
205
+ def _ensure_cozeloop_sdk():
206
+ try:
207
+ import cozeloop # noqa: F401
208
+ return True
209
+ except ImportError:
210
+ pass
211
+ import subprocess
212
+ import importlib
213
+ import site
214
+ attempts = (
215
+ ["--quiet", "--disable-pip-version-check", "cozeloop"],
216
+ ["--quiet", "--disable-pip-version-check", "--break-system-packages", "cozeloop"],
217
+ ["--quiet", "--disable-pip-version-check", "--break-system-packages", "--user", "cozeloop"],
218
+ )
219
+ for extra in attempts:
220
+ try:
221
+ subprocess.run(
222
+ [sys.executable, "-m", "pip", "install", *extra],
223
+ timeout=180, check=True,
224
+ stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
225
+ )
226
+ except Exception:
227
+ continue
228
+ try:
229
+ importlib.reload(site)
230
+ user_site = site.getusersitepackages()
231
+ for p in ([user_site] if isinstance(user_site, str) else list(user_site)):
232
+ if p and p not in sys.path:
233
+ sys.path.insert(0, p)
234
+ importlib.invalidate_caches()
235
+ import cozeloop # noqa: F401
236
+ print("[CozeLoop] cozeloop SDK auto-installed at runtime.", file=sys.stderr)
237
+ return True
238
+ except ImportError:
239
+ continue
240
+ return False
241
+
242
+
243
+ if _ensure_cozeloop_sdk():
206
244
  import cozeloop
207
245
  from cozeloop.spec.tracespec import (
208
246
  Runtime, ModelInput, ModelMessage, ModelToolChoice,
209
247
  ModelOutput, ModelChoice, ModelToolCall, ModelToolCallFunction,
210
248
  ModelMessagePart, ModelMessagePartType
211
249
  )
212
- except ImportError:
213
- print("Error: cozeloop SDK not found. Please install it with: pip install cozeloop", file=sys.stderr)
250
+ else:
251
+ print("Error: cozeloop SDK not found and auto-install failed. Try: pip install cozeloop", file=sys.stderr)
214
252
  sys.exit(1)
215
253
 
216
254
  # --- Configuration ---
@@ -1120,4 +1158,3 @@ def main():
1120
1158
 
1121
1159
  if __name__ == "__main__":
1122
1160
  main()
1123
-