@teith/openclaw-runware-provider 0.3.3 → 0.3.4

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.
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Emits `openclaw.cost.usd` OpenTelemetry counter for runware completions.
3
+ *
4
+ * Why this file exists
5
+ * --------------------
6
+ * OpenClaw 2026.6.1 has two cost-computation paths with different data
7
+ * sources:
8
+ *
9
+ * Completion path (works) — openai-completions runtime calls
10
+ * `calculateCost(model, usage)` with the live `model` object returned
11
+ * by this plugin's `catalog.run`. `model.cost` is populated from
12
+ * `/v1/models`. Result is written into transcript JSONL as
13
+ * `usage.cost`. Usage UI reads from there.
14
+ *
15
+ * Diagnostic path (broken) — `agent-runner` emits `model.usage`
16
+ * diagnostic events with `costUsd = estimateUsageCost({ usage, cost:
17
+ * resolveModelCostConfig(provider, model, config) })`. That resolver
18
+ * reads ONLY from:
19
+ * • `models.json` cost index
20
+ * • `openclaw.json` `models.providers.*.models[].cost`
21
+ * • `cachedPricing` Map (seeded from manifest `modelCatalog` and
22
+ * upstream OpenRouter/LiteLLM catalogs)
23
+ * None of those carry runware pricing — pricing flows through the
24
+ * plugin's runtime `catalog.run`, which is invisible to this resolver.
25
+ * So `costUsd` is undefined, the diagnostics-otel handler's
26
+ * `if (evt.costUsd) costCounter.add(...)` guard is falsy, and the
27
+ * `openclaw_cost_usd_total` counter stays at zero.
28
+ *
29
+ * What this file does
30
+ * -------------------
31
+ * Tails session transcripts (`~/.openclaw/agents/<id>/sessions/*.jsonl`),
32
+ * which already contain `usage.cost.total` because the completion path
33
+ * filled them in. Parses new entries on a 2s tick, filters to
34
+ * `provider === "runware"`, and writes to the same global OTel counter
35
+ * `openclaw.cost.usd` that diagnostics-otel tried (and failed) to write
36
+ * to. The OTel API stores its MeterProvider on a globalThis symbol slot
37
+ * so plugin-side `getMeter(...).createCounter("openclaw.cost.usd", ...)`
38
+ * shares the MeterProvider that diagnostics-otel registered at gateway
39
+ * start. Counter writes from both sides land on the same
40
+ * `(name, attributes)` time series in OTLP → Prometheus → GMP.
41
+ *
42
+ * Why polling and not a hook
43
+ * --------------------------
44
+ * `llm_output` and `agent_end` carry usage, but openclaw blocks them for
45
+ * non-bundled plugins unless `plugins.entries.<id>.hooks
46
+ * .allowConversationAccess: true` is set in openclaw.json — i.e. in the
47
+ * manager. `model_call_ended` is bundled-accessible but only carries
48
+ * sanitized metadata (no usage). `wrapStreamFn` is a provider-runtime
49
+ * hook on `registerProvider` but `register(api)` is not invoked for
50
+ * external plugins in 2026.5.x and behavior is unverified in 2026.6.1.
51
+ * Tailing the transcript file is the one path that does not depend on
52
+ * any of those (the transcripts are written by the completion path
53
+ * regardless of hooks).
54
+ *
55
+ * Double-counting safety
56
+ * ----------------------
57
+ * On startup the poller takes the current size of every transcript
58
+ * file as the initial offset — existing entries are assumed already
59
+ * accounted for by whatever was running before. Only bytes appended
60
+ * after startup emit metrics. Gateway restart resets all offsets, which
61
+ * is the correct behavior for a process-scoped counter (Prometheus
62
+ * `rate()` handles counter resets).
63
+ *
64
+ * If openclaw eventually fixes the diagnostic path so that
65
+ * `evt.costUsd` is populated for runware, both writers will increment
66
+ * the same series and the metric will double for runware. At that point
67
+ * delete this module. (We do not attempt to detect that case at runtime
68
+ * because diagnostics-otel does not expose its emit-or-skip decision to
69
+ * other plugins.)
70
+ */
71
+ /**
72
+ * Idempotent. Safe to call from multiple plugin entry files; only the
73
+ * first call starts the interval, subsequent calls return immediately.
74
+ * Survives openclaw plugin hot-reload because state lives on
75
+ * `globalThis`.
76
+ */
77
+ export declare function startCostMetricPoller(opts?: {
78
+ openclawHome?: string;
79
+ intervalMs?: number;
80
+ }): void;
81
+ //# sourceMappingURL=cost-metric.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cost-metric.d.ts","sourceRoot":"","sources":["../src/cost-metric.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqEG;AAgDH;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,CAAC,EAAE;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,IAAI,CAiCP"}
@@ -0,0 +1,334 @@
1
+ /**
2
+ * Emits `openclaw.cost.usd` OpenTelemetry counter for runware completions.
3
+ *
4
+ * Why this file exists
5
+ * --------------------
6
+ * OpenClaw 2026.6.1 has two cost-computation paths with different data
7
+ * sources:
8
+ *
9
+ * Completion path (works) — openai-completions runtime calls
10
+ * `calculateCost(model, usage)` with the live `model` object returned
11
+ * by this plugin's `catalog.run`. `model.cost` is populated from
12
+ * `/v1/models`. Result is written into transcript JSONL as
13
+ * `usage.cost`. Usage UI reads from there.
14
+ *
15
+ * Diagnostic path (broken) — `agent-runner` emits `model.usage`
16
+ * diagnostic events with `costUsd = estimateUsageCost({ usage, cost:
17
+ * resolveModelCostConfig(provider, model, config) })`. That resolver
18
+ * reads ONLY from:
19
+ * • `models.json` cost index
20
+ * • `openclaw.json` `models.providers.*.models[].cost`
21
+ * • `cachedPricing` Map (seeded from manifest `modelCatalog` and
22
+ * upstream OpenRouter/LiteLLM catalogs)
23
+ * None of those carry runware pricing — pricing flows through the
24
+ * plugin's runtime `catalog.run`, which is invisible to this resolver.
25
+ * So `costUsd` is undefined, the diagnostics-otel handler's
26
+ * `if (evt.costUsd) costCounter.add(...)` guard is falsy, and the
27
+ * `openclaw_cost_usd_total` counter stays at zero.
28
+ *
29
+ * What this file does
30
+ * -------------------
31
+ * Tails session transcripts (`~/.openclaw/agents/<id>/sessions/*.jsonl`),
32
+ * which already contain `usage.cost.total` because the completion path
33
+ * filled them in. Parses new entries on a 2s tick, filters to
34
+ * `provider === "runware"`, and writes to the same global OTel counter
35
+ * `openclaw.cost.usd` that diagnostics-otel tried (and failed) to write
36
+ * to. The OTel API stores its MeterProvider on a globalThis symbol slot
37
+ * so plugin-side `getMeter(...).createCounter("openclaw.cost.usd", ...)`
38
+ * shares the MeterProvider that diagnostics-otel registered at gateway
39
+ * start. Counter writes from both sides land on the same
40
+ * `(name, attributes)` time series in OTLP → Prometheus → GMP.
41
+ *
42
+ * Why polling and not a hook
43
+ * --------------------------
44
+ * `llm_output` and `agent_end` carry usage, but openclaw blocks them for
45
+ * non-bundled plugins unless `plugins.entries.<id>.hooks
46
+ * .allowConversationAccess: true` is set in openclaw.json — i.e. in the
47
+ * manager. `model_call_ended` is bundled-accessible but only carries
48
+ * sanitized metadata (no usage). `wrapStreamFn` is a provider-runtime
49
+ * hook on `registerProvider` but `register(api)` is not invoked for
50
+ * external plugins in 2026.5.x and behavior is unverified in 2026.6.1.
51
+ * Tailing the transcript file is the one path that does not depend on
52
+ * any of those (the transcripts are written by the completion path
53
+ * regardless of hooks).
54
+ *
55
+ * Double-counting safety
56
+ * ----------------------
57
+ * On startup the poller takes the current size of every transcript
58
+ * file as the initial offset — existing entries are assumed already
59
+ * accounted for by whatever was running before. Only bytes appended
60
+ * after startup emit metrics. Gateway restart resets all offsets, which
61
+ * is the correct behavior for a process-scoped counter (Prometheus
62
+ * `rate()` handles counter resets).
63
+ *
64
+ * If openclaw eventually fixes the diagnostic path so that
65
+ * `evt.costUsd` is populated for runware, both writers will increment
66
+ * the same series and the metric will double for runware. At that point
67
+ * delete this module. (We do not attempt to detect that case at runtime
68
+ * because diagnostics-otel does not expose its emit-or-skip decision to
69
+ * other plugins.)
70
+ */
71
+ import { createReadStream } from "node:fs";
72
+ import { readdir, stat } from "node:fs/promises";
73
+ import { homedir } from "node:os";
74
+ import { join } from "node:path";
75
+ const GLOBAL_KEY = "__runware_openclaw_cost_metric__";
76
+ const POLL_INTERVAL_MS = 2000;
77
+ const RUNWARE_PROVIDER = "runware";
78
+ const METER_NAME = "runware-openclaw-provider";
79
+ const METRIC_NAME = "openclaw.cost.usd";
80
+ function loadState() {
81
+ const g = globalThis;
82
+ const existing = g[GLOBAL_KEY];
83
+ if (existing)
84
+ return existing;
85
+ const fresh = {
86
+ initialized: false,
87
+ counter: null,
88
+ counterInit: null,
89
+ emittedAny: false,
90
+ fileStates: new Map(),
91
+ intervalHandle: null,
92
+ };
93
+ g[GLOBAL_KEY] = fresh;
94
+ return fresh;
95
+ }
96
+ /**
97
+ * Idempotent. Safe to call from multiple plugin entry files; only the
98
+ * first call starts the interval, subsequent calls return immediately.
99
+ * Survives openclaw plugin hot-reload because state lives on
100
+ * `globalThis`.
101
+ */
102
+ export function startCostMetricPoller(opts) {
103
+ const state = loadState();
104
+ if (state.initialized)
105
+ return;
106
+ state.initialized = true;
107
+ const openclawHome = opts?.openclawHome ??
108
+ process.env.OPENCLAW_HOME ??
109
+ join(homedir(), ".openclaw");
110
+ const intervalMs = opts?.intervalMs ?? POLL_INTERVAL_MS;
111
+ state.counterInit = initCounter()
112
+ .then((counter) => {
113
+ state.counter = counter;
114
+ })
115
+ .catch((err) => {
116
+ console.warn("[runware-cost-metric] OTel init failed:", err);
117
+ state.counter = null;
118
+ });
119
+ const tick = () => {
120
+ pollOnce(openclawHome, state).catch((err) => {
121
+ console.error("[runware-cost-metric] poll error:", err);
122
+ });
123
+ };
124
+ const handle = setInterval(tick, intervalMs);
125
+ state.intervalHandle = handle;
126
+ if (typeof handle.unref === "function")
127
+ handle.unref();
128
+ console.log(`[runware-cost-metric] started, intervalMs=${intervalMs} openclawHome=${openclawHome}`);
129
+ }
130
+ async function initCounter() {
131
+ // Dynamic import so a missing @opentelemetry/api doesn't break the
132
+ // plugin entry. Typed structurally — we don't import OTel types
133
+ // statically because verbatimModuleSyntax disallows type-only imports
134
+ // here without `import type`, and the dynamic shape is all we need.
135
+ const otel = (await import("@opentelemetry/api"));
136
+ const meter = otel.metrics.getMeter(METER_NAME);
137
+ return meter.createCounter(METRIC_NAME, {
138
+ description: "Estimated model cost in USD (emitted by runware plugin)",
139
+ unit: "USD",
140
+ });
141
+ }
142
+ async function pollOnce(openclawHome, state) {
143
+ if (state.counterInit) {
144
+ await state.counterInit;
145
+ state.counterInit = null;
146
+ }
147
+ if (!state.counter)
148
+ return;
149
+ const agentsDir = join(openclawHome, "agents");
150
+ let agents;
151
+ try {
152
+ agents = await readdir(agentsDir);
153
+ }
154
+ catch {
155
+ return;
156
+ }
157
+ for (const agent of agents) {
158
+ await pollSessionsDir(join(agentsDir, agent, "sessions"), state);
159
+ }
160
+ }
161
+ async function pollSessionsDir(sessionsDir, state) {
162
+ let entries;
163
+ try {
164
+ entries = await readdir(sessionsDir);
165
+ }
166
+ catch {
167
+ return;
168
+ }
169
+ for (const entry of entries) {
170
+ if (!entry.endsWith(".jsonl"))
171
+ continue;
172
+ await pollSessionFile(join(sessionsDir, entry), state);
173
+ }
174
+ }
175
+ async function pollSessionFile(path, state) {
176
+ let info;
177
+ try {
178
+ const s = await stat(path);
179
+ info = { ino: s.ino, size: s.size };
180
+ }
181
+ catch {
182
+ state.fileStates.delete(path);
183
+ return;
184
+ }
185
+ const prev = state.fileStates.get(path);
186
+ // First sighting: anchor to current size. Existing content predates
187
+ // this poller and is assumed already counted by whatever metric path
188
+ // was active before. We only emit for bytes appended after startup.
189
+ if (!prev) {
190
+ state.fileStates.set(path, {
191
+ offset: info.size,
192
+ inode: info.ino,
193
+ size: info.size,
194
+ });
195
+ return;
196
+ }
197
+ // Rotation or truncation: re-anchor and skip emission for this tick.
198
+ if (prev.inode !== info.ino || info.size < prev.size) {
199
+ state.fileStates.set(path, {
200
+ offset: info.size,
201
+ inode: info.ino,
202
+ size: info.size,
203
+ });
204
+ return;
205
+ }
206
+ if (info.size === prev.offset) {
207
+ state.fileStates.set(path, {
208
+ offset: prev.offset,
209
+ inode: info.ino,
210
+ size: info.size,
211
+ });
212
+ return;
213
+ }
214
+ const chunk = await readBytes(path, prev.offset, info.size);
215
+ const consumed = parseAndEmit(chunk, state);
216
+ state.fileStates.set(path, {
217
+ offset: prev.offset + consumed,
218
+ inode: info.ino,
219
+ size: info.size,
220
+ });
221
+ }
222
+ function readBytes(path, start, end) {
223
+ return new Promise((resolve, reject) => {
224
+ const parts = [];
225
+ const stream = createReadStream(path, {
226
+ start,
227
+ end: Math.max(start, end - 1),
228
+ encoding: "utf8",
229
+ });
230
+ stream.on("data", (chunk) => {
231
+ parts.push(typeof chunk === "string" ? chunk : chunk.toString("utf8"));
232
+ });
233
+ stream.on("end", () => resolve(parts.join("")));
234
+ stream.on("error", reject);
235
+ });
236
+ }
237
+ function parseAndEmit(chunk, state) {
238
+ if (chunk.length === 0)
239
+ return 0;
240
+ // Trailing bytes after the last `\n` are a partial line still being
241
+ // flushed by openclaw. Leave them for the next tick.
242
+ const lastNewline = chunk.lastIndexOf("\n");
243
+ if (lastNewline === -1)
244
+ return 0;
245
+ const lines = chunk.slice(0, lastNewline).split("\n");
246
+ for (const line of lines) {
247
+ if (line.length === 0 || line.trim().length === 0)
248
+ continue;
249
+ let parsed;
250
+ try {
251
+ parsed = JSON.parse(line);
252
+ }
253
+ catch {
254
+ continue;
255
+ }
256
+ emitFromEntry(parsed, state);
257
+ }
258
+ return lastNewline + 1;
259
+ }
260
+ function emitFromEntry(entry, state) {
261
+ if (!state.counter || !isRecord(entry))
262
+ return;
263
+ if (readProvider(entry) !== RUNWARE_PROVIDER)
264
+ return;
265
+ const cost = readCostUsd(entry);
266
+ if (cost <= 0)
267
+ return;
268
+ const attrs = {
269
+ "openclaw.provider": RUNWARE_PROVIDER,
270
+ "openclaw.model": readModel(entry) ?? "unknown",
271
+ };
272
+ const channel = readChannel(entry);
273
+ if (channel)
274
+ attrs["openclaw.channel"] = channel;
275
+ try {
276
+ state.counter.add(cost, attrs);
277
+ if (!state.emittedAny) {
278
+ state.emittedAny = true;
279
+ console.log(`[runware-cost-metric] first emit: ${cost.toFixed(6)} USD ${JSON.stringify(attrs)}`);
280
+ }
281
+ }
282
+ catch (err) {
283
+ console.error("[runware-cost-metric] counter.add failed:", err);
284
+ }
285
+ }
286
+ function isRecord(v) {
287
+ return v !== null && typeof v === "object";
288
+ }
289
+ function readProvider(entry) {
290
+ if (typeof entry.provider === "string")
291
+ return entry.provider;
292
+ const model = entry.model;
293
+ if (typeof model === "string") {
294
+ const slash = model.indexOf("/");
295
+ if (slash > 0)
296
+ return model.slice(0, slash);
297
+ }
298
+ return undefined;
299
+ }
300
+ function readCostUsd(entry) {
301
+ const usage = entry.usage;
302
+ if (isRecord(usage)) {
303
+ const cost = usage.cost;
304
+ if (isRecord(cost) &&
305
+ typeof cost.total === "number" &&
306
+ Number.isFinite(cost.total)) {
307
+ return cost.total;
308
+ }
309
+ if (typeof usage.costUsd === "number" &&
310
+ Number.isFinite(usage.costUsd)) {
311
+ return usage.costUsd;
312
+ }
313
+ }
314
+ if (typeof entry.costUsd === "number" && Number.isFinite(entry.costUsd)) {
315
+ return entry.costUsd;
316
+ }
317
+ return 0;
318
+ }
319
+ function readModel(entry) {
320
+ if (typeof entry.model === "string")
321
+ return entry.model;
322
+ if (typeof entry.modelId === "string")
323
+ return entry.modelId;
324
+ return undefined;
325
+ }
326
+ function readChannel(entry) {
327
+ if (typeof entry.channel === "string")
328
+ return entry.channel;
329
+ const meta = entry.metadata;
330
+ if (isRecord(meta) && typeof meta.channel === "string")
331
+ return meta.channel;
332
+ return undefined;
333
+ }
334
+ //# sourceMappingURL=cost-metric.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cost-metric.js","sourceRoot":"","sources":["../src/cost-metric.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAkB,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,QAAA,MAAM,KAAK,EAAE,WAkCZ,CAAC;AAEF,eAAe,KAAK,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAkB,WAAW,EAAE,MAAM,mBAAmB,CAAC;AASrE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,QAAA,MAAM,KAAK,EAAE,WAkCZ,CAAC;AAEF,eAAe,KAAK,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,8 @@
1
1
  import { API_KEY_ENV_VAR, BASE_URL_ENV_VAR, PROVIDER_ID, PROVIDER_LABEL, buildCatalogRows, buildProvider, resolveApiKey, resolveBaseUrl, } from "./models.js";
2
+ import { startCostMetricPoller } from "./cost-metric.js";
3
+ // See cost-metric.ts. Idempotent across both entry files via
4
+ // globalThis-stored state — whichever module openclaw loads first wins.
5
+ startCostMetricPoller();
2
6
  const PLUGIN_ID = "runware-openclaw-provider";
3
7
  /**
4
8
  * Plugin entry that openclaw's plugin loader invokes after `npm install`-ing
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,cAAc,GACf,MAAM,aAAa,CAAC;AAGrB,MAAM,SAAS,GAAG,2BAA2B,CAAC;AAE9C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,KAAK,GAAgB;IACzB,EAAE,EAAE,SAAS;IACb,IAAI,EAAE,cAAc;IACpB,WAAW,EACT,yGAAyG;IAE3G,QAAQ,CAAC,GAAG;QACV,GAAG,CAAC,gBAAgB,CAAC;YACnB,EAAE,EAAE,WAAW;YACf,KAAK,EAAE,cAAc;YACrB,QAAQ,EAAE,yBAAyB;YACnC,OAAO,EAAE,CAAC,eAAe,EAAE,gBAAgB,CAAC;YAC5C,IAAI,EAAE,EAAE;YACR,OAAO,EAAE;gBACP,KAAK,EAAE,QAAQ;gBACf,GAAG,EAAE,KAAK,EAAE,GAAmB,EAAE,EAAE;oBACjC,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;oBAClC,IAAI,CAAC,MAAM;wBAAE,OAAO,IAAI,CAAC;oBACzB,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;oBACtE,OAAO,EAAE,QAAQ,EAAE,CAAC;gBACtB,CAAC;aACF;SACF,CAAC,CAAC;QAEH,GAAG,CAAC,4BAA4B,CAAC;YAC/B,QAAQ,EAAE,WAAW;YACrB,KAAK,EAAE,CAAC,MAAM,CAAC;YACf,WAAW,EAAE,KAAK,EAAE,GAAmB,EAAE,EAAE;gBACzC,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;gBAClC,IAAI,CAAC,MAAM;oBAAE,OAAO,IAAI,CAAC;gBACzB,OAAO,gBAAgB,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3D,CAAC;SACF,CAAC,CAAC;IACL,CAAC;CACF,CAAC;AAEF,eAAe,KAAK,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,cAAc,GACf,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,6DAA6D;AAC7D,wEAAwE;AACxE,qBAAqB,EAAE,CAAC;AAExB,MAAM,SAAS,GAAG,2BAA2B,CAAC;AAE9C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,KAAK,GAAgB;IACzB,EAAE,EAAE,SAAS;IACb,IAAI,EAAE,cAAc;IACpB,WAAW,EACT,yGAAyG;IAE3G,QAAQ,CAAC,GAAG;QACV,GAAG,CAAC,gBAAgB,CAAC;YACnB,EAAE,EAAE,WAAW;YACf,KAAK,EAAE,cAAc;YACrB,QAAQ,EAAE,yBAAyB;YACnC,OAAO,EAAE,CAAC,eAAe,EAAE,gBAAgB,CAAC;YAC5C,IAAI,EAAE,EAAE;YACR,OAAO,EAAE;gBACP,KAAK,EAAE,QAAQ;gBACf,GAAG,EAAE,KAAK,EAAE,GAAmB,EAAE,EAAE;oBACjC,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;oBAClC,IAAI,CAAC,MAAM;wBAAE,OAAO,IAAI,CAAC;oBACzB,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;oBACtE,OAAO,EAAE,QAAQ,EAAE,CAAC;gBACtB,CAAC;aACF;SACF,CAAC,CAAC;QAEH,GAAG,CAAC,4BAA4B,CAAC;YAC/B,QAAQ,EAAE,WAAW;YACrB,KAAK,EAAE,CAAC,MAAM,CAAC;YACf,WAAW,EAAE,KAAK,EAAE,GAAmB,EAAE,EAAE;gBACzC,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;gBAClC,IAAI,CAAC,MAAM;oBAAE,OAAO,IAAI,CAAC;gBACzB,OAAO,gBAAgB,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3D,CAAC;SACF,CAAC,CAAC;IACL,CAAC;CACF,CAAC;AAEF,eAAe,KAAK,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"provider-discovery.d.ts","sourceRoot":"","sources":["../src/provider-discovery.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,gBAAgB,EAMjB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD;;;;;;;;;;;;;;GAcG;AAEH,UAAU,YAAY;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,qBAAqB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACrE;AAYD,iBAAe,iBAAiB,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,aAAa,CAAA;CAAE,CAAC,CAUxF;AAED,QAAA,MAAM,wBAAwB;;;;;;;;;;CAU7B,CAAC;AAEF,eAAe,wBAAwB,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
1
+ {"version":3,"file":"provider-discovery.d.ts","sourceRoot":"","sources":["../src/provider-discovery.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,gBAAgB,EAMjB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAUjD;;;;;;;;;;;;;;GAcG;AAEH,UAAU,YAAY;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,qBAAqB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACrE;AAYD,iBAAe,iBAAiB,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,aAAa,CAAA;CAAE,CAAC,CAUxF;AAED,QAAA,MAAM,wBAAwB;;;;;;;;;;CAU7B,CAAC;AAEF,eAAe,wBAAwB,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
@@ -1,4 +1,11 @@
1
1
  import { API_KEY_ENV_VAR, BASE_URL_ENV_VAR, DEFAULT_BASE_URL, PROVIDER_ID, PROVIDER_LABEL, buildProvider, resolveApiKey, resolveBaseUrl, } from "./models.js";
2
+ import { startCostMetricPoller } from "./cost-metric.js";
3
+ // Emit `openclaw.cost.usd` OpenTelemetry counter from runware transcript
4
+ // entries. Compensates for openclaw's broken diagnostic-path pricing
5
+ // resolver (cachedPricing Map never sees runware pricing). See
6
+ // cost-metric.ts for the full rationale. Idempotent: also called from
7
+ // index.ts, second call is a no-op.
8
+ startCostMetricPoller();
2
9
  function emptyProvider(baseUrl) {
3
10
  return {
4
11
  baseUrl,
@@ -1 +1 @@
1
- {"version":3,"file":"provider-discovery.js","sourceRoot":"","sources":["../src/provider-discovery.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,aAAa,EACb,aAAa,EACb,cAAc,GACf,MAAM,aAAa,CAAC;AAwBrB,SAAS,aAAa,CAAC,OAAe;IACpC,OAAO;QACL,OAAO;QACP,MAAM,EAAE,EAAE;QACV,GAAG,EAAE,oBAAoB;QACzB,cAAc,EAAE,GAAG;QACnB,MAAM,EAAE,EAAE;KACX,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,GAAiB;IAChD,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IAClC,uEAAuE;IACvE,0EAA0E;IAC1E,uEAAuE;IACvE,wEAAwE;IACxE,yDAAyD;IACzD,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;IACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;AAC5D,CAAC;AAED,MAAM,wBAAwB,GAAG;IAC/B,EAAE,EAAE,WAAW;IACf,KAAK,EAAE,cAAc;IACrB,QAAQ,EAAE,yBAAyB;IACnC,OAAO,EAAE,CAAC,eAAe,EAAE,gBAAgB,CAAC;IAC5C,IAAI,EAAE,EAAE;IACR,OAAO,EAAE;QACP,KAAK,EAAE,MAAe;QACtB,GAAG,EAAE,iBAAiB;KACvB;CACF,CAAC;AAEF,eAAe,wBAAwB,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
1
+ {"version":3,"file":"provider-discovery.js","sourceRoot":"","sources":["../src/provider-discovery.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,aAAa,EACb,aAAa,EACb,cAAc,GACf,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,yEAAyE;AACzE,qEAAqE;AACrE,+DAA+D;AAC/D,sEAAsE;AACtE,oCAAoC;AACpC,qBAAqB,EAAE,CAAC;AAuBxB,SAAS,aAAa,CAAC,OAAe;IACpC,OAAO;QACL,OAAO;QACP,MAAM,EAAE,EAAE;QACV,GAAG,EAAE,oBAAoB;QACzB,cAAc,EAAE,GAAG;QACnB,MAAM,EAAE,EAAE;KACX,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,GAAiB;IAChD,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IAClC,uEAAuE;IACvE,0EAA0E;IAC1E,uEAAuE;IACvE,wEAAwE;IACxE,yDAAyD;IACzD,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;IACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;AAC5D,CAAC;AAED,MAAM,wBAAwB,GAAG;IAC/B,EAAE,EAAE,WAAW;IACf,KAAK,EAAE,cAAc;IACrB,QAAQ,EAAE,yBAAyB;IACnC,OAAO,EAAE,CAAC,eAAe,EAAE,gBAAgB,CAAC;IAC5C,IAAI,EAAE,EAAE;IACR,OAAO,EAAE;QACP,KAAK,EAAE,MAAe;QACtB,GAAG,EAAE,iBAAiB;KACvB;CACF,CAAC;AAEF,eAAe,wBAAwB,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teith/openclaw-runware-provider",
3
- "version": "0.3.3",
3
+ "version": "0.3.4",
4
4
  "description": "OpenClaw provider plugin for Runware — unified OpenAI-compatible access to Claude, GPT, Gemini, Qwen, GLM, MiniMax, Kimi, and Gemma.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -54,6 +54,9 @@
54
54
  "engines": {
55
55
  "node": ">=20"
56
56
  },
57
+ "dependencies": {
58
+ "@opentelemetry/api": "^1.9.0"
59
+ },
57
60
  "devDependencies": {
58
61
  "@types/node": "^22.0.0",
59
62
  "typescript": "^5.6.0",