coze_lab 0.1.45 → 0.1.47
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 +9 -3
- package/index.js +35 -9
- package/package.json +1 -1
- package/scripts/claude-code/cozeloop_hook.py +30 -0
- package/scripts/codex/cozeloop_hook.py +30 -0
package/README.md
CHANGED
|
@@ -83,10 +83,16 @@ For Python SDK uploads, `OTEL_ENDPOINT` is not used as the SDK base URL; set
|
|
|
83
83
|
|
|
84
84
|
## Supported Versions
|
|
85
85
|
|
|
86
|
+
The current hook scheme requires these local capabilities:
|
|
87
|
+
|
|
88
|
+
- `claude-code`: `settings.json` command hooks for `Stop` and `PostToolUse`.
|
|
89
|
+
- `codex`: `hooks.json` command hooks for `Stop` and `PostToolUse`.
|
|
90
|
+
- `openclaw`: plugin lifecycle/tool hooks with conversation access enabled.
|
|
91
|
+
|
|
86
92
|
| Agent | Supported versions |
|
|
87
93
|
|-------|--------------------|
|
|
88
|
-
| `claude-code` |
|
|
89
|
-
| `codex` | 0.134.
|
|
90
|
-
| `openclaw` | 2026.3.
|
|
94
|
+
| `claude-code` | >= 1.0.0 |
|
|
95
|
+
| `codex` | >= 0.134.0 |
|
|
96
|
+
| `openclaw` | >= 2026.3.0 |
|
|
91
97
|
|
|
92
98
|
Versions outside this list show a warning but onboarding continues.
|
package/index.js
CHANGED
|
@@ -459,12 +459,16 @@ function checkCozeloopSdk(pythonCmd, options = {}) {
|
|
|
459
459
|
}
|
|
460
460
|
|
|
461
461
|
// ─── 6. Version whitelist check ──────────────────────────────────────────────
|
|
462
|
-
//
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
'
|
|
466
|
-
'
|
|
462
|
+
// Forward-compatible lower bounds. Newer CLI releases are treated as
|
|
463
|
+
// supported by default because the hook selfcheck is the authoritative guard.
|
|
464
|
+
const VERSION_SUPPORT = {
|
|
465
|
+
'claude-code': { min: '1.0.0', display: ['>= 1.0.0'] },
|
|
466
|
+
'codex': { min: '0.134.0', display: ['>= 0.134.0'] },
|
|
467
|
+
'openclaw': { min: '2026.3.0', display: ['>= 2026.3.0'] },
|
|
467
468
|
};
|
|
469
|
+
const VERSION_WHITELIST = Object.fromEntries(
|
|
470
|
+
Object.entries(VERSION_SUPPORT).map(([agent, cfg]) => [agent, cfg.display]),
|
|
471
|
+
);
|
|
468
472
|
|
|
469
473
|
const UPGRADE_CMD = {
|
|
470
474
|
'claude-code': 'npm install -g @anthropic-ai/claude-code@latest',
|
|
@@ -473,15 +477,15 @@ const UPGRADE_CMD = {
|
|
|
473
477
|
};
|
|
474
478
|
|
|
475
479
|
function checkVersionWhitelist(agent, version) {
|
|
476
|
-
const
|
|
477
|
-
const supported =
|
|
480
|
+
const support = VERSION_SUPPORT[agent];
|
|
481
|
+
const supported = support && isVersionAtLeast(version, support.min);
|
|
478
482
|
|
|
479
483
|
if (supported) {
|
|
480
484
|
ok(`${agent} v${version} — OK`);
|
|
481
485
|
return;
|
|
482
486
|
}
|
|
483
487
|
|
|
484
|
-
const supportedList =
|
|
488
|
+
const supportedList = (support?.display || []).map(v => ` • ${v}`);
|
|
485
489
|
warnBox([
|
|
486
490
|
`⚠ WARNING: Unsupported ${agent} version: ${version}`,
|
|
487
491
|
'',
|
|
@@ -491,10 +495,29 @@ function checkVersionWhitelist(agent, version) {
|
|
|
491
495
|
'Trace reporting may not work correctly.',
|
|
492
496
|
'Please upgrade and re-run:',
|
|
493
497
|
` ${UPGRADE_CMD[agent]}`,
|
|
494
|
-
|
|
498
|
+
' npx coze_lab --agent-id=<id>',
|
|
495
499
|
]);
|
|
496
500
|
}
|
|
497
501
|
|
|
502
|
+
function parseVersionNumbers(version) {
|
|
503
|
+
const m = String(version || '').match(/(\d+(?:\.\d+){0,3})/);
|
|
504
|
+
return m ? m[1].split('.').map((part) => Number(part)) : [];
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
function isVersionAtLeast(version, minVersion) {
|
|
508
|
+
const got = parseVersionNumbers(version);
|
|
509
|
+
const min = parseVersionNumbers(minVersion);
|
|
510
|
+
if (!got.length || !min.length) return false;
|
|
511
|
+
const len = Math.max(got.length, min.length);
|
|
512
|
+
for (let i = 0; i < len; i += 1) {
|
|
513
|
+
const a = got[i] || 0;
|
|
514
|
+
const b = min[i] || 0;
|
|
515
|
+
if (a > b) return true;
|
|
516
|
+
if (a < b) return false;
|
|
517
|
+
}
|
|
518
|
+
return true;
|
|
519
|
+
}
|
|
520
|
+
|
|
498
521
|
// ─── 7. Hook writers ─────────────────────────────────────────────────────────
|
|
499
522
|
const fs = require('fs');
|
|
500
523
|
const path = require('path');
|
|
@@ -1780,4 +1803,7 @@ module.exports = {
|
|
|
1780
1803
|
getAgentPatToken,
|
|
1781
1804
|
mergeJson,
|
|
1782
1805
|
atomicWriteFileSync,
|
|
1806
|
+
VERSION_WHITELIST,
|
|
1807
|
+
VERSION_SUPPORT,
|
|
1808
|
+
isVersionAtLeast,
|
|
1783
1809
|
};
|
package/package.json
CHANGED
|
@@ -107,6 +107,36 @@ _OTEL_SUFFIX = "/v1/loop/opentelemetry"
|
|
|
107
107
|
_DEFAULT_WORKSPACE_ID = "7649231955045072915" # hardcoded spaceID fallback
|
|
108
108
|
|
|
109
109
|
|
|
110
|
+
def _normalize_api_base_url(raw: str) -> str:
|
|
111
|
+
"""Normalize CozeLoop API/OTLP endpoint env vars to the SDK api_base_url."""
|
|
112
|
+
base = (raw or "").strip().rstrip("/")
|
|
113
|
+
if not base:
|
|
114
|
+
return ""
|
|
115
|
+
suffixes = [
|
|
116
|
+
"/api/v1/loop/traces/ingest",
|
|
117
|
+
"/v1/loop/traces/ingest",
|
|
118
|
+
"/api/v1/loop/opentelemetry/v1/traces",
|
|
119
|
+
"/v1/loop/opentelemetry/v1/traces",
|
|
120
|
+
"/api/v1/loop/opentelemetry",
|
|
121
|
+
"/v1/loop/opentelemetry",
|
|
122
|
+
"/api/v1",
|
|
123
|
+
"/v1",
|
|
124
|
+
]
|
|
125
|
+
for suffix in suffixes:
|
|
126
|
+
if base.endswith(suffix):
|
|
127
|
+
return base[:-len(suffix)].rstrip("/")
|
|
128
|
+
return base
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def get_api_base_url() -> str:
|
|
132
|
+
"""Return optional CozeLoop SDK api_base_url from onboard-injected env."""
|
|
133
|
+
return _normalize_api_base_url(
|
|
134
|
+
os.environ.get("COZELOOP_API_BASE_URL")
|
|
135
|
+
or os.environ.get("OTEL_ENDPOINT")
|
|
136
|
+
or ""
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
|
|
110
140
|
# --- coze-context parsing -------------------------------------------------
|
|
111
141
|
# User messages may embed a block like:
|
|
112
142
|
# <coze-context>
|
|
@@ -133,6 +133,36 @@ else:
|
|
|
133
133
|
DEBUG = os.environ.get("CC_COZELOOP_DEBUG", "").lower() == "true"
|
|
134
134
|
|
|
135
135
|
|
|
136
|
+
def _normalize_api_base_url(raw: str) -> str:
|
|
137
|
+
"""Normalize CozeLoop API/OTLP endpoint env vars to the SDK api_base_url."""
|
|
138
|
+
base = (raw or "").strip().rstrip("/")
|
|
139
|
+
if not base:
|
|
140
|
+
return ""
|
|
141
|
+
suffixes = [
|
|
142
|
+
"/api/v1/loop/traces/ingest",
|
|
143
|
+
"/v1/loop/traces/ingest",
|
|
144
|
+
"/api/v1/loop/opentelemetry/v1/traces",
|
|
145
|
+
"/v1/loop/opentelemetry/v1/traces",
|
|
146
|
+
"/api/v1/loop/opentelemetry",
|
|
147
|
+
"/v1/loop/opentelemetry",
|
|
148
|
+
"/api/v1",
|
|
149
|
+
"/v1",
|
|
150
|
+
]
|
|
151
|
+
for suffix in suffixes:
|
|
152
|
+
if base.endswith(suffix):
|
|
153
|
+
return base[:-len(suffix)].rstrip("/")
|
|
154
|
+
return base
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def get_api_base_url() -> str:
|
|
158
|
+
"""Return optional CozeLoop SDK api_base_url from onboard-injected env."""
|
|
159
|
+
return _normalize_api_base_url(
|
|
160
|
+
os.environ.get("COZELOOP_API_BASE_URL")
|
|
161
|
+
or os.environ.get("OTEL_ENDPOINT")
|
|
162
|
+
or ""
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
|
|
136
166
|
def _log_file_path() -> str:
|
|
137
167
|
return os.environ.get("COZELOOP_HOOK_LOG", "").strip()
|
|
138
168
|
|