Skip to content

Commit

Permalink
deepinfra support
Browse files Browse the repository at this point in the history
  • Loading branch information
Laurent Denoue committed Dec 2, 2024
1 parent cee083d commit f0b9e60
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 64 deletions.
112 changes: 89 additions & 23 deletions code.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,39 @@
import { marked } from "https://esm.run/marked"
import { GoogleGenerativeAI } from "https://esm.run/@google/generative-ai"
import { OpenAI} from "https://cdn.jsdelivr.net/npm/[email protected]/+esm"

const geminiModels = ['gemini-1.5-flash-8b']
const geminiModel = geminiModels[0]

//const groqModels = ['llama-3.1-8b-instant', 'llama-3.2-1b-preview', 'llama-3.2-3b-preview']
const groqModels = ['llama-3.1-8b-instant']
const deepInfraModels = ['meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo']

const API_KEY = window.localStorage.API_KEY
if (API_KEY) {
/*if (API_KEY) {
apiKey.value = API_KEY
}
}*/

const model = await getGenerativeModel(API_KEY, { model: geminiModel, generationConfig: { temperature: 0.0} });
window.model = model

const GROQ_API_KEY = window.localStorage.GROQ_API_KEY
if (GROQ_API_KEY) {
/*if (GROQ_API_KEY) {
groqApiKey.value = GROQ_API_KEY
}*/

let openai = null
const DEEP_INFRA_API_KEY = window.localStorage.DEEP_INFRA_API_KEY
if (DEEP_INFRA_API_KEY) {
//deepInfraApiKey.value = DEEP_INFRA_API_KEY
openai = new OpenAI({
apiKey: DEEP_INFRA_API_KEY,
baseURL: 'https://api.deepinfra.com/v1/openai',
dangerouslyAllowBrowser: true,
});
}

const params = new URLSearchParams(window.location.search)
let groqModel = params.get('model')
if (groqModel === geminiModel)
groqModel = null
let currentProvider = params.get('model') || geminiModel

const languageCode = params.get('language') || 'en'
const followingAudio = true
Expand Down Expand Up @@ -266,12 +276,17 @@ function timeout(ms) {
let outputTokens = 0
let inputTokens = 0
let totalTokens = 0
let totalPrice = 0

const llmProviders = {
'gemini-1.5-flash-8b': {
inputPrice: 0.0375,
outputPrice: 0.15,
},
'meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo': {
inputPrice: 0.05,
outputPrice: 0.05,
},
'llama-3.1-8b-instant': {
inputPrice: 0.05,
outputPrice: 0.08,
Expand All @@ -294,24 +309,45 @@ function formatPrice(price) {
return price.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 5, style: "currency", currency: "USD" })
}

function updateEstimatedPrice( inputTokens, outputTokens, totalTokens) {
let usageCaption = `Tokens ${totalTokens}<br>`
function updateEstimatedPrice( inputTokens, outputTokens, totalTokens, totalPrice = null) {
totalTokensSpan.textContent = totalTokens
let usageCaption = ''
for (let providerName in llmProviders) {
const data = llmProviders[providerName]
const priceInput = computePrice(inputTokens, data.inputPrice)
const priceOutput = computePrice(outputTokens, data.outputPrice)
const priceTotal = priceInput + priceOutput
const isCurrentProvider = (providerName === groqModel) || (groqModel === null && providerName === geminiModel)
const priceTotal = (priceInput + priceOutput)
const isCurrentProvider = providerName === currentProvider
usageCaption += isCurrentProvider ? '<b>' : ''
usageCaption += ` <a href="./?id=${videoId}&model=${providerName}">${providerName}: ${formatPrice(priceTotal)}</a>`
usageCaption += ` <a onclick="updateModel('${providerName}')" href="#">${providerName}: ${formatPrice(priceTotal)}</a>`
usageCaption += isCurrentProvider ? '</b>' : ''
usageCaption += '<br>'
}
usageDiv.innerHTML = usageCaption
usageDiv.style.display = 'block'
}

async function getGroq(prompt, systemPrompt = 'You are a helpful assistant and only return the result without extra explanation.') {
const SYSTEM_PROMPT = 'You are a helpful assistant and only return the result without extra explanation.'

async function getDeepInfra(prompt, systemPrompt = SYSTEM_PROMPT) {
const completion = await openai.chat.completions.create({
messages: [
{ role: "system", content: systemPrompt },
{ role: "user", content: prompt }
],
model: currentProvider,
stream: false,
});
let text = completion.choices[0].message.content
inputTokens += completion.usage.prompt_tokens
outputTokens += completion.usage.completion_tokens
totalTokens += completion.usage.total_tokens
totalPrice += completion.usage.estimated_cost
updateEstimatedPrice(inputTokens, outputTokens, totalTokens, totalPrice)
return text
}

async function getGroq(prompt, systemPrompt = SYSTEM_PROMPT) {
const obj = {
"messages": [
{
Expand All @@ -323,7 +359,7 @@ async function getGroq(prompt, systemPrompt = 'You are a helpful assistant and o
"content": prompt
}
],
"model": groqModel,
"model": currentProvider,
"temperature": 0,
}
try {
Expand Down Expand Up @@ -359,9 +395,10 @@ async function getModelAnswer(prompt, maxretry = 4, retryDelayMs = 4000) {
for (let i = 0; i < maxretry; i++) {
try {
let res = null
if (groqModel) {
res = await getGroq(prompt)
return res
if (deepInfraModels.indexOf(currentProvider) !== -1) {
return await getDeepInfra(prompt)
} else if (groqModels.indexOf(currentProvider) !== -1) {
return await getGroq(prompt)
} else {
res = await model.generateContent([prompt])
inputTokens += res.response.usageMetadata.promptTokenCount
Expand Down Expand Up @@ -1179,6 +1216,7 @@ async function getLocal(videoId, languageCode = 'en') {
// https://stackoverflow.com/questions/67615278/get-video-info-youtube-endpoint-suddenly-returning-404-not-found
const json = await postData(
"https://release-youtubei.sandbox.googleapis.com/youtubei/v1/player", payload)
window.yt = json
const obj = {}
if (json.error || json.videoDetails === undefined)
return { error: 'invalid video' }
Expand Down Expand Up @@ -1290,6 +1328,11 @@ function showError(msg) {
let transcript = null
let vocab = null
async function punctuate(videoId, languageCode = 'en') {
totalPrice = 0
inputTokens = 0
outputTokens = 0
totalTokens = 0
updateEstimatedPrice(inputTokens, outputTokens, totalTokens, totalPrice)
let json = await getLocal(videoId, languageCode)
window.json = json
if (json.error) {
Expand Down Expand Up @@ -1365,6 +1408,8 @@ async function punctuate(videoId, languageCode = 'en') {
return
} else if (res.length === 1) {
let punctuatedText = res[0]
let endTime = Date.now()
durationSpan.textContent = msToTime(endTime - startTime)
json[languageCode].punctuatedText = punctuatedText
localforage.setItem(videoId, json)
let punctuatedTimes = testDiff(wordTimes, punctuatedText)
Expand Down Expand Up @@ -1436,16 +1481,28 @@ highlighter.onmousedown = (evt) => addHighlight(evt)

pdfBtn.onclick = () => { window.print() }

keyBtn.onclick = () => {
window.localStorage.API_KEY = apiKey.value.trim()
window.location.reload()

geminiBtn.onclick = () => {
const result = prompt("Enter your Gemini API_KEY", API_KEY || '')
if (result) {
window.localStorage.API_KEY = result
}
}

groqKeyBtn.onclick = () => {
window.localStorage.GROQ_API_KEY = groqApiKey.value.trim()
window.location.reload()
groqBtn.onclick = () => {
const result = prompt("Enter your Groq API_KEY", GROQ_API_KEY || '')
if (result) {
window.localStorage.GROQ_API_KEY = result
}
}

deepInfraBtn.onclick = () => {
const result = prompt("Enter your DeepInfra API_KEY", DEEP_INFRA_API_KEY || '')
if (result) {
window.localStorage.DEEP_INFRA_API_KEY = result
}
}

function startObserving() {
const target = document.getElementById('playercontainer')
const marker = document.getElementById('marker')
Expand Down Expand Up @@ -1488,6 +1545,15 @@ downloadBtn.onclick = async () => {
URL.revokeObjectURL(url)
}

async function updateModel(newProvider) {
if (newProvider !== currentProvider) {
await window.localforage.removeItem(videoId)
window.location.href = `./?id=${videoId}&model=${newProvider}&language=${selectLanguage.value}`
}
}

window.updateModel = updateModel

clearCacheBtn.onclick = async () => {
await window.localforage.removeItem(videoId)
window.location.reload()
Expand Down
27 changes: 10 additions & 17 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,32 +26,25 @@
<h1><a href="./">Readable Transcripts</a></h1>
<form method="get">
<div class="flexrow">
<input type="text" name="q" id="q" placeholder="YouTube link or query" value="">
<button type="submit" id="searchBtn">Search</button>
<input type="text" name="q" id="q" size="32" placeholder="YouTube link or query" value="">
<button type="submit" id="searchBtn"><i class="fa-solid fa-magnifying-glass"></i></button>
</div>
</form>
<form method="get">
<div class="flexrow">
Gemini <input type="text" id="apiKey" placeholder="Gemini API Key" value="">
<button type="submit" id="keyBtn">Set Key</button>
</div>
<div class="flexrow">
Groq <input type="text" id="groqApiKey" placeholder="Groq API Key" value="">
<button type="submit" id="groqKeyBtn">Set Key</button>
</div>
<p>Get free API keys for <a href="https://aistudio.google.com/apikey" target="_blank">Gemini</a> and/or <a href="https://console.groq.com/keys">Groq</a>. Keys is used in your browser only.</p>
</form>
<div class="flex">
<button id="geminiBtn">Gemini</button>
<button id="groqBtn">Groq</button>
<button id="deepInfraBtn">DeepInfra</button>
</div>
</div>
<div id="items">
</div>
<div id="container" class="row">
<div class="column" id="col1">
<h2>
<a href="./"><i class="btn fa-solid fa-home"></i></a>
</h2>
<a href="./"><i class="btn fa-solid fa-home"></i></a>
<b id="vtitle"></b>
<a id="vurl" target="_blank" href=""></a>
<div class="flexrow start"><span id="vduration"></span> <span id="usageDiv"></span> <span id="durationSpan"></span><a title="Refresh (clears cached data for this video)" href="#" id="clearCacheBtn"><i class="fa-solid fa-rotate-left"></i></a></div>
<div><span id="vduration">--:--</span> Tokens: <span id="totalTokensSpan"></span> Time: <span id="durationSpan">--:--</span></div>
<div><span id="usageDiv"></span> <a title="Refresh (clears cached data for this video)" href="#" id="clearCacheBtn"><i class="fa-solid fa-rotate-left"></i></a></div>
<div id="marker"></div>
<div id="dd">
<div id="playercontainer">
Expand Down
37 changes: 13 additions & 24 deletions styles.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
:root {
--formw: 800px;
--font-name: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
--byellow: #F38181;
--showts: block;
Expand Down Expand Up @@ -49,7 +48,6 @@ button {
border-radius: 4px;
padding: 8px 16px;
font-size: 1rem;
width: 120px;
font-family: var(--font-name);
background-color: var(--byellow);
color: white;
Expand Down Expand Up @@ -197,8 +195,9 @@ div.video-annotations {
z-index: 3;
}
.btn {
font-size: 24px;
font-size: 20px;
width: 48px;
aspect-ratio: 1;
height: 48px;
background-color: var(--byellow);
color: white;
Expand Down Expand Up @@ -309,14 +308,6 @@ input[type="range"]::-moz-range-thumb {
display: none;
}

form {
margin: 16px 0;
}

form input {
margin: 8px 0;
}

.prop {
display: inline-block;
padding: 8px 12px;
Expand All @@ -338,9 +329,6 @@ form input {
opacity: 1.0 !important;
}

.start {
align-self: flex-start;
}
input[type='color'] {
width: 200%;
height: 200%;
Expand Down Expand Up @@ -400,8 +388,7 @@ input[type='color'] {
#myform {
margin: 16px auto;
display: flex;
width: var(--formw);
max-width: calc(100% - 32px);
max-width: 420px;
flex-direction: column;
justify-content: center;
align-items: center;
Expand All @@ -413,19 +400,19 @@ input[type='color'] {
justify-content: center;
align-items: center;
gap: 8px;

width: 100%;
}
form {
margin: 0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
justify-content: flex-start;
align-items: flex-start;
}
#items {
margin: 16px auto;
display: none;
width: var(--formw);
width: 800px;
max-width: calc(100% - 32px);
flex-direction: column;
justify-content: center;
Expand Down Expand Up @@ -558,10 +545,6 @@ h2, h1 {
padding-top: 80px;
}

#usageDiv, #vduration, #clearCacheBtn, #durationSpan {
font-size: 0.9rem;
}

#marker {
height: 1px;
}
Expand Down Expand Up @@ -647,6 +630,12 @@ h2, h1 {
padding-top: 16px!important;
}

.github-corner {
z-index: 3;
position: fixed;
right: 0;
top: 0;
}
@media print {
body {
padding-top: 0!important;
Expand Down

0 comments on commit f0b9e60

Please sign in to comment.