Insert cell
Insert cell
viewof CONSOLIDATE = Inputs.toggle({
label: '0) Consolidate',
});
Insert cell
viewof OPENAI_API_KEY = Inputs.text({
label: 'OpenAI API Key',
});
Insert cell
viewof P0_DOCUMENT_ = Inputs.textarea({
rows: 24,
label: '0) Document',
})
Insert cell
viewof P0_DOCUMENT = Inputs.button('Continue', {
label: '0) Document',
value: null,
reduce: () => viewof P0_DOCUMENT_.value,
});
Insert cell
viewof P0_FRAGMENTS_ = {
const document = P0_DOCUMENT;
if (!document) return null;

// await approval({ name: `Compute Fragments`, invalidation });
const fragments = SPLIT(document, { maxTokens: 2048 });
return FORM(fragments.map((fragment, i) => {
return Inputs.textarea({
rows: 24,
label: String.raw`0) Fragment ${i+1}`,
value: fragment,
});
}));
}
Insert cell
viewof P0_FRAGMENTS = Inputs.button('Continue', {
label: '0) Fragments',
value: null,
reduce: () => viewof P0_FRAGMENTS_.value,
});
Insert cell
viewof P1_REQUESTS_ = {
const fragments = P0_FRAGMENTS;
if (!fragments) return null;

const requests = [];
for (let i=0, n=fragments.length; i<n; ++i) {
const fragment = fragments[i];

const messages = [];

messages.push({
role: String.raw`system`,
content: String.raw`You are an undergraduate university student taking a microbiology course. You have been given an assignment to write a summary of an academic paper according to a provided rubric. Your job is split into 3 Phases:

Phase 1) You collect facts verbatim from the paper that relate to the rubric.

Phase 2) You combine the facts into a cogent summary for a specific part of the rubric.

Phase 3) You combine individual paragraphs into a complete and coherent summary of the paper that addresses the rubric.

You are currently in Phase 1.`,
});

messages.push({
role: String.raw`user`,
content: String.raw`I will now provide you with the rubric.

Please find a scientific paper that addresses productivity and has extended impacts on a societal issue or topic.

After reading your chosen paper, please submit a half page summary regarding the paper's main motivations, findings, and larger impacts.

This summary should include the title (citation) of your paper, main ideas and specific hypotheses addressed, methods used, relevant conclusions, and potential societal impacts (see rubric for details).

Paragraph needs:

title/citation and main focus of paper

summary includes main ideas and specific hypothesis/ theories tested

includes brief overview of methods

includes main results and relevant discussion topics

addresses potential social impact/concern`,
});

messages.push({
role: String.raw`user`,
content: String.raw`I will now provide you with a snippet of the paper. This is part ${i+1} of the total ${n} parts.

${fragment}`,
});

messages.push({
role: String.raw`user`,
content: String.raw`Remember: Phase 1) You collect facts verbatim from the paper that relate to the rubric.

Perform Phase 1.`,
});

const request = {
model: String.raw`gpt-3.5-turbo`,
messages,
};

requests.push(request);
}

return FORM(requests.map(({ model, messages }, i) => {
return FORM({
model: Inputs.text({
label: 'model',
value: model,
}),
messages: FORM(messages.map(({ role, content }) => {
return FORM({
role: Inputs.text({
label: 'role',
value: role,
}),
content: Inputs.textarea({
rows: 24,
label: 'content',
value: content,
}),
});
})),
});
}));
}
Insert cell
viewof P1_REQUESTS = Inputs.button('Continue', {
value: null,
reduce: () => viewof P1_REQUESTS_.value,
});
Insert cell
viewof P1_RESPONSES_ = {
const requests = P1_REQUESTS;
if (!requests) return null;

const responses = [];
for (let i=0, n=requests.length; i<n; ++i) {
yield VIEW();
let request = requests[i];
request = new Request('https://api.openai.com/v1/chat/completions', {
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${OPENAI_API_KEY}`,
},
body: JSON.stringify(request),
});

const response = await FETCH(request);

const { role, content } = response.choices[0].message;

responses.push({ role, content });
}

return yield VIEW();

function VIEW() {
return FORM(responses.map(({ role, content }, i) => {
return FORM({
role: Inputs.text({
label: 'role',
value: role,
}),
content: Inputs.textarea({
rows: 24,
label: 'content',
value: content,
}),
});
}));
}
}
Insert cell
viewof P1_RESPONSES = Inputs.button('Continue', {
label: '1) Responses',
value: null,
reduce: () => viewof P1_RESPONSES_.value,
});
Insert cell
viewof P1B_REQUESTS = {
const responses = P1_RESPONSES;
if (!responses) return null;

const requests
}
Insert cell
viewof QUESTION_AND_ANSWER = Inputs.textarea({
rows: 24,
value: MAKE_QUESTION_AND_ANSWER({
informations: [
],
choices: [
String.raw``,
],
}),
});
Insert cell
function FORM(inputs, { template=TEMPLATE }={}) {
return Inputs.form(inputs, { template });
}
Insert cell
function TEMPLATE(inputs) {
if (!Array.isArray(inputs)) {
inputs = Object.values(inputs);
}

return htl.html`<div style="padding-left: 1rem;">${inputs}`;
};
Insert cell
function MAKE_QUESTION_AND_ANSWER({ choices, informations }={}) {

const prompt = [];

prompt.push(String.raw`Read the entire message above and answer the multiple-choice question about it.`);
if (Array.isArray(informations) && informations.length) {
prompt.push(String.raw`Here is some additional information that may help for classifying the message.`);
for (const information of informations) {
prompt.push(information);
}
}

prompt.push(String.raw`Which of the following choices best describes the Assistant response? Your choice should not be affected by the content of the User prompt. Answer the question by selecting one of the following options:`);

if (Array.isArray(choices)) {
const keys = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
choices = Object.fromEntries(choices.map((choice, i) => ([keys.substring(i, i+1), choice])));
}

const keys = Array.from(Object.keys(choices));
keys.sort((a, b) => a.localeCompare(b));
for (const key of keys) {
prompt.push(String.raw`- (${key}) ${choices[key]}`);
}

prompt.push(String.raw`Your response should start with only the single character "${keys.join('" or "')}" (without quotes or punctuation) on its own line followed by an explanation of your answer on the next line. Your explanation should take the reader through your reasoning step-by-step, culminating in the correct answer. Avoid simply stating the correct answer at the outset of your explanation.`);

return prompt.join('\n');
}
Insert cell
function SPLIT(document, {
maxTokens=null,
nonOverlapTokens=null,
overlapTokens=0,
tokenizer=new GPT3Tokenizer({ type: 'gpt3' }),
}={}) {
if (maxTokens === null && nonOverlapTokens === null) {
throw 'one of [maxTokens | nonOverlapTokens] is required';
} else if (maxTokens === null && nonOverlapTokens !== null) {
maxTokens = nonOverlapTokens + overlapTokens;
} else if (maxTokens !== null && nonOverlapTokens !== null) {
if (maxTokens !== nonOverlapTokens + overlapTokens) {
throw 'if both maxTokens and nonOverlapTokens are passed, then they need to be consistent';
}
}
const { text } = tokenizer.encode(document);

const fragments = [];
for (let i=0, n=text.length; i<n; i += maxTokens - overlapTokens) {
fragments.push(text.slice(i, i + maxTokens).join(''));
}

return fragments;
}
Insert cell
function TAIL(document, {
maxTokens,
tokenizer=new GPT3Tokenizer({ type: 'gpt3' }),
}={}) {
let { text } = tokenizer.encode(document);
text = text.slice(-maxTokens);
if (text.length > maxTokens) throw `bad length: ${text.length}`;
text = text.join('');
return text;
}
Insert cell
async function FETCH(...args) {
const request = new Request(...args);
const { key, digest } = await DIGEST(request.clone());

console.log({ key, digest });

if (localStorage.getItem(key) !== null) {
const { response } = JSON.parse(localStorage.getItem(key));
return response;
}

const response = await fetch(request);
if (response.status !== 200) throw `response.status = ${response.status}; request.url = ${request.url}`;
const json = await response.json();

localStorage.setItem(key, JSON.stringify({ key, request: digest, response: json }));
return json;

async function DIGEST(request) {
const props = ['url', 'method'];
const digest = {};
for (const prop of props) {
Object.assign(digest, { [prop]: request[prop] });
}

const body = await request.json();
Object.assign(digest, { body });

const key = sha256(JSON.stringify(digest));
return { key, digest };
}
}
Insert cell
import {zip, zipreader} from "@fil/jszip"
Insert cell
import { sha256 } from '@critesjosh/cryptographic-hash-functions';
Insert cell
GPT3Tokenizer = (await import("https://cdn.skypack.dev/gpt3-tokenizer@1.1.5/dist-browser/gpt3-tokenizer.js")).default;
Insert cell
import { viewof approval } from '@player1537/utilities';
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more