Spaces:
Paused
Paused
Download static/contract.js from vllm-sr/decision1-studio: direct link, hf CLI and curl.
- Browser
- Download file 7.74 kB
-
https://huggingface.co/spaces/vllm-sr/decision1-studio/resolve/main/static/contract.js
- Command line
-
hf download hf://spaces/vllm-sr/decision1-studio/static/contract.js
-
curl -L -o contract.js https://huggingface.co/spaces/vllm-sr/decision1-studio/resolve/main/static/contract.js
7.74 kB
| // Strict browser-side mirror of the bounded local System One request contract. | |
| // The server remains authoritative; this module never edits unsupported fields. | |
| const object = v => v !== null && typeof v === 'object' && !Array.isArray(v); | |
| const keys = (value, allowed, label) => { if (!object(value) || Object.keys(value).some(k => !allowed.includes(k))) throw Error(`${label}: unsupported fields or invalid object.`); }; | |
| const content = (v,label) => { if (typeof v === 'string') { if(!v.trim()) throw Error(`${label} must not be empty.`); } else if(!object(v) && !Array.isArray(v)) throw Error(`${label} must be text, an object, or an array.`); }; | |
| const id = (v,label,maxLength) => { | |
| if(typeof v!=='string'||!v.trim())throw Error(`${label} needs a nonempty string.`); | |
| if(maxLength!==undefined&&v.length>maxLength)throw Error(`${label} needs at most ${maxLength} characters.`); | |
| }; | |
| function finiteJSON(value) { | |
| if(typeof value==='number'&&!Number.isFinite(value))throw Error('JSON numbers must be finite.'); | |
| if(value && typeof value==='object')Object.values(value).forEach(finiteJSON); | |
| } | |
| export function validateRequest(body, expectedModel) { | |
| finiteJSON(body); | |
| keys(body,['state','states','model','questions'],'Request'); | |
| if(typeof expectedModel!=='string'||!expectedModel||body.model!==expectedModel)throw Error('Request model does not match the selected model.'); | |
| if(Object.hasOwn(body,'state')===Object.hasOwn(body,'states'))throw Error('Use one context or batch contexts, not both.'); | |
| if(Object.hasOwn(body,'states')){ | |
| if(!Array.isArray(body.states)||body.states.length<1)throw Error('Provide at least one context.'); | |
| const seen=new Set(); | |
| for(const row of body.states){keys(row,['id','state'],'Context');id(row.id,'Context ID',128);if(seen.has(row.id))throw Error('Context IDs must be unique.');seen.add(row.id);content(row.state,`Context ${row.id}`);} | |
| }else content(body.state,'State'); | |
| if(!object(body.questions)||Object.keys(body.questions).length<1)throw Error('Provide at least one named question.'); | |
| for(const[qid,q]of Object.entries(body.questions)) { | |
| id(qid,'Question ID');keys(q,['type','instructions','criteria'],qid); | |
| if(!['choice','noul','score'].includes(q.type))throw Error(`${qid}: unsupported question type.`); | |
| content(q.instructions,`${qid} instructions`); | |
| if(q.type==='choice') { | |
| if(!object(q.criteria)||Object.keys(q.criteria).length<2||Object.keys(q.criteria).length>255)throw Error(`${qid}: Choice needs 2–255 named options.`); | |
| for(const[name,v]of Object.entries(q.criteria)){id(name,'Option name');if(v!==null)content(v,`${qid} option description`);} | |
| } else if(q.type==='score') { | |
| if(!Array.isArray(q.criteria)||q.criteria.length<2||q.criteria.length>10)throw Error(`${qid}: Score needs 2–10 ordered levels.`); | |
| q.criteria.forEach(v=>content(v,`${qid} level`)); | |
| } else if(q.criteria!==undefined&&q.criteria!==null) { | |
| keys(q.criteria,['false','true'],`${qid} criteria`); | |
| Object.values(q.criteria).forEach(v=>{if(v!==null)content(v,`${qid} criterion`);}); | |
| } | |
| } | |
| const requestLimit=Object.hasOwn(body,'states')?2*1024*1024:256*1024; | |
| if(new TextEncoder().encode(JSON.stringify(body)).length>requestLimit)throw Error(`The complete request must fit within ${requestLimit===256*1024?'256 KiB':'2 MiB'}.`); | |
| const utf8=new TextEncoder(), states=body.states?body.states.map(x=>x.state):[body.state]; | |
| const stateBytes=states.reduce((n,v)=>n+utf8.encode(typeof v==='string'?v:JSON.stringify(v)).length,0); | |
| const expanded=stateBytes*Object.keys(body.questions).length+utf8.encode(JSON.stringify(body.questions)).length*states.length; | |
| if(expanded>16*1024*1024)throw Error('Expanded context/question input exceeds 16 MiB; split this workload into requests.'); | |
| return body; | |
| } | |
| export function validateResult(result,request,canonicalModel=request.model){ | |
| if(!object(result))throw Error('The server returned an invalid response.'); | |
| const legacy=Object.hasOwn(result,'source'); | |
| if(legacy){ | |
| if(result.model!==request.model||result.source!=='live_native')throw Error('The server returned a different model or prediction source.'); | |
| }else{ | |
| if(result.model!==canonicalModel)throw Error('The server returned a different model.'); | |
| const fields=request.states?['model','results','usage']:['model','answers','usage']; | |
| if(Object.keys(result).length!==fields.length||fields.some(key=>!Object.hasOwn(result,key)))throw Error('The server returned a non-standard response.'); | |
| } | |
| const usage=value=>object(value)&&Object.keys(value).length===2&&Number.isInteger(value.input_tokens)&&value.input_tokens>=0&&Number.isInteger(value.output_tokens)&&value.output_tokens>=0; | |
| if(!usage(result.usage))throw Error('Invalid response usage.'); | |
| const expectedIds=Object.keys(request.questions); | |
| const answerSet=answers=>{ | |
| if(!object(answers)||Object.keys(answers).length!==expectedIds.length||expectedIds.some(id=>!Object.hasOwn(answers,id))||legacy&&JSON.stringify(Object.keys(answers))!==JSON.stringify(expectedIds))throw Error('The response does not match the shared questions.'); | |
| for(const id of expectedIds){const a=answers[id],q=request.questions[id]; | |
| if(!object(a)||a.type!==q.type)throw Error('Invalid decision identity.'); | |
| if(legacy){if(!Number.isInteger(a.input_tokens)||a.input_tokens<1)throw Error('Invalid decision token usage.');} | |
| else{ | |
| const fields=q.type==='noul'?['type','noul']:q.type==='choice'?['type','choice','confidence','probabilities']:['type','score','confidence','legend','probabilities']; | |
| if(Object.keys(a).length!==fields.length||fields.some(key=>!Object.hasOwn(a,key)))throw Error('The server returned non-standard answer fields.'); | |
| } | |
| if(q.type==='noul'){if(!Number.isFinite(a.noul)||a.noul<0||a.noul>1)throw Error('Invalid yes probability.');} | |
| else {const ids=q.type==='choice'?Object.keys(q.criteria):q.criteria.map((_,i)=>String(i)); | |
| if(!object(a.probabilities)||Object.keys(a.probabilities).length!==ids.length||ids.some(k=>!Object.hasOwn(a.probabilities,k)))throw Error('Invalid candidate identity.'); | |
| const p=ids.map(k=>a.probabilities[k]);if(p.some(v=>!Number.isFinite(v)||v<0||v>1)||Math.abs(p.reduce((a,b)=>a+b,0)-1)>2e-5)throw Error('Invalid candidate probabilities.'); | |
| if(!legacy&&(!Number.isFinite(a.confidence)||a.confidence<0||a.confidence>1))throw Error('Invalid decision confidence.'); | |
| if(q.type==='choice'&&!ids.includes(a.choice)||q.type==='score'&&(!Number.isFinite(a.score)||a.score<0||a.score>ids.length-1))throw Error('Invalid decision value.'); | |
| if(q.type==='score'&&(!object(a.legend)||JSON.stringify(Object.keys(a.legend))!==JSON.stringify(ids)))throw Error('Invalid score legend.'); | |
| } | |
| } | |
| }; | |
| if(request.states){ | |
| if(!Array.isArray(result.results)||result.results.length!==request.states.length)throw Error('Incomplete context results.'); | |
| result.results.forEach((r,i)=>{if(!object(r)||r.id!==request.states[i].id||!usage(r.usage))throw Error('Context order or identity mismatch.');if(!legacy&&(Object.keys(r).length!==3||['id','answers','usage'].some(key=>!Object.hasOwn(r,key))))throw Error('The server returned non-standard context fields.');answerSet(r.answers);}); | |
| }else answerSet(result.answers); | |
| return result; | |
| } | |
| export function validateServingResult(result,request,canonicalModel,backend){ | |
| const native=result!==null&&typeof result==='object'&&Object.hasOwn(result,'source'); | |
| if(backend==='native_rocm'&&!native||backend==='direct'&&native||!['native_rocm','direct','pull_queue'].includes(backend))throw Error('The server returned an unexpected prediction format.'); | |
| return validateResult(result,request,canonicalModel); | |
| } | |