Skip to content
This repository has been archived by the owner on Apr 18, 2024. It is now read-only.

Track LLM Request ID as llmReqId #5

Merged
merged 6 commits into from
Feb 11, 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
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ const openai = new OpenAI({
});

// Pass the above `openai` object along with your DOKU URL and API key and this will make sure that all OpenAI calls are automatically tracked.
DokuMetry.init({llm: openai, dokuURL: "YOUR_DOKU_URL", apiKey: "YOUR_DOKU_TOKEN"})
DokuMetry.init({llm: openai, dokuUrl: "YOUR_DOKU_URL", apiKey: "YOUR_DOKU_TOKEN"})

async function main() {
const chatCompletion = await openai.chat.completions.create({
Expand All @@ -73,7 +73,7 @@ const anthropic = new Anthropic({
});

// Pass the above `anthropic` object along with your DOKU URL and API key and this will make sure that all Anthropic calls are automatically tracked.
DokuMetry.init({llm: anthropic, dokuURL: "YOUR_DOKU_URL", apiKey: "YOUR_DOKU_TOKEN"})
DokuMetry.init({llm: anthropic, dokuUrl: "YOUR_DOKU_URL", apiKey: "YOUR_DOKU_TOKEN"})

async function main() {
const completion = await anthropic.completions.create({
Expand All @@ -97,7 +97,7 @@ const cohere = new CohereClient({
});

// Pass the above `cohere` object along with your DOKU URL and API key and this will make sure that all Cohere calls are automatically tracked.
DokuMetry.init({llm: cohere, dokuURL: "YOUR_DOKU_URL", apiKey: "YOUR_DOKU_TOKEN"})
DokuMetry.init({llm: cohere, dokuUrl: "YOUR_DOKU_URL", apiKey: "YOUR_DOKU_TOKEN"})

(async () => {
const prediction = await cohere.generate({
Expand All @@ -114,7 +114,7 @@ DokuMetry.init({llm: cohere, dokuURL: "YOUR_DOKU_URL", apiKey: "YOUR_DOKU_TOKEN"
| Parameter | Description | Required |
|-------------------|-----------------------------------------------------------|---------------|
| llm | Language Learning Model (LLM) Object to track | Yes |
| dokuURL | URL of your Doku Instance | Yes |
| dokuUrl | URL of your Doku Instance | Yes |
| apiKey | Your Doku API key | Yes |
| environment | Custom environment tag to include in your metrics | Optional |
| applicationName | Custom application name tag for your metrics | Optional |
Expand Down
1 change: 1 addition & 0 deletions src/anthropic.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export default function initAnthropic({ llm, dokuUrl, apiKey, environment, appli
const duration = (end - start) / 1000;

const data = {
llmReqId: response.id,
environment: environment,
applicationName: applicationName,
sourceLanguage: 'Javascript',
Expand Down
49 changes: 16 additions & 33 deletions src/cohere.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,5 @@
import {sendData} from './helpers.js';

/**
* Counts the number of tokens in the given text.
*
* @param {string} text - The input text.
* @return {number} - The calculated number of tokens.
*
* @jsondoc
* {
* "description": "Counts the number of tokens in the given text",
* "params": [{"name": "text", "type": "string", "description": "Text"}],
* "returns": {"type": "number", "description": "Number of tokens."}
* }
*/
function countTokens(text) {
const tokensPerWord = 2.5;

// Split the text into words
const words = text.split(/\s+/);

// Calculate the number of tokens
const numTokens = Math.round(words.length * tokensPerWord);

return numTokens;
}
/**
* Initializes Cohere functionality with performance tracking and data logging.
*
Expand Down Expand Up @@ -72,13 +48,14 @@ export default function initCohere({ llm, dokuUrl, apiKey, environment, applicat

for (const generation of response.generations) {
const data = {
llmReqId: generation.id,
environment: environment,
applicationName: applicationName,
sourceLanguage: 'Javascript',
endpoint: 'cohere.generate',
skipResp: skipResp,
completionTokens: countTokens(generation.text),
promptTokens: countTokens(prompt),
completionTokens: response.meta["billedUnits"]["outputTokens"],
promptTokens: response.meta["billedUnits"]["inputTokens"],
requestDuration: duration,
model: model,
prompt: prompt,
Expand All @@ -89,7 +66,8 @@ export default function initCohere({ llm, dokuUrl, apiKey, environment, applicat
if (!params.hasOwnProperty('stream') || params.stream !== true) {
data.finishReason = generation.finish_reason;
}
await sendData(data, dokuUrl, apiKey);
console.log(data);
//await sendData(data, dokuUrl, apiKey);
}

return response;
Expand All @@ -113,7 +91,7 @@ export default function initCohere({ llm, dokuUrl, apiKey, environment, applicat
requestDuration: duration,
model: model,
prompt: prompt,
promptTokens: response.meta["billed_units"]["input_tokens"],
promptTokens: response.meta["billedUnits"]["inputTokens"],
};

await sendData(data, dokuUrl, apiKey);
Expand All @@ -131,6 +109,7 @@ export default function initCohere({ llm, dokuUrl, apiKey, environment, applicat
const prompt = params.message;

const data = {
llmReqId: response.response_id,
environment: environment,
applicationName: applicationName,
sourceLanguage: 'Javascript',
Expand All @@ -141,7 +120,7 @@ export default function initCohere({ llm, dokuUrl, apiKey, environment, applicat
prompt: prompt,
promptTokens: response.meta["billed_units"]["output_tokens"],
completionTokens: response.meta["billed_units"]["input_tokens"],
totalTokens: response.token_count["billed_tokens"],
totalTokens: response.token_count["billed_units"],
response: response.text,
};

Expand Down Expand Up @@ -169,12 +148,15 @@ export default function initCohere({ llm, dokuUrl, apiKey, environment, applicat

data.response = ""
for await (const message of response) {
if (message.eventType === "stream-end") {
data.llmReqId = message.response.response_id;
data.promptTokens = message.response.meta.billed_units["input_tokens"];
data.completionTokens = message.response.meta.billed_units["output_tokens"];
}
data.response += message.eventType === "text-generation" ? message.text : "";
// Pass the message along so it's not consumed
yield message; // this allows the message to flow back to the original caller
}
data.promptTokens = countTokens(prompt)
data.completionTokens = countTokens(data.response)
data.totalTokens = data.promptTokens + data.completionTokens

const end = performance.now();
Expand All @@ -195,14 +177,15 @@ export default function initCohere({ llm, dokuUrl, apiKey, environment, applicat
const prompt = params.text;

const data = {
llmReqId: response.id,
environment: environment,
applicationName: applicationName,
sourceLanguage: 'Javascript',
endpoint: 'cohere.summarize',
skipResp: skipResp,
requestDuration: duration,
completionTokens: response.meta["billed_units"]["output_tokens"],
promptTokens: response.meta["billed_units"]["input_tokens"],
completionTokens: response.meta["billedUnits"]["outputTokens"],
promptTokens: response.meta["billedUnits"]["inputTokens"],
model: model,
prompt: prompt,
response: response.summary,
Expand Down
14 changes: 12 additions & 2 deletions src/openai.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export default function initOpenAI({ llm, dokuUrl, apiKey, environment, applicat
dataResponse += content;
passThroughStream.push(chunk); // Push chunk to the pass-through stream
}
var responseId = chunk.id;
}
passThroughStream.push(null); // Signal end of the pass-through stream

Expand Down Expand Up @@ -93,6 +94,7 @@ export default function initOpenAI({ llm, dokuUrl, apiKey, environment, applicat

// Prepare the data object for Doku
const data = {
llmReqId: responseId,
environment: environment,
applicationName: applicationName,
sourceLanguage: 'Javascript',
Expand Down Expand Up @@ -136,6 +138,7 @@ export default function initOpenAI({ llm, dokuUrl, apiKey, environment, applicat
}
let prompt = formattedMessages.join("\n");
const data = {
llmReqId: response.id,
environment: environment,
applicationName: applicationName,
sourceLanguage: 'Javascript',
Expand Down Expand Up @@ -169,6 +172,7 @@ export default function initOpenAI({ llm, dokuUrl, apiKey, environment, applicat
data.promptTokens = response.usage.prompt_tokens;
data.totalTokens = response.usage.total_tokens;
}

await sendData(data, dokuUrl, apiKey);

return response;
Expand Down Expand Up @@ -198,6 +202,7 @@ export default function initOpenAI({ llm, dokuUrl, apiKey, environment, applicat
dataResponse += content;
passThroughStream.push(chunk); // Push chunk to the pass-through stream
}
var responseId = chunk.id;
}
passThroughStream.push(null); // Signal end of the pass-through stream

Expand All @@ -206,6 +211,7 @@ export default function initOpenAI({ llm, dokuUrl, apiKey, environment, applicat
const duration = (end - start) / 1000;
// Prepare the data object for Doku
const data = {
llmReqId: responseId,
environment: environment,
applicationName: applicationName,
sourceLanguage: 'Javascript',
Expand All @@ -229,6 +235,7 @@ export default function initOpenAI({ llm, dokuUrl, apiKey, environment, applicat
const duration = (end - start) / 1000;

const data = {
llmReqId: response.id,
environment: environment,
applicationName: applicationName,
sourceLanguage: 'Javascript',
Expand Down Expand Up @@ -308,7 +315,7 @@ export default function initOpenAI({ llm, dokuUrl, apiKey, environment, applicat
skipResp: skipResp,
requestDuration: duration,
model: params.model,
finetuneJobId: response.id,
llmReqId: response.id,
finetuneJobStatus: response.status,
};

Expand All @@ -331,9 +338,10 @@ export default function initOpenAI({ llm, dokuUrl, apiKey, environment, applicat
}

const quality = params.quality ?? 'standard';

var responseId = response.created;
for (const item of response.data) {
const data = {
llmReqId: responseId,
environment: environment,
applicationName: applicationName,
sourceLanguage: 'Javascript',
Expand Down Expand Up @@ -365,8 +373,10 @@ export default function initOpenAI({ llm, dokuUrl, apiKey, environment, applicat
if (params.response_format && params.response_format === 'b64_json') {
imageFormat = 'b64_json';
}
var responseId = response.created;
for (const item of response.data) {
const data = {
llmReqId: responseId,
environment: environment,
applicationName: applicationName,
sourceLanguage: 'Javascript',
Expand Down
8 changes: 4 additions & 4 deletions tests/cohere.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,9 @@ describe('Cohere Test', () => {
const cohere = new CohereClient({
apiKey: process.env.COHERE_API_TOKEN,
});

before(async () => {
DokuMetry.init({llm: cohere, dokuUrl: process.env.DOKU_URL, apiKey: process.env.DOKU_TOKEN, environment: "dokumetry-testing", applicationName: "dokumetry-node-test", skipResp: false});
});

it('should return a response with "created" field', async () => {
DokuMetry.init({llm: cohere, dokuUrl: process.env.DOKU_URL, apiKey: process.env.DOKU_TOKEN, environment: "dokumetry-testing", applicationName: "dokumetry-node-test", skipResp: false});
const text =
'Ice cream is a sweetened frozen food eaten as a snack or dessert. ' +
'It may be made from milk or cream and is flavoured with a sweetener, ' +
Expand Down Expand Up @@ -48,6 +45,7 @@ describe('Cohere Test', () => {
}).timeout(10000);

it('should return a response with prompt as "Doku"', async () => {
DokuMetry.init({llm: cohere, dokuUrl: process.env.DOKU_URL, apiKey: process.env.DOKU_TOKEN, environment: "dokumetry-testing", applicationName: "dokumetry-node-test", skipResp: false});
try {
const generate = await cohere.generate({
prompt: 'Doku',
Expand All @@ -64,6 +62,7 @@ describe('Cohere Test', () => {
}).timeout(10000);

it('should return a response with object as "embed"', async () => {
DokuMetry.init({llm: cohere, dokuUrl: process.env.DOKU_URL, apiKey: process.env.DOKU_TOKEN, environment: "dokumetry-testing", applicationName: "dokumetry-node-test", skipResp: false});
try {
const embeddings = await cohere.embed({
texts: ['This is a test'],
Expand All @@ -79,6 +78,7 @@ describe('Cohere Test', () => {
}).timeout(20000);

it('should return a response with object as "chat"', async () => {
DokuMetry.init({llm: cohere, dokuUrl: process.env.DOKU_URL, apiKey: process.env.DOKU_TOKEN, environment: "dokumetry-testing", applicationName: "dokumetry-node-test", skipResp: false});
try {
const chatResponse = await cohere.chat({
message: 'Say this is a test',
Expand Down
11 changes: 8 additions & 3 deletions tests/openai.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ describe('OpenAI Test', () => {
openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
await DokuMetry.init({llm: openai, dokuUrl: process.env.DOKU_URL, apiKey: process.env.DOKU_TOKEN, environment: "dokumetry-testing", applicationName: "dokumetry-node-test", skipResp: false});
});

it('should return a response with object as "chat.completion"', async () => {
await DokuMetry.init({llm: openai, dokuUrl: process.env.DOKU_URL, apiKey: process.env.DOKU_TOKEN, environment: "dokumetry-testing", applicationName: "dokumetry-node-test", skipResp: false});
const chatCompletion = await openai.chat.completions.create({
messages: [{role: 'user', content: 'Say this is a test'}],
model: 'gpt-3.5-turbo',
Expand All @@ -23,6 +23,7 @@ describe('OpenAI Test', () => {
});

it('should return a response with object as "text_completion"', async () => {
await DokuMetry.init({llm: openai, dokuUrl: process.env.DOKU_URL, apiKey: process.env.DOKU_TOKEN, environment: "dokumetry-testing", applicationName: "dokumetry-node-test", skipResp: false});
const completion = await openai.completions.create({
model: 'gpt-3.5-turbo-instruct',
prompt: 'Say this is a test.',
Expand All @@ -33,6 +34,7 @@ describe('OpenAI Test', () => {
});

it('should return a response with object as "embedding"', async () => {
await DokuMetry.init({llm: openai, dokuUrl: process.env.DOKU_URL, apiKey: process.env.DOKU_TOKEN, environment: "dokumetry-testing", applicationName: "dokumetry-node-test", skipResp: false});
const embeddings = await openai.embeddings.create({
model: 'text-embedding-ada-002',
input: 'The quick brown fox jumped over the lazy dog',
Expand All @@ -43,6 +45,7 @@ describe('OpenAI Test', () => {
});

it('should return a response with object as "fine_tuning.job"', async () => {
await DokuMetry.init({llm: openai, dokuUrl: process.env.DOKU_URL, apiKey: process.env.DOKU_TOKEN, environment: "dokumetry-testing", applicationName: "dokumetry-node-test", skipResp: false});
try {
const fineTuningJob = await openai.fineTuning.jobs.create({
training_file: 'file-m36cc45komO83VJKAY1qVgeP',
Expand All @@ -59,6 +62,7 @@ describe('OpenAI Test', () => {
}).timeout(10000);

it('should return a response with "created" field', async () => {
await DokuMetry.init({llm: openai, dokuUrl: process.env.DOKU_URL, apiKey: process.env.DOKU_TOKEN, environment: "dokumetry-testing", applicationName: "dokumetry-node-test", skipResp: false});
const imageGeneration = await openai.images.generate({
model: 'dall-e-2',
prompt: 'Generate an image of a cat.',
Expand All @@ -68,6 +72,7 @@ describe('OpenAI Test', () => {
}).timeout(30000);

it('should return a response with "created" field', async () => {
await DokuMetry.init({llm: openai, dokuUrl: process.env.DOKU_URL, apiKey: process.env.DOKU_TOKEN, environment: "dokumetry-testing", applicationName: "dokumetry-node-test", skipResp: false});
const imageVariation = await openai.images.createVariation({
image: fs.createReadStream('tests/test-image-for-openai.png'),
});
Expand All @@ -76,12 +81,12 @@ describe('OpenAI Test', () => {
}).timeout(30000);

it('should return a response with url as "https://api.openai.com/v1/audio/speech"', async () => {
DokuMetry.init({llm: openai, dokuUrl: process.env.DOKU_URL, apiKey: process.env.DOKU_TOKEN, environment: "dokumetry-testing", applicationName: "dokumetry-node-test", skipResp: false});
const audioSpeech = await openai.audio.speech.create({
model: 'tts-1',
voice: 'alloy',
input: 'Today is a wonderful day to build something people love!',
});

expect(audioSpeech.url).to.equal('https://api.openai.com/v1/audio/speech');
});
}).timeout(30000);
});
Loading