@epam/statgpt-dial-toolkit 0.2.0-rc.3 → 0.2.0-rc.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/index.cjs +3 -3
  2. package/index.mjs +43 -43
  3. package/package.json +2 -2
package/index.cjs CHANGED
@@ -1,3 +1,3 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const m="v1",R=`/${m}/ops/resource/share`,u={VERSION:`/${m}`,BUCKET:`/${m}/bucket`,CONVERSATIONS:`/${m}/metadata/conversations`,CONVERSATION_BY_ID:s=>`/${m}/metadata/conversations/${s}`,CHAT:s=>`/openai/deployments/${s}/chat/completions`,MODELS:"/openai/models",CONFIGURATION:s=>`/${m}/deployments/${s}/configuration`,SHARE_CONVERSATION:`${R}/create`,SHARE_CONVERSATION_ACCEPT:s=>`/${m}/invitations/${s}?accept=true`,SHARE_CONVERSATION_DETAILS:s=>`/${m}/invitations/${s}`,SHARE_CONVERSATION_LIST:`${R}/list`,SHARE_CONVERSATION_DISCARD:`${R}/discard`,SHARE_CONVERSATION_REVOKE:`${R}/revoke`,RATE:`/${m}/rate`,RENAME:`/${m}/ops/resource/move`};var O=(s=>(s.CONVERSATION="CONVERSATION",s))(O||{}),_=(s=>(s.ME="me",s.OTHERS="others",s))(_||{}),T=(s=>(s.CSV="text/csv",s.TABLE="application/dial-ttyd-table",s.PLOTLY="application/vnd.plotly.v1+json",s.MARKDOWN="text/markdown",s.JSON="application/json",s.JPEG="image/jpeg",s.PNG="image/png",s.CUSTOM_DATA_GRID="custom_data_grid",s.CUSTOM_CHART="custom_chart",s))(T||{}),I=(s=>(s.LINK="link",s))(I||{});const b=s=>{var t,r,e,n,o,a;return s.content?(console.info(`Using direct content format: ${s.content}`),s.content):(e=(r=(t=s.choices)==null?void 0:t[0])==null?void 0:r.delta)!=null&&e.content?(console.info(`Using OpenAI delta format: ${s.choices[0].delta.content}`),s.choices[0].delta.content):(a=(o=(n=s.choices)==null?void 0:n[0])==null?void 0:o.message)!=null&&a.content?(console.info(`Using complete message format: ${s.choices[0].message.content}`),s.choices[0].message.content):(console.info("Unknown SSE data format:",s),null)},g=(s,t,r)=>{if(t==null||t(s),r){const e=b(s);e&&r(e)}},p=(s,t)=>s.error||s.message||`${t.status} ${t.statusText}`,x=(s,t)=>{const r=s==null?void 0:s.reduce((e,n)=>(e[n.index]=n,e),{});return t.forEach(e=>{r[e.index]?(e.attachments&&(r[e.index].attachments=(r[e.index].attachments||[]).concat(e.attachments)),e.content&&(r[e.index].content=(r[e.index].content||"")+e.content),e.name&&(r[e.index].name=(r[e.index].name||"")+e.name),e.status&&(r[e.index].status=e.status)):r[e.index]=e}),Object.values(r)},P=(s,t)=>{const r=structuredClone(s);return t.forEach(e=>{e.errorMessage&&(r.errorMessage=e.errorMessage),e.role&&(r.role=e.role),e.responseId&&(r.responseId=e.responseId),e.content&&(r.content=`${r.content||""}${e.content}`),e.custom_content&&(r.custom_content||(r.custom_content={}),e.custom_content.attachments&&(r.custom_content.attachments||(r.custom_content.attachments=[]),r.custom_content.attachments=r.custom_content.attachments.concat(e.custom_content.attachments)),e.custom_content.stages&&(r.custom_content.stages||(r.custom_content.stages=[]),r.custom_content.stages=x(r.custom_content.stages,e.custom_content.stages)),e.custom_content.state&&(r.custom_content.state=e.custom_content.state),e.custom_content.form_schema&&(r.custom_content.form_schema=e.custom_content.form_schema),e.custom_content.form_value&&(r.custom_content.form_value=e.custom_content.form_value))}),r},V={CHAT:"/api/chat"},H="application/json",D="Content-Type",A="Api-Key",L="X-CONVERSATION-ID",U=s=>(s==null?void 0:s.toLowerCase().replace(/[^\p{L}\p{N}]+/gu,"-").replace(/^-+|-+$/g,"").replace(/-/g," "))||"",C=(s,t,r)=>{const e={[D]:(t==null?void 0:t.contentType)||H};return t!=null&&t.jwt?e.Authorization=`Bearer ${t.jwt}`:s&&(e[A]=s),t!=null&&t.chatReference&&(e[L]=t.chatReference),{...e,...r}},j=s=>{const t={...s};return t[A]&&(t[A]=t[A].substring(0,8)+"...[REDACTED]"),t.Authorization&&(t.Authorization="Bearer [REDACTED]"),t},M=s=>({"Content-Type":`multipart/form-data; boundary=${s}`}),$=s=>{var n;const t=((n=s.name)==null?void 0:n.split("__"))||[],r=t.length>1?t.slice(1).join("__"):s.name;return{modelId:t[0],conversationName:r}},N=s=>{const t=Date.now(),r=U(s.name);return`${s.folderId}/${r}-${t}`},k=s=>({resourceTypes:[O.CONVERSATION],with:s}),E=async(s,t,r)=>await fetch(s,{method:r.method||"GET",headers:t,body:r!=null&&r.isFormData&&typeof(r==null?void 0:r.body)=="string"?r.body:JSON.stringify(r.body),signal:r==null?void 0:r.signal});function f(s){return s.split("/").map(t=>encodeURIComponent(t)).join("/")}function F(s){return s.split("/").map(t=>decodeURIComponent(t)).join("/")}class w{constructor(){this.decoder=new TextDecoder}async streamChat(t,r,e={},n){const{onMessage:o,onError:a,onComplete:c,signal:d}=e;try{const i=await this.initializeStreamRequest(t,r,d,n);await this.processStreamData(i,o),c==null||c()}catch(i){this.handleStreamError(i,a)}}async initializeStreamRequest(t,r,e,n){const o=C(void 0,{jwt:n}),a=await E(t,{Accept:"text/event-stream",...o},{method:"POST",body:r,signal:e});if(!a.ok){const c=await a.text();throw new Error(JSON.stringify({status:a.status,message:c}))}if(!a.body)throw new Error("No response body");return a.body.getReader()}async processStreamData(t,r){let e="";try{for(;;){const{done:n,value:o}=await t.read();if(n){e.trim()&&this.parseSSEDataLine(e,r);break}const a=this.decoder.decode(o,{stream:!0});e+=a;const c=e.split(`
2
- `);e=c.pop()||"";for(const d of c)this.parseSSEDataLine(d,r)}}finally{t.releaseLock()}}handleStreamError(t,r){const e=t instanceof Error?t:new Error(String(t));throw r==null||r(e),e}parseSSEDataLine(t,r){const e=t.trim();if(!(!e||e.startsWith(":"))&&e.startsWith("data: ")){const n=e.slice(6);if(n==="[DONE]"){console.info("SSE: Stream completed");return}try{const o=JSON.parse(n);r==null||r(o)}catch(o){console.error(`Failed to parse SSE data: ${n} ${o}`)}}}}const q=new w,K=async(s,t,r,e,n)=>{const{onMessage:o,onToken:a,onComplete:c,onError:d,model:i,signal:l}=r,y={conversationId:s,messages:t,model:i,custom_fields:n};await q.streamChat(V.CHAT,y,{onMessage:v=>g(v,o,a),onComplete:c,onError:d,signal:l},e)},h=s=>s instanceof Error&&s.message.includes("404"),S=s=>`/v1/conversations/${f(s)}`;class B{constructor(t){this.client=t}async getConversations(t,r,e){const n=`${r?e?`${r}/${e}`:`${r}`:""}`,o=`${u.CONVERSATIONS}/${n}`;try{return(await this.client.getRequest(o+"/?limit=1000&recursive=false",t).then(c=>c.items||[])).map(c=>{var l;const{conversationName:d,modelId:i}=$(c);return{id:((l=c.url)==null?void 0:l.replace("conversations/",""))||c.name,name:d,folderId:n,createdAt:c.createdAt,updatedAt:c.updatedAt,model:{id:i,name:i}}})}catch(a){if(h(a))return[];throw a}}async getConversation(t,r){try{return await this.client.getRequest(S(t),r)}catch(e){if(h(e))return null;throw e}}async getFile(t,r){try{const e=`${u.VERSION}/${f(t)}`;return await this.client.getRequest(e,r)}catch(e){if(h(e))return null;throw e}}async putOnboardingFile(t,r,e,n){try{const o=`${u.VERSION}/${f(r)}`,a="----NodeMultipartBoundary",d=[`--${a}`,`Content-Disposition: form-data; name="file"; filename="${t}"`,"Content-Type: application/json","",JSON.stringify(e),`--${a}--`,""].join(`\r
3
- `);return await this.client.request(o,n,{method:"PUT",body:d,headers:M(a),isFormData:!0})}catch(o){if(h(o))return null;throw o}}async getOnboardingFile(t,r){try{const e=`${u.VERSION}/${f(t)}`;return await this.client.getRequest(e,r)}catch(e){if(h(e))return null;throw e}}async getFileBlob(t,r){try{const e=`${u.VERSION}/${f(t)}`;return await this.client.requestBlob(e,r,{method:"GET"})}catch(e){if(h(e))return null;throw e}}async createConversation(t,r){const e=(t==null?void 0:t.id)||N(t),{name:n,folderId:o,model:a,messages:c,custom_fields:d}=t,i={id:e,name:n,folderId:o,model:a,messages:c||[],selectedAddons:t.selectedAddons||[],prompt:t.prompt||"",temperature:t.temperature||.7,createdAt:Date.now(),updatedAt:Date.now(),custom_fields:d};return await this.client.request(S(e),r,{method:"PUT",body:i}),{id:e,name:n,folderId:o,model:a,createdAt:i.createdAt,updatedAt:i.updatedAt}}async generateConversationLink(t,r){return await this.client.postRequest(u.SHARE_CONVERSATION,t,{body:r})}async getSharedConversations(t,r){return await this.client.postRequest(u.SHARE_CONVERSATION_LIST,t,{body:r})}async revokeSharedConversations(t,r){await this.client.postRequest(u.SHARE_CONVERSATION_REVOKE,t,{body:r})}async updateConversation(t,r,e){const n=await this.getConversation(t,e);if(!n)throw new Error(`Conversation with id ${t} not found`);const o={...n,...r,updatedAt:Date.now()};return await this.client.request(S(t),e,{method:"PUT",body:o})}async deleteConversation(t,r){t!=null&&t.isShared?await this.client.postRequest(u.SHARE_CONVERSATION_DISCARD,r,{body:{resources:[{url:t==null?void 0:t.url}]}}):await this.client.request(S(decodeURI(t==null?void 0:t.id)),r,{method:"DELETE"})}async streamChat(t,r){const e=t.model.id,n=encodeURIComponent(e),o=`${u.CHAT(n)}?api-version=${this.client.config.version}`,a={messages:t.messages,stream:!0,temperature:.7,max_tokens:4096,custom_fields:t.custom_fields};return await this.client.stream(o,r,{method:"POST",body:a,chatReference:t.conversationId})}async rateResponse(t,r,e){return await this.client.postRequest(u.RATE,e,{body:{responseId:t,rate:r}})}async renameConversation(t,r,e){return await this.client.postRequest(u.RENAME,e,{body:{sourceUrl:t,destinationUrl:r,overwrite:!0}})}}class J{constructor(t){this.config=t,console.info("DialApiClient initialized",{host:t.host||"NOT SET",hasApiKey:!!t.apiKey,version:t.version})}async getRequest(t,r,e){return this.request(t,r,{...e,method:"GET"})}async postRequest(t,r,e){return this.request(t,r,{...e,method:"POST"})}async requestBlob(t,r,e){const n=`${this.config.host}${t}`,o={...C(this.config.apiKey,{jwt:r,chatReference:e.chatReference}),...e.headers};try{return(await E(n,o,e)).blob()}catch(a){throw console.error("API Request Exception",{method:e.method,url:n,error:a instanceof Error?a.message:String(a)}),a}}async request(t,r,e){const n=Date.now(),o=`${this.config.host}${t}`,a={...C(this.config.apiKey,{jwt:r,chatReference:e.chatReference}),...e.headers};this.addInfoRequestLog("API Request",o,e,a);try{const c=await E(o,a,e),d=Date.now()-n;let i;const l=await c.text();try{i=l?JSON.parse(l):{}}catch{if(this.addErrorRequestParsing(o,e,c,d,l),!c.ok)throw new Error(`API request failed: ${c.status} ${c.statusText} - ${l.substring(0,100)}`);i={data:l}}if(!c.ok){this.addErrorRequestLog(o,e,c,d,i);const y=p(i,c);throw new Error(`API request failed: ${y}`)}return i}catch(c){const d=Date.now()-n;throw console.error("API Request Exception",{method:e.method,url:o,duration:`${d}ms`,error:c instanceof Error?c.message:String(c)}),c}}async stream(t,r,e){const n=`${this.config.host}${t}`,o=C(this.config.apiKey,{jwt:r,chatReference:e.chatReference},e.headers);this.addInfoRequestLog("Stream Request",n,e,o);const a=await E(n,o,e);if(!a.ok)throw console.error("Stream Request Failed",{method:e.method||"POST",url:n,status:a.status,statusText:a.statusText}),new Error(`Stream request failed: ${a.status} ${a.statusText}`);if(!a.body)throw new Error("No response body for stream");return a.body}addInfoRequestLog(t,r,e,n){const o={method:e.method||"GET",url:r,headers:j(n)};e.body&&(o.body=e.body),console.info(t,o)}addErrorRequestLog(t,r,e,n,o){console.error("API Request Failed",{method:r.method,url:t,status:e.status,statusText:e.statusText,duration:`${n}ms`,response:o})}addErrorRequestParsing(t,r,e,n,o){console.error("API Response Parse Error",{method:r.method,url:t,status:e.status,statusText:e.statusText,duration:`${n}ms`,responseText:o.substring(0,200),error:"Response is not valid JSON"})}}exports.AttachmentType=T;exports.ChatStreamSSEClient=w;exports.ConversationApi=B;exports.DIAL_API_ROUTES=u;exports.DialApiClient=J;exports.InvitationType=I;exports.ResourceTypes=O;exports.ShareTarget=_;exports.chatStreamSSEClient=q;exports.decodeApiUrl=F;exports.encodeApiUrl=f;exports.generateConversationId=N;exports.getErrorMessage=p;exports.getSharedConversationsRequest=k;exports.handleStreamMessage=g;exports.mergeMessages=P;exports.parseConversationName=$;exports.sendRequest=E;exports.streamChatResponse=K;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const m="v1",R=`/${m}/ops/resource/share`,u={VERSION:`/${m}`,BUCKET:`/${m}/bucket`,CONVERSATIONS:`/${m}/metadata/conversations`,CONVERSATION_BY_ID:s=>`/${m}/metadata/conversations/${s}`,CHAT:s=>`/openai/deployments/${s}/chat/completions`,MODELS:"/openai/models",CONFIGURATION:s=>`/${m}/deployments/${s}/configuration`,SHARE_CONVERSATION:`${R}/create`,SHARE_CONVERSATION_ACCEPT:s=>`/${m}/invitations/${s}?accept=true`,SHARE_CONVERSATION_DETAILS:s=>`/${m}/invitations/${s}`,SHARE_CONVERSATION_LIST:`${R}/list`,SHARE_CONVERSATION_DISCARD:`${R}/discard`,SHARE_CONVERSATION_REVOKE:`${R}/revoke`,RATE:`/${m}/rate`,RENAME:`/${m}/ops/resource/move`};var O=(s=>(s.CONVERSATION="CONVERSATION",s))(O||{}),I=(s=>(s.ME="me",s.OTHERS="others",s))(I||{}),T=(s=>(s.CSV="text/csv",s.TABLE="application/dial-ttyd-table",s.PLOTLY="application/vnd.plotly.v1+json",s.MARKDOWN="text/markdown",s.JSON="application/json",s.JPEG="image/jpeg",s.PNG="image/png",s.CUSTOM_DATA_GRID="custom_data_grid",s.CUSTOM_CHART="custom_chart",s))(T||{}),p=(s=>(s.LINK="link",s))(p||{});const P=s=>{var t,r,e,n,o,a;return s.content?(console.info(`Using direct content format: ${s.content}`),s.content):(e=(r=(t=s.choices)==null?void 0:t[0])==null?void 0:r.delta)!=null&&e.content?(console.info(`Using OpenAI delta format: ${s.choices[0].delta.content}`),s.choices[0].delta.content):(a=(o=(n=s.choices)==null?void 0:n[0])==null?void 0:o.message)!=null&&a.content?(console.info(`Using complete message format: ${s.choices[0].message.content}`),s.choices[0].message.content):(console.info("Unknown SSE data format:",s),null)},g=(s,t,r)=>{if(t==null||t(s),r){const e=P(s);e&&r(e)}},N=(s,t)=>s.error||s.message||`${t.status} ${t.statusText}`,x=(s,t)=>{const r=s==null?void 0:s.reduce((e,n)=>(e[n.index]=n,e),{});return t.forEach(e=>{r[e.index]?(e.attachments&&(r[e.index].attachments=(r[e.index].attachments||[]).concat(e.attachments)),e.content&&(r[e.index].content=(r[e.index].content||"")+e.content),e.name&&(r[e.index].name=(r[e.index].name||"")+e.name),e.status&&(r[e.index].status=e.status)):r[e.index]=e}),Object.values(r)},D=(s,t)=>{const r=structuredClone(s);return t.forEach(e=>{e.errorMessage&&(r.errorMessage=e.errorMessage),e.role&&(r.role=e.role),e.responseId&&(r.responseId=e.responseId),e.content&&(r.content=`${r.content||""}${e.content}`),e.custom_content&&(r.custom_content||(r.custom_content={}),e.custom_content.attachments&&(r.custom_content.attachments||(r.custom_content.attachments=[]),r.custom_content.attachments=r.custom_content.attachments.concat(e.custom_content.attachments)),e.custom_content.stages&&(r.custom_content.stages||(r.custom_content.stages=[]),r.custom_content.stages=x(r.custom_content.stages,e.custom_content.stages)),e.custom_content.state&&(r.custom_content.state=e.custom_content.state),e.custom_content.form_schema&&(r.custom_content.form_schema=e.custom_content.form_schema),e.custom_content.form_value&&(r.custom_content.form_value=e.custom_content.form_value))}),r},H={CHAT:"/api/chat"},V="application/json",L="Content-Type",A="Api-Key",U="X-CONVERSATION-ID",_="Ocp-Apim-Subscription-Key",j=s=>(s==null?void 0:s.toLowerCase().replace(/[^\p{L}\p{N}]+/gu,"-").replace(/^-+|-+$/g,"").replace(/-/g," "))||"",C=(s,t,r)=>{const e={[L]:(t==null?void 0:t.contentType)||V};return t!=null&&t.jwt?e.Authorization=`Bearer ${t.jwt}`:s&&(e[A]=s),t!=null&&t.chatReference&&(e[U]=t.chatReference),{...e,...r}},M=s=>{const t={...s};return t[A]&&(t[A]=t[A].substring(0,8)+"...[REDACTED]"),t.Authorization&&(t.Authorization="Bearer [REDACTED]"),t[_]&&(t[_]=t[_].substring(0,8)+"...[REDACTED]"),t},k=s=>({"Content-Type":`multipart/form-data; boundary=${s}`}),$=s=>{var n;const t=((n=s.name)==null?void 0:n.split("__"))||[],r=t.length>1?t.slice(1).join("__"):s.name;return{modelId:t[0],conversationName:r}},w=s=>{const t=Date.now(),r=j(s.name);return`${s.folderId}/${r}-${t}`},K=s=>({resourceTypes:[O.CONVERSATION],with:s}),f=async(s,t,r)=>await fetch(s,{method:r.method||"GET",headers:t,body:r!=null&&r.isFormData&&typeof(r==null?void 0:r.body)=="string"?r.body:JSON.stringify(r.body),signal:r==null?void 0:r.signal});function E(s){return s.split("/").map(t=>encodeURIComponent(t)).join("/")}function B(s){return s.split("/").map(t=>decodeURIComponent(t)).join("/")}class q{constructor(){this.decoder=new TextDecoder}async streamChat(t,r,e={},n){const{onMessage:o,onError:a,onComplete:c,signal:d}=e;try{const i=await this.initializeStreamRequest(t,r,d,n);await this.processStreamData(i,o),c==null||c()}catch(i){this.handleStreamError(i,a)}}async initializeStreamRequest(t,r,e,n){const o=C(void 0,{jwt:n}),a=await f(t,{Accept:"text/event-stream",...o},{method:"POST",body:r,signal:e});if(!a.ok){const c=await a.text();throw new Error(JSON.stringify({status:a.status,message:c}))}if(!a.body)throw new Error("No response body");return a.body.getReader()}async processStreamData(t,r){let e="";try{for(;;){const{done:n,value:o}=await t.read();if(n){e.trim()&&this.parseSSEDataLine(e,r);break}const a=this.decoder.decode(o,{stream:!0});e+=a;const c=e.split(`
2
+ `);e=c.pop()||"";for(const d of c)this.parseSSEDataLine(d,r)}}finally{t.releaseLock()}}handleStreamError(t,r){const e=t instanceof Error?t:new Error(String(t));throw r==null||r(e),e}parseSSEDataLine(t,r){const e=t.trim();if(!(!e||e.startsWith(":"))&&e.startsWith("data: ")){const n=e.slice(6);if(n==="[DONE]"){console.info("SSE: Stream completed");return}try{const o=JSON.parse(n);r==null||r(o)}catch(o){console.error(`Failed to parse SSE data: ${n} ${o}`)}}}}const b=new q,F=async(s,t,r,e,n)=>{const{onMessage:o,onToken:a,onComplete:c,onError:d,model:i,signal:l}=r,y={conversationId:s,messages:t,model:i,custom_fields:n};await b.streamChat(H.CHAT,y,{onMessage:v=>g(v,o,a),onComplete:c,onError:d,signal:l},e)},h=s=>s instanceof Error&&s.message.includes("404"),S=s=>`/v1/conversations/${E(s)}`;class J{constructor(t){this.client=t}async getConversations(t,r,e){const n=`${r?e?`${r}/${e}`:`${r}`:""}`,o=`${u.CONVERSATIONS}/${n}`;try{return(await this.client.getRequest(o+"/?limit=1000&recursive=false",t).then(c=>c.items||[])).map(c=>{var l;const{conversationName:d,modelId:i}=$(c);return{id:((l=c.url)==null?void 0:l.replace("conversations/",""))||c.name,name:d,folderId:n,createdAt:c.createdAt,updatedAt:c.updatedAt,model:{id:i,name:i}}})}catch(a){if(h(a))return[];throw a}}async getConversation(t,r){try{return await this.client.getRequest(S(t),r)}catch(e){if(h(e))return null;throw e}}async getFile(t,r){try{const e=`${u.VERSION}/${E(t)}`;return await this.client.getRequest(e,r)}catch(e){if(h(e))return null;throw e}}async putOnboardingFile(t,r,e,n){try{const o=`${u.VERSION}/${E(r)}`,a="----NodeMultipartBoundary",d=[`--${a}`,`Content-Disposition: form-data; name="file"; filename="${t}"`,"Content-Type: application/json","",JSON.stringify(e),`--${a}--`,""].join(`\r
3
+ `);return await this.client.request(o,n,{method:"PUT",body:d,headers:k(a),isFormData:!0})}catch(o){if(h(o))return null;throw o}}async getOnboardingFile(t,r){try{const e=`${u.VERSION}/${E(t)}`;return await this.client.getRequest(e,r)}catch(e){if(h(e))return null;throw e}}async getFileBlob(t,r){try{const e=`${u.VERSION}/${E(t)}`;return await this.client.requestBlob(e,r,{method:"GET"})}catch(e){if(h(e))return null;throw e}}async createConversation(t,r){const e=(t==null?void 0:t.id)||w(t),{name:n,folderId:o,model:a,messages:c,custom_fields:d}=t,i={id:e,name:n,folderId:o,model:a,messages:c||[],selectedAddons:t.selectedAddons||[],prompt:t.prompt||"",temperature:t.temperature||.7,createdAt:Date.now(),updatedAt:Date.now(),custom_fields:d};return await this.client.request(S(e),r,{method:"PUT",body:i}),{id:e,name:n,folderId:o,model:a,createdAt:i.createdAt,updatedAt:i.updatedAt}}async generateConversationLink(t,r){return await this.client.postRequest(u.SHARE_CONVERSATION,t,{body:r})}async getSharedConversations(t,r){return await this.client.postRequest(u.SHARE_CONVERSATION_LIST,t,{body:r})}async revokeSharedConversations(t,r){await this.client.postRequest(u.SHARE_CONVERSATION_REVOKE,t,{body:r})}async updateConversation(t,r,e){const n=await this.getConversation(t,e);if(!n)throw new Error(`Conversation with id ${t} not found`);const o={...n,...r,updatedAt:Date.now()};return await this.client.request(S(t),e,{method:"PUT",body:o})}async deleteConversation(t,r){t!=null&&t.isShared?await this.client.postRequest(u.SHARE_CONVERSATION_DISCARD,r,{body:{resources:[{url:t==null?void 0:t.url}]}}):await this.client.request(S(decodeURI(t==null?void 0:t.id)),r,{method:"DELETE"})}async streamChat(t,r){const e=t.model.id,n=encodeURIComponent(e),o=`${u.CHAT(n)}?api-version=${this.client.config.version}`,a={messages:t.messages,stream:!0,temperature:.7,max_tokens:4096,custom_fields:t.custom_fields};return await this.client.stream(o,r,{method:"POST",body:a,chatReference:t.conversationId})}async rateResponse(t,r,e){return await this.client.postRequest(u.RATE,e,{body:{responseId:t,rate:r}})}async renameConversation(t,r,e){return await this.client.postRequest(u.RENAME,e,{body:{sourceUrl:t,destinationUrl:r,overwrite:!0}})}}class z{constructor(t){this.config=t,console.info("DialApiClient initialized",{host:t.host||"NOT SET",hasApiKey:!!t.apiKey,version:t.version})}async getRequest(t,r,e){return this.request(t,r,{...e,method:"GET"})}async postRequest(t,r,e){return this.request(t,r,{...e,method:"POST"})}async requestBlob(t,r,e){const n=`${this.config.host}${t}`,o={...C(this.config.apiKey,{jwt:r,chatReference:e.chatReference}),...e.headers};try{return(await f(n,o,e)).blob()}catch(a){throw console.error("API Request Exception",{method:e.method,url:n,error:a instanceof Error?a.message:String(a)}),a}}async request(t,r,e){const n=Date.now(),o=`${this.config.host}${t}`,a={...C(this.config.apiKey,{jwt:r,chatReference:e.chatReference}),...e.headers};this.addInfoRequestLog("API Request",o,e,a);try{const c=await f(o,a,e),d=Date.now()-n;let i;const l=await c.text();try{i=l?JSON.parse(l):{}}catch{if(this.addErrorRequestParsing(o,e,c,d,l),!c.ok)throw new Error(`API request failed: ${c.status} ${c.statusText} - ${l.substring(0,100)}`);i={data:l}}if(!c.ok){this.addErrorRequestLog(o,e,c,d,i);const y=N(i,c);throw new Error(`API request failed: ${y}`)}return i}catch(c){const d=Date.now()-n;throw console.error("API Request Exception",{method:e.method,url:o,duration:`${d}ms`,error:c instanceof Error?c.message:String(c)}),c}}async stream(t,r,e){const n=`${this.config.host}${t}`,o=C(this.config.apiKey,{jwt:r,chatReference:e.chatReference},e.headers);this.addInfoRequestLog("Stream Request",n,e,o);const a=await f(n,o,e);if(!a.ok)throw console.error("Stream Request Failed",{method:e.method||"POST",url:n,status:a.status,statusText:a.statusText}),new Error(`Stream request failed: ${a.status} ${a.statusText}`);if(!a.body)throw new Error("No response body for stream");return a.body}addInfoRequestLog(t,r,e,n){const o={method:e.method||"GET",url:r,headers:M(n)};e.body&&(o.body=e.body),console.info(t,o)}addErrorRequestLog(t,r,e,n,o){console.error("API Request Failed",{method:r.method,url:t,status:e.status,statusText:e.statusText,duration:`${n}ms`,response:o})}addErrorRequestParsing(t,r,e,n,o){console.error("API Response Parse Error",{method:r.method,url:t,status:e.status,statusText:e.statusText,duration:`${n}ms`,responseText:o.substring(0,200),error:"Response is not valid JSON"})}}exports.AttachmentType=T;exports.ChatStreamSSEClient=q;exports.ConversationApi=J;exports.DIAL_API_ROUTES=u;exports.DialApiClient=z;exports.InvitationType=p;exports.ResourceTypes=O;exports.ShareTarget=I;exports.chatStreamSSEClient=b;exports.decodeApiUrl=B;exports.encodeApiUrl=E;exports.generateConversationId=w;exports.getErrorMessage=N;exports.getSharedConversationsRequest=K;exports.handleStreamMessage=g;exports.mergeMessages=D;exports.parseConversationName=$;exports.sendRequest=f;exports.streamChatResponse=F;
package/index.mjs CHANGED
@@ -15,18 +15,18 @@ const E = "/v1/ops/resource/share", u = {
15
15
  RATE: "/v1/rate",
16
16
  RENAME: "/v1/ops/resource/move"
17
17
  };
18
- var I = /* @__PURE__ */ ((s) => (s.CONVERSATION = "CONVERSATION", s))(I || {}), y = /* @__PURE__ */ ((s) => (s.ME = "me", s.OTHERS = "others", s))(y || {}), _ = /* @__PURE__ */ ((s) => (s.CSV = "text/csv", s.TABLE = "application/dial-ttyd-table", s.PLOTLY = "application/vnd.plotly.v1+json", s.MARKDOWN = "text/markdown", s.JSON = "application/json", s.JPEG = "image/jpeg", s.PNG = "image/png", s.CUSTOM_DATA_GRID = "custom_data_grid", s.CUSTOM_CHART = "custom_chart", s))(_ || {}), C = /* @__PURE__ */ ((s) => (s.LINK = "link", s))(C || {});
19
- const T = (s) => {
18
+ var _ = /* @__PURE__ */ ((s) => (s.CONVERSATION = "CONVERSATION", s))(_ || {}), y = /* @__PURE__ */ ((s) => (s.ME = "me", s.OTHERS = "others", s))(y || {}), C = /* @__PURE__ */ ((s) => (s.CSV = "text/csv", s.TABLE = "application/dial-ttyd-table", s.PLOTLY = "application/vnd.plotly.v1+json", s.MARKDOWN = "text/markdown", s.JSON = "application/json", s.JPEG = "image/jpeg", s.PNG = "image/png", s.CUSTOM_DATA_GRID = "custom_data_grid", s.CUSTOM_CHART = "custom_chart", s))(C || {}), T = /* @__PURE__ */ ((s) => (s.LINK = "link", s))(T || {});
19
+ const $ = (s) => {
20
20
  var t, r, e, n, o, c;
21
21
  return s.content ? (console.info(`Using direct content format: ${s.content}`), s.content) : (e = (r = (t = s.choices) == null ? void 0 : t[0]) == null ? void 0 : r.delta) != null && e.content ? (console.info(`Using OpenAI delta format: ${s.choices[0].delta.content}`), s.choices[0].delta.content) : (c = (o = (n = s.choices) == null ? void 0 : n[0]) == null ? void 0 : o.message) != null && c.content ? (console.info(
22
22
  `Using complete message format: ${s.choices[0].message.content}`
23
23
  ), s.choices[0].message.content) : (console.info("Unknown SSE data format:", s), null);
24
- }, $ = (s, t, r) => {
24
+ }, p = (s, t, r) => {
25
25
  if (t == null || t(s), r) {
26
- const e = T(s);
26
+ const e = $(s);
27
27
  e && r(e);
28
28
  }
29
- }, p = (s, t) => s.error || s.message || `${t.status} ${t.statusText}`, g = (s, t) => {
29
+ }, g = (s, t) => s.error || s.message || `${t.status} ${t.statusText}`, w = (s, t) => {
30
30
  const r = s == null ? void 0 : s.reduce(
31
31
  (e, n) => (e[n.index] = n, e),
32
32
  {}
@@ -34,36 +34,36 @@ const T = (s) => {
34
34
  return t.forEach((e) => {
35
35
  r[e.index] ? (e.attachments && (r[e.index].attachments = (r[e.index].attachments || []).concat(e.attachments)), e.content && (r[e.index].content = (r[e.index].content || "") + e.content), e.name && (r[e.index].name = (r[e.index].name || "") + e.name), e.status && (r[e.index].status = e.status)) : r[e.index] = e;
36
36
  }), Object.values(r);
37
- }, j = (s, t) => {
37
+ }, k = (s, t) => {
38
38
  const r = structuredClone(s);
39
39
  return t.forEach((e) => {
40
40
  e.errorMessage && (r.errorMessage = e.errorMessage), e.role && (r.role = e.role), e.responseId && (r.responseId = e.responseId), e.content && (r.content = `${r.content || ""}${e.content}`), e.custom_content && (r.custom_content || (r.custom_content = {}), e.custom_content.attachments && (r.custom_content.attachments || (r.custom_content.attachments = []), r.custom_content.attachments = r.custom_content.attachments.concat(
41
41
  e.custom_content.attachments
42
- )), e.custom_content.stages && (r.custom_content.stages || (r.custom_content.stages = []), r.custom_content.stages = g(
42
+ )), e.custom_content.stages && (r.custom_content.stages || (r.custom_content.stages = []), r.custom_content.stages = w(
43
43
  r.custom_content.stages,
44
44
  e.custom_content.stages
45
45
  )), e.custom_content.state && (r.custom_content.state = e.custom_content.state), e.custom_content.form_schema && (r.custom_content.form_schema = e.custom_content.form_schema), e.custom_content.form_value && (r.custom_content.form_value = e.custom_content.form_value));
46
46
  }), r;
47
- }, w = {
47
+ }, q = {
48
48
  CHAT: "/api/chat"
49
- }, q = "application/json", b = "Content-Type", f = "Api-Key", V = "X-CONVERSATION-ID", v = (s) => (s == null ? void 0 : s.toLowerCase().replace(/[^\p{L}\p{N}]+/gu, "-").replace(/^-+|-+$/g, "").replace(/-/g, " ")) || "", S = (s, t, r) => {
49
+ }, b = "application/json", V = "Content-Type", f = "Api-Key", v = "X-CONVERSATION-ID", I = "Ocp-Apim-Subscription-Key", x = (s) => (s == null ? void 0 : s.toLowerCase().replace(/[^\p{L}\p{N}]+/gu, "-").replace(/^-+|-+$/g, "").replace(/-/g, " ")) || "", S = (s, t, r) => {
50
50
  const e = {
51
- [b]: (t == null ? void 0 : t.contentType) || q
51
+ [V]: (t == null ? void 0 : t.contentType) || b
52
52
  };
53
- return t != null && t.jwt ? e.Authorization = `Bearer ${t.jwt}` : s && (e[f] = s), t != null && t.chatReference && (e[V] = t.chatReference), { ...e, ...r };
54
- }, x = (s) => {
53
+ return t != null && t.jwt ? e.Authorization = `Bearer ${t.jwt}` : s && (e[f] = s), t != null && t.chatReference && (e[v] = t.chatReference), { ...e, ...r };
54
+ }, P = (s) => {
55
55
  const t = { ...s };
56
- return t[f] && (t[f] = t[f].substring(0, 8) + "...[REDACTED]"), t.Authorization && (t.Authorization = "Bearer [REDACTED]"), t;
57
- }, P = (s) => ({
56
+ return t[f] && (t[f] = t[f].substring(0, 8) + "...[REDACTED]"), t.Authorization && (t.Authorization = "Bearer [REDACTED]"), t[I] && (t[I] = t[I].substring(0, 8) + "...[REDACTED]"), t;
57
+ }, H = (s) => ({
58
58
  "Content-Type": `multipart/form-data; boundary=${s}`
59
- }), H = (s) => {
59
+ }), D = (s) => {
60
60
  var n;
61
61
  const t = ((n = s.name) == null ? void 0 : n.split("__")) || [], r = t.length > 1 ? t.slice(1).join("__") : s.name;
62
62
  return { modelId: t[0], conversationName: r };
63
63
  }, L = (s) => {
64
- const t = Date.now(), r = v(s.name);
64
+ const t = Date.now(), r = x(s.name);
65
65
  return `${s.folderId}/${r}-${t}`;
66
- }, k = (s) => ({ resourceTypes: [I.CONVERSATION], with: s }), O = async (s, t, r) => await fetch(s, {
66
+ }, K = (s) => ({ resourceTypes: [_.CONVERSATION], with: s }), O = async (s, t, r) => await fetch(s, {
67
67
  method: r.method || "GET",
68
68
  headers: t,
69
69
  body: r != null && r.isFormData && typeof (r == null ? void 0 : r.body) == "string" ? r.body : JSON.stringify(r.body),
@@ -72,10 +72,10 @@ const T = (s) => {
72
72
  function h(s) {
73
73
  return s.split("/").map((t) => encodeURIComponent(t)).join("/");
74
74
  }
75
- function F(s) {
75
+ function B(s) {
76
76
  return s.split("/").map((t) => decodeURIComponent(t)).join("/");
77
77
  }
78
- class D {
78
+ class U {
79
79
  constructor() {
80
80
  this.decoder = new TextDecoder();
81
81
  }
@@ -160,18 +160,18 @@ class D {
160
160
  }
161
161
  }
162
162
  }
163
- const U = new D(), K = async (s, t, r, e, n) => {
163
+ const j = new U(), F = async (s, t, r, e, n) => {
164
164
  const { onMessage: o, onToken: c, onComplete: a, onError: d, model: i, signal: m } = r, A = {
165
165
  conversationId: s,
166
166
  messages: t,
167
167
  model: i,
168
168
  custom_fields: n
169
169
  };
170
- await U.streamChat(
171
- w.CHAT,
170
+ await j.streamChat(
171
+ q.CHAT,
172
172
  A,
173
173
  {
174
- onMessage: (N) => $(N, o, c),
174
+ onMessage: (N) => p(N, o, c),
175
175
  onComplete: a,
176
176
  onError: d,
177
177
  signal: m
@@ -179,7 +179,7 @@ const U = new D(), K = async (s, t, r, e, n) => {
179
179
  e
180
180
  );
181
181
  }, l = (s) => s instanceof Error && s.message.includes("404"), R = (s) => `/v1/conversations/${h(s)}`;
182
- class B {
182
+ class M {
183
183
  constructor(t) {
184
184
  this.client = t;
185
185
  }
@@ -188,7 +188,7 @@ class B {
188
188
  try {
189
189
  return (await this.client.getRequest(o + "/?limit=1000&recursive=false", t).then((a) => a.items || [])).map((a) => {
190
190
  var m;
191
- const { conversationName: d, modelId: i } = H(a);
191
+ const { conversationName: d, modelId: i } = D(a);
192
192
  return {
193
193
  id: ((m = a.url) == null ? void 0 : m.replace("conversations/", "")) || a.name,
194
194
  name: d,
@@ -241,7 +241,7 @@ class B {
241
241
  return await this.client.request(o, n, {
242
242
  method: "PUT",
243
243
  body: d,
244
- headers: P(c),
244
+ headers: H(c),
245
245
  isFormData: !0
246
246
  });
247
247
  } catch (o) {
@@ -398,7 +398,7 @@ class B {
398
398
  });
399
399
  }
400
400
  }
401
- class M {
401
+ class J {
402
402
  constructor(t) {
403
403
  this.config = t, console.info("DialApiClient initialized", {
404
404
  host: t.host || "NOT SET",
@@ -460,7 +460,7 @@ class M {
460
460
  }
461
461
  if (!a.ok) {
462
462
  this.addErrorRequestLog(o, e, a, d, i);
463
- const A = p(i, a);
463
+ const A = g(i, a);
464
464
  throw new Error(`API request failed: ${A}`);
465
465
  }
466
466
  return i;
@@ -502,7 +502,7 @@ class M {
502
502
  const o = {
503
503
  method: e.method || "GET",
504
504
  url: r,
505
- headers: x(n)
505
+ headers: P(n)
506
506
  };
507
507
  e.body && (o.body = e.body), console.info(t, o);
508
508
  }
@@ -530,23 +530,23 @@ class M {
530
530
  }
531
531
  }
532
532
  export {
533
- _ as AttachmentType,
534
- D as ChatStreamSSEClient,
535
- B as ConversationApi,
533
+ C as AttachmentType,
534
+ U as ChatStreamSSEClient,
535
+ M as ConversationApi,
536
536
  u as DIAL_API_ROUTES,
537
- M as DialApiClient,
538
- C as InvitationType,
539
- I as ResourceTypes,
537
+ J as DialApiClient,
538
+ T as InvitationType,
539
+ _ as ResourceTypes,
540
540
  y as ShareTarget,
541
- U as chatStreamSSEClient,
542
- F as decodeApiUrl,
541
+ j as chatStreamSSEClient,
542
+ B as decodeApiUrl,
543
543
  h as encodeApiUrl,
544
544
  L as generateConversationId,
545
- p as getErrorMessage,
546
- k as getSharedConversationsRequest,
547
- $ as handleStreamMessage,
548
- j as mergeMessages,
549
- H as parseConversationName,
545
+ g as getErrorMessage,
546
+ K as getSharedConversationsRequest,
547
+ p as handleStreamMessage,
548
+ k as mergeMessages,
549
+ D as parseConversationName,
550
550
  O as sendRequest,
551
- K as streamChatResponse
551
+ F as streamChatResponse
552
552
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@epam/statgpt-dial-toolkit",
3
- "version": "0.2.0-rc.3",
3
+ "version": "0.2.0-rc.4",
4
4
  "license": "MIT",
5
5
  "exports": {
6
6
  ".": {
@@ -14,7 +14,7 @@
14
14
  "module": "./index.mjs",
15
15
  "types": "./index.d.ts",
16
16
  "dependencies": {
17
- "@epam/statgpt-shared-toolkit": "0.2.0-rc.3",
17
+ "@epam/statgpt-shared-toolkit": "0.2.0-rc.4",
18
18
  "@epam/ai-dial-shared": "^0.34.0"
19
19
  }
20
20
  }