Skip to content

Commit 488245f

Browse files
authored
Fix plugin ID mismatch and enforce canonical opik-openclaw config (#12)
* chore(manifest): use opik-openclaw plugin id * chore(plugin): align runtime plugin id with manifest * feat(configure): migrate config writes to opik-openclaw entry * feat(service): read canonical and legacy plugin entry config * test(configure): cover canonical id and legacy entry migration * test(smoke): assert opik-openclaw plugin id * test(service): cover canonical and legacy plugins.entries config * docs(readme): document opik-openclaw config key and trust allowlist * refactor(configure): remove legacy opik entry fallback * refactor(service): drop legacy config compatibility paths * test(configure): keep canonical opik-openclaw expectations only * test(service): remove legacy config scenario coverage * test(e2e): use direct opik service config shape * docs(readme): remove legacy config key note * chore(release): bump package version to 0.1.6 * chore(release): sync lockfile version to 0.1.6
1 parent 6f9e235 commit 488245f

11 files changed

Lines changed: 53 additions & 37 deletions

README.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ The plugin runs inside the OpenClaw Gateway process. If your gateway is remote,
4343
openclaw opik configure
4444
```
4545

46-
The setup wizard validates endpoint and credentials, then writes config under `plugins.entries.opik`.
46+
The setup wizard validates endpoint and credentials, then writes config under `plugins.entries.opik-openclaw`.
4747

4848
### 2. Check effective settings
4949

@@ -68,7 +68,7 @@ Then confirm traces in your Opik project.
6868
{
6969
"plugins": {
7070
"entries": {
71-
"opik": {
71+
"opik-openclaw": {
7272
"enabled": true,
7373
"config": {
7474
"enabled": true,
@@ -89,6 +89,18 @@ Then confirm traces in your Opik project.
8989
}
9090
```
9191

92+
### Plugin trust allowlist
93+
94+
OpenClaw warns when `plugins.allow` is empty and a community plugin is discovered. Pin trusted plugins explicitly:
95+
96+
```json
97+
{
98+
"plugins": {
99+
"allow": ["opik-openclaw"]
100+
}
101+
}
102+
```
103+
92104
### Environment fallbacks
93105

94106
- `OPIK_API_KEY`

index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { parseOpikPluginConfig } from "./src/types.js";
99
disableLogger();
1010

1111
const plugin = {
12-
id: "opik",
12+
id: "opik-openclaw",
1313
name: "Opik",
1414
description: "Export LLM traces and spans to Opik for observability",
1515
configSchema: emptyPluginConfigSchema(),

openclaw.plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"id": "opik",
2+
"id": "opik-openclaw",
33
"name": "Opik",
44
"description": "Export OpenClaw LLM traces to Opik",
55
"configSchema": {

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@opik/opik-openclaw",
3-
"version": "0.1.5",
3+
"version": "0.1.6",
44
"description": "OpenClaw Opik exporter — sends LLM traces to Opik",
55
"type": "module",
66
"engines": {

src/configure.test.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
} from "./configure.js";
99

1010
describe("configure helpers", () => {
11-
test("setOpikPluginEntry writes plugins.entries.opik", () => {
11+
test("setOpikPluginEntry writes plugins.entries.opik-openclaw", () => {
1212
const next = setOpikPluginEntry(
1313
{} as any,
1414
{
@@ -22,8 +22,8 @@ describe("configure helpers", () => {
2222
true,
2323
) as any;
2424

25-
expect(next.plugins.entries.opik.enabled).toBe(true);
26-
expect(next.plugins.entries.opik.config).toEqual({
25+
expect(next.plugins.entries["opik-openclaw"].enabled).toBe(true);
26+
expect(next.plugins.entries["opik-openclaw"].config).toEqual({
2727
enabled: true,
2828
apiKey: "test-key",
2929
apiUrl: "https://opik.example.com",
@@ -33,11 +33,11 @@ describe("configure helpers", () => {
3333
});
3434
});
3535

36-
test("getOpikPluginEntry reads plugin-scoped config", () => {
36+
test("getOpikPluginEntry reads canonical plugin-scoped config", () => {
3737
const parsed = getOpikPluginEntry({
3838
plugins: {
3939
entries: {
40-
opik: {
40+
"opik-openclaw": {
4141
enabled: false,
4242
config: {
4343
projectName: "project-x",
@@ -59,7 +59,7 @@ describe("opik status command", () => {
5959
({
6060
plugins: {
6161
entries: {
62-
opik: {
62+
"opik-openclaw": {
6363
enabled: true,
6464
config: {
6565
enabled: true,
@@ -100,7 +100,7 @@ describe("opik status command", () => {
100100
({
101101
plugins: {
102102
entries: {
103-
opik: {
103+
"opik-openclaw": {
104104
enabled: true,
105105
config: {
106106
enabled: true,

src/configure.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const OPIK_CLOUD_HOST = "https://www.comet.com/";
1717
const DEFAULT_LOCAL_URL = "http://localhost:5173/";
1818
/** Max URL validation retries (matches SDK's MAX_URL_VALIDATION_RETRIES). */
1919
const MAX_URL_RETRIES = 3;
20-
const OPIK_PLUGIN_ID = "opik";
20+
const OPIK_PLUGIN_ID = "opik-openclaw";
2121

2222
function asObject(value: unknown): Record<string, unknown> {
2323
if (!value || typeof value !== "object" || Array.isArray(value)) {

src/plugin.smoke.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ describe("plugin smoke", () => {
3333
} as any);
3434

3535
expect(registerService).toHaveBeenCalledTimes(1);
36-
expect(registerService.mock.calls[0]?.[0]?.id).toBe("opik");
36+
expect(registerService.mock.calls[0]?.[0]?.id).toBe("opik-openclaw");
3737

3838
expect(registerCli).toHaveBeenCalledTimes(1);
3939
expect(registerCli.mock.calls[0]?.[1]).toEqual({ commands: ["opik"] });
@@ -53,7 +53,7 @@ describe("plugin smoke", () => {
5353
const manifestPath = new URL("../openclaw.plugin.json", import.meta.url);
5454
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
5555

56-
expect(manifest.id).toBe("opik");
56+
expect(manifest.id).toBe("opik-openclaw");
5757
expect(manifest.configSchema?.properties?.apiKey?.type).toBe("string");
5858
expect(manifest.configSchema?.properties?.projectName?.type).toBe("string");
5959
expect(manifest.uiHints?.apiKey?.sensitive).toBe(true);

src/service.e2e.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ function createApi() {
198198

199199
function createServiceContext() {
200200
return {
201-
config: { opik: { enabled: true } },
201+
config: { enabled: true },
202202
logger: {
203203
info: () => undefined,
204204
warn: () => undefined,

src/service.test.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,7 @@ function createServiceContext(
100100
opikCfg: OpikCfg = { enabled: true, apiKey: "test-key" },
101101
) {
102102
return {
103-
config: {
104-
opik: opikEnabled ? opikCfg : { ...opikCfg, enabled: false },
105-
},
103+
config: opikEnabled ? opikCfg : { ...opikCfg, enabled: false },
106104
logger: createLogger(),
107105
stateDir: "/tmp/opik-test",
108106
};
@@ -178,7 +176,7 @@ describe("opik service", () => {
178176
});
179177
});
180178

181-
test("prefers pluginConfig over legacy top-level config", async () => {
179+
test("prefers pluginConfig over runtime service config", async () => {
182180
const { api } = createApi();
183181
const service = createOpikService(api as any, {
184182
enabled: true,
@@ -191,10 +189,10 @@ describe("opik service", () => {
191189
await service.start(
192190
createServiceContext(true, {
193191
enabled: false,
194-
apiKey: "legacy-key",
195-
apiUrl: "https://legacy-opik.example.com",
196-
projectName: "legacy-project",
197-
workspaceName: "legacy-workspace",
192+
apiKey: "runtime-key",
193+
apiUrl: "https://runtime-opik.example.com",
194+
projectName: "runtime-project",
195+
workspaceName: "runtime-workspace",
198196
}) as any,
199197
);
200198

0 commit comments

Comments
 (0)