Skip to content

Commit

Permalink
Merge pull request #1 from scalable-dynamics/gpt-maker
Browse files Browse the repository at this point in the history
Gpt maker
  • Loading branch information
scalabled authored Nov 22, 2023
2 parents c81d558 + fa1cce7 commit 57a6ed2
Show file tree
Hide file tree
Showing 8 changed files with 2,089 additions and 778 deletions.
1,065 changes: 287 additions & 778 deletions index.html

Large diffs are not rendered by default.

119 changes: 119 additions & 0 deletions js/cards.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
export function contentCard(content) {
const card = {
type: 'AdaptiveCard',
version: '1.5',
body: [{
type: 'TextBlock',
text: content,
wrap: true
}]
}
const adaptiveCard = new AdaptiveCards.AdaptiveCard();
adaptiveCard.parse(card);
return adaptiveCard.render();
}

export function confirmationCard(message) {
const card = {
type: 'AdaptiveCard',
version: '1.5',
body: [{
type: 'TextBlock',
text: message,
wrap: true
}],
actions: [{
type: 'Action.Submit',
title: 'Yes',
data: 'yes'
}, {
type: 'Action.Submit',
title: 'No',
data: 'no'
}]
}
const adaptiveCard = new AdaptiveCards.AdaptiveCard();
adaptiveCard.parse(card);
const renderedCard = adaptiveCard.render();
return {
render: () => renderedCard,
getAnswer: () => new Promise((resolve) => {
adaptiveCard.onExecuteAction = (action) => {
renderedCard.parentNode.removeChild(renderedCard)
resolve(action.data === 'yes')
}
})
}
}

export function questionCard(question, answers = [], defaultValue = "") {
const card = {
type: 'AdaptiveCard',
version: '1.5',
body: [{
type: 'TextBlock',
text: question,
wrap: true
}],
actions: answers.filter(answer => answer && answer.trim()).map(answer => ({
type: 'Action.Submit',
title: answer,
data: answer
}))
}
if (card.actions.length == 0) {
card.body = [{
type: "Input.Text",
id: "answer",
label: question,
value: defaultValue,
isMultiline: question.indexOf('prompt') > -1
}];
card.actions.push({
type: 'Action.Submit',
title: 'Save'
});
}
const adaptiveCard = new AdaptiveCards.AdaptiveCard();
adaptiveCard.parse(card);
const renderedCard = adaptiveCard.render();
return {
render: () => renderedCard,
getAnswer: () => new Promise((resolve) => {
adaptiveCard.onExecuteAction = (action) => {
renderedCard.parentNode.removeChild(renderedCard)
if (action.data === '_cancel_' || (typeof action.data === 'object' && !action.data.answer)) {
resolve()
} else if (typeof action.data === 'object') {
resolve(action.data.answer)
} else {
resolve(action.data)
}
}
})
}
}

export async function configCard(outputContainer, option, text = `Enter the value for ${option}:`, defaultValue = undefined) {
const value = getQueryString(option) || localStorage.getItem(option)
if (value) return value
const question = questionCard(text, undefined, defaultValue)
outputContainer.appendChild(question.render())
const answer = await question.getAnswer()
if (answer) {
localStorage.setItem(option, answer)
return answer
}
}

export function useCardMarkdownRenderer(render) {
AdaptiveCards.AdaptiveCard.onProcessMarkdown = function (text, result) {
result.outputHtml = render(text);
result.didProcess = true;
};
}

function getQueryString(key) {
var urlParams = new URLSearchParams(window.location.search)
return urlParams.get(key)
}
24 changes: 24 additions & 0 deletions js/chat.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
export function createConversation(systemPrompt, getCompletion, getImage, vectorSearch) {
const messages = [{ role: "system", content: systemPrompt }];
return async (content, onTextReceived = undefined, useVectorSearch = false, generateImage = false) => {
const useVision = Array.isArray(content)
if (useVectorSearch) {
const results = await vectorSearch(useVision ? content[0].text : content);
if (results.length > 0) {
const retrieval = results[0].text;
messages.push({ content: `More details: ${retrieval}`, role: 'user' });
}
}
messages.push({ content, role: 'user' });
if (generateImage) {
messages.push({ content: 'Create a prompt for DALL-E to generate an image. Only return the prompt, NO OTHER TEXT.', role: 'user' });
}
const response = await getCompletion(messages, onTextReceived, useVision);
messages.push({ content: response, role: 'assistant' });
if (generateImage) {
return await getImage(response);
} else {
return response;
}
}
}
93 changes: 93 additions & 0 deletions js/files.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import * as pdfjsLib from 'https://mozilla.github.io/pdf.js/build/pdf.mjs';
pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://mozilla.github.io/pdf.js/build/pdf.worker.mjs';

export function onFilesDropped(element, onFilesAdded) {
element.addEventListener('dragover', prevent_defaults, false);
element.addEventListener('dragenter', prevent_defaults, false);
element.addEventListener('drop', async (e) => {
prevent_defaults(e);
addFiles(e.dataTransfer.files);
}, false);
return async function addFiles(files) {
const contents = [];
for (let i = 0; i < files.length; i++) {
const name = files[i].name;
const type = files[i].type;
try {
if (type === 'application/pdf') {
contents.push({
name,
type,
content: await read_pdf(files[i])
});
} else if (type.indexOf('image') === 0) {
contents.push({
name,
type,
content: await read_image(files[i])
})
} else {
contents.push({
name,
type,
content: await read_file(files[i])
});
}
} catch (e) {
console.error('FileReader error: ', e);
alert(`Error reading file ${name}`)
}
}
onFilesAdded(contents);
}
}

function read_file(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = (event) => {
resolve(event.target.result);
};
reader.onerror = reject;
reader.readAsText(file);
});
}

function read_image(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onloadend = function () {
resolve(reader.result);
}
reader.onerror = reject;
reader.readAsDataURL(file);
});
}

function read_pdf(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = async (event) => {
try {
const pdfData = new Uint8Array(reader.result);
const pdfDoc = await pdfjsLib.getDocument({ data: pdfData }).promise;
let content = "";
for (let i = 1; i <= pdfDoc.numPages; i++) {
const page = await pdfDoc.getPage(i);
const textContent = await page.getTextContent();
content += textContent.items.map(item => item.str).join(" ");
}
resolve(content);
} catch (error) {
reject(error);
}
};
reader.onerror = reject;
reader.readAsArrayBuffer(file);
});
}

function prevent_defaults(e) {
e.preventDefault();
e.stopPropagation();
}
Loading

0 comments on commit 57a6ed2

Please sign in to comment.