Public
Edited
Apr 16, 2023
1 fork
Insert cell
Insert cell
viewof DEFAULTS = {
const $apiKey = Inputs.password({
label: 'OpenAI API Key',
});

const $mode = Inputs.radio(['real', 'fake'], {
label: 'mode',
value: 'fake',
});

const $form = Inputs.form({
apiKey: $apiKey,
mode: $mode,
});

return Object.assign($form, {
$mode,
$apiKey,
});
}
Insert cell
// viewof OPENAI_API_KEY = Inputs.password({
// label: 'OpenAI API Key',
// })
Insert cell
// viewof CHAT_DEFAULT_MODE =
Insert cell
viewof DOCUMENT = Inputs.textarea({
rows: 24,
label: 'document',
});
Insert cell
viewof FRAGMENT = Inputs.textarea({
rows: 24,
label: 'fragment',
});
Insert cell
Insert cell
CHAT
Insert cell
function Chat(messages, {
url=`https://api.openai.com/v1/chat/completions`,
model=`gpt-3.5-turbo`,
temperature=1.0,

label='Chat',
rows=24,
invalidation,
}={}) {
const $messages = FORM({
label: 'messages',
inputs: messages.map(({ role, content }, i) => {
return FORM({
label: `messages[${i}]`,
inputs: {
role: Inputs.radio(['system', 'assistant', 'user'], {
label: 'role',
value: role,
}),
content: Inputs.textarea({
label: 'content',
value: content,
rows,
}),
},
});
}),
});

const $request = FORM({
label: 'Request',
inputs: {
apiKey: Inputs.bind(Inputs.password({
label: 'OpenAI API Key',
}), viewof DEFAULTS.$apiKey, invalidation),
mode: Inputs.bind(Inputs.radio(['real', 'fake'], {
label: 'mode',
}), viewof DEFAULTS.$mode, invalidation),
url: Inputs.text({
label: 'url',
value: url,
}),
model: Inputs.text({
label: 'model',
value: model,
}),
temperature: Inputs.number([0, 2], {
label: 'temperature',
value: temperature,
step: 0.1,
}),
messages: $messages,
},
});

const $response = FORM({
label: 'response',
inputs: {
choices: FORM({
label: 'choices',
inputs: [
/* 0 */ FORM({
label: 'choices[0]',
inputs: {
message: FORM({
label: 'message',
inputs: {
role: Inputs.text({
label: 'role',
}),
content: Inputs.textarea({
label: 'content',
rows,
}),
},
}),
},
}),
],
}),
},
});

const $send = Inputs.button('Send', {
reduce: async () => {
const request = $request.value;

const { mode } = request;

const func = mode === 'real' ? REAL : FAKE;

const response = await func(request);

$response.value = response;

$response.dispatchEvent(new CustomEvent('input'));
},
});

// Inputs.bind($send, $response, invalidation);

// Inputs.bind($request$input, $request$view, invalidation);
// Inputs.bind($response$view, $response$input, invalidation);

const $form = FORM({
label,
inputs: {
request: $request,
send: $send,
response: $response,
},
});

return Object.assign($form, {
$request,
$response,
});

function BIND({ target, source, invalidation }={}) {
return Inputs.bind(target, source, invalidation);
}

function FORM({ inputs, label=null }) {
return Inputs.form(inputs, {
template(inputs) {
if (!Array.isArray(inputs)) {
inputs = Object.values(inputs);
}

return htl.html`<div style="padding-left: 1rem">${inputs}`;
},
});
}

async function REAL(request) {
const { url, apiKey, model, temperature, messages } = request;

request = new Request(url, {
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${apiKey}`,
},
body: JSON.stringify({
model,
temperature,
messages,
}),
});

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

response = await response.json();

return response;
}

async function FAKE(request) {
await new Promise((resolve) => setTimeout(resolve, 100));

return ({
choices: [
{
message: {
role: 'assistant',
content: 'auto-generated',
},
},
],
});
}
}
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