coze_lab 0.1.37 → 0.1.38

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.
Files changed (3) hide show
  1. package/README.md +4 -4
  2. package/index.js +43 -11
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -8,7 +8,7 @@ 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
- # Per-agent setup. Cloud/local is inferred from coze-bridge config.
11
+ # Per-agent setup. Cloud/local is inferred from coze-bridge config or CLOUD_ENV=1.
12
12
  npx coze_lab --agent-id=<agentId>
13
13
 
14
14
  # Auth-only commands (no agent configuration)
@@ -23,8 +23,8 @@ npx coze_lab --logout # Clear cached credentials
23
23
  | Parameter | Required | Values / Effect |
24
24
  |-----------|----------|-----------------|
25
25
  | `--agent` | ✓ (for setup) | `claude-code`, `codex`, `openclaw` |
26
- | `--agent-id` | — | Resolve `~/.coze/agents/<agentId>/config.json` and write per-agent config. `deployType=cloud` enables cloud mode automatically |
27
- | `--cloud` | — | Backward-compatible override for old callers. New callers should rely on `--agent-id` + config `deployType` |
26
+ | `--agent-id` | — | Resolve `~/.coze/agents/<agentId>/config.json` and write per-agent config. Cloud mode is inferred from `deployType=cloud`, `CLOUD_ENV=1`, or bridge cloud-only fields |
27
+ | `--cloud` | — | Backward-compatible override for old manual callers. New callers should rely on `--agent-id` auto-detection |
28
28
  | `--codex-home` | — | Override Codex config home for non-cloud/custom runs |
29
29
  | `--login` | — | Run the Device Code login flow only |
30
30
  | `--status` | — | Print local token status (valid / expiring / expired) |
@@ -56,7 +56,7 @@ npx coze_lab --logout # Clear cached credentials
56
56
  | `codex` | `~/.codex/hooks/cozeloop_hook.py` | `~/.codex/hooks.json` | `~/.codex/hooks/cozeloop.env` |
57
57
  | `openclaw` | — (Node.js plugin) | `~/.openclaw/openclaw.json` | inline in config |
58
58
 
59
- For cloud Codex with `--agent-id=<agentId>` and config `deployType=cloud`, Codex hooks are written to
59
+ For cloud Codex with `--agent-id=<agentId>`, Codex hooks are written to
60
60
  `~/.coze/agents/<agentId>/codex-home` by default. The directory is created if it
61
61
  does not already exist, so callers do not need to pass `--codex-home` for the
62
62
  standard coze-bridge layout.
package/index.js CHANGED
@@ -53,6 +53,11 @@ function getCloudTokenInfo() {
53
53
  return { token: '', source: '', traceUsable: false };
54
54
  }
55
55
 
56
+ function isCloudRuntimeEnv() {
57
+ const v = readEnv('CLOUD_ENV').toLowerCase();
58
+ return v === '1' || v === 'true' || v === 'yes' || v === 'cloud';
59
+ }
60
+
56
61
  // ─── 1. Color helpers ────────────────────────────────────────────────────────
57
62
  const C = {
58
63
  reset: '\x1b[0m',
@@ -156,6 +161,30 @@ function parseArgs() {
156
161
 
157
162
  const VALID_AGENTS = ['claude-code', 'codex', 'openclaw'];
158
163
 
164
+ function hasCloudSessionToken(cfg) {
165
+ const sessions = cfg?.sessions;
166
+ if (!sessions || typeof sessions !== 'object' || Array.isArray(sessions)) return false;
167
+ return Object.values(sessions).some((record) => (
168
+ record
169
+ && typeof record === 'object'
170
+ && typeof record.modelToken === 'string'
171
+ && record.modelToken.trim()
172
+ ));
173
+ }
174
+
175
+ function hasCloudModelInfo(cfg) {
176
+ return !!(cfg?.modelInfo && typeof cfg.modelInfo === 'object' && !Array.isArray(cfg.modelInfo));
177
+ }
178
+
179
+ function inferDeployTypeFromAgentConfig(cfg) {
180
+ if (cfg?.deployType === 'cloud') return { deployType: 'cloud', reason: 'config.deployType=cloud' };
181
+ if (isCloudRuntimeEnv()) return { deployType: 'cloud', reason: 'env CLOUD_ENV=1' };
182
+ if (cfg?.deployType === 'local') return { deployType: 'local', reason: 'config.deployType=local' };
183
+ if (hasCloudSessionToken(cfg)) return { deployType: 'cloud', reason: 'config.sessions[*].modelToken' };
184
+ if (hasCloudModelInfo(cfg)) return { deployType: 'cloud', reason: 'config.modelInfo' };
185
+ return { deployType: 'local', reason: 'no cloud signal' };
186
+ }
187
+
159
188
  // resolveAgent 读 ~/.coze/agents/<agentId>/config.json,返回 { framework, workspace, deployType, agentId, root }。
160
189
  // soft=true 时,config 不存在 / 解析失败 / framework 非法均返回 null(不退出),供云端回退到显式 --agent。
161
190
  function resolveAgent(agentId, soft) {
@@ -186,8 +215,8 @@ function resolveAgent(agentId, soft) {
186
215
  `支持的类型: ${VALID_AGENTS.join(', ')}`,
187
216
  ]);
188
217
  }
189
- const deployType = cfg.deployType === 'cloud' ? 'cloud' : 'local';
190
- return { framework, workspace: cfg.workspace || '', deployType, agentId, root };
218
+ const inferred = inferDeployTypeFromAgentConfig(cfg);
219
+ return { framework, workspace: cfg.workspace || '', deployType: inferred.deployType, deployReason: inferred.reason, agentId, root };
191
220
  }
192
221
 
193
222
  function validateArgs(args) {
@@ -197,11 +226,12 @@ function validateArgs(args) {
197
226
  if (args['refresh']) return { refresh: true };
198
227
  if (args['verify']) return { verify: true, pairCode: args['pair-code'] };
199
228
 
200
- // --agent-id:优先读 coze-bridge 的 ~/.coze/agents/<id>/config.json 拿 framework/workspace/deployType
201
- // deployType=cloud 时自动进入云端注入路径;显式 --cloud 仍保留,供 config 缺失时兜底。
229
+ // --agent-id:优先读 coze-bridge 的 ~/.coze/agents/<id>/config.json 拿 framework/workspace。
230
+ // 云端判定优先看 deployType / CLOUD_ENV;兼容老 config 时再看 cloud-only 落盘字段。
202
231
  if (args['agent-id']) {
203
232
  const explicitCloud = !!args['cloud'];
204
- const resolved = resolveAgent(args['agent-id'], explicitCloud /* soft */);
233
+ const runtimeCloud = isCloudRuntimeEnv();
234
+ const resolved = resolveAgent(args['agent-id'], explicitCloud || runtimeCloud /* soft */);
205
235
  if (resolved) {
206
236
  const cloud = explicitCloud || resolved.deployType === 'cloud';
207
237
  return {
@@ -210,20 +240,22 @@ function validateArgs(args) {
210
240
  workspace: resolved.workspace,
211
241
  agentRoot: resolved.root,
212
242
  deployType: resolved.deployType,
243
+ deployReason: explicitCloud ? '--cloud' : resolved.deployReason,
213
244
  'codex-home': args['codex-home'],
214
245
  pairCode: args['pair-code'],
215
246
  cloud,
216
247
  force: !!args['force'],
217
248
  };
218
249
  }
219
- // 显式 --cloud 且 config.json 缺失:回退到显式 --agent(workspace 在 main 推断)。
220
- if (!args['agent'] || !VALID_AGENTS.includes(args['agent'])) {
250
+ // 显式 --cloud 或 CLOUD_ENV=1 且 config.json 缺失:回退到显式 --agent
251
+ // (workspace main 推断)。没有云端信号时仍按本地 config 缺失报错。
252
+ if ((!explicitCloud && !runtimeCloud) || !args['agent'] || !VALID_AGENTS.includes(args['agent'])) {
221
253
  errorBox([
222
254
  `ERROR: 未找到 agent "${args['agent-id']}" 的 config.json,且未显式指定 --agent`,
223
255
  '',
224
256
  '新调用方应确认 coze-bridge 已在目标环境写入该 agent config。',
225
- '如需兼容旧手工命令,可显式拼上 framework 和 --cloud:',
226
- ` npx coze_lab --cloud --agent-id=${args['agent-id']} --agent=claude-code|codex|openclaw`,
257
+ '如需兼容旧手工命令,可显式拼上 framework:',
258
+ ` npx coze_lab --agent-id=${args['agent-id']} --agent=claude-code|codex|openclaw`,
227
259
  ]);
228
260
  }
229
261
  return {
@@ -231,6 +263,7 @@ function validateArgs(args) {
231
263
  agentId: args['agent-id'],
232
264
  workspace: args['workspace'] || '',
233
265
  deployType: 'cloud',
266
+ deployReason: explicitCloud ? '--cloud' : 'env CLOUD_ENV=1',
234
267
  'codex-home': args['codex-home'],
235
268
  pairCode: args['pair-code'],
236
269
  cloud: true,
@@ -1784,14 +1817,13 @@ async function main() {
1784
1817
  // 云端模式:开启结构化输出 + errorBox 抛异常(而非 exit)。
1785
1818
  CLOUD_MODE = !!args.cloud;
1786
1819
  // per-agent 路由时 agent 的 workspace(claude-code 用它做配置根目录)。
1787
- // per-agent 路由时 agent 的 workspace(claude-code 用它做配置根目录)。
1788
1820
  // 云端 claude-code 未显式传 workspace 时,按约定路径 ~/.coze/agents/<id>/workspace 推断。
1789
1821
  let agentWorkspace = args.workspace || '';
1790
1822
  if (args.cloud && args.agentId && agent === 'claude-code' && !agentWorkspace) {
1791
1823
  agentWorkspace = path.join(os.homedir(), '.coze', 'agents', args.agentId, 'workspace');
1792
1824
  }
1793
1825
  if (args.agentId) {
1794
- info(`目标 agent: ${args.agentId} (framework=${agent}, workspace=${agentWorkspace || 'N/A'})`);
1826
+ info(`目标 agent: ${args.agentId} (framework=${agent}, workspace=${agentWorkspace || 'N/A'}, deploy=${args.cloud ? 'cloud' : 'local'}, reason=${args.deployReason || 'n/a'})`);
1795
1827
  console.log('');
1796
1828
  }
1797
1829
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coze_lab",
3
- "version": "0.1.37",
3
+ "version": "0.1.38",
4
4
  "description": "Configure local AI agents (Claude Code, Codex, OpenClaw) to report traces to CozeLoop",
5
5
  "keywords": [
6
6
  "cozeloop",