ref: 3b49941153a3ca965ba574d9e64f0325383316fd
dir: /oailib.c/
#include <u.h>
#include <libc.h>
#include <bio.h>
#include <json.h>
#include "oai.h"
static char *baseurl = nil;
static char *apikey = nil;
int
initoai(char *url, char *key)
{
baseurl = url;
apikey = key;
if (!baseurl) {
werrstr("invalid baseurl");
return 0;
}
JSONfmtinstall();
return 1;
}
static JSONEl*
mkstrjson(char *name, char *value)
{
JSONEl *el;
el = mallocz(sizeof(JSONEl), 1);
assert(el);
el->name = strdup(name);
assert(el->name);
el->val = mallocz(sizeof(JSON), 1);
assert(el->val);
el->val->t = JSONString;
el->val->s = strdup(value);
assert(el->val->s);
return el;
}
static JSONEl*
prompt2json(OPrompt *p)
{
JSONEl *el;
el = mallocz(sizeof(JSONEl), 1);
el->val = mallocz(sizeof(JSON), 1);
el->val->t = JSONObject;
el->val->first = mkstrjson("role", p->role);
el->val->first->next = mkstrjson("content", p->content);
return el;
}
static JSON*
req2json(ORequest *req)
{
JSON *j;
JSONEl *el;
OPrompt *p;
j = mallocz(sizeof(JSON), 1);
assert(j);
j->t = JSONObject;
el = mallocz(sizeof(JSONEl), 1);
assert(el);
el->name = strdup("messages");
assert(el->name);
el->val = mallocz(sizeof(JSON), 1);
assert(el->val);
el->val->t = JSONArray;
j->first = el;
for (p = req->prompts; p; p = p->next) {
if (!el->val->first) {
el->val->first = prompt2json(p);
el = el->val->first;
continue;
}
el->next = prompt2json(p);
el = el->next;
}
if (req->model) {
j->first->next = mkstrjson("model", req->model);
}
return j;
}
static OResult
j2res(JSON *j)
{
OResult r;
JSON *choices;
JSON *message;
JSON *role;
JSON *content;
choices = jsonbyname(j, "choices");
if (!choices)
sysfatal("no choices");
if (choices->t != JSONArray)
sysfatal("invalid response: choices not an array");
if (!(choices->first && choices->first->val))
sysfatal("no response message");
message = jsonbyname(choices->first->val, "message");
if (!message)
sysfatal("choice has no message");
if (message->t != JSONObject)
sysfatal("message is not an object");
role = jsonbyname(message, "role");
r.role = jsonstr(role);
if (!r.role)
sysfatal("choice has no role");
content = jsonbyname(message, "content");
r.message = jsonstr(content);
if (!r.message)
sysfatal("choice has no content");
r.role = strdup(r.role);
r.message = strdup(r.message);
return r;
}
OResult
makerequest(ORequest req)
{
char buf[128];
int ctlfd, pbodyfd;
Biobuf *body;
char *s;
int n;
OResult ret;
JSON *jreq;
JSON *jres;
jreq = req2json(&req);
ctlfd = open("/mnt/web/clone", ORDWR);
if (ctlfd < 0)
sysfatal("webfs ctl open: %r");
if ((n = read(ctlfd, buf, sizeof buf)) < 0)
sysfatal("webfs ctl read: %r");
buf[n] = 0;
n = atoi(buf);
fprint(ctlfd, "useragent 9front\n");
fprint(ctlfd, "contenttype application/json\n");
fprint(ctlfd, "headers Authorization: Bearer %s\n", apikey ? apikey : "no-key");
fprint(ctlfd, "baseurl %s\n", baseurl);
fprint(ctlfd, "url ./v1/chat/completions\n");
snprint(buf, sizeof buf, "/mnt/web/%d/postbody", n);
pbodyfd = open(buf, OWRITE);
if (pbodyfd < 0)
sysfatal("webfs pbody open: %r");
fprint(pbodyfd, "%J", jreq);
close(pbodyfd);
snprint(buf, sizeof buf, "/mnt/web/%d/body", n);
body = Bopen(buf, OREAD);
if (!body)
sysfatal("webfs body open: %r");
s = Brdstr(body, 0, 0);
Bterm(body);
close(ctlfd);
jres = jsonparse(s);
ret = j2res(jres);
free(s);
jsonfree(jreq);
jsonfree(jres);
return ret;
}