opik-vercel 1.9.86 → 1.9.88
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/README.md +7 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +4 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -129,10 +129,12 @@ const exporter = new OpikExporter({
|
|
|
129
129
|
version: "1.0.0",
|
|
130
130
|
team: "ai-team",
|
|
131
131
|
},
|
|
132
|
+
// Optional: associate traces with a conversation thread
|
|
133
|
+
threadId: "conversation-123",
|
|
132
134
|
});
|
|
133
135
|
```
|
|
134
136
|
|
|
135
|
-
Tags are useful for filtering and grouping traces, while metadata adds additional context for debugging and analysis.
|
|
137
|
+
Tags are useful for filtering and grouping traces, while metadata adds additional context for debugging and analysis. The `threadId` parameter is useful for tracking multi-turn conversations or grouping related AI interactions.
|
|
136
138
|
|
|
137
139
|
### Telemetry Settings
|
|
138
140
|
|
|
@@ -144,6 +146,10 @@ const result = await generateText({
|
|
|
144
146
|
prompt: "Tell a joke",
|
|
145
147
|
experimental_telemetry: OpikExporter.getSettings({
|
|
146
148
|
name: "custom-trace-name",
|
|
149
|
+
// Optional: set threadId per request (overrides exporter-level threadId)
|
|
150
|
+
metadata: {
|
|
151
|
+
threadId: "conversation-456",
|
|
152
|
+
},
|
|
147
153
|
}),
|
|
148
154
|
});
|
|
149
155
|
```
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
'use strict';var opik=require('opik');var
|
|
1
|
+
'use strict';var opik=require('opik');var k=new opik.Opik,f=class{constructor({client:n=k,tags:t=[],metadata:e={},threadId:i}={}){this.traces=new Map;this.spans=new Map;this.getSpanInput=n=>{let t={},{attributes:e}=n;return Object.keys(e).forEach(o=>{if(o==="ai.prompt"||o==="gen_ai.request"){let r=w(e[o]);r&&(t={...t,...r});}if(o.startsWith("ai.prompt.")){let r=o.replace("ai.prompt.","");t[r]=m(e[o]);}if(o.startsWith("gen_ai.request.")){let r=o.replace("gen_ai.request.","");t[r]=m(e[o]);}}),Object.keys(t).length>0||("ai.toolCall.name"in e&&(t.toolName=e["ai.toolCall.name"]),"ai.toolCall.args"in e&&(t.args=e["ai.toolCall.args"])),t};this.getSpanOutput=n=>{let{attributes:t}=n;return t["ai.response.text"]?{text:t["ai.response.text"]}:t["ai.toolCall.result"]?{result:t["ai.toolCall.result"]}:t["ai.response.toolCalls"]?{toolCalls:m(t["ai.response.toolCalls"])}:{}};this.getSpanMetadata=n=>{let{attributes:t}=n,e={};return t["gen_ai.response.model"]&&(e.model=t["gen_ai.response.model"]),t["gen_ai.system"]&&(e.system=t["gen_ai.system"]),e};this.getSpanUsage=n=>{let{attributes:t}=n,e={};return "ai.usage.promptTokens"in t&&(e.prompt_tokens=t["ai.usage.promptTokens"]),"gen_ai.usage.input_tokens"in t&&(e.prompt_tokens=t["gen_ai.usage.input_tokens"]),"ai.usage.completionTokens"in t&&(e.completion_tokens=t["ai.usage.completionTokens"]),"gen_ai.usage.output_tokens"in t&&(e.completion_tokens=t["gen_ai.usage.output_tokens"]),("prompt_tokens"in e||"completion_tokens"in e)&&(e.total_tokens=(e.prompt_tokens||0)+(e.completion_tokens||0)),e};this.getThreadId=n=>{var e;let{attributes:t}=n;return t["ai.telemetry.metadata.threadId"]!=null?(e=t["ai.telemetry.metadata.threadId"])==null?void 0:e.toString():this.threadId};this.processSpan=({otelSpan:n,parentSpan:t,trace:e})=>e.span({name:n.name,startTime:new Date(l(n.startTime)),endTime:new Date(l(n.endTime)),parentSpanId:t==null?void 0:t.data.id,input:this.getSpanInput(n),output:this.getSpanOutput(n),metadata:this.getSpanMetadata(n),usage:this.getSpanUsage(n),type:"llm"});this.shutdown=async()=>{await this.client.flush();};this.forceFlush=async()=>{await this.client.flush();};this.export=async(n,t)=>{let e=n.filter(r=>r.instrumentationScope.name==="ai"),i=n.length-e.length;if(i>0&&opik.logger.debug(`Ignored ${i} non-AI SDK spans`),e.length===0){opik.logger.debug("No AI SDK spans found"),t({code:0});return}let o=E(e);opik.logger.debug("Exporting spans",e),Object.entries(o).forEach(([r,d])=>{var h,S;let[a,...u]=d,p=this.client.trace({startTime:new Date(l(a.startTime)),endTime:new Date(l(a.endTime)),name:(S=(h=a.attributes["ai.telemetry.metadata.traceName"])==null?void 0:h.toString())!=null?S:a.name,input:this.getSpanInput(a),output:this.getSpanOutput(a),metadata:{...this.getSpanMetadata(a),...this.metadata},tags:this.tags,usage:this.getSpanUsage(a),threadId:this.getThreadId(a)});this.traces.set(r,p),u.forEach(g=>{var b,y;let I=this.spans.get((y=(b=g.parentSpanContext)==null?void 0:b.spanId)!=null?y:""),R=this.processSpan({parentSpan:I,otelSpan:g,trace:p});this.spans.set(g.spanContext().spanId,R);});});try{await this.client.flush(),t({code:0});}catch(r){opik.logger.error("Error exporting spans",r),t({code:1,error:r instanceof Error?r:new Error("Unknown error")});}};this.client=n,this.tags=[...t],this.metadata={...e},this.threadId=i;}static getSettings(n){var e,i,o;let t={...n.metadata};return n.name&&(t.traceName=n.name),{isEnabled:(e=n.isEnabled)!=null?e:true,recordInputs:(i=n.recordInputs)!=null?i:true,recordOutputs:(o=n.recordOutputs)!=null?o:true,functionId:n.functionId,metadata:t}}};function E(s){let n={};return s.forEach(t=>{let e=t.spanContext();n[e.traceId]||(n[e.traceId]=[]),n[e.traceId].push(t);}),Object.entries(n).forEach(([t,e])=>{n[t]=C(e);}),n}function l(s){return s[0]*1e3+s[1]/1e6}function m(s){try{return JSON.parse(s)}catch{return s}}function w(s){if(typeof s=="string")try{let n=JSON.parse(s);if(n!==null&&typeof n=="object"&&!Array.isArray(n))return n}catch{return}}function C(s){var r,d;let n=new Map,t=new Map;for(let a of s){let{spanId:u}=a.spanContext(),p=(d=(r=a.parentSpanContext)==null?void 0:r.spanId)!=null?d:"";n.set(u,a),p&&(t.has(p)||t.set(p,[]),t.get(p).push(a));}let e=s.filter(a=>{var u;return !((u=a.parentSpanContext)!=null&&u.spanId)||!n.has(a.parentSpanContext.spanId)}),i=[],o=[...e];for(;o.length>0;){let a=o.shift();i.push(a);let u=a.spanContext().spanId,p=t.get(u)||[];o.push(...p);}return i}exports.OpikExporter=f;
|
package/dist/index.d.cts
CHANGED
|
@@ -20,6 +20,7 @@ type OpikExporterOptions = {
|
|
|
20
20
|
client?: Opik;
|
|
21
21
|
tags?: string[];
|
|
22
22
|
metadata?: Record<string, AttributeValue>;
|
|
23
|
+
threadId?: string;
|
|
23
24
|
};
|
|
24
25
|
declare class OpikExporter implements SpanExporter {
|
|
25
26
|
private readonly traces;
|
|
@@ -27,11 +28,13 @@ declare class OpikExporter implements SpanExporter {
|
|
|
27
28
|
private readonly client;
|
|
28
29
|
private readonly tags;
|
|
29
30
|
private readonly metadata;
|
|
30
|
-
|
|
31
|
+
private readonly threadId?;
|
|
32
|
+
constructor({ client, tags, metadata, threadId, }?: OpikExporterOptions);
|
|
31
33
|
private getSpanInput;
|
|
32
34
|
private getSpanOutput;
|
|
33
35
|
private getSpanMetadata;
|
|
34
36
|
private getSpanUsage;
|
|
37
|
+
private getThreadId;
|
|
35
38
|
processSpan: ({ otelSpan, parentSpan, trace, }: {
|
|
36
39
|
otelSpan: ReadableSpan;
|
|
37
40
|
parentSpan?: Span;
|
package/dist/index.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ type OpikExporterOptions = {
|
|
|
20
20
|
client?: Opik;
|
|
21
21
|
tags?: string[];
|
|
22
22
|
metadata?: Record<string, AttributeValue>;
|
|
23
|
+
threadId?: string;
|
|
23
24
|
};
|
|
24
25
|
declare class OpikExporter implements SpanExporter {
|
|
25
26
|
private readonly traces;
|
|
@@ -27,11 +28,13 @@ declare class OpikExporter implements SpanExporter {
|
|
|
27
28
|
private readonly client;
|
|
28
29
|
private readonly tags;
|
|
29
30
|
private readonly metadata;
|
|
30
|
-
|
|
31
|
+
private readonly threadId?;
|
|
32
|
+
constructor({ client, tags, metadata, threadId, }?: OpikExporterOptions);
|
|
31
33
|
private getSpanInput;
|
|
32
34
|
private getSpanOutput;
|
|
33
35
|
private getSpanMetadata;
|
|
34
36
|
private getSpanUsage;
|
|
37
|
+
private getThreadId;
|
|
35
38
|
processSpan: ({ otelSpan, parentSpan, trace, }: {
|
|
36
39
|
otelSpan: ReadableSpan;
|
|
37
40
|
parentSpan?: Span;
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import {Opik,logger}from'opik';var
|
|
1
|
+
import {Opik,logger}from'opik';var k=new Opik,f=class{constructor({client:n=k,tags:t=[],metadata:e={},threadId:i}={}){this.traces=new Map;this.spans=new Map;this.getSpanInput=n=>{let t={},{attributes:e}=n;return Object.keys(e).forEach(o=>{if(o==="ai.prompt"||o==="gen_ai.request"){let r=w(e[o]);r&&(t={...t,...r});}if(o.startsWith("ai.prompt.")){let r=o.replace("ai.prompt.","");t[r]=m(e[o]);}if(o.startsWith("gen_ai.request.")){let r=o.replace("gen_ai.request.","");t[r]=m(e[o]);}}),Object.keys(t).length>0||("ai.toolCall.name"in e&&(t.toolName=e["ai.toolCall.name"]),"ai.toolCall.args"in e&&(t.args=e["ai.toolCall.args"])),t};this.getSpanOutput=n=>{let{attributes:t}=n;return t["ai.response.text"]?{text:t["ai.response.text"]}:t["ai.toolCall.result"]?{result:t["ai.toolCall.result"]}:t["ai.response.toolCalls"]?{toolCalls:m(t["ai.response.toolCalls"])}:{}};this.getSpanMetadata=n=>{let{attributes:t}=n,e={};return t["gen_ai.response.model"]&&(e.model=t["gen_ai.response.model"]),t["gen_ai.system"]&&(e.system=t["gen_ai.system"]),e};this.getSpanUsage=n=>{let{attributes:t}=n,e={};return "ai.usage.promptTokens"in t&&(e.prompt_tokens=t["ai.usage.promptTokens"]),"gen_ai.usage.input_tokens"in t&&(e.prompt_tokens=t["gen_ai.usage.input_tokens"]),"ai.usage.completionTokens"in t&&(e.completion_tokens=t["ai.usage.completionTokens"]),"gen_ai.usage.output_tokens"in t&&(e.completion_tokens=t["gen_ai.usage.output_tokens"]),("prompt_tokens"in e||"completion_tokens"in e)&&(e.total_tokens=(e.prompt_tokens||0)+(e.completion_tokens||0)),e};this.getThreadId=n=>{var e;let{attributes:t}=n;return t["ai.telemetry.metadata.threadId"]!=null?(e=t["ai.telemetry.metadata.threadId"])==null?void 0:e.toString():this.threadId};this.processSpan=({otelSpan:n,parentSpan:t,trace:e})=>e.span({name:n.name,startTime:new Date(l(n.startTime)),endTime:new Date(l(n.endTime)),parentSpanId:t==null?void 0:t.data.id,input:this.getSpanInput(n),output:this.getSpanOutput(n),metadata:this.getSpanMetadata(n),usage:this.getSpanUsage(n),type:"llm"});this.shutdown=async()=>{await this.client.flush();};this.forceFlush=async()=>{await this.client.flush();};this.export=async(n,t)=>{let e=n.filter(r=>r.instrumentationScope.name==="ai"),i=n.length-e.length;if(i>0&&logger.debug(`Ignored ${i} non-AI SDK spans`),e.length===0){logger.debug("No AI SDK spans found"),t({code:0});return}let o=E(e);logger.debug("Exporting spans",e),Object.entries(o).forEach(([r,d])=>{var h,S;let[a,...u]=d,p=this.client.trace({startTime:new Date(l(a.startTime)),endTime:new Date(l(a.endTime)),name:(S=(h=a.attributes["ai.telemetry.metadata.traceName"])==null?void 0:h.toString())!=null?S:a.name,input:this.getSpanInput(a),output:this.getSpanOutput(a),metadata:{...this.getSpanMetadata(a),...this.metadata},tags:this.tags,usage:this.getSpanUsage(a),threadId:this.getThreadId(a)});this.traces.set(r,p),u.forEach(g=>{var b,y;let I=this.spans.get((y=(b=g.parentSpanContext)==null?void 0:b.spanId)!=null?y:""),R=this.processSpan({parentSpan:I,otelSpan:g,trace:p});this.spans.set(g.spanContext().spanId,R);});});try{await this.client.flush(),t({code:0});}catch(r){logger.error("Error exporting spans",r),t({code:1,error:r instanceof Error?r:new Error("Unknown error")});}};this.client=n,this.tags=[...t],this.metadata={...e},this.threadId=i;}static getSettings(n){var e,i,o;let t={...n.metadata};return n.name&&(t.traceName=n.name),{isEnabled:(e=n.isEnabled)!=null?e:true,recordInputs:(i=n.recordInputs)!=null?i:true,recordOutputs:(o=n.recordOutputs)!=null?o:true,functionId:n.functionId,metadata:t}}};function E(s){let n={};return s.forEach(t=>{let e=t.spanContext();n[e.traceId]||(n[e.traceId]=[]),n[e.traceId].push(t);}),Object.entries(n).forEach(([t,e])=>{n[t]=C(e);}),n}function l(s){return s[0]*1e3+s[1]/1e6}function m(s){try{return JSON.parse(s)}catch{return s}}function w(s){if(typeof s=="string")try{let n=JSON.parse(s);if(n!==null&&typeof n=="object"&&!Array.isArray(n))return n}catch{return}}function C(s){var r,d;let n=new Map,t=new Map;for(let a of s){let{spanId:u}=a.spanContext(),p=(d=(r=a.parentSpanContext)==null?void 0:r.spanId)!=null?d:"";n.set(u,a),p&&(t.has(p)||t.set(p,[]),t.get(p).push(a));}let e=s.filter(a=>{var u;return !((u=a.parentSpanContext)!=null&&u.spanId)||!n.has(a.parentSpanContext.spanId)}),i=[],o=[...e];for(;o.length>0;){let a=o.shift();i.push(a);let u=a.spanContext().spanId,p=t.get(u)||[];o.push(...p);}return i}export{f as OpikExporter};
|