mirror of
https://github.com/openobserve/openobserve.git
synced 2026-11-05 16:10:43 +00:00
101 lines
3.3 KiB
JavaScript
101 lines
3.3 KiB
JavaScript
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { readFileSync } from "node:fs";
|
|
|
|
import {
|
|
cleanAttributeValue,
|
|
genAiRequestAttributes,
|
|
genAiResponseAttributes,
|
|
sha256,
|
|
} from "../telemetry.mjs";
|
|
|
|
test("request content uses standard GenAI attributes without TraceLoop prompt keys", () => {
|
|
const attributes = genAiRequestAttributes("Follow the review policy.", "Review this diff.");
|
|
|
|
assert.equal(
|
|
Object.keys(attributes).some(key => key.startsWith("gen_ai.prompt.")),
|
|
false,
|
|
);
|
|
assert.deepEqual(JSON.parse(attributes["gen_ai.system_instructions"]), [
|
|
{ type: "text", content: "Follow the review policy." },
|
|
]);
|
|
assert.deepEqual(JSON.parse(attributes["gen_ai.input.messages"]), [
|
|
{
|
|
role: "user",
|
|
parts: [{ type: "text", content: "Review this diff." }],
|
|
},
|
|
]);
|
|
assert.equal(
|
|
attributes["ai.review.system_instructions.sha256"],
|
|
sha256("Follow the review policy."),
|
|
);
|
|
});
|
|
|
|
test("response content and provider-reported usage use standard attributes", () => {
|
|
const attributes = genAiResponseAttributes(
|
|
{
|
|
info: {
|
|
id: "msg-123",
|
|
modelID: "deepseek-v4-pro",
|
|
finish: "stop",
|
|
cost: 0.42,
|
|
tokens: {
|
|
input: 1234,
|
|
output: 56,
|
|
reasoning: 12,
|
|
cache: { read: 78, write: 9 },
|
|
},
|
|
},
|
|
},
|
|
"Looks good.",
|
|
"fallback-model",
|
|
);
|
|
|
|
assert.deepEqual(JSON.parse(attributes["gen_ai.output.messages"]), [
|
|
{
|
|
role: "assistant",
|
|
parts: [{ type: "text", content: "Looks good." }],
|
|
},
|
|
]);
|
|
assert.deepEqual(attributes["gen_ai.response.finish_reasons"], ["stop"]);
|
|
assert.equal(attributes["gen_ai.usage.input_tokens"], 1234);
|
|
assert.equal(attributes["gen_ai.usage.output_tokens"], 56);
|
|
assert.equal(attributes["gen_ai.usage.total_tokens"], 1290);
|
|
assert.equal(attributes["gen_ai.usage.cache_read_tokens"], 78);
|
|
assert.equal(attributes["gen_ai.usage.cache_write_tokens"], 9);
|
|
assert.equal(attributes["gen_ai.usage.cost"], 0.42);
|
|
assert.equal(attributes["ai.review.usage.reasoning_tokens"], 12);
|
|
assert.equal(
|
|
Object.keys(attributes).some(key => key.startsWith("gen_ai.completion.")),
|
|
false,
|
|
);
|
|
});
|
|
|
|
test("missing provider usage is omitted instead of replaced with synthetic counts", () => {
|
|
const attributes = genAiResponseAttributes(
|
|
{ info: { id: "msg-456" } },
|
|
"No usage available.",
|
|
"requested-model",
|
|
);
|
|
|
|
assert.equal(attributes["gen_ai.usage.input_tokens"], undefined);
|
|
assert.equal(attributes["gen_ai.usage.output_tokens"], undefined);
|
|
assert.equal(attributes["gen_ai.usage.cost"], undefined);
|
|
assert.equal(attributes["gen_ai.response.model"], "requested-model");
|
|
});
|
|
|
|
test("homogeneous primitive arrays remain native OTel attribute arrays", () => {
|
|
assert.deepEqual(cleanAttributeValue(["security", "performance"]), [
|
|
"security",
|
|
"performance",
|
|
]);
|
|
assert.equal(cleanAttributeValue([{ name: "security" }]), '[{"name":"security"}]');
|
|
});
|
|
|
|
test("review instrumentation does not emit legacy TraceLoop content attributes", () => {
|
|
const reviewSource = readFileSync(new URL("../run-review.mjs", import.meta.url), "utf8");
|
|
|
|
assert.doesNotMatch(reviewSource, /["']gen_ai\.prompt\./);
|
|
assert.doesNotMatch(reviewSource, /["']gen_ai\.completion\./);
|
|
});
|