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',
},
},
],
});
}
}