feat: add diagnostics events and otel exporter
This commit is contained in:
@@ -136,6 +136,72 @@ Tool summaries can redact sensitive tokens before they hit the console:
|
||||
|
||||
Redaction affects **console output only** and does not alter file logs.
|
||||
|
||||
## Diagnostics + OpenTelemetry
|
||||
|
||||
Diagnostics are **opt-in** structured events for model runs (usage + cost +
|
||||
context + duration). They do **not** replace logs; they exist to feed metrics,
|
||||
traces, and other exporters.
|
||||
|
||||
Clawdbot currently emits a `model.usage` event after each agent run with:
|
||||
|
||||
- Token counts (input/output/cache/prompt/total)
|
||||
- Estimated cost (USD)
|
||||
- Context window used/limit
|
||||
- Duration (ms)
|
||||
- Provider/channel/model + session identifiers
|
||||
|
||||
### Enable diagnostics (no exporter)
|
||||
|
||||
Use this if you want diagnostics events available to plugins or custom sinks:
|
||||
|
||||
```json
|
||||
{
|
||||
"diagnostics": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Export to OpenTelemetry
|
||||
|
||||
Diagnostics can be exported via the `diagnostics-otel` plugin (OTLP/HTTP). This
|
||||
works with any OpenTelemetry collector/backend that accepts OTLP/HTTP.
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": {
|
||||
"allow": ["diagnostics-otel"],
|
||||
"entries": {
|
||||
"diagnostics-otel": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"diagnostics": {
|
||||
"enabled": true,
|
||||
"otel": {
|
||||
"enabled": true,
|
||||
"endpoint": "http://otel-collector:4318",
|
||||
"protocol": "http/protobuf",
|
||||
"serviceName": "clawdbot-gateway",
|
||||
"traces": true,
|
||||
"metrics": true,
|
||||
"sampleRate": 0.2,
|
||||
"flushIntervalMs": 60000
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Notes:
|
||||
- You can also enable the plugin with `clawdbot plugins enable diagnostics-otel`.
|
||||
- `protocol` currently supports `http/protobuf`.
|
||||
- Metrics include token usage, cost, context size, and run duration.
|
||||
- Traces/metrics can be toggled with `traces` / `metrics` (default: on).
|
||||
- Set `headers` when your collector requires auth.
|
||||
- Environment variables supported: `OTEL_EXPORTER_OTLP_ENDPOINT`,
|
||||
`OTEL_SERVICE_NAME`, `OTEL_EXPORTER_OTLP_PROTOCOL`.
|
||||
|
||||
## Troubleshooting tips
|
||||
|
||||
- **Gateway not reachable?** Run `clawdbot doctor` first.
|
||||
|
||||
8
extensions/diagnostics-otel/clawdbot.plugin.json
Normal file
8
extensions/diagnostics-otel/clawdbot.plugin.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"id": "diagnostics-otel",
|
||||
"configSchema": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {}
|
||||
}
|
||||
}
|
||||
16
extensions/diagnostics-otel/index.ts
Normal file
16
extensions/diagnostics-otel/index.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import type { ClawdbotPluginApi } from "clawdbot/plugin-sdk";
|
||||
import { emptyPluginConfigSchema } from "clawdbot/plugin-sdk";
|
||||
|
||||
import { createDiagnosticsOtelService } from "./src/service.js";
|
||||
|
||||
const plugin = {
|
||||
id: "diagnostics-otel",
|
||||
name: "Diagnostics OpenTelemetry",
|
||||
description: "Export diagnostics events to OpenTelemetry",
|
||||
configSchema: emptyPluginConfigSchema(),
|
||||
register(api: ClawdbotPluginApi) {
|
||||
api.registerService(createDiagnosticsOtelService());
|
||||
},
|
||||
};
|
||||
|
||||
export default plugin;
|
||||
19
extensions/diagnostics-otel/package.json
Normal file
19
extensions/diagnostics-otel/package.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "@clawdbot/diagnostics-otel",
|
||||
"version": "2026.1.17-1",
|
||||
"type": "module",
|
||||
"description": "Clawdbot diagnostics OpenTelemetry exporter",
|
||||
"clawdbot": {
|
||||
"extensions": ["./index.ts"]
|
||||
},
|
||||
"dependencies": {
|
||||
"@opentelemetry/api": "^1.9.0",
|
||||
"@opentelemetry/exporter-metrics-otlp-http": "^0.210.0",
|
||||
"@opentelemetry/exporter-trace-otlp-http": "^0.210.0",
|
||||
"@opentelemetry/resources": "^2.4.0",
|
||||
"@opentelemetry/sdk-metrics": "^2.4.0",
|
||||
"@opentelemetry/sdk-node": "^0.210.0",
|
||||
"@opentelemetry/sdk-trace-base": "^2.4.0",
|
||||
"@opentelemetry/semantic-conventions": "^1.39.0"
|
||||
}
|
||||
}
|
||||
196
extensions/diagnostics-otel/src/service.ts
Normal file
196
extensions/diagnostics-otel/src/service.ts
Normal file
@@ -0,0 +1,196 @@
|
||||
import { metrics, trace } from "@opentelemetry/api";
|
||||
import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-http";
|
||||
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
|
||||
import { Resource } from "@opentelemetry/resources";
|
||||
import { PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics";
|
||||
import { NodeSDK } from "@opentelemetry/sdk-node";
|
||||
import { ParentBasedSampler, TraceIdRatioBasedSampler } from "@opentelemetry/sdk-trace-base";
|
||||
import { SemanticResourceAttributes } from "@opentelemetry/semantic-conventions";
|
||||
|
||||
import type {
|
||||
ClawdbotPluginService,
|
||||
DiagnosticUsageEvent,
|
||||
} from "clawdbot/plugin-sdk";
|
||||
import { onDiagnosticEvent } from "clawdbot/plugin-sdk";
|
||||
|
||||
const DEFAULT_SERVICE_NAME = "clawdbot";
|
||||
|
||||
function normalizeEndpoint(endpoint?: string): string | undefined {
|
||||
const trimmed = endpoint?.trim();
|
||||
return trimmed ? trimmed.replace(/\/+$/, "") : undefined;
|
||||
}
|
||||
|
||||
function resolveOtelUrl(endpoint: string | undefined, path: string): string | undefined {
|
||||
if (!endpoint) return undefined;
|
||||
if (endpoint.includes("/v1/")) return endpoint;
|
||||
return `${endpoint}/${path}`;
|
||||
}
|
||||
|
||||
function resolveSampleRate(value: number | undefined): number | undefined {
|
||||
if (typeof value !== "number" || !Number.isFinite(value)) return undefined;
|
||||
if (value < 0 || value > 1) return undefined;
|
||||
return value;
|
||||
}
|
||||
|
||||
export function createDiagnosticsOtelService(): ClawdbotPluginService {
|
||||
let sdk: NodeSDK | null = null;
|
||||
let unsubscribe: (() => void) | null = null;
|
||||
|
||||
return {
|
||||
id: "diagnostics-otel",
|
||||
async start(ctx) {
|
||||
const cfg = ctx.config.diagnostics;
|
||||
const otel = cfg?.otel;
|
||||
if (!cfg?.enabled || !otel?.enabled) return;
|
||||
|
||||
const protocol = otel.protocol ?? process.env.OTEL_EXPORTER_OTLP_PROTOCOL ?? "http/protobuf";
|
||||
if (protocol !== "http/protobuf") {
|
||||
ctx.logger.warn(`diagnostics-otel: unsupported protocol ${protocol}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const endpoint = normalizeEndpoint(otel.endpoint ?? process.env.OTEL_EXPORTER_OTLP_ENDPOINT);
|
||||
const headers = otel.headers ?? undefined;
|
||||
const serviceName =
|
||||
otel.serviceName?.trim() || process.env.OTEL_SERVICE_NAME || DEFAULT_SERVICE_NAME;
|
||||
const sampleRate = resolveSampleRate(otel.sampleRate);
|
||||
|
||||
const tracesEnabled = otel.traces !== false;
|
||||
const metricsEnabled = otel.metrics !== false;
|
||||
if (!tracesEnabled && !metricsEnabled) return;
|
||||
|
||||
const resource = new Resource({
|
||||
[SemanticResourceAttributes.SERVICE_NAME]: serviceName,
|
||||
});
|
||||
|
||||
const traceUrl = resolveOtelUrl(endpoint, "v1/traces");
|
||||
const metricUrl = resolveOtelUrl(endpoint, "v1/metrics");
|
||||
const traceExporter = tracesEnabled
|
||||
? new OTLPTraceExporter({
|
||||
...(traceUrl ? { url: traceUrl } : {}),
|
||||
...(headers ? { headers } : {}),
|
||||
})
|
||||
: undefined;
|
||||
|
||||
const metricExporter = metricsEnabled
|
||||
? new OTLPMetricExporter({
|
||||
...(metricUrl ? { url: metricUrl } : {}),
|
||||
...(headers ? { headers } : {}),
|
||||
})
|
||||
: undefined;
|
||||
|
||||
const metricReader = metricExporter
|
||||
? new PeriodicExportingMetricReader({
|
||||
exporter: metricExporter,
|
||||
...(typeof otel.flushIntervalMs === "number"
|
||||
? { exportIntervalMillis: Math.max(1000, otel.flushIntervalMs) }
|
||||
: {}),
|
||||
})
|
||||
: undefined;
|
||||
|
||||
sdk = new NodeSDK({
|
||||
resource,
|
||||
...(traceExporter ? { traceExporter } : {}),
|
||||
...(metricReader ? { metricReader } : {}),
|
||||
...(sampleRate !== undefined
|
||||
? {
|
||||
sampler: new ParentBasedSampler({
|
||||
root: new TraceIdRatioBasedSampler(sampleRate),
|
||||
}),
|
||||
}
|
||||
: {}),
|
||||
});
|
||||
|
||||
await sdk.start();
|
||||
|
||||
const meter = metrics.getMeter("clawdbot");
|
||||
const tracer = trace.getTracer("clawdbot");
|
||||
|
||||
const tokensCounter = meter.createCounter("clawdbot.tokens", {
|
||||
unit: "1",
|
||||
description: "Token usage by type",
|
||||
});
|
||||
const costCounter = meter.createCounter("clawdbot.cost.usd", {
|
||||
unit: "1",
|
||||
description: "Estimated model cost (USD)",
|
||||
});
|
||||
const durationHistogram = meter.createHistogram("clawdbot.run.duration_ms", {
|
||||
unit: "ms",
|
||||
description: "Agent run duration",
|
||||
});
|
||||
const contextHistogram = meter.createHistogram("clawdbot.context.tokens", {
|
||||
unit: "1",
|
||||
description: "Context window size and usage",
|
||||
});
|
||||
|
||||
unsubscribe = onDiagnosticEvent((evt) => {
|
||||
if (evt.type !== "model.usage") return;
|
||||
const usageEvent = evt as DiagnosticUsageEvent;
|
||||
const attrs = {
|
||||
"clawdbot.channel": usageEvent.channel ?? "unknown",
|
||||
"clawdbot.provider": usageEvent.provider ?? "unknown",
|
||||
"clawdbot.model": usageEvent.model ?? "unknown",
|
||||
};
|
||||
|
||||
const usage = usageEvent.usage;
|
||||
if (usage.input) tokensCounter.add(usage.input, { ...attrs, "clawdbot.token": "input" });
|
||||
if (usage.output)
|
||||
tokensCounter.add(usage.output, { ...attrs, "clawdbot.token": "output" });
|
||||
if (usage.cacheRead)
|
||||
tokensCounter.add(usage.cacheRead, { ...attrs, "clawdbot.token": "cache_read" });
|
||||
if (usage.cacheWrite)
|
||||
tokensCounter.add(usage.cacheWrite, { ...attrs, "clawdbot.token": "cache_write" });
|
||||
if (usage.promptTokens)
|
||||
tokensCounter.add(usage.promptTokens, { ...attrs, "clawdbot.token": "prompt" });
|
||||
if (usage.total)
|
||||
tokensCounter.add(usage.total, { ...attrs, "clawdbot.token": "total" });
|
||||
|
||||
if (usageEvent.costUsd) costCounter.add(usageEvent.costUsd, attrs);
|
||||
if (usageEvent.durationMs) durationHistogram.record(usageEvent.durationMs, attrs);
|
||||
if (usageEvent.context?.limit)
|
||||
contextHistogram.record(usageEvent.context.limit, {
|
||||
...attrs,
|
||||
"clawdbot.context": "limit",
|
||||
});
|
||||
if (usageEvent.context?.used)
|
||||
contextHistogram.record(usageEvent.context.used, {
|
||||
...attrs,
|
||||
"clawdbot.context": "used",
|
||||
});
|
||||
|
||||
if (!tracesEnabled) return;
|
||||
const spanAttrs: Record<string, string | number> = {
|
||||
...attrs,
|
||||
"clawdbot.sessionKey": usageEvent.sessionKey ?? "",
|
||||
"clawdbot.sessionId": usageEvent.sessionId ?? "",
|
||||
"clawdbot.tokens.input": usage.input ?? 0,
|
||||
"clawdbot.tokens.output": usage.output ?? 0,
|
||||
"clawdbot.tokens.cache_read": usage.cacheRead ?? 0,
|
||||
"clawdbot.tokens.cache_write": usage.cacheWrite ?? 0,
|
||||
"clawdbot.tokens.total": usage.total ?? 0,
|
||||
};
|
||||
|
||||
const startTime = usageEvent.durationMs
|
||||
? Date.now() - Math.max(0, usageEvent.durationMs)
|
||||
: undefined;
|
||||
const span = tracer.startSpan("clawdbot.model.usage", {
|
||||
attributes: spanAttrs,
|
||||
...(startTime ? { startTime } : {}),
|
||||
});
|
||||
span.end();
|
||||
});
|
||||
|
||||
if (otel.logs) {
|
||||
ctx.logger.warn("diagnostics-otel: logs exporter not wired yet");
|
||||
}
|
||||
},
|
||||
async stop() {
|
||||
unsubscribe?.();
|
||||
unsubscribe = null;
|
||||
if (sdk) {
|
||||
await sdk.shutdown().catch(() => undefined);
|
||||
sdk = null;
|
||||
}
|
||||
},
|
||||
} satisfies ClawdbotPluginService;
|
||||
}
|
||||
540
pnpm-lock.yaml
generated
540
pnpm-lock.yaml
generated
@@ -243,7 +243,7 @@ importers:
|
||||
version: 5.9.3
|
||||
vitest:
|
||||
specifier: ^4.0.17
|
||||
version: 4.0.17(@types/node@25.0.9)(@vitest/browser-playwright@4.0.17)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)
|
||||
version: 4.0.17(@opentelemetry/api@1.9.0)(@types/node@25.0.9)(@vitest/browser-playwright@4.0.17)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)
|
||||
wireit:
|
||||
specifier: ^0.14.12
|
||||
version: 0.14.12
|
||||
@@ -259,6 +259,33 @@ importers:
|
||||
|
||||
extensions/copilot-proxy: {}
|
||||
|
||||
extensions/diagnostics-otel:
|
||||
dependencies:
|
||||
'@opentelemetry/api':
|
||||
specifier: ^1.9.0
|
||||
version: 1.9.0
|
||||
'@opentelemetry/exporter-metrics-otlp-http':
|
||||
specifier: ^0.210.0
|
||||
version: 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/exporter-trace-otlp-http':
|
||||
specifier: ^0.210.0
|
||||
version: 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/resources':
|
||||
specifier: ^2.4.0
|
||||
version: 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/sdk-metrics':
|
||||
specifier: ^2.4.0
|
||||
version: 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/sdk-node':
|
||||
specifier: ^0.210.0
|
||||
version: 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/sdk-trace-base':
|
||||
specifier: ^2.4.0
|
||||
version: 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/semantic-conventions':
|
||||
specifier: ^1.39.0
|
||||
version: 1.39.0
|
||||
|
||||
extensions/discord: {}
|
||||
|
||||
extensions/google-antigravity-auth: {}
|
||||
@@ -393,7 +420,7 @@ importers:
|
||||
version: 5.9.3
|
||||
vitest:
|
||||
specifier: 4.0.17
|
||||
version: 4.0.17(@types/node@25.0.9)(@vitest/browser-playwright@4.0.17)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)
|
||||
version: 4.0.17(@opentelemetry/api@1.9.0)(@types/node@25.0.9)(@vitest/browser-playwright@4.0.17)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)
|
||||
|
||||
packages:
|
||||
|
||||
@@ -817,6 +844,15 @@ packages:
|
||||
'@grammyjs/types@3.23.0':
|
||||
resolution: {integrity: sha512-D3jQ4UWERPsyR3op/YFudMMIPNTU47vy7L51uO9/73tMELmjO/+LX5N36/Y0CG5IQfIsz43MxiHI5rgsK0/k+g==}
|
||||
|
||||
'@grpc/grpc-js@1.14.3':
|
||||
resolution: {integrity: sha512-Iq8QQQ/7X3Sac15oB6p0FmUg/klxQvXLeileoqrTRGJYLV+/9tubbr9ipz0GKHjmXVsgFPo/+W+2cA8eNcR+XA==}
|
||||
engines: {node: '>=12.10.0'}
|
||||
|
||||
'@grpc/proto-loader@0.8.0':
|
||||
resolution: {integrity: sha512-rc1hOQtjIWGxcxpb9aHAfLpIctjEnsDehj0DAiVfBlmT84uvR0uUtN2hEi/ecvWVjXUGf5qPF4qEgiLOx1YIMQ==}
|
||||
engines: {node: '>=6'}
|
||||
hasBin: true
|
||||
|
||||
'@hapi/boom@9.1.4':
|
||||
resolution: {integrity: sha512-Ls1oH8jaN1vNsqcaHVYJrKmgMcKsC1wcp8bujvXrHaAqD2iDYq3HoOwsxwo09Cuda5R5nC0o0IxlrlTuvPuzSw==}
|
||||
|
||||
@@ -1000,6 +1036,9 @@ packages:
|
||||
'@jridgewell/trace-mapping@0.3.31':
|
||||
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
|
||||
|
||||
'@js-sdsl/ordered-map@4.4.2':
|
||||
resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==}
|
||||
|
||||
'@keyv/bigmap@1.3.0':
|
||||
resolution: {integrity: sha512-KT01GjzV6AQD5+IYrcpoYLkCu1Jod3nau1Z7EsEuViO3TZGRacSbO9MfHmbJ1WaOXFtWLxPVj169cn2WNKPkIg==}
|
||||
engines: {node: '>= 18'}
|
||||
@@ -1494,6 +1533,174 @@ packages:
|
||||
resolution: {integrity: sha512-da6KbdNCV5sr1/txD896V+6W0iamFWrvVl8cHkBSPT+YlvmT3DwXa4jxZnQc+gnuTEqSWbBeoSZYTayXH9wXcw==}
|
||||
engines: {node: '>= 20'}
|
||||
|
||||
'@opentelemetry/api-logs@0.210.0':
|
||||
resolution: {integrity: sha512-CMtLxp+lYDriveZejpBND/2TmadrrhUfChyxzmkFtHaMDdSKfP59MAYyA0ICBvEBdm3iXwLcaj/8Ic/pnGw9Yg==}
|
||||
engines: {node: '>=8.0.0'}
|
||||
|
||||
'@opentelemetry/api@1.9.0':
|
||||
resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==}
|
||||
engines: {node: '>=8.0.0'}
|
||||
|
||||
'@opentelemetry/configuration@0.210.0':
|
||||
resolution: {integrity: sha512-tM0ROS/hZM72kB55cSjDcghVcUXBJdGkGzpkhD7M1B/gpcvZPSGfjFgKN3dgmxNgF76NxtbUwv3ik0wS+Kz52g==}
|
||||
engines: {node: ^18.19.0 || >=20.6.0}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.9.0
|
||||
|
||||
'@opentelemetry/context-async-hooks@2.4.0':
|
||||
resolution: {integrity: sha512-jn0phJ+hU7ZuvaoZE/8/Euw3gvHJrn2yi+kXrymwObEPVPjtwCmkvXDRQCWli+fCTTF/aSOtXaLr7CLIvv3LQg==}
|
||||
engines: {node: ^18.19.0 || >=20.6.0}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': '>=1.0.0 <1.10.0'
|
||||
|
||||
'@opentelemetry/core@2.4.0':
|
||||
resolution: {integrity: sha512-KtcyFHssTn5ZgDu6SXmUznS80OFs/wN7y6MyFRRcKU6TOw8hNcGxKvt8hsdaLJfhzUszNSjURetq5Qpkad14Gw==}
|
||||
engines: {node: ^18.19.0 || >=20.6.0}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': '>=1.0.0 <1.10.0'
|
||||
|
||||
'@opentelemetry/exporter-logs-otlp-grpc@0.210.0':
|
||||
resolution: {integrity: sha512-+BolenqOO6ow65go7uWRYPvvs/BBIWp1mtRn93VvGduqvMVH/IY8nXrt80a4L9hZ7lHi2Tq2/NcC3H2QzcWKag==}
|
||||
engines: {node: ^18.19.0 || >=20.6.0}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.3.0
|
||||
|
||||
'@opentelemetry/exporter-logs-otlp-http@0.210.0':
|
||||
resolution: {integrity: sha512-Q8/SEQtgrErbVVRg9M9iaG8m5wdPNdU0UOF7U43sAhwfmPG92ZOk/aenKhg0DXSNJHhkCDNCgS1kSoErAB3z0A==}
|
||||
engines: {node: ^18.19.0 || >=20.6.0}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.3.0
|
||||
|
||||
'@opentelemetry/exporter-logs-otlp-proto@0.210.0':
|
||||
resolution: {integrity: sha512-Y/yPc+gDhsWB7AsNzQWxblw4ULbvhCycMaQ2aAn+HSAVbgbMiZa0SbclPVHSnpnNzKSLVavFjweAr0pQA1KKLg==}
|
||||
engines: {node: ^18.19.0 || >=20.6.0}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.3.0
|
||||
|
||||
'@opentelemetry/exporter-metrics-otlp-grpc@0.210.0':
|
||||
resolution: {integrity: sha512-pWZ/Tjrqev9rdkqe8F6A9FGddLZrjl6iRAU5LBvvRL6I3PSgG8z1xM0cESAy1jzAF4wGohnAh8rB7hHzpUOYEA==}
|
||||
engines: {node: ^18.19.0 || >=20.6.0}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.3.0
|
||||
|
||||
'@opentelemetry/exporter-metrics-otlp-http@0.210.0':
|
||||
resolution: {integrity: sha512-JpLThG8Hh8A/Jzdzw9i4Ftu+EzvLaX/LouN+mOOHmadL0iror0Qsi3QWzucXeiUsDDsiYgjfKyi09e6sltytgA==}
|
||||
engines: {node: ^18.19.0 || >=20.6.0}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.3.0
|
||||
|
||||
'@opentelemetry/exporter-metrics-otlp-proto@0.210.0':
|
||||
resolution: {integrity: sha512-CFa7SOinYOVWIWJuQL7XFeyedzmFGIpHpSMNFE8Xefb6iGB4m+MukQecdssvPcJKYlfF5FpovEOLXwafAzsXWQ==}
|
||||
engines: {node: ^18.19.0 || >=20.6.0}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.3.0
|
||||
|
||||
'@opentelemetry/exporter-prometheus@0.210.0':
|
||||
resolution: {integrity: sha512-8i+7d70Hho6pcheTtbqIuS+bo+AIX/oNUTMwIEZoehUE4ZdbGmeVaE+hJS2LAErFeFaU71w164lAgYyMUEQ8zw==}
|
||||
engines: {node: ^18.19.0 || >=20.6.0}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.3.0
|
||||
|
||||
'@opentelemetry/exporter-trace-otlp-grpc@0.210.0':
|
||||
resolution: {integrity: sha512-1GPLOyxIfUX24WM8Oea+vx9d9TlewposUnsQXTjusxVMQ/dWvt5JIDJyTsfNDS412XRUOORgF97PwsfDY5QKGA==}
|
||||
engines: {node: ^18.19.0 || >=20.6.0}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.3.0
|
||||
|
||||
'@opentelemetry/exporter-trace-otlp-http@0.210.0':
|
||||
resolution: {integrity: sha512-9JkyaCl70anEtuKZdoCQmjDuz1/paEixY/DWfsvHt7PGKq3t8/nQ/6/xwxHjG+SkPAUbo1Iq4h7STe7Pk2bc5A==}
|
||||
engines: {node: ^18.19.0 || >=20.6.0}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.3.0
|
||||
|
||||
'@opentelemetry/exporter-trace-otlp-proto@0.210.0':
|
||||
resolution: {integrity: sha512-qVUY7Hsm/t5buGOtPcTV1Ch4W9kj2wGaQaAF5FO4XR8TMKl2GM45tUCnr0/1dF3wo4RG9khMxrddeQWdRL4fIg==}
|
||||
engines: {node: ^18.19.0 || >=20.6.0}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.3.0
|
||||
|
||||
'@opentelemetry/exporter-zipkin@2.4.0':
|
||||
resolution: {integrity: sha512-qpiXY0TUEFjBBp9b1na9LfuVQw6W8LH+te7uv+CC+0Up78ZDtZZwOjK2M7CL7Nspnw+yS4JdgEA7oxsBu0Ctsg==}
|
||||
engines: {node: ^18.19.0 || >=20.6.0}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.0.0
|
||||
|
||||
'@opentelemetry/instrumentation@0.210.0':
|
||||
resolution: {integrity: sha512-sLMhyHmW9katVaLUOKpfCnxSGhZq2t1ReWgwsu2cSgxmDVMB690H9TanuexanpFI94PJaokrqbp8u9KYZDUT5g==}
|
||||
engines: {node: ^18.19.0 || >=20.6.0}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.3.0
|
||||
|
||||
'@opentelemetry/otlp-exporter-base@0.210.0':
|
||||
resolution: {integrity: sha512-uk78DcZoBNHIm26h0oXc8Pizh4KDJ/y04N5k/UaI9J7xR7mL8QcMcYPQG9xxN7m8qotXOMDRW6qTAyptav4+3w==}
|
||||
engines: {node: ^18.19.0 || >=20.6.0}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.3.0
|
||||
|
||||
'@opentelemetry/otlp-grpc-exporter-base@0.210.0':
|
||||
resolution: {integrity: sha512-fEJs8UhkFMrdXMOCLXyKd2uc6N209tIi8IBNqSTi83ri+MlMFrBKnOtklmv9/zzxovoN5zD1waRt6XBFGPfmIw==}
|
||||
engines: {node: ^18.19.0 || >=20.6.0}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.3.0
|
||||
|
||||
'@opentelemetry/otlp-transformer@0.210.0':
|
||||
resolution: {integrity: sha512-nkHBJVSJGOwkRZl+BFIr7gikA93/U8XkL2EWaiDbj3DVjmTEZQpegIKk0lT8oqQYfP8FC6zWNjuTfkaBVqa0ZQ==}
|
||||
engines: {node: ^18.19.0 || >=20.6.0}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.3.0
|
||||
|
||||
'@opentelemetry/propagator-b3@2.4.0':
|
||||
resolution: {integrity: sha512-6VPsFiMUkJBre/86F0d+PZMaUCcuLA9DtZuC46KH8EeVEKZPEM2WlX35M/qmde8UpzoQL9qzdz54YjUYABt8Uw==}
|
||||
engines: {node: ^18.19.0 || >=20.6.0}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': '>=1.0.0 <1.10.0'
|
||||
|
||||
'@opentelemetry/propagator-jaeger@2.4.0':
|
||||
resolution: {integrity: sha512-t6muBL/3AMD++1EMF658C/KIpj3gfmTmftX3mEQql4KIxNGFvacCmmTtrQt9IZAJmQRfjQRCkv+vsGbQugeJIw==}
|
||||
engines: {node: ^18.19.0 || >=20.6.0}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': '>=1.0.0 <1.10.0'
|
||||
|
||||
'@opentelemetry/resources@2.4.0':
|
||||
resolution: {integrity: sha512-RWvGLj2lMDZd7M/5tjkI/2VHMpXebLgPKvBUd9LRasEWR2xAynDwEYZuLvY9P2NGG73HF07jbbgWX2C9oavcQg==}
|
||||
engines: {node: ^18.19.0 || >=20.6.0}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': '>=1.3.0 <1.10.0'
|
||||
|
||||
'@opentelemetry/sdk-logs@0.210.0':
|
||||
resolution: {integrity: sha512-YuaL92Dpyk/Kc1o4e9XiaWWwiC0aBFN+4oy+6A9TP4UNJmRymPMEX10r6EMMFMD7V0hktiSig9cwWo59peeLCQ==}
|
||||
engines: {node: ^18.19.0 || >=20.6.0}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': '>=1.4.0 <1.10.0'
|
||||
|
||||
'@opentelemetry/sdk-metrics@2.4.0':
|
||||
resolution: {integrity: sha512-qSbfq9mXbLMqmPEjijl32f3ZEmiHekebRggPdPjhHI6t1CsAQOR2Aw/SuTDftk3/l2aaPHpwP3xM2DkgBA1ANw==}
|
||||
engines: {node: ^18.19.0 || >=20.6.0}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': '>=1.9.0 <1.10.0'
|
||||
|
||||
'@opentelemetry/sdk-node@0.210.0':
|
||||
resolution: {integrity: sha512-KymqUtYvfpblDNgGxBXYqCcDjYXwjOF7Muc6ocs0rMlG/66Hcs9KiJ7hg4zLOv63JubF/vxi5WXaLrQrPKyaZQ==}
|
||||
engines: {node: ^18.19.0 || >=20.6.0}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': '>=1.3.0 <1.10.0'
|
||||
|
||||
'@opentelemetry/sdk-trace-base@2.4.0':
|
||||
resolution: {integrity: sha512-WH0xXkz/OHORDLKqaxcUZS0X+t1s7gGlumr2ebiEgNZQl2b0upK2cdoD0tatf7l8iP74woGJ/Kmxe82jdvcWRw==}
|
||||
engines: {node: ^18.19.0 || >=20.6.0}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': '>=1.3.0 <1.10.0'
|
||||
|
||||
'@opentelemetry/sdk-trace-node@2.4.0':
|
||||
resolution: {integrity: sha512-MBc2l04hZPYygnWPT38UiOPy9ueutPqmJ47z0m9IKuoVQh3MblmbSgwspjhdHagZLfSfmlzhWR1xtbgVNmjX2A==}
|
||||
engines: {node: ^18.19.0 || >=20.6.0}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': '>=1.0.0 <1.10.0'
|
||||
|
||||
'@opentelemetry/semantic-conventions@1.39.0':
|
||||
resolution: {integrity: sha512-R5R9tb2AXs2IRLNKLBJDynhkfmx7mX0vi8NkhZb3gUkPWHn6HXk5J8iQ/dql0U3ApfWym4kXXmBDRGO+oeOfjg==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
'@oxc-project/types@0.108.0':
|
||||
resolution: {integrity: sha512-7lf13b2IA/kZO6xgnIZA88sq3vwrxWk+2vxf6cc+omwYCRTiA5e63Beqf3fz/v8jEviChWWmFYBwzfSeyrsj7Q==}
|
||||
|
||||
@@ -2376,6 +2583,16 @@ packages:
|
||||
resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
acorn-import-attributes@1.9.5:
|
||||
resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==}
|
||||
peerDependencies:
|
||||
acorn: ^8
|
||||
|
||||
acorn@8.15.0:
|
||||
resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
hasBin: true
|
||||
|
||||
agent-base@7.1.4:
|
||||
resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==}
|
||||
engines: {node: '>= 14'}
|
||||
@@ -2633,6 +2850,9 @@ packages:
|
||||
resolution: {integrity: sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
cjs-module-lexer@2.2.0:
|
||||
resolution: {integrity: sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==}
|
||||
|
||||
class-variance-authority@0.7.1:
|
||||
resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==}
|
||||
|
||||
@@ -3269,6 +3489,9 @@ packages:
|
||||
immediate@3.0.6:
|
||||
resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==}
|
||||
|
||||
import-in-the-middle@2.0.4:
|
||||
resolution: {integrity: sha512-Al0kMpa0BqfvDnxjxGlab9vdQ0vTDs82TBKrD59X9jReUoPAzSGBb6vGDzMUMFBGyyDF03RpLT4oxGn6BpASzQ==}
|
||||
|
||||
inherits@2.0.4:
|
||||
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
|
||||
|
||||
@@ -3759,6 +3982,9 @@ packages:
|
||||
engines: {node: '>=10'}
|
||||
hasBin: true
|
||||
|
||||
module-details-from-path@1.0.4:
|
||||
resolution: {integrity: sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==}
|
||||
|
||||
morgan@1.10.1:
|
||||
resolution: {integrity: sha512-223dMRJtI/l25dJKWpgij2cMtywuG/WiUKXdvwfbhGKBhy1puASqXwFzmWZ7+K73vUPoR7SS2Qz2cI/g9MKw0A==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
@@ -4161,6 +4387,10 @@ packages:
|
||||
resolution: {integrity: sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
|
||||
protobufjs@8.0.0:
|
||||
resolution: {integrity: sha512-jx6+sE9h/UryaCZhsJWbJtTEy47yXoGNYI4z8ZaRncM0zBKeRqjO2JEcOUYwrYGb1WLhXM1FfMzW3annvFv0rw==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
|
||||
proxy-addr@2.0.7:
|
||||
resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
|
||||
engines: {node: '>= 0.10'}
|
||||
@@ -4275,6 +4505,10 @@ packages:
|
||||
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
require-in-the-middle@8.0.1:
|
||||
resolution: {integrity: sha512-QT7FVMXfWOYFbeRBF6nu+I6tr2Tf3u0q8RIEjNob/heKY/nh7drD/k7eeMFmSQgnTtCzLDcCu/XEnpW2wk4xCQ==}
|
||||
engines: {node: '>=9.3.0 || >=8.10.0 <9.0.0'}
|
||||
|
||||
resolve-pkg-maps@1.0.0:
|
||||
resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
|
||||
|
||||
@@ -5632,6 +5866,18 @@ snapshots:
|
||||
|
||||
'@grammyjs/types@3.23.0': {}
|
||||
|
||||
'@grpc/grpc-js@1.14.3':
|
||||
dependencies:
|
||||
'@grpc/proto-loader': 0.8.0
|
||||
'@js-sdsl/ordered-map': 4.4.2
|
||||
|
||||
'@grpc/proto-loader@0.8.0':
|
||||
dependencies:
|
||||
lodash.camelcase: 4.3.0
|
||||
long: 5.3.2
|
||||
protobufjs: 7.5.4
|
||||
yargs: 17.7.2
|
||||
|
||||
'@hapi/boom@9.1.4':
|
||||
dependencies:
|
||||
'@hapi/hoek': 9.3.0
|
||||
@@ -5779,6 +6025,8 @@ snapshots:
|
||||
'@jridgewell/resolve-uri': 3.1.2
|
||||
'@jridgewell/sourcemap-codec': 1.5.5
|
||||
|
||||
'@js-sdsl/ordered-map@4.4.2': {}
|
||||
|
||||
'@keyv/bigmap@1.3.0(keyv@5.5.5)':
|
||||
dependencies:
|
||||
hashery: 1.4.0
|
||||
@@ -6333,6 +6581,241 @@ snapshots:
|
||||
'@octokit/webhooks-methods': 6.0.0
|
||||
optional: true
|
||||
|
||||
'@opentelemetry/api-logs@0.210.0':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.9.0
|
||||
|
||||
'@opentelemetry/api@1.9.0': {}
|
||||
|
||||
'@opentelemetry/configuration@0.210.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/core': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
yaml: 2.8.2
|
||||
|
||||
'@opentelemetry/context-async-hooks@2.4.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.9.0
|
||||
|
||||
'@opentelemetry/core@2.4.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/semantic-conventions': 1.39.0
|
||||
|
||||
'@opentelemetry/exporter-logs-otlp-grpc@0.210.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@grpc/grpc-js': 1.14.3
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/core': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/otlp-exporter-base': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/otlp-grpc-exporter-base': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/otlp-transformer': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/sdk-logs': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
|
||||
'@opentelemetry/exporter-logs-otlp-http@0.210.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/api-logs': 0.210.0
|
||||
'@opentelemetry/core': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/otlp-exporter-base': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/otlp-transformer': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/sdk-logs': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
|
||||
'@opentelemetry/exporter-logs-otlp-proto@0.210.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/api-logs': 0.210.0
|
||||
'@opentelemetry/core': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/otlp-exporter-base': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/otlp-transformer': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/resources': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/sdk-logs': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/sdk-trace-base': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
|
||||
'@opentelemetry/exporter-metrics-otlp-grpc@0.210.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@grpc/grpc-js': 1.14.3
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/core': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/exporter-metrics-otlp-http': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/otlp-exporter-base': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/otlp-grpc-exporter-base': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/otlp-transformer': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/resources': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/sdk-metrics': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
|
||||
'@opentelemetry/exporter-metrics-otlp-http@0.210.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/core': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/otlp-exporter-base': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/otlp-transformer': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/resources': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/sdk-metrics': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
|
||||
'@opentelemetry/exporter-metrics-otlp-proto@0.210.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/core': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/exporter-metrics-otlp-http': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/otlp-exporter-base': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/otlp-transformer': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/resources': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/sdk-metrics': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
|
||||
'@opentelemetry/exporter-prometheus@0.210.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/core': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/resources': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/sdk-metrics': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
|
||||
'@opentelemetry/exporter-trace-otlp-grpc@0.210.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@grpc/grpc-js': 1.14.3
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/core': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/otlp-exporter-base': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/otlp-grpc-exporter-base': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/otlp-transformer': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/resources': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/sdk-trace-base': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
|
||||
'@opentelemetry/exporter-trace-otlp-http@0.210.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/core': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/otlp-exporter-base': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/otlp-transformer': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/resources': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/sdk-trace-base': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
|
||||
'@opentelemetry/exporter-trace-otlp-proto@0.210.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/core': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/otlp-exporter-base': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/otlp-transformer': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/resources': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/sdk-trace-base': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
|
||||
'@opentelemetry/exporter-zipkin@2.4.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/core': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/resources': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/sdk-trace-base': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/semantic-conventions': 1.39.0
|
||||
|
||||
'@opentelemetry/instrumentation@0.210.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/api-logs': 0.210.0
|
||||
import-in-the-middle: 2.0.4
|
||||
require-in-the-middle: 8.0.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@opentelemetry/otlp-exporter-base@0.210.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/core': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/otlp-transformer': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
|
||||
'@opentelemetry/otlp-grpc-exporter-base@0.210.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@grpc/grpc-js': 1.14.3
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/core': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/otlp-exporter-base': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/otlp-transformer': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
|
||||
'@opentelemetry/otlp-transformer@0.210.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/api-logs': 0.210.0
|
||||
'@opentelemetry/core': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/resources': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/sdk-logs': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/sdk-metrics': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/sdk-trace-base': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
protobufjs: 8.0.0
|
||||
|
||||
'@opentelemetry/propagator-b3@2.4.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/core': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
|
||||
'@opentelemetry/propagator-jaeger@2.4.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/core': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
|
||||
'@opentelemetry/resources@2.4.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/core': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/semantic-conventions': 1.39.0
|
||||
|
||||
'@opentelemetry/sdk-logs@0.210.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/api-logs': 0.210.0
|
||||
'@opentelemetry/core': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/resources': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
|
||||
'@opentelemetry/sdk-metrics@2.4.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/core': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/resources': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
|
||||
'@opentelemetry/sdk-node@0.210.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/api-logs': 0.210.0
|
||||
'@opentelemetry/configuration': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/context-async-hooks': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/core': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/exporter-logs-otlp-grpc': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/exporter-logs-otlp-http': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/exporter-logs-otlp-proto': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/exporter-metrics-otlp-grpc': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/exporter-metrics-otlp-http': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/exporter-metrics-otlp-proto': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/exporter-prometheus': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/exporter-trace-otlp-grpc': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/exporter-trace-otlp-http': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/exporter-trace-otlp-proto': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/exporter-zipkin': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/instrumentation': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/propagator-b3': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/propagator-jaeger': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/resources': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/sdk-logs': 0.210.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/sdk-metrics': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/sdk-trace-base': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/sdk-trace-node': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/semantic-conventions': 1.39.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@opentelemetry/sdk-trace-base@2.4.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/core': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/resources': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/semantic-conventions': 1.39.0
|
||||
|
||||
'@opentelemetry/sdk-trace-node@2.4.0(@opentelemetry/api@1.9.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/context-async-hooks': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/core': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
'@opentelemetry/sdk-trace-base': 2.4.0(@opentelemetry/api@1.9.0)
|
||||
|
||||
'@opentelemetry/semantic-conventions@1.39.0': {}
|
||||
|
||||
'@oxc-project/types@0.108.0': {}
|
||||
|
||||
'@oxfmt/darwin-arm64@0.26.0':
|
||||
@@ -7145,7 +7628,7 @@ snapshots:
|
||||
'@vitest/mocker': 4.0.17(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))
|
||||
playwright: 1.57.0
|
||||
tinyrainbow: 3.0.3
|
||||
vitest: 4.0.17(@types/node@25.0.9)(@vitest/browser-playwright@4.0.17)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)
|
||||
vitest: 4.0.17(@opentelemetry/api@1.9.0)(@types/node@25.0.9)(@vitest/browser-playwright@4.0.17)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- msw
|
||||
@@ -7161,7 +7644,7 @@ snapshots:
|
||||
pngjs: 7.0.0
|
||||
sirv: 3.0.2
|
||||
tinyrainbow: 3.0.3
|
||||
vitest: 4.0.17(@types/node@25.0.9)(@vitest/browser-playwright@4.0.17)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)
|
||||
vitest: 4.0.17(@opentelemetry/api@1.9.0)(@types/node@25.0.9)(@vitest/browser-playwright@4.0.17)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)
|
||||
ws: 8.19.0
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
@@ -7181,7 +7664,7 @@ snapshots:
|
||||
obug: 2.1.1
|
||||
std-env: 3.10.0
|
||||
tinyrainbow: 3.0.3
|
||||
vitest: 4.0.17(@types/node@25.0.9)(@vitest/browser-playwright@4.0.17)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)
|
||||
vitest: 4.0.17(@opentelemetry/api@1.9.0)(@types/node@25.0.9)(@vitest/browser-playwright@4.0.17)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)
|
||||
optionalDependencies:
|
||||
'@vitest/browser': 4.0.17(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.17)
|
||||
|
||||
@@ -7290,6 +7773,12 @@ snapshots:
|
||||
mime-types: 3.0.2
|
||||
negotiator: 1.0.0
|
||||
|
||||
acorn-import-attributes@1.9.5(acorn@8.15.0):
|
||||
dependencies:
|
||||
acorn: 8.15.0
|
||||
|
||||
acorn@8.15.0: {}
|
||||
|
||||
agent-base@7.1.4: {}
|
||||
|
||||
ajv-formats@3.0.1(ajv@8.17.1):
|
||||
@@ -7575,6 +8064,8 @@ snapshots:
|
||||
ci-info@4.3.1:
|
||||
optional: true
|
||||
|
||||
cjs-module-lexer@2.2.0: {}
|
||||
|
||||
class-variance-authority@0.7.1:
|
||||
dependencies:
|
||||
clsx: 2.1.1
|
||||
@@ -7607,7 +8098,6 @@ snapshots:
|
||||
string-width: 4.2.3
|
||||
strip-ansi: 6.0.1
|
||||
wrap-ansi: 7.0.0
|
||||
optional: true
|
||||
|
||||
clsx@2.1.1: {}
|
||||
|
||||
@@ -8323,6 +8813,13 @@ snapshots:
|
||||
|
||||
immediate@3.0.6: {}
|
||||
|
||||
import-in-the-middle@2.0.4:
|
||||
dependencies:
|
||||
acorn: 8.15.0
|
||||
acorn-import-attributes: 1.9.5(acorn@8.15.0)
|
||||
cjs-module-lexer: 2.2.0
|
||||
module-details-from-path: 1.0.4
|
||||
|
||||
inherits@2.0.4: {}
|
||||
|
||||
ini@1.3.8:
|
||||
@@ -8804,6 +9301,8 @@ snapshots:
|
||||
|
||||
mkdirp@3.0.1: {}
|
||||
|
||||
module-details-from-path@1.0.4: {}
|
||||
|
||||
morgan@1.10.1:
|
||||
dependencies:
|
||||
basic-auth: 2.0.1
|
||||
@@ -9255,6 +9754,21 @@ snapshots:
|
||||
'@types/node': 25.0.9
|
||||
long: 5.3.2
|
||||
|
||||
protobufjs@8.0.0:
|
||||
dependencies:
|
||||
'@protobufjs/aspromise': 1.1.2
|
||||
'@protobufjs/base64': 1.1.2
|
||||
'@protobufjs/codegen': 2.0.4
|
||||
'@protobufjs/eventemitter': 1.1.0
|
||||
'@protobufjs/fetch': 1.1.0
|
||||
'@protobufjs/float': 1.0.2
|
||||
'@protobufjs/inquire': 1.1.0
|
||||
'@protobufjs/path': 1.1.2
|
||||
'@protobufjs/pool': 1.1.0
|
||||
'@protobufjs/utf8': 1.1.0
|
||||
'@types/node': 25.0.9
|
||||
long: 5.3.2
|
||||
|
||||
proxy-addr@2.0.7:
|
||||
dependencies:
|
||||
forwarded: 0.2.0
|
||||
@@ -9409,6 +9923,13 @@ snapshots:
|
||||
|
||||
require-from-string@2.0.2: {}
|
||||
|
||||
require-in-the-middle@8.0.1:
|
||||
dependencies:
|
||||
debug: 4.4.3
|
||||
module-details-from-path: 1.0.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
resolve-pkg-maps@1.0.0: {}
|
||||
|
||||
restore-cursor@5.1.0:
|
||||
@@ -9998,7 +10519,7 @@ snapshots:
|
||||
tsx: 4.21.0
|
||||
yaml: 2.8.2
|
||||
|
||||
vitest@4.0.17(@types/node@25.0.9)(@vitest/browser-playwright@4.0.17)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2):
|
||||
vitest@4.0.17(@opentelemetry/api@1.9.0)(@types/node@25.0.9)(@vitest/browser-playwright@4.0.17)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2):
|
||||
dependencies:
|
||||
'@vitest/expect': 4.0.17
|
||||
'@vitest/mocker': 4.0.17(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))
|
||||
@@ -10021,6 +10542,7 @@ snapshots:
|
||||
vite: 7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)
|
||||
why-is-node-running: 2.3.0
|
||||
optionalDependencies:
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@types/node': 25.0.9
|
||||
'@vitest/browser-playwright': 4.0.17(playwright@1.57.0)(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.17)
|
||||
transitivePeerDependencies:
|
||||
@@ -10109,8 +10631,7 @@ snapshots:
|
||||
|
||||
yargs-parser@20.2.9: {}
|
||||
|
||||
yargs-parser@21.1.1:
|
||||
optional: true
|
||||
yargs-parser@21.1.1: {}
|
||||
|
||||
yargs@16.2.0:
|
||||
dependencies:
|
||||
@@ -10131,7 +10652,6 @@ snapshots:
|
||||
string-width: 4.2.3
|
||||
y18n: 5.0.8
|
||||
yargs-parser: 21.1.1
|
||||
optional: true
|
||||
|
||||
yoctocolors@2.1.2: {}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
import type { TypingMode } from "../../config/types.js";
|
||||
import { logVerbose } from "../../globals.js";
|
||||
import { defaultRuntime } from "../../runtime.js";
|
||||
import { resolveModelCostConfig } from "../../utils/usage-format.js";
|
||||
import { estimateUsageCost, resolveModelCostConfig } from "../../utils/usage-format.js";
|
||||
import type { OriginatingChannelType, TemplateContext } from "../templating.js";
|
||||
import { resolveResponseUsageMode, type VerboseLevel } from "../thinking.js";
|
||||
import type { GetReplyOptions, ReplyPayload } from "../types.js";
|
||||
@@ -41,6 +41,7 @@ import { createReplyToModeFilterForChannel, resolveReplyToMode } from "./reply-t
|
||||
import { incrementCompactionCount } from "./session-updates.js";
|
||||
import type { TypingController } from "./typing.js";
|
||||
import { createTypingSignaler } from "./typing-mode.js";
|
||||
import { emitDiagnosticEvent, isDiagnosticsEnabled } from "../../infra/diagnostic-events.js";
|
||||
|
||||
const BLOCK_REPLY_SEND_TIMEOUT_MS = 15_000;
|
||||
|
||||
@@ -296,6 +297,7 @@ export async function runReplyAgent(params: {
|
||||
cleanupTranscripts: true,
|
||||
});
|
||||
try {
|
||||
const runStartedAt = Date.now();
|
||||
const runOutcome = await runAgentTurnWithFallback({
|
||||
commandBody,
|
||||
followupRun,
|
||||
@@ -403,6 +405,43 @@ export async function runReplyAgent(params: {
|
||||
activeSessionEntry?.contextTokens ??
|
||||
DEFAULT_CONTEXT_TOKENS;
|
||||
|
||||
if (isDiagnosticsEnabled(cfg) && hasNonzeroUsage(usage)) {
|
||||
const input = usage.input ?? 0;
|
||||
const output = usage.output ?? 0;
|
||||
const cacheRead = usage.cacheRead ?? 0;
|
||||
const cacheWrite = usage.cacheWrite ?? 0;
|
||||
const promptTokens = input + cacheRead + cacheWrite;
|
||||
const totalTokens = usage.total ?? promptTokens + output;
|
||||
const costConfig = resolveModelCostConfig({
|
||||
provider: providerUsed,
|
||||
model: modelUsed,
|
||||
config: cfg,
|
||||
});
|
||||
const costUsd = estimateUsageCost({ usage, cost: costConfig });
|
||||
emitDiagnosticEvent({
|
||||
type: "model.usage",
|
||||
sessionKey,
|
||||
sessionId: followupRun.run.sessionId,
|
||||
channel: replyToChannel,
|
||||
provider: providerUsed,
|
||||
model: modelUsed,
|
||||
usage: {
|
||||
input,
|
||||
output,
|
||||
cacheRead,
|
||||
cacheWrite,
|
||||
promptTokens,
|
||||
total: totalTokens,
|
||||
},
|
||||
context: {
|
||||
limit: contextTokensUsed,
|
||||
used: totalTokens,
|
||||
},
|
||||
costUsd,
|
||||
durationMs: Date.now() - runStartedAt,
|
||||
});
|
||||
}
|
||||
|
||||
if (storePath && sessionKey) {
|
||||
if (hasNonzeroUsage(usage)) {
|
||||
try {
|
||||
|
||||
@@ -47,6 +47,7 @@ export type ChannelUiMetadata = {
|
||||
const GROUP_LABELS: Record<string, string> = {
|
||||
wizard: "Wizard",
|
||||
update: "Update",
|
||||
diagnostics: "Diagnostics",
|
||||
logging: "Logging",
|
||||
gateway: "Gateway",
|
||||
agents: "Agents",
|
||||
@@ -73,6 +74,7 @@ const GROUP_LABELS: Record<string, string> = {
|
||||
const GROUP_ORDER: Record<string, number> = {
|
||||
wizard: 20,
|
||||
update: 25,
|
||||
diagnostics: 27,
|
||||
gateway: 30,
|
||||
agents: 40,
|
||||
tools: 50,
|
||||
@@ -101,6 +103,17 @@ const FIELD_LABELS: Record<string, string> = {
|
||||
"meta.lastTouchedAt": "Config Last Touched At",
|
||||
"update.channel": "Update Channel",
|
||||
"update.checkOnStart": "Update Check on Start",
|
||||
"diagnostics.enabled": "Diagnostics Enabled",
|
||||
"diagnostics.otel.enabled": "OpenTelemetry Enabled",
|
||||
"diagnostics.otel.endpoint": "OpenTelemetry Endpoint",
|
||||
"diagnostics.otel.protocol": "OpenTelemetry Protocol",
|
||||
"diagnostics.otel.headers": "OpenTelemetry Headers",
|
||||
"diagnostics.otel.serviceName": "OpenTelemetry Service Name",
|
||||
"diagnostics.otel.traces": "OpenTelemetry Traces Enabled",
|
||||
"diagnostics.otel.metrics": "OpenTelemetry Metrics Enabled",
|
||||
"diagnostics.otel.logs": "OpenTelemetry Logs Enabled",
|
||||
"diagnostics.otel.sampleRate": "OpenTelemetry Trace Sample Rate",
|
||||
"diagnostics.otel.flushIntervalMs": "OpenTelemetry Flush Interval (ms)",
|
||||
"gateway.remote.url": "Remote Gateway URL",
|
||||
"gateway.remote.sshTarget": "Remote Gateway SSH Target",
|
||||
"gateway.remote.sshIdentity": "Remote Gateway SSH Identity",
|
||||
|
||||
@@ -102,6 +102,26 @@ export type LoggingConfig = {
|
||||
redactPatterns?: string[];
|
||||
};
|
||||
|
||||
export type DiagnosticsOtelConfig = {
|
||||
enabled?: boolean;
|
||||
endpoint?: string;
|
||||
protocol?: "http/protobuf" | "grpc";
|
||||
headers?: Record<string, string>;
|
||||
serviceName?: string;
|
||||
traces?: boolean;
|
||||
metrics?: boolean;
|
||||
logs?: boolean;
|
||||
/** Trace sample rate (0.0 - 1.0). */
|
||||
sampleRate?: number;
|
||||
/** Metric export interval (ms). */
|
||||
flushIntervalMs?: number;
|
||||
};
|
||||
|
||||
export type DiagnosticsConfig = {
|
||||
enabled?: boolean;
|
||||
otel?: DiagnosticsOtelConfig;
|
||||
};
|
||||
|
||||
export type WebReconnectConfig = {
|
||||
initialMs?: number;
|
||||
maxMs?: number;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { AgentBinding, AgentsConfig } from "./types.agents.js";
|
||||
import type { AuthConfig } from "./types.auth.js";
|
||||
import type { LoggingConfig, SessionConfig, WebConfig } from "./types.base.js";
|
||||
import type { DiagnosticsConfig, LoggingConfig, SessionConfig, WebConfig } from "./types.base.js";
|
||||
import type { BrowserConfig } from "./types.browser.js";
|
||||
import type { ChannelsConfig } from "./types.channels.js";
|
||||
import type { CronConfig } from "./types.cron.js";
|
||||
@@ -53,6 +53,7 @@ export type ClawdbotConfig = {
|
||||
lastRunCommand?: string;
|
||||
lastRunMode?: "local" | "remote";
|
||||
};
|
||||
diagnostics?: DiagnosticsConfig;
|
||||
logging?: LoggingConfig;
|
||||
update?: {
|
||||
/** Update channel for git + npm installs ("stable", "beta", or "dev"). */
|
||||
|
||||
@@ -38,6 +38,27 @@ export const ClawdbotSchema = z
|
||||
})
|
||||
.strict()
|
||||
.optional(),
|
||||
diagnostics: z
|
||||
.object({
|
||||
enabled: z.boolean().optional(),
|
||||
otel: z
|
||||
.object({
|
||||
enabled: z.boolean().optional(),
|
||||
endpoint: z.string().optional(),
|
||||
protocol: z.union([z.literal("http/protobuf"), z.literal("grpc")]).optional(),
|
||||
headers: z.record(z.string(), z.string()).optional(),
|
||||
serviceName: z.string().optional(),
|
||||
traces: z.boolean().optional(),
|
||||
metrics: z.boolean().optional(),
|
||||
logs: z.boolean().optional(),
|
||||
sampleRate: z.number().min(0).max(1).optional(),
|
||||
flushIntervalMs: z.number().int().nonnegative().optional(),
|
||||
})
|
||||
.strict()
|
||||
.optional(),
|
||||
})
|
||||
.strict()
|
||||
.optional(),
|
||||
logging: z
|
||||
.object({
|
||||
level: z
|
||||
|
||||
28
src/infra/diagnostic-events.test.ts
Normal file
28
src/infra/diagnostic-events.test.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { describe, expect, test } from "vitest";
|
||||
|
||||
import {
|
||||
emitDiagnosticEvent,
|
||||
onDiagnosticEvent,
|
||||
resetDiagnosticEventsForTest,
|
||||
} from "./diagnostic-events.js";
|
||||
|
||||
describe("diagnostic-events", () => {
|
||||
test("emits monotonic seq", async () => {
|
||||
resetDiagnosticEventsForTest();
|
||||
const seqs: number[] = [];
|
||||
const stop = onDiagnosticEvent((evt) => seqs.push(evt.seq));
|
||||
|
||||
emitDiagnosticEvent({
|
||||
type: "model.usage",
|
||||
usage: { total: 1 },
|
||||
});
|
||||
emitDiagnosticEvent({
|
||||
type: "model.usage",
|
||||
usage: { total: 2 },
|
||||
});
|
||||
|
||||
stop();
|
||||
|
||||
expect(seqs).toEqual([1, 2]);
|
||||
});
|
||||
});
|
||||
60
src/infra/diagnostic-events.ts
Normal file
60
src/infra/diagnostic-events.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import type { ClawdbotConfig } from "../config/config.js";
|
||||
|
||||
export type DiagnosticUsageEvent = {
|
||||
type: "model.usage";
|
||||
ts: number;
|
||||
seq: number;
|
||||
sessionKey?: string;
|
||||
sessionId?: string;
|
||||
channel?: string;
|
||||
provider?: string;
|
||||
model?: string;
|
||||
usage: {
|
||||
input?: number;
|
||||
output?: number;
|
||||
cacheRead?: number;
|
||||
cacheWrite?: number;
|
||||
promptTokens?: number;
|
||||
total?: number;
|
||||
};
|
||||
context?: {
|
||||
limit?: number;
|
||||
used?: number;
|
||||
};
|
||||
costUsd?: number;
|
||||
durationMs?: number;
|
||||
};
|
||||
|
||||
export type DiagnosticEventPayload = DiagnosticUsageEvent;
|
||||
|
||||
let seq = 0;
|
||||
const listeners = new Set<(evt: DiagnosticEventPayload) => void>();
|
||||
|
||||
export function isDiagnosticsEnabled(config?: ClawdbotConfig): boolean {
|
||||
return config?.diagnostics?.enabled === true;
|
||||
}
|
||||
|
||||
export function emitDiagnosticEvent(event: Omit<DiagnosticEventPayload, "seq" | "ts">) {
|
||||
const enriched: DiagnosticEventPayload = {
|
||||
...event,
|
||||
seq: (seq += 1),
|
||||
ts: Date.now(),
|
||||
};
|
||||
for (const listener of listeners) {
|
||||
try {
|
||||
listener(enriched);
|
||||
} catch {
|
||||
// Ignore listener failures.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function onDiagnosticEvent(listener: (evt: DiagnosticEventPayload) => void): () => void {
|
||||
listeners.add(listener);
|
||||
return () => listeners.delete(listener);
|
||||
}
|
||||
|
||||
export function resetDiagnosticEventsForTest(): void {
|
||||
seq = 0;
|
||||
listeners.clear();
|
||||
}
|
||||
@@ -58,7 +58,11 @@ export type {
|
||||
ChannelToolSend,
|
||||
} from "../channels/plugins/types.js";
|
||||
export type { ChannelConfigSchema, ChannelPlugin } from "../channels/plugins/types.plugin.js";
|
||||
export type { ClawdbotPluginApi } from "../plugins/types.js";
|
||||
export type {
|
||||
ClawdbotPluginApi,
|
||||
ClawdbotPluginService,
|
||||
ClawdbotPluginServiceContext,
|
||||
} from "../plugins/types.js";
|
||||
export type { PluginRuntime } from "../plugins/runtime/types.js";
|
||||
export { emptyPluginConfigSchema } from "../plugins/config-schema.js";
|
||||
export type { ClawdbotConfig } from "../config/config.js";
|
||||
@@ -178,6 +182,12 @@ export { formatDocsLink } from "../terminal/links.js";
|
||||
export type { HookEntry } from "../hooks/types.js";
|
||||
export { normalizeE164 } from "../utils.js";
|
||||
export { missingTargetError } from "../infra/outbound/target-errors.js";
|
||||
export {
|
||||
emitDiagnosticEvent,
|
||||
isDiagnosticsEnabled,
|
||||
onDiagnosticEvent,
|
||||
} from "../infra/diagnostic-events.js";
|
||||
export type { DiagnosticEventPayload, DiagnosticUsageEvent } from "../infra/diagnostic-events.js";
|
||||
|
||||
// Channel: Discord
|
||||
export {
|
||||
|
||||
Reference in New Issue
Block a user