Skip to content

Commit aa22aff

Browse files
authored
feat(openinference-core): decorators (#2344)
1 parent 2842b9f commit aa22aff

22 files changed

+3533
-245
lines changed

js/packages/openinference-core/README.md

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,187 @@ span.setAttributes(contextAttributes);
8989
span.end();
9090
```
9191
92+
## Tracing Helpers
93+
94+
This package provides convenient helpers to instrument your functions, agents, and LLM operations with OpenInference spans.
95+
96+
### Function Tracing
97+
98+
**`withSpan`** - Wraps any function (sync or async) with OpenTelemetry tracing:
99+
100+
```typescript
101+
import { withSpan } from "@arizeai/openinference-core";
102+
import { OpenInferenceSpanKind } from "@arizeai/openinference-semantic-conventions";
103+
104+
const processUserQuery = async (query: string) => {
105+
// Your business logic here
106+
const response = await fetch(`/api/process?q=${query}`);
107+
return response.json();
108+
};
109+
110+
const tracedProcess = withSpan(processUserQuery, {
111+
name: "user-query-processor",
112+
kind: OpenInferenceSpanKind.CHAIN,
113+
});
114+
```
115+
116+
**`traceChain`** - Convenience wrapper for tracing workflow sequences:
117+
118+
```typescript
119+
import { traceChain } from "@arizeai/openinference-core";
120+
121+
const ragPipeline = async (question: string) => {
122+
const documents = await retrieveDocuments(question);
123+
const context = documents.map((d) => d.content).join("\n");
124+
const answer = await generateAnswer(question, context);
125+
return answer;
126+
};
127+
128+
const tracedRag = traceChain(ragPipeline, { name: "rag-pipeline" });
129+
```
130+
131+
**`traceAgent`** - Convenience wrapper for tracing autonomous agents:
132+
133+
```typescript
134+
import { traceAgent } from "@arizeai/openinference-core";
135+
136+
const simpleAgent = async (question: string) => {
137+
// Agent logic that may call tools, make decisions, etc.
138+
const documents = await retrieveDocuments(question);
139+
const analysis = await analyzeContext(question, documents);
140+
return await executePlan(analysis);
141+
};
142+
143+
const tracedAgent = traceAgent(simpleAgent, { name: "qa-agent" });
144+
```
145+
146+
**`traceTool`** - Convenience wrapper for tracing external tools:
147+
148+
```typescript
149+
import { traceTool } from "@arizeai/openinference-core";
150+
151+
const weatherTool = async (city: string) => {
152+
const response = await fetch(`https://api.weather.com/v1/${city}`);
153+
return response.json();
154+
};
155+
156+
const tracedWeatherTool = traceTool(weatherTool, { name: "weather-api" });
157+
```
158+
159+
### Decorators
160+
161+
**`@observe`** - Decorator for automatically tracing class methods:
162+
163+
```typescript
164+
import { observe } from "@arizeai/openinference-core";
165+
166+
class ChatService {
167+
@observe({ kind: "chain" })
168+
async processMessage(message: string) {
169+
// Your method implementation
170+
return `Processed: ${message}`;
171+
}
172+
173+
@observe({ name: "llm-call", kind: "llm" })
174+
async callLLM(prompt: string) {
175+
// LLM invocation
176+
return await llmClient.generate(prompt);
177+
}
178+
}
179+
```
180+
181+
### Attribute Helpers
182+
183+
**`getLLMAttributes`** - Generate attributes for LLM operations:
184+
185+
```typescript
186+
import { getLLMAttributes } from "@arizeai/openinference-core";
187+
import { trace } from "@opentelemetry/api";
188+
189+
const tracer = trace.getTracer("llm-service");
190+
191+
tracer.startActiveSpan("llm-inference", (span) => {
192+
const attributes = getLLMAttributes({
193+
provider: "openai",
194+
modelName: "gpt-4",
195+
inputMessages: [{ role: "user", content: "What is AI?" }],
196+
outputMessages: [{ role: "assistant", content: "AI is..." }],
197+
tokenCount: { prompt: 10, completion: 50, total: 60 },
198+
});
199+
span.setAttributes(attributes);
200+
span.end();
201+
});
202+
```
203+
204+
**`getEmbeddingAttributes`** - Generate attributes for embedding operations:
205+
206+
```typescript
207+
import { getEmbeddingAttributes } from "@arizeai/openinference-core";
208+
import { trace } from "@opentelemetry/api";
209+
210+
const tracer = trace.getTracer("embedding-service");
211+
212+
tracer.startActiveSpan("generate-embeddings", (span) => {
213+
const attributes = getEmbeddingAttributes({
214+
modelName: "text-embedding-ada-002",
215+
embeddings: [
216+
{ text: "The quick brown fox", vector: [0.1, 0.2, 0.3, ...] },
217+
{ text: "jumps over the lazy dog", vector: [0.4, 0.5, 0.6, ...] },
218+
],
219+
});
220+
span.setAttributes(attributes);
221+
span.end();
222+
});
223+
```
224+
225+
**`getRetrieverAttributes`** - Generate attributes for document retrieval:
226+
227+
```typescript
228+
import { getRetrieverAttributes } from "@arizeai/openinference-core";
229+
import { trace } from "@opentelemetry/api";
230+
231+
const tracer = trace.getTracer("retriever-service");
232+
233+
async function retrieveDocuments(query: string) {
234+
return tracer.startActiveSpan("retrieve-documents", async (span) => {
235+
const documents = await vectorStore.similaritySearch(query, 5);
236+
const attributes = getRetrieverAttributes({
237+
documents: documents.map((doc) => ({
238+
content: doc.pageContent,
239+
id: doc.metadata.id,
240+
score: doc.score,
241+
metadata: doc.metadata,
242+
})),
243+
});
244+
span.setAttributes(attributes);
245+
span.end();
246+
return documents;
247+
});
248+
}
249+
```
250+
251+
**`getToolAttributes`** - Generate attributes for tool definitions:
252+
253+
```typescript
254+
import { getToolAttributes } from "@arizeai/openinference-core";
255+
import { trace } from "@opentelemetry/api";
256+
257+
const tracer = trace.getTracer("tool-service");
258+
259+
tracer.startActiveSpan("define-tool", (span) => {
260+
const attributes = getToolAttributes({
261+
name: "search_web",
262+
description: "Search the web for information",
263+
parameters: {
264+
query: { type: "string", description: "The search query" },
265+
maxResults: { type: "number", description: "Maximum results to return" },
266+
},
267+
});
268+
span.setAttributes(attributes);
269+
span.end();
270+
});
271+
```
272+
92273
## Trace Config
93274
94275
This package also provides support for controlling settings like data privacy and payload sizes. For instance, you may want to keep sensitive information from being logged for security reasons, or you may want to limit the size of the base64 encoded images logged to reduced payload size.

0 commit comments

Comments
 (0)