Skip to content

fix: require instrumentation dependencies at runtime #67

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 49 additions & 23 deletions src/instrumentation/index.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
import OpenAI from 'openai';

import { LiteralClient, Maybe } from '..';
import { LiteralCallbackHandler } from './langchain';
import { instrumentLlamaIndex, withThread } from './llamaindex';
import instrumentOpenAI from './openai';
import { makeInstrumentVercelSDK } from './vercel-sdk';
import { Thread } from '../observability/thread';
import type { AllVercelFn } from './vercel-sdk';

export type OpenAIGlobalOptions = {
tags?: Maybe<string[]>;
metadata?: Maybe<Record<string, any>>;
client?: OpenAI;
client?: any;
};

export default (client: LiteralClient) => ({
Expand All @@ -23,14 +19,26 @@ export default (client: LiteralClient) => ({
* @param options.metadata Metadata to attach to all generations.
* @returns
*/
openai: (options?: OpenAIGlobalOptions) => instrumentOpenAI(client, options),
openai: (options?: OpenAIGlobalOptions) => {
try {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { default: instrumentOpenAI } = require('./openai');
return instrumentOpenAI(client, options);
} catch (error) {
throw new Error(
'Failed to load OpenAI. Please ensure openai is installed.'
);
}
},

langchain: {
literalCallback: (params?: {
threadId?: string;
chainTypesToIgnore?: string[];
}) => {
try {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { LiteralCallbackHandler } = require('./langchain');
return new LiteralCallbackHandler(
client,
params?.threadId,
Expand All @@ -45,23 +53,41 @@ export default (client: LiteralClient) => ({
},

vercel: {
/**
* Instrument a Vercel SDK function to log all invocations to the Literal AI API.
* It will be augmented with a `literalAiParent` option that allows you to specify a parent step or thread.
* @param fn The function to instrument. This can be Vercel SDK's `generateText` or `streamText` functions.
* @returns A new function that logs all invocations to the Literal AI API.
*/
instrument: makeInstrumentVercelSDK(client)
instrument: <TFunction extends AllVercelFn>(fn: TFunction) => {
try {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { makeInstrumentVercelSDK } = require('./vercel-sdk');
return makeInstrumentVercelSDK(client)(fn);
} catch (error) {
throw new Error(
'Failed to load Vercel SDK. Please ensure @vercel/ai is installed.'
);
}
}
},

llamaIndex: {
/**
* Instrument the LlamaIndex client to log all generations to the Literal AI API.
*/
instrument: () => instrumentLlamaIndex(client),
/**
* Run a callback with a thread context.
*/
withThread
instrument: () => {
try {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { instrumentLlamaIndex } = require('./llamaindex');
return instrumentLlamaIndex(client);
} catch (error) {
throw new Error(
'Failed to load LlamaIndex. Please ensure llamaindex is installed.'
);
}
},
withThread: <R>(thread: Thread, callback: () => R) => {
try {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { withThread } = require('./llamaindex');
return withThread(thread, callback);
} catch (error) {
throw new Error(
'Failed to load LlamaIndex. Please ensure llamaindex is installed.'
);
}
}
}
});
4 changes: 2 additions & 2 deletions src/instrumentation/vercel-sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type Result<T extends (...args: any[]) => any> = Awaited<ReturnType<T>>;

type GenerateFn = typeof generateObject | typeof generateText;
type StreamFn = typeof streamObject | typeof streamText;
type AllVercelFn = GenerateFn | StreamFn;
export type AllVercelFn = GenerateFn | StreamFn;

type OriginalStreamPart = string | ObjectStreamPart<any> | TextStreamPart<any>;

Expand Down Expand Up @@ -289,7 +289,7 @@ export type InstrumentationVercelMethod = {
options: Parameters<typeof streamText<TOOLS>>[0] & VercelExtraOptions
) => ReturnType<typeof streamText<TOOLS>>;

(fn: typeof generateObject): <T>(
(fn: typeof generateObject): <T extends string>(
options: Parameters<typeof generateObject<T>>[0] & VercelExtraOptions
) => ReturnType<typeof generateObject<T>>;

Expand Down
4 changes: 2 additions & 2 deletions tests/integration/vercel-sdk.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ describe.skip('Vercel SDK Instrumentation', () => {
parameters: z.object({
value: z.number().describe('The value in celsius')
}),
execute: async ({ value }) => {
execute: async ({ value }: any) => {
const celsius = parseFloat(value);
const fahrenheit = celsius * (9 / 5) + 32;
return fahrenheit;
Expand Down Expand Up @@ -345,7 +345,7 @@ describe.skip('Vercel SDK Instrumentation', () => {
parameters: z.object({
value: z.number().describe('The value in celsius')
}),
execute: async ({ value }) => {
execute: async ({ value }: any) => {
const celsius = parseFloat(value);
const fahrenheit = celsius * (9 / 5) + 32;
return fahrenheit;
Expand Down
Loading