diff options
Diffstat (limited to 'desk/lib/openai.hoon')
-rw-r--r-- | desk/lib/openai.hoon | 763 |
1 files changed, 763 insertions, 0 deletions
diff --git a/desk/lib/openai.hoon b/desk/lib/openai.hoon new file mode 100644 index 0000000..4d42bd8 --- /dev/null +++ b/desk/lib/openai.hoon @@ -0,0 +1,763 @@ +/- cookies +/+ server, sr=sortug +:: |_ key=@t +|% +++ key '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' +.^(scry:cookies ()) +:: follows open AI reference docs as of 07-OCT-2023 +++ api-key (crip "Bearer {(trip key)}") +++ base-url "https://api.openai.com/v1" +:: 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 ++$ ljson $%([%s @t] [%n @t]) +:: Passes each member of list a to gate b, which must produce a unit. Produces a new list with all the results that do not produce ~. +++ clean +|* [key=@tas j=?(%s %n) d=(unit)] +?~ d ~ +`[key j u.d] + +:: ++ audio +:: |% +:: ++ endpoint "/audio" +:: +$ response-format $?(%json %text %srt %verbose-json %vtt) +:: ++ transcription +:: |% +:: ++ endpoint "/transcriptions" +:: +$ req +:: $: file=file +:: model=@t :: 'whisper-1' +:: language=(unit @t) +:: prompt=(unit @t) +:: response-format=(unit response-format) +:: temperature=(unit @rd) :: 0-1 + +:: == +:: ++ ret %todo +:: -- +:: ++ translation +:: |% +:: ++ endpoint "/audio/translation" +:: +$ req +:: $: file=file +:: model=@t :: 'whisper-1' +:: prompt=(unit @t) +:: response-format=(unit response-format) +:: temperature=(unit @rd) :: 0-1 +:: == +:: -- +:: -- +++ test +|= text=@t +(chat [~[[%system text 'Pepe']] 'gpt-3.5-turbo']) +++ chat +|^ request:completions + ++ endpoint "/chat" + ++ completions + |% + ++ t + |% + +$ role $?(%system %user %assistant %function) + +$ function-call + $: name=@t + arguments=@t + == + +$ function + $: description=(unit @t) + name=@t + parameters=object:json-schema:sortug + == + +$ logit-bias (map @t @ud) + +$ stop $@(@t (list @t)) :: up to 4 sequences + +$ message + $: =role + content=$?(@t ~) :: not optional, but can be null + name=@t + == + +$ request + $: messages=(list message) + model=@tas + :: frequency-penalty=(unit @ud) :: -2.0 to 2.0 + :: function-call=(unit function-call) + :: functions=(list function) + :: logit-bias=(unit logit-bias) + :: max-tokens=(unit @ud) + :: n=(unit @ud) + :: presence-penalty=(unit @ud) + :: stop=(unit stop) + :: stream=(unit ?) :: SSE, nice + :: temperature=(unit @ud) + :: top-p=(unit @ud) + :: user=(unit @t) + == + +$ full-response + $: id=@t + choices=(list choice) + created=@da + model=@t + object=@t :: 'chat.completion.chunk' + =usage + == + +$ usage + $: completion-tokens=@ud + prompt-tokens=@ud + total-tokens=@ud + == + +$ chunk-response + $: id=@t + choices=(list choice) + created=@da + model=@t + object=@t :: 'chat.completion.chunk' + == + +$ choice + $: index=@ud + =delta + =finish-reason + == + +$ finish-reason $?(%stop %length %content-filter %function-call ~) + +$ chunk-choice + $: index=@ud + =delta + =finish-reason + == + +$ delta + $: content=$?(@t ~) + =role + function-call=(unit function-call) + == + ++ dejs + =, dejs:format + =/ de de:json-helpers:sortug + |% + ++ full + |= jon=@t ^- full-response + %. (need (de:json:html jon)) + %- ot + :~ id+so + choices+(ar de-choice) + created+du + model+so + object+so + usage+de-usage + == + ++ de-choice + %- ot + :~ index+ni + message+de-delta + ['finish_reason' de-finish-reason] + == + ++ de-usage + %- ot + :~ ['completion_tokens' ni] + ['prompt_tokens' ni] + ['total_tokens' ni] + == + + ++ chunk + |= jon=@t ^- chunk-response + %. (need (de:json:html jon)) + %- ot + :~ id+so + choices+(ar de-chunk-choice) + created+du + model+so + object+so + == + ++ de-chunk-choice + %- ot + :~ index+ni + delta+de-delta + ['finish-reason' de-finish-reason] + == + ++ de-role %- su %- perk + :~(%system %user %assistant %function) + ++ de-finish-reason %- maybe:de %- su %- perk + :~(%stop %length %content-filter %function-call) + ++ de-delta + %- ou + :~ + content+(un (maybe:de so)) + role+(un de-role) + ['function-call' (ur:de de-function-call)] + == + ++ de-function-call + %- ot + :~ name+so + arguments+so + == + -- + ++ enjs + =, enjs:format + |_ req=request + ++ $ + %- pairs + :~ messages+a+(turn messages.req en-msg) + model+s+model.req + == + ++ en-msg + |= msg=message + %- pairs + :~ role+s+role.msg + :- %content ?~ content.msg ~ s+content.msg + == + -- + -- + ++ endpoint "/completions" + ++ request + |= req=request:t + ^- request:http + =/ method %'POST' + =/ url %- crip "{base-url}{^endpoint}{endpoint}" + =/ headers + :~ + ['Authorization' api-key] + ['Content-type' 'application/json'] + == + =/ json (enjs:t req) + ~& > req=req + ~& >> sending=(en:json:html json) + =/ body (json-to-octs:server (enjs:t req)) + [method url headers `body] + + -- +-- +:: ++ embeddings +:: |% +:: ++ endpoint "/embeddings" +:: ++ req %'POST' +:: +$ input +:: $@ @t (list @t) +:: +$ req-type +:: $: =input +:: model=@tas +:: user=(unit @t) +:: == +:: +$ res +:: $: object=@t +:: data=(list embed) +:: model=@tas +:: usage=[prompt-tokens=@ud total-tokens=@ud] +:: == +:: +$ embed +:: $: index=@ud +:: embedding=(list @rd) :: TODO make this strings? +:: object=@t :: 'embedding' +:: == +:: ++ res-dejson +:: =, dejs:format +:: %- ot +:: :~ object+so +:: model+so +:: usage+usage-dejson +:: data+(ar embed-dejson) +:: == +:: ++ usage-dejson +:: =, dejs:format +:: %- ot +:: :~ ['prompt_tokens' ni] +:: ['total_tokens' ni] +:: == +:: ++ embed-dejson +:: %- ot +:: :~ object+so +:: index+ni +:: embedding+(ar ne) :: TODO make this strings?? +:: == +:: -- +:: ++ fine-tuning +:: |% +:: ++ endpoint "/fine_tuning/jobs +:: +$ job +:: $: id=@t +:: created-at=@ud +:: error=(unit error) +:: fine-tuned-model=(unit @t) +:: finished-at=(unit @ud) +:: =hyperparameters +:: model=@tas +:: organization-id=@t +:: result-files=(list @t) +:: =status +:: trained-tokens=(unit @ud) +:: training-file=@t +:: validation-file=(unit @t) +:: == +:: +$ job-event +:: $: id=@t +:: created-at=@ +:: level=@t :: 'warn', 'info', ... +:: message=@t +:: data=(unit job) :: I think +:: type=@t :: 'message' +:: == +:: ++ job-dejson +:: =, dejs:format +:: %- ot +:: :~ id+so +:: fine-tuned-model+uso +:: finished-at+uso +:: hyperparameters+hdj +:: model=(se %tas) +:: 'organization_id'+so +:: 'result_files'+(ar so) +:: status+(se %tas) +:: 'trained_tokens'+uso +:: 'training_file'+so +:: 'validation_file'+uso +:: == +:: ++ job-event-dejson +:: %- ot +:: :~ id+so +:: level+so +:: message+so +:: data+job-dejson +:: == +:: ++ uso +:: |= j=json +:: ?~ j ~ +:: ?: ?=(-.j %s) (so j) +:: ?: ?=(-.j %n) (ni j) ~ +:: ++ hdj +:: %- ot +:: :~ :- 'n_epochs' +:: |= j=json +:: ?: ?=(-.j %s) %auto +:: ?: ?=(-.j %n) (ni j) +:: == +:: +$ events-res +:: $: data=(list job-event) +:: has-more=? +:: == +:: ++ events-res-dejson +:: =, dejs:format +:: %- ot +:: :~ data+(ar job-event-djson) +:: has-more+bo +:: == +:: +$ status $?(%validating-files %queued %running %succeeded %failed %cancelled) +:: +$ hyperparameters [%n-epochs $?(%auto @ud)] +:: ++ create +:: |% +:: ++ endpoint "" +:: ++ req %POST +:: +$ req-type +:: $: model=@tas +:: training-file=@t +:: hyperparameters=(unit hyperparameters) +:: validation-file=(unit @t) +:: suffix=(unit @t) +:: == +:: -- +:: ++ get-all +:: |_ [after=(unit @t) limit=(unit @ud)] +:: ++ endpoint +:: ?~ after +:: ?~ limit +:: :: none +:: "" +:: :: limit but not after +:: "?limit={<u.limit>}" +:: ?~ limit +:: :: after but not limit +:: "?after={(trip u.after)}" +:: :: both +:: "?limit={<u.limit>}&after={(trip u.after)}" +:: ++ req %GET +:: ++ res events-res +:: ++ dejs events-res-dejson + +:: -- +:: ++ get +:: |_ id=@t +:: ++ endpoint "/{(trip id)}" +:: ++ req %GET +:: ++ res job +:: ++ res-dejson job-dejson +:: -- +:: ++ cancel +:: |_ id=@t +:: ++ endpoint "/{(trip id)}/cancel" +:: ++ req %POST +:: ++ res job +:: ++ res-dejson job-dejson +:: -- +:: ++ get-events +:: |_ [id=@t after=(unit @t) limit=(unit @ud)] +:: :: TODO There must be a better way to handle optional query params +:: ++ endpoint "/{(trip id)}/events" +:: ++ req %GET +:: ++ res events-res +:: ++ dejs events-res-dejson +:: -- +:: -- +:: ++ files +:: |% +:: ++ endpoint "/files" +:: +$ file-type +:: $: id=@t +:: bytes=@ud +:: created-at=@ud +:: filename=@t +:: purpose=@t :: 'currently only fine-tune' +:: =status +:: status-details=(unit @t) +:: == +:: ++ dejs +:: =, dejs:format +:: %- ot +:: :~ id+so +:: bytes+ni +:: ['created_at' ni] +:: filename+so +:: purpose+so +:: == +:: +$ status $?(%uploaded %processed %pending %error %deleting %deleted) +:: ++ get-all +:: |% +:: ++ endpoint "" +:: ++ req %GET +:: +$ res (list file-type) +:: ++ dejs +:: %- ot +:: :~ data+(ar ^dejs) +:: == +:: -- +:: ++ upload +:: |_ [file=@t purpose=@t] :: file is the actual file, not the name +:: ++ endpoint "" +:: ++ req %POST :: mulipart wtf +:: +$ res file-type +:: ++ dejs ^dejs +:: -- +:: ++ delete +:: |_ file-id=@t +:: ++ endpoint "/{file-id}" +:: ++ req %DELETE +:: +$ res +:: $: id=@t +:: deleted=? +:: == +:: ++ dejs +:: =, dejs:format +:: %- ot +:: :~ it+so +:: deleted+bo +:: == +:: -- +:: ++ get +:: |_ file-id=@t +:: ++ endpoint "/{file-id}" +:: ++ req %GET +:: +$ res file-type +:: ++ dejs ^dejs +:: -- +:: ++ content +:: |_ file-id=@t +:: ++ endpoint "/{file-id}/content" +:: ++ req %GET +:: +$ res "" :: the file content +:: -- +:: -- +++ images +|% + ++ endpoint "/images" + ++ t + |% + +$ image + $% [%'b64_json' @t] + [%url @t] + == + +$ response-format $?(%url %b64-json) + +$ size $?(%'256x256' %'512x512' %'1024x1024') + +$ res + $: created=@ud + data=(list image) + == + ++ dejs + =, dejs:format + |_ jon=@t + ++ $ ^- res + %. (need (de:json:html jon)) + %- ot + :~ created+ni + data+(ar de-data) + == + ++ de-data + %- of + :~ [%'b64_json' so] + [%url so] + == + -- + -- + ++ create + |^ request + ++ t + |% + +$ req + $: prompt=@t + n=(unit @ud) + response-format=(unit response-format:^t) + size=(unit size:^t) + user=(unit @t) + == + ++ enjs + =, enjs:format + |_ =req + ++ $ + %- pairs + :- prompt+s+prompt.req + :: %- murn :_ clean + :: :~ n+n+n.req + :: ['response_format' %s response-format.req] + :: size+s+size.req + :: user+s+user.req + :: == + ~ + -- + -- + ++ endpoint "/generations" + ++ request |= =req:t + ^- request:http + =/ method %'POST' + =/ url %- crip "{base-url}{^endpoint}{endpoint}" + =/ headers + :~ + ['Authorization' api-key] + ['Content-type' 'application/json'] + == + =/ body (json-to-octs:server (enjs:t req)) + [method url headers `body] + -- + :: ++ edit + :: :: TODO guess image is alread octs once it gets here so we just send tha + :: :: images must be png, <4mb, square + :: |^ request + :: ++ t + :: |% + :: ++ req + :: $: image=@t + :: prompt=@t + :: mask=(unit @t) + :: n=(unit @ud) + :: size=(unit size) + :: response-format=(unit response-format:t) + :: user=(unit @t) + :: == + :: -- + :: ++ endpoint "/edits" + :: ++ request :: multipart + :: ^- request:http + :: =/ method %'POST' + :: =/ url %- crip "{base-url}{^endpoint}{endpoint}" + :: =/ headers + :: :~ + :: ['Authorization' api-key] + :: == + :: =/ body ~ :: can we even do multipart + :: [method url headers ~] + :: -- + :: ++ variation + :: |_ [image=@t n=(unit @ud) size=(unit size) response-format=(unit response-format) user=(unit @t)] + :: ++ endpoint "/variations" + :: ++ request :: multipart + :: ^- request:http + :: =/ method %'POST' + :: =/ url %- crip "{base-url}{^endpoint}{endpoint}" + :: =/ headers + :: :~ + :: ['Authorization' api-key] + :: == + :: =/ body ~ :: can we even do multipart + :: [method url headers ~] + :: -- +-- +:: ++ models +:: |% +:: ++ endpoint "/models" +:: ++ request +:: ^- request:http +:: =/ method %'GET' +:: =/ url %- crip "{base-url}{endpoint}" +:: =/ headers +:: :~ +:: ['Authorization' api-key] +:: == +:: [method url headers ~] +:: +$ res (list model-res) +:: +$ model-res +:: $: id=@t +:: created=@ :: unix ts +:: object=@t :: always 'model' +:: owned-by=@t :: 'openai etc.' +:: == +:: ++ res-dejson +:: =, dejs:format +:: %- ot +:: :~ object+so +:: data+(ar model-res-dejson) +:: == +:: ++ model-res-dejson +:: =, dejs:format +:: %- ot +:: :~ id+so +:: created+ni +:: object+so +:: owned-by+so +:: == +:: ++ model +:: |_ name=@t +:: ++ endpoint "/{name}" +:: ++ request +:: ^- request:http +:: =/ method %'GET' +:: =/ url %- crip "{base-url}{^endpoint}{endpoint}" +:: =/ headers +:: :~ +:: ['Authorization' api-key] +:: == +:: [method url headers ~] +:: -- +:: ++ delete-model +:: |_ name=@t +:: ++ endpoint "{name}" +:: ++ request +:: ^- request:http +:: =/ method %'DELETE' +:: =/ url %- crip "{base-url}{^endpoint}{endpoint}" +:: =/ headers +:: :~ +:: ['Authorization' api-key] +:: == +:: [method url headers ~] +:: +$ res +:: $: id=@t +:: object=@t :: 'model' +:: deleted=? +:: == +:: ++ res-dejson +:: =, dejs:format +:: %- ot +:: :~ id+so +:: object+so +:: deleted+bo +:: == +:: -- +:: -- +:: ++ moderation +:: |% +:: ++ endpoints "/moderations" +:: +$ moderation-t +:: $: id=@t +:: model=@t +:: results=(list result) +:: == +:: +$ result +:: $: flagged=? +:: =categories +:: =category-scores +:: == +:: +$ categories +:: $: sexual=? +:: hate=? +:: harassment=? +:: self-harm=? +:: sexual-minors=? +:: hate-threatening=? +:: violence-graphic=? +:: self-harm-intent=? +:: self-harm-instructions=? +:: harassment-threatening=? +:: violence=? +:: == +:: +$ category-scores +:: $: sexual=@rd +:: hate=@rd +:: harassment=@rd +:: self-harm=@rd +:: sexual-minors=@rd +:: hate-threatening=@rd +:: violence-graphic=@rd +:: self-harm-intent=@rd +:: self-harm-instructions=@rd +:: harassment-threatening=@rd +:: violence=@rd +:: == +:: ++ dejs +:: =, dejs:format +:: %- ot +:: :~ id+so +:: model+(se %tas) +:: results+(ar de-result) +:: == +:: ++ de-result +:: =, dejs:format +:: %- ot +:: :~ flagged+bo +:: categories+de-categories +:: ['category_scores' de-category-scores] +:: == +:: ++ de-categories +:: =, dejs:format +:: %- ot +:: :~ sexual+bo +:: hate+bo +:: harassment+bo +:: self-harm+bo +:: 'sexual/minors'+bo +:: 'hate/threatening'+bo +:: 'violence/graphic'+bo +:: 'self-harm/intent'+bo +:: 'self-harm/instructions'+bo +:: 'harassment/threatening'+bo +:: violence+bo +:: == +:: ++ de-category-scores +:: =, dejs:format +:: %- ot +:: :~ sexual+ne +:: hate+ne +:: harassment+ne +:: self-harm+ne +:: 'sexual/minors'+ne +:: 'hate/threatening'+ne +:: 'violence/graphic'+ne +:: 'self-harm/intent'+ne +:: 'self-harm/instructions'+ne +:: 'harassment/threatening'+ne +:: violence+ne +:: == +:: ++ create +:: |_ =req +:: ++ endpoint "" +:: ++ request +:: ^- request:http +:: =/ method %'POST' +:: =/ url %- crip "{base-url}{^endpoint}{endpoint}" +:: =/ headers +:: :~ +:: ['content-type' 'application/json'] +:: ['Authorization' api-key] +:: == +:: =/ body (json-to-octs:server (enjs req)) +:: [method url headers `body] +:: +$ input $@ @t (list @t) +:: +$ model $?(%text-moderation-stable %text-moderation-latest) +:: +$ req +:: $: =input +:: model=(unit model) +:: == +:: ++ enjs +:: =, enjs:format +:: %- pairs +:: :~ input+s+(en-input input.req) +:: == +:: ++ en-input +:: =, enjs:format +:: ?^ input.req a+(turn input |=(s=@t s+s)) +:: s+input +:: +$ res moderation-t +:: ++ dejs ^dejs +:: -- +:: -- + +-- + |