@cogniformai/instructor-stream
Version:
Streaming-first structured data extraction from LLMs with real-time updates
48 lines (36 loc) • 32.3 kB
JavaScript
import ue from"openai";import{Stream as ce}from"openai/streaming";import{ZodError as me}from"zod";import{fromZodError as he}from"zod-validation-error";function g(o,e){let n={};for(let r in e)e.hasOwnProperty(r)&&!o.includes(r)&&(n[r]=e[r]);return n}async function j(o,e){let n=Array.from({length:e},()=>[]),r=[],t=o[Symbol.asyncIterator](),s=!1,i=async function*(u){for(;;)if(n[u].length>0)yield n[u].shift();else{if(s)break;await new Promise(f=>r.push(f))}};return await(async()=>{for await(let u of{[Symbol.asyncIterator]:()=>t}){for(let f of n)f.push(u);for(;r.length>0;)r.shift()()}for(s=!0;r.length>0;)r.shift()()})(),Array.from({length:e},(u,f)=>i(f))}function le(o){let e=typeof o=="string"?JSON.parse(o):o;return e.choices?.[0]?.delta?.function_call?.arguments??e.choices?.[0]?.message?.function_call?.arguments??""}function de(o){let e=typeof o=="string"?JSON.parse(o):o;return e.choices?.[0]?.delta?.tool_calls?.[0]?.function?.arguments??e.choices?.[0]?.message?.tool_calls?.[0]?.function?.arguments??""}function pe(o){let e=typeof o=="string"?JSON.parse(o):o,n=e.choices?.[0]?.delta?.content??e?.choices?.[0]?.message?.content??"",r=/```json\n([\s\S]*?)\n```/,t=n.match(r);return t?t[1]:n}function L(o){let e=typeof o=="string"?JSON.parse(o):o,n=e.choices?.[0]?.delta?.function_call?.arguments||e.choices?.[0]?.message?.function_call?.arguments||!1,r=e.choices?.[0]?.delta?.tool_calls?.[0]?.function?.arguments??e.choices?.[0]?.message?.tool_calls?.[0]?.function?.arguments??!1;return n?le(o):r?de(o):pe(o)}function V(o){return o.replace(/[\x00-\x1F\x7F-\x9F]/g,"")}function P({res:o}){let e,n=new TextEncoder;async function*r(s){let i=!1;e=()=>{i=!0};for await(let u of s){if(i)break;L(u)&&(yield L(u))}}let t=r(o);return new ReadableStream({async start(s){for await(let i of t)s.enqueue(n.encode(V(i)));s.close()},cancel(){e&&e()}})}async function*$(o){let e=o.getReader(),n=new TextDecoder;for(;;){let{done:r,value:t}=await e.read();if(r)break;let s=V(n.decode(t));yield JSON.parse(s)}}function Y(o,e,n){let r=o;for(let s=0;s<e.length-1;s++){let i=e[s],u=e[s+1];r[i]==null&&(r[i]=typeof u=="number"?[]:{}),r=r[i]}let t=e[e.length-1];r[t]=n}import{z as A}from"zod";var q=(a=>(a[a.LEFT_BRACE=0]="LEFT_BRACE",a[a.RIGHT_BRACE=1]="RIGHT_BRACE",a[a.LEFT_BRACKET=2]="LEFT_BRACKET",a[a.RIGHT_BRACKET=3]="RIGHT_BRACKET",a[a.COLON=4]="COLON",a[a.COMMA=5]="COMMA",a[a.TRUE=6]="TRUE",a[a.FALSE=7]="FALSE",a[a.NULL=8]="NULL",a[a.STRING=9]="STRING",a[a.NUMBER=10]="NUMBER",a[a.SEPARATOR=11]="SEPARATOR",a))(q||{}),d=q;function W(o){return["VALUE","KEY","COLON","COMMA","ENDED","ERROR","SEPARATOR"][o]}var Te={paths:void 0,keepStack:!0,separator:void 0},N=class extends Error{constructor(n){super(n);this.name="TokenParserError"}},y=class{constructor(e){this.state=0;this.mode=void 0;this.key=void 0;this.value=void 0;this.stack=[];e={...Te,...e},e.paths&&(this.paths=e.paths.map(n=>{if(n===void 0||n==="$*")return;if(!n.startsWith("$"))throw new N(`Invalid selector "${n}". Should start with "$".`);let r=n.split(".").slice(1);if(r.includes(""))throw new N(`Invalid selector "${n}". ".." syntax not supported.`);return r})),this.keepStack=!0,this.separator=e.separator}shouldEmit(){return this.paths?this.paths.some(e=>{if(e===void 0)return!0;if(e.length!==this.stack.length)return!1;for(let r=0;r<e.length-1;r++){let t=e[r],{key:s}=this.stack[r+1];if(t!=="*"&&t!==s)return!1}let n=e[e.length-1];return n==="*"?!0:n===this.key?.toString()}):!0}push(){this.stack.push({key:this.key,value:this.value,mode:this.mode,emit:this.shouldEmit()})}pop(){let e=this.value,n,r=this.stack.pop();this.key=r.key,this.value=r.value,this.mode=r.mode,n=r.emit,this.state=this.mode!==void 0?3:0,this.emit(e,n)}emit(e,n){!this.keepStack&&this.value&&this.stack.every(r=>!r.emit)&&delete this.value[this.key],n&&this.onValue({value:e,key:this.key,parent:this.value,stack:this.stack}),this.stack.length===0&&(this.separator?this.state=6:this.separator===void 0&&this.end())}get isEnded(){return this.state===4}write({token:e,value:n,partial:r}){if(!r){if(this.state===0){if(e===d.STRING||e===d.NUMBER||e===d.TRUE||e===d.FALSE||e===d.NULL){this.mode===0?(this.value[this.key]=n,this.state=3):this.mode===1&&(this.value.push(n),this.state=3),this.emit(n,this.shouldEmit());return}if(e===d.LEFT_BRACE){if(this.push(),this.mode===0)this.value=this.value[this.key]={};else if(this.mode===1){let t={};this.value.push(t),this.value=t}else this.value={};this.mode=0,this.state=1,this.key=void 0;return}if(e===d.LEFT_BRACKET){if(this.push(),this.mode===0)this.value=this.value[this.key]=[];else if(this.mode===1){let t=[];this.value.push(t),this.value=t}else this.value=[];this.mode=1,this.state=0,this.key=0;return}if(this.mode===1&&e===d.RIGHT_BRACKET&&this.value.length===0){this.pop();return}}if(this.state===1){if(e===d.STRING){this.key=n,this.state=2;return}if(e===d.RIGHT_BRACE&&Object.keys(this.value).length===0){this.pop();return}}if(this.state===2&&e===d.COLON){this.state=0;return}if(this.state===3){if(e===d.COMMA){if(this.mode===1){this.state=0,this.key++;return}if(this.mode===0){this.state=1;return}}if(e===d.RIGHT_BRACE&&this.mode===0||e===d.RIGHT_BRACKET&&this.mode===1){this.pop();return}}if(this.state===6&&e===d.SEPARATOR&&n===this.separator){this.state=0;return}this.error(new N(`Unexpected ${d[e]} (${JSON.stringify(n)}) in state ${W(this.state)}`))}}error(e){this.state!==4&&(this.state=5),this.onError(e)}end(){this.state!==0&&this.state!==6||this.stack.length>0?this.error(new Error(`Parser ended in mid-parsing (state: ${W(this.state)}). Either not all the data was received or the data was invalid.`)):(this.state=4,this.onEnd())}onValue(e){throw new N(`Can't emit data before the "onValue" callback has been set up.`)}onError(e){throw e}onEnd(){}};var k=class{constructor({onIncrementalString:e}){this.decoder=new TextDecoder("utf-8");this.assembled="";this.byteLength=0;this.onIncrementalString=e??void 0}appendChar(e){this.assembled+=String.fromCharCode(e),this.byteLength++,this.update()}appendBuf(e,n=0,r=e.length){let t=this.decoder.decode(e.subarray(n,r));this.assembled+=t,this.byteLength+=r-n,this.update()}update(){this.onIncrementalString&&this.onIncrementalString(this.assembled)}reset(){this.assembled="",this.byteLength=0}toString(){return this.assembled}},M=class{constructor(e,n){this.decoder=new TextDecoder("utf-8");this.bufferOffset=0;this.string="";this.byteLength=0;this.buffer=new Uint8Array(e),this.onIncrementalString=n??void 0}appendChar(e){this.bufferOffset>=this.buffer.length&&this.flushStringBuffer(),this.buffer[this.bufferOffset++]=e,this.byteLength++}appendBuf(e,n=0,r=e.length){let t=r-n;this.bufferOffset+t>this.buffer.length&&this.flushStringBuffer(),this.buffer.set(e.subarray(n,r),this.bufferOffset),this.bufferOffset+=t,this.byteLength+=t}flushStringBuffer(){this.string+=this.decoder.decode(this.buffer.subarray(0,this.bufferOffset)),this.bufferOffset=0,this.update()}update(){this.onIncrementalString&&this.onIncrementalString(this.string)}reset(){this.string="",this.bufferOffset=0,this.byteLength=0}toString(){return this.string+=this.decoder.decode(this.buffer.subarray(0,this.bufferOffset)),this.bufferOffset=0,this.string}};var J={34:34,92:92,47:47,98:8,102:12,110:10,114:13,116:9};function Q(o){let e=typeof o=="string"?o:"choices"in o&&o.choices?.[0]?o.choices[0].message?.content??"":"",n=/<think(?:ing)?>([\s\S]*?)(?:<\/think(?:ing)?>|\Z)/i,r=e.match(n),t=r?r[1].trim():"",s=e.replace(n,"").trim();if(s.trim().startsWith("{")||s.trim().startsWith("["))return{json:s.trim(),thinking:t};let i=/```(?:json)?\s*([\s\S]*?)```/,u=s.match(i);if(u)return{json:u[1].trim(),thinking:t};let f=s.match(/```(?:json)?\s*([\s\S]*)/i);if(f){let m=f[1].trim();if(m.startsWith("{")||m.startsWith("["))return{json:m,thinking:t}}return{json:"",thinking:t}}function X(o){return["START","ENDED","ERROR","TRUE1","TRUE2","TRUE3","FALSE1","FALSE2","FALSE3","FALSE4","NULL1","NULL2","NULL3","STRING_DEFAULT","STRING_AFTER_BACKSLASH","STRING_UNICODE_DIGIT_1","STRING_UNICODE_DIGIT_2","STRING_UNICODE_DIGIT_3","STRING_UNICODE_DIGIT_4","STRING_INCOMPLETE_CHAR","NUMBER_AFTER_INITIAL_MINUS","NUMBER_AFTER_INITIAL_ZERO","NUMBER_AFTER_INITIAL_NON_ZERO","NUMBER_AFTER_FULL_STOP","NUMBER_AFTER_DECIMAL","NUMBER_AFTER_E","NUMBER_AFTER_E_AND_SIGN","NUMBER_AFTER_E_AND_DIGIT","SEPARATOR"][o]}var fe={stringBufferSize:0,numberBufferSize:0,separator:void 0,handleUnescapedNewLines:!1},x=class extends Error{constructor(n){super(n);this.name="TokenizerError"}},v=class{constructor(e){this.state=0;this.separatorIndex=0;this.bytes_remaining=0;this.bytes_in_sequence=0;this.char_split_buffer=new Uint8Array(4);this.encoder=new TextEncoder;this.offset=-1;e={...fe,...e};let n=r=>{this.onToken({token:d.STRING,value:r,partial:!0})};this.bufferedString=e?.stringBufferSize&&e.stringBufferSize>0?new M(e.stringBufferSize):new k({onIncrementalString:n}),this.bufferedNumber=e?.numberBufferSize&&e.numberBufferSize>0?new M(e.numberBufferSize,n):new k({}),this.handleUnescapedNewLines=e?.handleUnescapedNewLines??!1,this.separator=e?.separator,this.separatorBytes=e?.separator?this.encoder.encode(e.separator):void 0}get isEnded(){return this.state===1}write(e){let n;if(e instanceof Uint8Array)n=e;else if(typeof e=="string")n=this.encoder.encode(e);else if(typeof e=="object"&&"buffer"in e||Array.isArray(e))n=Uint8Array.from(e);else{this.error(new TypeError("Unexpected type. The `write` function only accepts Arrays, TypedArrays and Strings."));return}for(let r=0;r<n.length;r++){let t=n[r];switch(this.state){case 0:if(this.offset++,this.separatorBytes&&t===this.separatorBytes[0]){if(this.separatorBytes.length===1){this.state=0,this.onToken({token:d.SEPARATOR,value:this.separator,offset:this.offset+this.separatorBytes.length-1});continue}this.state=28;continue}if(t===32||t===10||t===13||t===9)continue;if(t===123){this.onToken({token:d.LEFT_BRACE,value:"{",offset:this.offset});continue}if(t===125){this.onToken({token:d.RIGHT_BRACE,value:"}",offset:this.offset});continue}if(t===91){this.onToken({token:d.LEFT_BRACKET,value:"[",offset:this.offset});continue}if(t===93){this.onToken({token:d.RIGHT_BRACKET,value:"]",offset:this.offset});continue}if(t===58){this.onToken({token:d.COLON,value:":",offset:this.offset});continue}if(t===44){this.onToken({token:d.COMMA,value:",",offset:this.offset});continue}if(t===116){this.state=3;continue}if(t===102){this.state=6;continue}if(t===110){this.state=10;continue}if(t===34){this.bufferedString.reset(),this.state=13;continue}if(t>=49&&t<=57){this.bufferedNumber.reset(),this.bufferedNumber.appendChar(t),this.state=22;continue}if(t===48){this.bufferedNumber.reset(),this.bufferedNumber.appendChar(t),this.state=21;continue}if(t===45){this.bufferedNumber.reset(),this.bufferedNumber.appendChar(t),this.state=20;continue}break;case 13:if(this.handleUnescapedNewLines&&t===10){this.bufferedString.appendChar(92),this.bufferedString.appendChar(110);continue}if(t===34){let s=this.bufferedString.toString();this.state=0,this.onToken({token:d.STRING,value:s,offset:this.offset}),this.offset+=this.bufferedString.byteLength+1;continue}if(t===92){this.state=14;continue}if(t>=128){if(t>=194&&t<=223?this.bytes_in_sequence=2:t<=239?this.bytes_in_sequence=3:this.bytes_in_sequence=4,this.bytes_in_sequence<=n.length-r){this.bufferedString.appendBuf(n,r,r+this.bytes_in_sequence),r+=this.bytes_in_sequence-1;continue}this.bytes_remaining=r+this.bytes_in_sequence-n.length,this.char_split_buffer.set(n.subarray(r)),r=n.length-1,this.state=19;continue}if(t>=32){this.bufferedString.appendChar(t);continue}break;case 19:this.char_split_buffer.set(n.subarray(r,r+this.bytes_remaining),this.bytes_in_sequence-this.bytes_remaining),this.bufferedString.appendBuf(this.char_split_buffer,0,this.bytes_in_sequence),r=this.bytes_remaining-1,this.state=13;continue;case 14:if(J?.[t]){this.bufferedString.appendChar(J[t]),this.state=13;continue}if(t===117){this.unicode="",this.state=15;continue}break;case 15:case 16:case 17:if(t>=48&&t<=57||t>=65&&t<=70||t>=97&&t<=102){this.unicode+=String.fromCharCode(t),this.state+=1;continue}break;case 18:if(t>=48&&t<=57||t>=65&&t<=70||t>=97&&t<=102){let s=parseInt(this.unicode+String.fromCharCode(t),16);this.highSurrogate===void 0?s>=55296&&s<=56319?this.highSurrogate=s:this.bufferedString.appendBuf(this.encoder.encode(String.fromCharCode(s))):(s>=56320&&s<=57343?this.bufferedString.appendBuf(this.encoder.encode(String.fromCharCode(this.highSurrogate,s))):this.bufferedString.appendBuf(this.encoder.encode(String.fromCharCode(this.highSurrogate))),this.highSurrogate=void 0),this.state=13;continue}break;case 20:if(t===48){this.bufferedNumber.appendChar(t),this.state=21;continue}if(t>=49&&t<=57){this.bufferedNumber.appendChar(t),this.state=22;continue}break;case 21:if(t===46){this.bufferedNumber.appendChar(t),this.state=23;continue}if(t===101||t===69){this.bufferedNumber.appendChar(t),this.state=25;continue}r--,this.state=0,this.emitNumber();continue;case 22:if(t>=48&&t<=57){this.bufferedNumber.appendChar(t);continue}if(t===46){this.bufferedNumber.appendChar(t),this.state=23;continue}if(t===101||t===69){this.bufferedNumber.appendChar(t),this.state=25;continue}r--,this.state=0,this.emitNumber();continue;case 23:if(t>=48&&t<=57){this.bufferedNumber.appendChar(t),this.state=24;continue}break;case 24:if(t>=48&&t<=57){this.bufferedNumber.appendChar(t);continue}if(t===101||t===69){this.bufferedNumber.appendChar(t),this.state=25;continue}r--,this.state=0,this.emitNumber();continue;case 25:if(t===43||t===45){this.bufferedNumber.appendChar(t),this.state=26;continue}case 26:if(t>=48&&t<=57){this.bufferedNumber.appendChar(t),this.state=27;continue}break;case 27:if(t>=48&&t<=57){this.bufferedNumber.appendChar(t);continue}r--,this.state=0,this.emitNumber();continue;case 3:if(t===114){this.state=4;continue}break;case 4:if(t===117){this.state=5;continue}break;case 5:if(t===101){this.state=0,this.onToken({token:d.TRUE,value:!0,offset:this.offset}),this.offset+=3;continue}break;case 6:if(t===97){this.state=7;continue}break;case 7:if(t===108){this.state=8;continue}break;case 8:if(t===115){this.state=9;continue}break;case 9:if(t===101){this.state=0,this.onToken({token:d.FALSE,value:!1,offset:this.offset}),this.offset+=4;continue}break;case 10:if(t===117){this.state=11;continue}break;case 11:if(t===108){this.state=12;continue}break;case 12:if(t===108){this.state=0,this.onToken({token:d.NULL,value:null,offset:this.offset}),this.offset+=3;continue}break;case 28:if(this.separatorIndex++,!this.separatorBytes||t!==this.separatorBytes[this.separatorIndex])break;this.separatorIndex===this.separatorBytes.length-1&&(this.state=0,this.onToken({token:d.SEPARATOR,value:this.separator,offset:this.offset+this.separatorIndex}),this.separatorIndex=0);continue;case 1:if(t===32||t===10||t===13||t===9)continue}this.error(new x(`Unexpected "${String.fromCharCode(t)}" at position "${r}" in state ${X(this.state)}`));return}}emitNumber(){this.onToken({token:d.NUMBER,value:this.parseNumber(this.bufferedNumber.toString()),offset:this.offset}),this.offset+=this.bufferedNumber.byteLength-1}parseNumber(e){return Number(e)}error(e){this.state!==1&&(this.state=2),this.onError(e)}end(){switch(this.state){case 21:case 22:case 24:case 27:this.state=1,this.emitNumber(),this.onEnd();break;case 0:case 2:case 28:this.state=1,this.onEnd();break;default:this.error(new x(`Tokenizer ended in the middle of a token (state: ${X(this.state)}). Either not all the data was received or the data was invalid.`))}}onToken(e){throw new x(`Can't emit tokens before the "onToken" callback has been set up.`)}onError(e){throw e}onEnd(){}};var w=class{constructor(e={}){this.tokenizer=new v(e),this.tokenParser=new y(e),this.tokenizer.onToken=this.tokenParser.write.bind(this.tokenParser),this.tokenizer.onEnd=()=>{this.tokenParser.isEnded||this.tokenParser.end()},this.tokenParser.onError=this.tokenizer.error.bind(this.tokenizer),this.tokenParser.onEnd=()=>{this.tokenizer.isEnded||this.tokenizer.end()}}get isEnded(){return this.tokenizer.isEnded&&this.tokenParser.isEnded}write(e){this.tokenizer.write(e)}end(){this.tokenizer.end()}set onToken(e){this.tokenizer.onToken=n=>{let r=[d.STRING,d.NUMBER,d.TRUE,d.FALSE,d.NULL];this.tokenParser.state===0&&r.includes(n.token)&&e({parser:{state:this.tokenParser.state,key:this.tokenParser.key,mode:this.tokenParser.mode,stack:this.tokenParser.stack},tokenizer:n}),this.tokenParser.write(n)}}set onValue(e){this.tokenParser.onValue=e}set onError(e){this.tokenizer.onError=e}set onEnd(e){this.tokenParser.onEnd=()=>{this.tokenizer.isEnded||this.tokenizer.end(),e.call(this.tokenParser)}}};var U=class{constructor(e,n={}){this.activePath=[];this.completedPaths=[];let{defaultData:r,onKeyComplete:t,typeDefaults:s}=n;this.schemaInstance=this.createBlankObject(e,r,s),this.onKeyComplete=t}getDefaultValue(e,n){try{let r=e.safeParse(void 0);if(r.success&&r.data!==void 0)return r.data}catch{}if(e instanceof A.ZodString)return Object.prototype.hasOwnProperty.call(n??{},"string")?n?.string:null;if(e instanceof A.ZodNumber)return Object.prototype.hasOwnProperty.call(n??{},"number")?n?.number:null;if(e instanceof A.ZodBoolean)return Object.prototype.hasOwnProperty.call(n??{},"boolean")?n?.boolean:null;if(e instanceof A.ZodArray)return[];if(e instanceof A.ZodObject)return this.createBlankObject(e,void 0,n);if(e instanceof A.ZodRecord)return{};if(e instanceof A.ZodOptional||e instanceof A.ZodNullable||"unwrap"in e&&typeof e.unwrap=="function")try{let r=e.unwrap();return this.getDefaultValue(r,n)}catch{return null}return null}createBlankObject(e,n,r){if(e instanceof A.ZodObject){let s={},{shape:i}=e;for(let u in i)s[u]=n&&Object.prototype.hasOwnProperty.call(n,u)?n[u]:this.getDefaultValue(i[u],r);return s}let t=this.getDefaultValue(e,r);return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}getPathFromStack(e=[],n){let r=e.length,t=r>0?r-1:0,s=new Array(t+1);for(let i=1;i<r;i++)s[i-1]=e[i].key;return s[t]=n,s}handleToken({parser:{key:e,stack:n},tokenizer:{value:r,partial:t}}){let s=this.getPathFromStack(n,e),i=this.activePath.length===0||!this.arePathsEqual(this.activePath,s);i&&(this.activePath=s),t||this.completedPaths.push(s),(i||!t)&&this.onKeyComplete&&this.onKeyComplete({activePath:this.activePath,completedPaths:this.completedPaths}),Y(this.schemaInstance,s,r)}arePathsEqual(e,n){if(e.length!==n.length)return!1;for(let r=0;r<e.length;r++)if(e[r]!==n[r])return!1;return!0}getSchemaStub(e,n,r){return this.createBlankObject(e,n,r)}parse(e={stringBufferSize:0,handleUnescapedNewLines:!0}){let n=new TextEncoder,r=new w({stringBufferSize:e.stringBufferSize??0,handleUnescapedNewLines:e.handleUnescapedNewLines??!0});return r.onToken=this.handleToken.bind(this),r.onValue=()=>{},r.onError=t=>{console.error("Error in the json parser transform stream: parsing chunk",t)},new TransformStream({transform:async(t,s)=>{try{r.write(t),s.enqueue(n.encode(JSON.stringify(this.schemaInstance)))}catch(i){typeof r.onError=="function"?r.onError(i):s.error(i)}},flush:()=>{this.onKeyComplete&&this.onKeyComplete({completedPaths:this.completedPaths,activePath:[]}),this.activePath=[]}})}};var O=class{constructor({debug:e=!1}={}){this.debug=!1;this.debug=e}log(e,...n){if(!this.debug&&e==="debug")return;let r=new Date().toISOString();switch(e){case"debug":console.debug(`[ZodStream-CLIENT:DEBUG] ${r}:`,...n);break;case"info":console.info(`[ZodStream-CLIENT:INFO] ${r}:`,...n);break;case"warn":console.warn(`[ZodStream-CLIENT:WARN] ${r}:`,...n);break;case"error":console.error(`[ZodStream-CLIENT:ERROR] ${r}:`,...n);break}}async chatCompletionStream({completionPromise:e,data:n,response_model:r}){let t=[],s=[];this.log("debug","Starting completion stream");let i=new U(r.schema,{onKeyComplete:({activePath:u,completedPaths:f})=>{this.log("debug","Key complete",u,f),t=u,s=f},typeDefaults:{string:null,number:null,boolean:null}});try{let u=i.parse({handleUnescapedNewLines:!0}),f=new TextEncoder,m=new TextDecoder,S=new TransformStream({transform:async(a,T)=>{try{let h=JSON.parse(m.decode(a)),I=await r.schema.safeParseAsync(h);this.log("debug","Validation result",I),T.enqueue(f.encode(JSON.stringify({data:[h],_meta:{_isValid:I.success,_activePath:t,_completedPaths:s,_type:"default"}})))}catch(h){this.log("error","Error in the partial stream validation stream",h,a),T.error(h)}},flush(){}}),c=await e(n);if(!c)throw this.log("error","Completion call returned no data"),new Error(c);return c.pipeThrough(u),u.readable.pipeThrough(S),$(S.readable)}catch(u){throw this.log("error","Error making completion call"),u}}getSchemaStub({schema:e,defaultData:n={}}){return new U(e,{defaultData:n,typeDefaults:{string:null,number:null,boolean:null}}).getSchemaStub(e,n)}async create(e){return this.chatCompletionStream(e)}};var _={FUNCTIONS:"FUNCTIONS",TOOLS:"TOOLS",JSON:"JSON",MD_JSON:"MD_JSON",JSON_SCHEMA:"JSON_SCHEMA",THINKING_MD_JSON:"THINKING_MD_JSON"};function ee(o,e){let{name:n,description:r,...t}=o,s={name:n},i=[...e?.functions??[],{name:n,description:r??void 0,parameters:t}];return{...e,function_call:s,functions:i}}function te(o,e){let{name:n,description:r,...t}=o,s={type:"function",function:{name:n}},i=[{type:"function",function:{name:n,description:r,parameters:t}},...e.tools?.map(u=>({type:u.type,function:{name:u.function.name,description:u.function.description,parameters:u.function.parameters}}))??[]];return{...e,tool_choice:s,tools:i}}function z(o,e){return{...e,messages:[{role:"system",content:`
Given a user prompt, you will return fully valid JSON based on the following description and schema.
You will return no other prose. You will take into account any descriptions or required parameters within the schema
and return a valid and fully escaped JSON object that matches the schema and those instructions.
description: ${o.description}
json schema: ${JSON.stringify(o)}
`},...e.messages]}}function ne(o,e){return{...e,messages:[{role:"system",content:`
Given a user prompt, you will return fully valid JSON based on the provided description and schema.
You will take into account any descriptions or required parameters within the schema
and return a valid and fully escaped JSON object that matches the schema and those instructions.
You will always return your full thought process in one <think> tag and then return the JSON response in a \`\`\`json block after the </think> tag. Never include any prose or thinking process outside of the <think> tag.
For example:
<think>
I am analyzing the input to extract the required information...
</think>
\`\`\`json
{
"result": "the actual json response"
}
\`\`\`
description: ${o.description}
json schema: ${JSON.stringify(o)}
`},...e.messages]}}function re(o,e){return{...e,response_format:{type:"json_object"},messages:[{role:"system",content:`
Given a user prompt, you will return fully valid JSON based on the following description and schema.
You will return no other prose. You will take into account any descriptions or required parameters within the schema
and return a valid and fully escaped JSON object that matches the schema and those instructions.
description: ${o.description}
json schema: ${JSON.stringify(o)}
`},...e.messages]}}function oe(o,e){return{...e,response_format:{type:"json_object",schema:g(["name","description"],o)},messages:[{role:"system",content:`
Given a user prompt, you will return fully valid JSON based on the following description.
You will return no other prose. You will take into account any descriptions or required parameters within the schema
and return a valid and fully escaped JSON object that matches the schema and those instructions.
description: ${o.description}
`},...e.messages]}}import*as se from"zod";function B({response_model:{name:o,schema:e,description:n=""},mode:r,params:t}){let s=o.replace(/[^a-zA-Z0-9]/g,"_").replace(/\s/g,"_"),i=se.toJSONSchema(e);delete i.$schema;let u={name:s,description:n,...i};return r===_.FUNCTIONS?ee(u,t):r===_.TOOLS?te(u,t):r===_.JSON?re(u,t):r===_.JSON_SCHEMA?oe(u,t):r===_.MD_JSON?z(u,t):r===_.THINKING_MD_JSON?ne(u,t):z(u,t)}var l=_,ie={[l.THINKING_MD_JSON]:Q},p={OAI:"OAI",ANYSCALE:"ANYSCALE",TOGETHER:"TOGETHER",ANTHROPIC:"ANTHROPIC",GROQ:"GROQ",OTHER:"OTHER"},ae={[p.OTHER]:[l.FUNCTIONS,l.TOOLS,l.JSON,l.JSON_SCHEMA,l.MD_JSON],[p.OAI]:[l.FUNCTIONS,l.TOOLS,l.JSON,l.MD_JSON],[p.ANYSCALE]:[l.TOOLS,l.JSON,l.JSON_SCHEMA,l.MD_JSON],[p.TOGETHER]:[l.TOOLS,l.JSON,l.JSON_SCHEMA,l.MD_JSON],[p.ANTHROPIC]:[l.MD_JSON,l.TOOLS],[p.GROQ]:[l.TOOLS,l.FUNCTIONS,l.MD_JSON]},C={[p.ANYSCALE]:"api.endpoints.anyscale",[p.TOGETHER]:"api.together.xyz",[p.OAI]:"api.openai.com",[p.ANTHROPIC]:"api.anthropic.com",[p.GROQ]:"api.groq.com"},H={[p.GROQ]:{[l.TOOLS]:function(e){return e.tools&&e.tools.some(n=>n)&&e.stream&&console.warn("Streaming may not be supported when using tools in Groq, try MD_JSON instead"),e}},[p.ANYSCALE]:{[l.JSON_SCHEMA]:function(e){return e.response_format&&"additionalProperties"in e.response_format.schema?{...e,response_format:{...e.response_format,schema:g(["additionalProperties"],e.response_format.schema)}}:e},[l.TOOLS]:function(e){return e.tools&&e.tools.some(n=>n.function?.parameters)?{...e,tools:e.tools.map(n=>n.function?.parameters?{...n,function:{...n.function,parameters:g(["additionalProperties"],n.function.parameters)}}:n)}:e}},[p.OAI]:{},[p.TOGETHER]:{},[p.ANTHROPIC]:{},[p.OTHER]:{}},kt={[p.OTHER]:{[l.FUNCTIONS]:["*"],[l.TOOLS]:["*"],[l.JSON]:["*"],[l.MD_JSON]:["*"],[l.JSON_SCHEMA]:["*"],[l.THINKING_MD_JSON]:["*"]},[p.OAI]:{[l.FUNCTIONS]:["*"],[l.TOOLS]:["*"],[l.JSON]:["*"],[l.MD_JSON]:["*"]},[p.TOGETHER]:{[l.MD_JSON]:["*"]},[p.ANYSCALE]:{[l.MD_JSON]:["*"]},[p.ANTHROPIC]:{[l.MD_JSON]:["*"],[l.TOOLS]:["*"]},[p.GROQ]:{[l.TOOLS]:["*"],[l.MD_JSON]:["*"],[l.THINKING_MD_JSON]:["deepseek-r1-distill-llama-70b"]}};var b=class extends Error{constructor(n,r){super(n);this.cause=r;this.name="InstructorError"}},R=class extends b{constructor(e="Unsupported client type",n){super(e,n),this.name="UnsupportedClientError"}},D=class extends b{constructor(e,n){super(e,n),this.name="RetryableError"}},F=class extends b{constructor(e,n){super(e,n),this.name="NonRetryableError"}},G=class extends b{constructor(n,r){super("ValidationError",r);this.issues=n;this.name="ValidationError"}};var Ee=0,K=class{constructor({client:e,mode:n,debug:r=!1,logger:t=void 0,retryAllErrors:s=!1}){this.debug=!1;this.retryAllErrors=!1;this.chat={completions:{create:async(e,n)=>{if(this.isChatCompletionCreateParamsWithModel(e))return e.stream?this.chatCompletionStream(e,n):this.chatCompletionStandard(e,n);if(this.client.chat?.completions?.create)return this.isStandardStream(e)?await this.client.chat.completions.create(e,n):await this.client.chat.completions.create(e,n);throw new R("Completion method is undefined")}}};if(!Ae(e)&&!(e instanceof ue))throw new R("Client does not match the required structure");e instanceof ue?this.client=e:this.client=e,this.mode=n,this.debug=r,this.retryAllErrors=s,this.logger=t??void 0,this.provider=typeof this.client?.baseURL=="string"?this.client?.baseURL.includes(C.ANYSCALE)?p.ANYSCALE:this.client?.baseURL.includes(C.TOGETHER)?p.TOGETHER:this.client?.baseURL.includes(C.OAI)?p.OAI:this.client?.baseURL.includes(C.ANTHROPIC)?p.ANTHROPIC:this.client?.baseURL.includes(C.GROQ)?p.GROQ:p.OTHER:p.OTHER,this.validateOptions()}validateOptions(){let e=ae[this.provider].includes(this.mode);this.provider===p.OTHER&&this.log("debug","Unknown provider - cant validate options."),e||this.log("warn",`Mode ${this.mode} may not be supported by provider ${this.provider}`)}log(e,...n){if(this.logger&&this.logger(e,...n),!this.debug&&e==="debug")return;let r=new Date().toISOString();switch(e){case"debug":console.debug(`[Instructor:DEBUG] ${r}:`,...n);break;case"info":console.info(`[Instructor:INFO] ${r}:`,...n);break;case"warn":console.warn(`[Instructor:WARN] ${r}:`,...n);break;case"error":console.error(`[Instructor:ERROR] ${r}:`,...n);break}}async chatCompletionStandard({max_retries:e=Ee,response_model:n,...r},t){let s=0,i="",u=null,f=H?.[this.provider]?.[this.mode],m=B({params:{...r,stream:r.stream??!1},mode:this.mode,response_model:n});typeof f=="function"&&(m=f(m));let S=async()=>{let a=m;i?.length>0&&(a={...m,messages:[...m.messages,...u?[u]:[],{role:"user",content:`Please correct the function call; errors encountered:
${i}`}]});let T;try{if(this.client.chat?.completions?.create)T=await this.client.chat.completions.create({...a,stream:!1},t);else throw new R("Unsupported client type -- no completion method found.");this.log("debug","raw standard completion response: ",T)}catch(E){throw this.log("error",`Error making completion call - mode: ${this.mode} | Client base URL: ${this.client.baseURL} | with params:`,a,"raw error",E),new D(E instanceof Error?E.message:"Error making completion call",E)}let I=(ie?.[this.mode]??L)(T);try{let E=I.json??I;return{data:[JSON.parse(E)],_meta:{usage:T?.usage??void 0,thinking:I?.thinking??void 0}}}catch(E){throw this.log("error","failed to parse completion",I,this.mode,"attempt: ",s,"max attempts: ",e),new D("Failed to parse completion",E)}},c=async()=>{try{let a=await S(),T=await n.schema.safeParseAsync(a.data[0]);if(this.log("debug",n.name,"Completion validation: ",T),!T.success)if("error"in T&&T.error instanceof me){u={role:"assistant",content:JSON.stringify(a)};try{if(T.error&&Array.isArray(T.error.issues)&&T.error.issues.length>0)try{let h=T.error;i=he(h)?.message??"Validation failed with issues"}catch{i=T.error.issues?.[0]?.message??"Validation failed with issues"}else i="Validation failed: error structure missing or invalid",this.log("debug","Validation error structure:",JSON.stringify(T.error))}catch(h){i=`Validation failed: ${T.error?.issues?.[0]?.message??"unknown validation error"}`,this.log("debug","fromZodError failed:",h),this.log("debug","Original validation error:",JSON.stringify(T.error))}throw new G(T.error.issues,T.error)}else throw new F("Validation failed",T.error);return{data:[T.data],_meta:a?._meta??{}}}catch(a){if(!this.retryAllErrors&&!(a instanceof G))throw a;if(s<e)return this.log("debug",`response model: ${n.name} - Retrying, attempt: `,s),this.log("warn",`response model: ${n.name} - Validation issues: `,i," - Attempt: ",s," - Max attempts: ",e),s++,await c();throw this.log("debug",`response model: ${n.name} - Max attempts reached: ${s}`),this.log("error",`response model: ${n.name} - Validation issues: `,i),a}};return c()}async*chatCompletionStream({max_retries:e,response_model:n,...r},t){e&&this.log("warn","max_retries is not supported for streaming completions");let s=H?.[this.provider]?.[this.mode],i=B({params:{...r,stream:!0},response_model:n,mode:this.mode});typeof s=="function"&&(i=s(i));let u=new O({debug:this.debug??!1}),f=async c=>{for await(let a of c)"usage"in a&&(m=a.usage)},m,S=await u.create({completionPromise:async()=>{if(this.client.chat?.completions?.create){let c=await this.client.chat.completions.create({...i,stream:!0},t);if(this.log("debug","raw stream completion response: ",c),this.provider==="OAI"&&i?.stream&&"stream_options"in i&&c instanceof ce){let[a,T]=c.tee();return f(a),P({res:T})}if(this.provider!=="OAI"&&i?.stream&&c?.[Symbol.asyncIterator]){let[a,T]=await j(c,2);return f(a),P({res:T})}return P({res:c})}else throw new R("Unsupported client type")},response_model:{schema:n.schema}});for await(let c of S)yield{data:c.data,_meta:{usage:m??void 0,...c?._meta??{}}}}isChatCompletionCreateParamsWithModel(e){return"response_model"in e}isStandardStream(e){return"stream"in e&&e.stream===!0}};function Z(o){let e=new K(o);return new Proxy(e,{get:(r,t,s)=>t in r?Reflect.get(r,t,s):Reflect.get(r.client,t,s)})}function Ae(o){return typeof o=="object"&&o!==null&&"chat"in o&&typeof o.chat=="object"&&o.chat!==null&&"completions"in o.chat&&typeof o.chat.completions=="object"&&o.chat.completions!==null&&"create"in o.chat.completions&&typeof o.chat.completions.create=="function"}var $t=Z;export{$t as default};
//# sourceMappingURL=index.js.map