oh-langfuse 0.1.29 → 0.1.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -132,10 +132,10 @@ export function buildInteractionMetadata(options = {}) {
|
|
|
132
132
|
const sessionId = String(options.sessionId || options.session_id || "unknown");
|
|
133
133
|
const turnNumber = Number(options.turnNumber ?? options.turn_number ?? 0) || 0;
|
|
134
134
|
const tokenMetrics = normalizeTokenMetrics(options.tokenMetrics);
|
|
135
|
-
const toolCallCount = Number(options.toolCallCount ?? options.tool_call_count ?? 0) || 0;
|
|
136
|
-
const toolResultCount = Number(options.toolResultCount ?? options.tool_result_count ?? 0) || 0;
|
|
137
135
|
const skillNames = normalizeSkillNames(options.skillNames ?? options.skill_names);
|
|
138
136
|
const skillUseCount = skillNames.length || Number(options.skillUseCount ?? options.skill_use_count ?? 0) || 0;
|
|
137
|
+
const toolCallCount = Math.max(Number(options.toolCallCount ?? options.tool_call_count ?? 0) || 0, skillUseCount);
|
|
138
|
+
const toolResultCount = Math.max(Number(options.toolResultCount ?? options.tool_result_count ?? 0) || 0, skillUseCount);
|
|
139
139
|
|
|
140
140
|
const metadata = {
|
|
141
141
|
source,
|
|
@@ -172,47 +172,14 @@ export function buildInteractionMetadata(options = {}) {
|
|
|
172
172
|
export function buildOpencodeMetricAttributes(options = {}) {
|
|
173
173
|
const attrs = options.attributes || {};
|
|
174
174
|
const userId = String(options.userId || attrs["oh.langfuse.user_id"] || attrs["langfuse.user.id"] || "");
|
|
175
|
-
const sessionId = String(attrs["ai.request.headers.x-opencode-session"] || options.sessionId || options.session_id || "unknown");
|
|
176
|
-
const requestId = String(attrs["ai.request.headers.x-opencode-request"] || options.requestId || options.request_id || "unknown");
|
|
177
|
-
const spanId = String(options.spanId || attrs["span.id"] || "unknown");
|
|
178
175
|
const provider = attrs["ai.model.provider"] || attrs["gen_ai.system"] || "";
|
|
179
176
|
const modelId = attrs["ai.model.id"] || attrs["gen_ai.request.model"] || attrs["ai.response.model"] || "";
|
|
180
177
|
const model = provider && modelId ? `${provider}/${modelId}` : provider || modelId || null;
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
const toolResultCount = Number(options.toolResultCount ?? options.tool_result_count ?? 0) || 0;
|
|
184
|
-
const tokenMetrics = normalizeTokenMetrics({
|
|
185
|
-
input: attrs["ai.usage.inputTokens"] ?? attrs["ai.usage.promptTokens"] ?? attrs["gen_ai.usage.input_tokens"],
|
|
186
|
-
output: attrs["ai.usage.outputTokens"] ?? attrs["ai.usage.completionTokens"] ?? attrs["gen_ai.usage.output_tokens"],
|
|
187
|
-
total: attrs["ai.usage.totalTokens"],
|
|
188
|
-
cacheRead: attrs["ai.usage.cachedInputTokens"] ?? attrs["ai.usage.inputTokenDetails.cacheReadTokens"],
|
|
189
|
-
reasoning: attrs["ai.usage.reasoningTokens"] ?? attrs["ai.usage.outputTokenDetails.reasoningTokens"],
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
const out = {
|
|
178
|
+
|
|
179
|
+
return {
|
|
193
180
|
"langfuse.observation.metadata.source": "opencode",
|
|
194
181
|
"langfuse.observation.metadata.user_id": userId,
|
|
195
|
-
"langfuse.observation.metadata.session_id": sessionId,
|
|
196
|
-
"langfuse.observation.metadata.interaction_id": `opencode:${userId || "unknown"}:${sessionId}:${requestId}:${spanId}`,
|
|
197
182
|
"langfuse.observation.metadata.metrics_schema_version": METRICS_SCHEMA_VERSION,
|
|
198
|
-
"langfuse.observation.metadata.interaction_count": 1,
|
|
199
|
-
"langfuse.observation.metadata.user_message_count": 1,
|
|
200
|
-
"langfuse.observation.metadata.assistant_message_count": 1,
|
|
201
|
-
"langfuse.observation.metadata.tool_call_count": toolCallCount,
|
|
202
|
-
"langfuse.observation.metadata.tool_result_count": toolResultCount,
|
|
203
|
-
"langfuse.observation.metadata.skill_use_count": skillNames.length,
|
|
204
|
-
"langfuse.observation.metadata.token_metrics_available": tokenMetrics.token_metrics_available,
|
|
205
183
|
"langfuse.observation.metadata.model": model,
|
|
206
184
|
};
|
|
207
|
-
|
|
208
|
-
if (skillNames.length) {
|
|
209
|
-
out["langfuse.observation.metadata.skill_names"] = skillNames;
|
|
210
|
-
out["langfuse.observation.metadata.skill_names_json"] = JSON.stringify(skillNames);
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
for (const key of ["input_tokens", "output_tokens", "total_tokens", "cache_read_tokens", "reasoning_tokens"]) {
|
|
214
|
-
if (tokenMetrics[key] != null) out[`langfuse.observation.metadata.${key}`] = tokenMetrics[key];
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
return out;
|
|
218
185
|
}
|
|
@@ -218,34 +218,10 @@ function getPatchedLangfuseDistIndexJs() {
|
|
|
218
218
|
' const hasModel = attrs["ai.model.id"] || attrs["ai.model.provider"] || attrs["gen_ai.request.model"];',
|
|
219
219
|
' const isTool = attrs["ai.toolCall.name"] || attrs["ai.toolCall.id"];',
|
|
220
220
|
" if (!hasModel || isTool) return false;",
|
|
221
|
-
' if (typeof span.updateName === "function") span.updateName("AI Interaction");',
|
|
222
|
-
' const sessionId = String(attrs["ai.request.headers.x-opencode-session"] || attrs["session.id"] || "unknown");',
|
|
223
|
-
' const requestId = String(attrs["ai.request.headers.x-opencode-request"] || attrs["ai.response.id"] || attrs["ai.operationId"] || "unknown");',
|
|
224
|
-
' const spanId = span.spanContext?.().spanId || attrs["span.id"] || "unknown";',
|
|
225
221
|
' const provider = attrs["ai.model.provider"] || attrs["gen_ai.system"] || "";',
|
|
226
222
|
' const modelId = attrs["ai.model.id"] || attrs["gen_ai.request.model"] || attrs["ai.response.model"] || "";',
|
|
227
223
|
' const model = provider && modelId ? `${provider}/${modelId}` : provider || modelId || undefined;',
|
|
228
|
-
' const inputTokens = metricNumber(attrs["ai.usage.inputTokens"] ?? attrs["ai.usage.promptTokens"] ?? attrs["gen_ai.usage.input_tokens"]);',
|
|
229
|
-
' const outputTokens = metricNumber(attrs["ai.usage.outputTokens"] ?? attrs["ai.usage.completionTokens"] ?? attrs["gen_ai.usage.output_tokens"]);',
|
|
230
|
-
' const totalTokens = metricNumber(attrs["ai.usage.totalTokens"]) ?? (inputTokens !== undefined && outputTokens !== undefined ? inputTokens + outputTokens : undefined);',
|
|
231
|
-
' const cacheReadTokens = metricNumber(attrs["ai.usage.cachedInputTokens"] ?? attrs["ai.usage.inputTokenDetails.cacheReadTokens"]);',
|
|
232
|
-
' const reasoningTokens = metricNumber(attrs["ai.usage.reasoningTokens"] ?? attrs["ai.usage.outputTokenDetails.reasoningTokens"]);',
|
|
233
|
-
" const tokenAvailable = [inputTokens, outputTokens, totalTokens, cacheReadTokens, reasoningTokens].some((value) => value !== undefined);",
|
|
234
|
-
' writeMetric(span, "session_id", sessionId);',
|
|
235
|
-
' writeMetric(span, "interaction_id", `opencode:${userId || "unknown"}:${sessionId}:${requestId}:${spanId}`);',
|
|
236
|
-
' writeMetric(span, "interaction_count", 1);',
|
|
237
|
-
' writeMetric(span, "user_message_count", 1);',
|
|
238
|
-
' writeMetric(span, "assistant_message_count", 1);',
|
|
239
|
-
' writeMetric(span, "token_metrics_available", tokenAvailable);',
|
|
240
|
-
' writeMetric(span, "tool_call_count", 0);',
|
|
241
|
-
' writeMetric(span, "tool_result_count", 0);',
|
|
242
|
-
' writeMetric(span, "skill_use_count", 0);',
|
|
243
224
|
' writeMetric(span, "model", model);',
|
|
244
|
-
' writeMetric(span, "input_tokens", inputTokens);',
|
|
245
|
-
' writeMetric(span, "output_tokens", outputTokens);',
|
|
246
|
-
' writeMetric(span, "total_tokens", totalTokens);',
|
|
247
|
-
' writeMetric(span, "cache_read_tokens", cacheReadTokens);',
|
|
248
|
-
' writeMetric(span, "reasoning_tokens", reasoningTokens);',
|
|
249
225
|
" return true;",
|
|
250
226
|
"};",
|
|
251
227
|
"",
|
|
@@ -499,8 +475,8 @@ function getPatchedLangfuseDistIndexJs() {
|
|
|
499
475
|
" const span = metricsTracer.startSpan('AI Interaction');",
|
|
500
476
|
" const text = messageTextById.get(messageId) || '';",
|
|
501
477
|
" const skillNames = [...new Set([...(skillNamesByMessageId.get(messageId) ?? []), ...(skillNamesBySessionId.get(sessionId) ?? [])])];",
|
|
502
|
-
" const toolCallCount = new Set([...(toolCallIdsByMessageId.get(messageId) ?? []), ...(toolCallIdsBySessionId.get(sessionId) ?? [])]).size;",
|
|
503
|
-
" const toolResultCount = new Set([...(toolResultIdsByMessageId.get(messageId) ?? []), ...(toolResultIdsBySessionId.get(sessionId) ?? [])]).size;",
|
|
478
|
+
" const toolCallCount = Math.max(new Set([...(toolCallIdsByMessageId.get(messageId) ?? []), ...(toolCallIdsBySessionId.get(sessionId) ?? [])]).size, skillNames.length);",
|
|
479
|
+
" const toolResultCount = Math.max(new Set([...(toolResultIdsByMessageId.get(messageId) ?? []), ...(toolResultIdsBySessionId.get(sessionId) ?? [])]).size, skillNames.length);",
|
|
504
480
|
' span.setAttribute("oh.langfuse.source", "opencode");',
|
|
505
481
|
' span.setAttribute("oh.langfuse.user_id", userId || "");',
|
|
506
482
|
' span.setAttribute("oh.langfuse.metrics_schema_version", "1.0");',
|