@epam/statgpt-dial-toolkit 0.3.0-rc.10 → 0.3.0-rc.12

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.
@@ -20,6 +20,7 @@ export declare class ConversationApi {
20
20
  getOnboardingFile(filePath: string, token: string): Promise<OnboardingFileSchema | null>;
21
21
  getFileBlob(filePath: string, token: string): Promise<Blob | null>;
22
22
  deleteFile(filePath: string, token: string): Promise<void>;
23
+ putFile(filePath: string, file: Blob, token: string): Promise<void>;
23
24
  createConversation(data: CreateConversationRequest, token: string): Promise<ConversationInfo>;
24
25
  generateConversationLink(token: string, conversationData?: ConversationData): Promise<GeneratedLinkResponse>;
25
26
  getSharedConversations(token: string, requestData?: SharedConversationsRequest): Promise<SharedConversations>;
package/index.cjs CHANGED
@@ -1,3 +1,3 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l="v1",f=`/${l}/ops/resource/share`,d={VERSION:`/${l}`,BUCKET:`/${l}/bucket`,CONVERSATIONS:`/${l}/metadata/conversations`,CONVERSATION_BY_ID:n=>`/${l}/metadata/conversations/${n}`,CHAT:n=>`/openai/deployments/${n}/chat/completions`,MODELS:"/openai/models",CONFIGURATION:n=>`/${l}/deployments/${n}/configuration`,DATASETS_METADATA:n=>`/v1/deployments/${n}/route/metadata/datasets`,SHARE_CONVERSATION:`${f}/create`,SHARE_CONVERSATION_ACCEPT:n=>`/${l}/invitations/${n}?accept=true`,SHARE_CONVERSATION_DETAILS:n=>`/${l}/invitations/${n}`,SHARE_CONVERSATION_LIST:`${f}/list`,SHARE_CONVERSATION_DISCARD:`${f}/discard`,SHARE_CONVERSATION_REVOKE:`${f}/revoke`,RATE:n=>`/${l}/${n}/rate`,RENAME:`/${l}/ops/resource/move`},H={LENGTH:"length",STOP:"stop"},R={MINUTE:"minute",DAILY:"daily",WEEKLY:"weekly",MONTHLY:"monthly"},U={CONTENT_FILTER:"content_filter",500:"500"},x={RUNTIME_ERROR:"runtime_error",RATE_LIMIT_EXCEEDED:"rate_limit_exceeded"},V=[R.MINUTE,R.DAILY,R.WEEKLY,R.MONTHLY],K="statgpt",g={RATE_LIMIT:"rate_limit",UNKNOWN:"unknown"};var O=(n=>(n.CONVERSATION="CONVERSATION",n))(O||{}),N=(n=>(n.ME="me",n.OTHERS="others",n))(N||{}),y=(n=>(n.CSV="text/csv",n.TABLE="application/dial-ttyd-table",n.PLOTLY="application/vnd.plotly.v1+json",n.MARKDOWN="text/markdown",n.JSON="application/json",n.JPEG="image/jpeg",n.PNG="image/png",n.CROSS_DATASET_GRID="cross_dataset_grid",n.CUSTOM_DATA_GRID="custom_data_grid",n.CUSTOM_CHART="custom_chart",n.CUSTOM_CODE_SAMPLE="custom_code_sample",n))(y||{}),$=(n=>(n.LINK="link",n))($||{});const j=n=>n.content?(console.info(`Using direct content format: ${n.content}`),n.content):n.choices?.[0]?.delta?.content?(console.info(`Using OpenAI delta format: ${n.choices[0].delta.content}`),n.choices[0].delta.content):n.choices?.[0]?.message?.content?(console.info(`Using complete message format: ${n.choices[0].message.content}`),n.choices[0].message.content):(console.info("Unknown SSE data format:",n),null),D=(n,t,s)=>{if(t?.(n),s){const e=j(n);e&&s(e)}},v=(n,t)=>n.error||n.message||`${t.status} ${t.statusText}`,k=(n,t)=>{const s=n?.reduce((e,r)=>(e[r.index]=r,e),{});return t.forEach(e=>{s[e.index]?(e.attachments&&(s[e.index].attachments=(s[e.index].attachments||[]).concat(e.attachments)),e.content&&(s[e.index].content=(s[e.index].content||"")+e.content),e.name&&(s[e.index].name=(s[e.index].name||"")+e.name),e.status&&(s[e.index].status=e.status)):s[e.index]=e}),Object.values(s)},F=(n,t)=>{const s=structuredClone(n);return t.forEach(e=>{e.errorMessage&&(s.errorMessage=e.errorMessage),e.role&&(s.role=e.role),e.responseId&&(s.responseId=e.responseId),e.content&&Y(s,e),e.custom_content&&(s.custom_content||(s.custom_content={}),e.custom_content.attachments&&(s.custom_content.attachments||(s.custom_content.attachments=[]),s.custom_content.attachments=s.custom_content.attachments.concat(e.custom_content.attachments)),e.custom_content.stages&&(s.custom_content.stages||(s.custom_content.stages=[]),s.custom_content.stages=k(s.custom_content.stages,e.custom_content.stages)),e.custom_content.state&&(s.custom_content.state=e.custom_content.state),e.custom_content.form_schema&&(s.custom_content.form_schema=e.custom_content.form_schema),e.custom_content.form_value&&(s.custom_content.form_value=e.custom_content.form_value))}),s};function Y(n,t){if(t.content){const s=B(t.content);s!=null?n.content=n.content.slice(0,-s):n.content=`${n.content||""}${t.content}`}}function B(n){const t=n.match(/delete_chars\((\d+)\)/);return t!=null?parseInt(t[1],10):null}const G={CHAT:"/api/chat"},J="application/json",X="Content-Type",T="Api-Key",z="X-CONVERSATION-ID",p="Ocp-Apim-Subscription-Key";class C extends Error{constructor(t){super(t.message),this.isHttpError=!0,this.name="HttpError",this.code=t.code,this.status=t.status,this.details=t.details,this.displayMessage=t.displayMessage}}const W=n=>n?.toLowerCase().replace(/[^\p{L}\p{N}]+/gu,"-").replace(/^-+|-+$/g,"").replace(/-/g," ")||"",A=(n,t,s)=>{const e={[X]:t?.contentType||J};return t?.jwt?e.Authorization=`Bearer ${t.jwt}`:n&&(e[T]=n),t?.chatReference&&(e[z]=t.chatReference),{...e,...s}},Q=n=>{const t={...n};return t[T]&&(t[T]=t[T].substring(0,8)+"...[REDACTED]"),t.Authorization&&(t.Authorization="Bearer [REDACTED]"),t[p]&&(t[p]=t[p].substring(0,8)+"...[REDACTED]"),t},Z=n=>({"Content-Type":`multipart/form-data; boundary=${n}`}),w=n=>{const t=n.name?.split("__")||[],s=t.length>1?t.slice(1).join("__"):n.name;return{modelId:t[0],conversationName:s}},L=n=>{const t=Date.now(),s=W(n.name);return`${n.folderId}/${s}-${t}`},ee=n=>({resourceTypes:[O.CONVERSATION],with:n}),S=async(n,t,s)=>await fetch(n,{method:s.method||"GET",headers:t,body:s?.isFormData&&typeof s?.body=="string"?s.body:JSON.stringify(s.body),signal:s?.signal});function h(n){return n.split("/").map(t=>encodeURIComponent(t)).join("/")}function te(n){return n.split("/").map(t=>decodeURIComponent(t)).join("/")}function b(n){if(n?.kind!==g.RATE_LIMIT||typeof n.retryAfterSeconds!="number")return null;const t=new Date(n.occurredAt).getTime();return Number.isNaN(t)?null:new Date(t+n.retryAfterSeconds*1e3)}function se(n,t=Date.now()){const s=b(n);return s?s.getTime()>t:!1}function ne(n,t="en-GB"){return{date:n.toLocaleDateString(t),time:n.toLocaleTimeString(t,{hour:"2-digit",minute:"2-digit"})}}class q{constructor(){this.decoder=new TextDecoder}async streamChat(t,s,e={},r){const{onMessage:a,onError:o,onComplete:i,signal:c}=e;try{const u=await this.initializeStreamRequest(t,s,c,r);await this.processStreamData(u,a),i?.()}catch(u){this.handleStreamError(u,o)}}async initializeStreamRequest(t,s,e,r){const a=A(void 0,{jwt:r}),o=await S(t,{Accept:"text/event-stream",...a},{method:"POST",body:s,signal:e});if(!o.ok){const i=await o.text();let c={};try{c=JSON.parse(i)}catch{c.error="Failed to parse error body"}throw new C({status:o.status,message:c.error??"No response body"})}if(!o.body)throw new C({message:"No response body",status:o.status});return o.body.getReader()}async processStreamData(t,s){let e="";try{for(;;){const{done:r,value:a}=await t.read();if(r){e.trim()&&this.parseSSEDataLine(e,s);break}const o=this.decoder.decode(a,{stream:!0});e+=o;const i=e.split(`
2
- `);e=i.pop()||"";for(const c of i)this.parseSSEDataLine(c,s)}}finally{t.releaseLock()}}handleStreamError(t,s){const e=t instanceof Error?t:new Error(String(t));throw s?.(e),e}parseSSEDataLine(t,s){const e=t.trim();if(!(!e||e.startsWith(":"))&&e.startsWith("data: ")){const r=e.slice(6);if(r==="[DONE]"){console.info("SSE: Stream completed");return}let a;try{a=JSON.parse(r)}catch(o){console.error(`Failed to parse SSE data: ${r} ${o}`)}s?.(a)}}}const M=new q,re=async(n,t,s,e,r)=>{const{onMessage:a,onToken:o,onComplete:i,onError:c,model:u,signal:m}=s,I={conversationId:n,messages:t,model:u,custom_fields:r};await M.streamChat(G.CHAT,I,{onMessage:P=>D(P,a,o),onComplete:i,onError:c,signal:m},e)},E=n=>n instanceof Error&&n.message.includes("404"),_=n=>`/v1/conversations/${h(n)}`;class oe{constructor(t){this.client=t}async getConversations(t,s,e){const r=`${s?e?`${s}/${e}`:`${s}`:""}`,a=`${d.CONVERSATIONS}/${r}`;try{return(await this.client.getRequest(a+"/?limit=1000&recursive=false",t).then(i=>i.items||[])).map(i=>{const{conversationName:c,modelId:u}=w(i);return{id:i.url?.replace("conversations/","")||i.name,name:c,folderId:r,createdAt:i.createdAt,updatedAt:i.updatedAt,model:{id:u,name:u}}})}catch(o){if(E(o))return[];throw o}}async getConversation(t,s){try{return await this.client.getRequest(_(t),s)}catch(e){if(E(e))return null;throw e}}async getFile(t,s){try{const e=`${d.VERSION}/${h(t)}`;return await this.client.getRequest(e,s)}catch(e){if(E(e))return null;throw e}}async putOnboardingFile(t,s,e,r){try{const a=`${d.VERSION}/${h(s)}`,o="----NodeMultipartBoundary",c=[`--${o}`,`Content-Disposition: form-data; name="file"; filename="${t}"`,"Content-Type: application/json","",JSON.stringify(e),`--${o}--`,""].join(`\r
3
- `);return await this.client.request(a,r,{method:"PUT",body:c,headers:Z(o),isFormData:!0})}catch(a){if(E(a))return null;throw a}}async getOnboardingFile(t,s){try{const e=`${d.VERSION}/${h(t)}`;return await this.client.getRequest(e,s)}catch(e){if(E(e))return null;throw e}}async getFileBlob(t,s){try{const e=`${d.VERSION}/${h(t)}`;return await this.client.requestBlob(e,s,{method:"GET"})}catch(e){if(E(e))return null;throw e}}async deleteFile(t,s){try{const e=`${d.VERSION}/${h(t)}`;await this.client.request(e,s,{method:"DELETE"})}catch(e){if(E(e))return;throw e}}async createConversation(t,s){const e=t?.id||L(t),{name:r,folderId:a,model:o,messages:i,custom_fields:c}=t,u={id:e,name:r,folderId:a,model:o,messages:i||[],selectedAddons:t.selectedAddons||[],prompt:t.prompt||"",temperature:t.temperature||.7,createdAt:Date.now(),updatedAt:Date.now(),custom_fields:c};return await this.client.request(_(e),s,{method:"PUT",body:u}),{id:e,name:r,folderId:a,model:o,createdAt:u.createdAt,updatedAt:u.updatedAt}}async generateConversationLink(t,s){return await this.client.postRequest(d.SHARE_CONVERSATION,t,{body:s})}async getSharedConversations(t,s){return await this.client.postRequest(d.SHARE_CONVERSATION_LIST,t,{body:s})}async revokeSharedConversations(t,s){await this.client.postRequest(d.SHARE_CONVERSATION_REVOKE,t,{body:s})}async updateConversation(t,s,e){const r=await this.getConversation(t,e);if(!r)throw new Error(`Conversation with id ${t} not found`);const a={...r,...s,updatedAt:Date.now()};return await this.client.request(_(t),e,{method:"PUT",body:a})}async deleteConversation(t,s,e){s?.isShared?await this.client.postRequest(d.SHARE_CONVERSATION_DISCARD,e,{body:{resources:[{url:s?.url}]}}):await this.client.request(_(decodeURI(t)),e,{method:"DELETE"})}async streamChat(t,s){const e=t.model.id,r=encodeURIComponent(e),a=`${d.CHAT(r)}?api-version=${this.client.config.version}`,o={messages:t.messages,stream:!0,temperature:.7,max_tokens:4096,custom_fields:t.custom_fields};return await this.client.stream(a,s,{method:"POST",body:o,chatReference:t.conversationId})}async rateResponse(t,s,e,r){return await this.client.postRequest(d.RATE(t),r,{body:{responseId:s,rate:e}})}async renameConversation(t,s,e){return await this.client.postRequest(d.RENAME,e,{body:{sourceUrl:t,destinationUrl:s,overwrite:!0}})}}class ae{constructor(t){this.config=t,console.info("DialApiClient initialized",{host:t.host||"NOT SET",hasApiKey:!!t.apiKey,version:t.version})}async getRequest(t,s,e){return this.request(t,s,{...e,method:"GET"})}async postRequest(t,s,e){return this.request(t,s,{...e,method:"POST"})}async requestBlob(t,s,e){const r=`${this.config.host}${t}`,a={...A(this.config.apiKey,{jwt:s,chatReference:e.chatReference}),...e.headers};try{return(await S(r,a,e)).blob()}catch(o){throw console.error("API Request Exception",{method:e.method,url:r,error:o instanceof Error?o.message:String(o)}),o}}async request(t,s,e){const r=Date.now(),a=`${this.config.host}${t}`,o={...A(this.config.apiKey,{jwt:s,chatReference:e.chatReference}),...e.headers};this.addInfoRequestLog("API Request",a,e,o);try{const i=await S(a,o,e),c=Date.now()-r;let u;const m=await i.text();try{u=m?JSON.parse(m):{}}catch{if(this.addErrorRequestParsing(a,e,i,c,m),!i.ok)throw new Error(`API request failed: ${i.status} ${i.statusText} - ${m.substring(0,100)}`);u={data:m}}if(!i.ok){this.addErrorRequestLog(a,e,i,c,u);const I=v(u,i);throw new Error(`API request failed: ${I}`)}return u}catch(i){const c=Date.now()-r;throw console.error("API Request Exception",{method:e.method,url:a,duration:`${c}ms`,error:i instanceof Error?i.message:String(i)}),i}}async stream(t,s,e){const r=`${this.config.host}${t}`,a=A(this.config.apiKey,{jwt:s,chatReference:e.chatReference},e.headers);this.addInfoRequestLog("Stream Request",r,e,a);const o=await S(r,a,e);if(!o.ok)throw console.error("Stream Request Failed",{method:e.method||"POST",url:r,status:o.status,statusText:o.statusText}),new Error(`Stream request failed: ${o.status} ${o.statusText}`);if(!o.body)throw new Error("No response body for stream");return o.body}addInfoRequestLog(t,s,e,r){const a={method:e.method||"GET",url:s,headers:Q(r)};e.body&&(a.body=e.body),console.info(t,a)}addErrorRequestLog(t,s,e,r,a){console.error("API Request Failed",{method:s.method,url:t,status:e.status,statusText:e.statusText,duration:`${r}ms`,response:a})}addErrorRequestParsing(t,s,e,r,a){console.error("API Response Parse Error",{method:s.method,url:t,status:e.status,statusText:e.statusText,duration:`${r}ms`,responseText:a.substring(0,200),error:"Response is not valid JSON"})}}exports.AttachmentType=y;exports.COMPLETION_FINISH_REASON=H;exports.CUSTOM_VIEW_STATE_KEY=K;exports.ChatStreamSSEClient=q;exports.ConversationApi=oe;exports.DIAL_API_ROUTES=d;exports.DIAL_ERROR_CODES=U;exports.DIAL_ERROR_TYPES=x;exports.DialApiClient=ae;exports.ERROR_CONTEXT_KIND=g;exports.EXCEEDED_LIMIT=R;exports.EXCEEDED_LIMIT_ORDER=V;exports.InvitationType=$;exports.ResourceTypes=O;exports.ShareTarget=N;exports.chatStreamSSEClient=M;exports.decodeApiUrl=te;exports.encodeApiUrl=h;exports.formatDateTime=ne;exports.generateConversationId=L;exports.getErrorMessage=v;exports.getRateLimitRestoreDate=b;exports.getSharedConversationsRequest=ee;exports.handleStreamMessage=D;exports.isRateLimitStillActive=se;exports.mergeMessages=F;exports.parseConversationName=w;exports.sendRequest=S;exports.streamChatResponse=re;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l="v1",f=`/${l}/ops/resource/share`,u={VERSION:`/${l}`,BUCKET:`/${l}/bucket`,CONVERSATIONS:`/${l}/metadata/conversations`,CONVERSATION_BY_ID:s=>`/${l}/metadata/conversations/${s}`,CHAT:s=>`/openai/deployments/${s}/chat/completions`,MODELS:"/openai/models",CONFIGURATION:s=>`/${l}/deployments/${s}/configuration`,DATASETS_METADATA:s=>`/v1/deployments/${s}/route/metadata/datasets`,SHARE_CONVERSATION:`${f}/create`,SHARE_CONVERSATION_ACCEPT:s=>`/${l}/invitations/${s}?accept=true`,SHARE_CONVERSATION_DETAILS:s=>`/${l}/invitations/${s}`,SHARE_CONVERSATION_LIST:`${f}/list`,SHARE_CONVERSATION_DISCARD:`${f}/discard`,SHARE_CONVERSATION_REVOKE:`${f}/revoke`,RATE:s=>`/${l}/${s}/rate`,RENAME:`/${l}/ops/resource/move`},H={LENGTH:"length",STOP:"stop"},R={MINUTE:"minute",DAILY:"daily",WEEKLY:"weekly",MONTHLY:"monthly"},U={CONTENT_FILTER:"content_filter",500:"500"},V={RUNTIME_ERROR:"runtime_error",RATE_LIMIT_EXCEEDED:"rate_limit_exceeded"},x=[R.MINUTE,R.DAILY,R.WEEKLY,R.MONTHLY],F="statgpt",N={RATE_LIMIT:"rate_limit",UNKNOWN:"unknown"};var O=(s=>(s.CONVERSATION="CONVERSATION",s))(O||{}),g=(s=>(s.ME="me",s.OTHERS="others",s))(g||{}),y=(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.CROSS_DATASET_GRID="cross_dataset_grid",s.CUSTOM_DATA_GRID="custom_data_grid",s.CUSTOM_CHART="custom_chart",s.CUSTOM_CODE_SAMPLE="custom_code_sample",s))(y||{}),$=(s=>(s.LINK="link",s))($||{});const K=s=>s.content?(console.info(`Using direct content format: ${s.content}`),s.content):s.choices?.[0]?.delta?.content?(console.info(`Using OpenAI delta format: ${s.choices[0].delta.content}`),s.choices[0].delta.content):s.choices?.[0]?.message?.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),D=(s,t,n)=>{if(t?.(s),n){const e=K(s);e&&n(e)}},v=(s,t)=>s.error||s.message||`${t.status} ${t.statusText}`,j=(s,t)=>{const n=s?.reduce((e,r)=>(e[r.index]=r,e),{});return t.forEach(e=>{n[e.index]?(e.attachments&&(n[e.index].attachments=(n[e.index].attachments||[]).concat(e.attachments)),e.content&&(n[e.index].content=(n[e.index].content||"")+e.content),e.name&&(n[e.index].name=(n[e.index].name||"")+e.name),e.status&&(n[e.index].status=e.status)):n[e.index]=e}),Object.values(n)},k=(s,t)=>{const n=structuredClone(s);return t.forEach(e=>{e.errorMessage&&(n.errorMessage=e.errorMessage),e.role&&(n.role=e.role),e.responseId&&(n.responseId=e.responseId),e.content&&Y(n,e),e.custom_content&&(n.custom_content||(n.custom_content={}),e.custom_content.attachments&&(n.custom_content.attachments||(n.custom_content.attachments=[]),n.custom_content.attachments=n.custom_content.attachments.concat(e.custom_content.attachments)),e.custom_content.stages&&(n.custom_content.stages||(n.custom_content.stages=[]),n.custom_content.stages=j(n.custom_content.stages,e.custom_content.stages)),e.custom_content.state&&(n.custom_content.state=e.custom_content.state),e.custom_content.form_schema&&(n.custom_content.form_schema=e.custom_content.form_schema),e.custom_content.form_value&&(n.custom_content.form_value=e.custom_content.form_value))}),n};function Y(s,t){if(t.content){const n=B(t.content);n!=null?s.content=s.content.slice(0,-n):s.content=`${s.content||""}${t.content}`}}function B(s){const t=s.match(/delete_chars\((\d+)\)/);return t!=null?parseInt(t[1],10):null}const G={CHAT:"/api/chat"},J="application/json",X="Content-Type",T="Api-Key",z="X-CONVERSATION-ID",I="Ocp-Apim-Subscription-Key";class C extends Error{constructor(t){super(t.message),this.isHttpError=!0,this.name="HttpError",this.code=t.code,this.status=t.status,this.details=t.details,this.displayMessage=t.displayMessage}}const W=s=>s?.toLowerCase().replace(/[^\p{L}\p{N}]+/gu,"-").replace(/^-+|-+$/g,"").replace(/-/g," ")||"",p=(s,t,n)=>{const e={};return t?.contentType!==null&&(e[X]=t?.contentType||J),t?.jwt?e.Authorization=`Bearer ${t.jwt}`:s&&(e[T]=s),t?.chatReference&&(e[z]=t.chatReference),{...e,...n}},Q=s=>{const t={...s};return t[T]&&(t[T]=t[T].substring(0,8)+"...[REDACTED]"),t.Authorization&&(t.Authorization="Bearer [REDACTED]"),t[I]&&(t[I]=t[I].substring(0,8)+"...[REDACTED]"),t},Z=s=>({"Content-Type":`multipart/form-data; boundary=${s}`}),w=s=>{const t=s.name?.split("__")||[],n=t.length>1?t.slice(1).join("__"):s.name;return{modelId:t[0],conversationName:n}},L=s=>{const t=Date.now(),n=W(s.name);return`${s.folderId}/${n}-${t}`},ee=s=>({resourceTypes:[O.CONVERSATION],with:s}),S=async(s,t,n)=>{const e=n?.body===void 0?void 0:n?.isFormData?n.body:JSON.stringify(n.body);return await fetch(s,{method:n.method||"GET",headers:t,body:e,signal:n?.signal})};function E(s){return s.split("/").map(t=>encodeURIComponent(t)).join("/")}function te(s){return s.split("/").map(t=>decodeURIComponent(t)).join("/")}function b(s){if(s?.kind!==N.RATE_LIMIT||typeof s.retryAfterSeconds!="number")return null;const t=new Date(s.occurredAt).getTime();return Number.isNaN(t)?null:new Date(t+s.retryAfterSeconds*1e3)}function ne(s,t=Date.now()){const n=b(s);return n?n.getTime()>t:!1}function se(s,t="en-GB"){return{date:s.toLocaleDateString(t),time:s.toLocaleTimeString(t,{hour:"2-digit",minute:"2-digit"})}}class q{constructor(){this.decoder=new TextDecoder}async streamChat(t,n,e={},r){const{onMessage:a,onError:o,onComplete:i,signal:c}=e;try{const d=await this.initializeStreamRequest(t,n,c,r);await this.processStreamData(d,a),i?.()}catch(d){this.handleStreamError(d,o)}}async initializeStreamRequest(t,n,e,r){const a=p(void 0,{jwt:r}),o=await S(t,{Accept:"text/event-stream",...a},{method:"POST",body:n,signal:e});if(!o.ok){const i=await o.text();let c={};try{c=JSON.parse(i)}catch{c.error="Failed to parse error body"}throw new C({status:o.status,message:c.error??"No response body"})}if(!o.body)throw new C({message:"No response body",status:o.status});return o.body.getReader()}async processStreamData(t,n){let e="";try{for(;;){const{done:r,value:a}=await t.read();if(r){e.trim()&&this.parseSSEDataLine(e,n);break}const o=this.decoder.decode(a,{stream:!0});e+=o;const i=e.split(`
2
+ `);e=i.pop()||"";for(const c of i)this.parseSSEDataLine(c,n)}}finally{t.releaseLock()}}handleStreamError(t,n){const e=t instanceof Error?t:new Error(String(t));throw n?.(e),e}parseSSEDataLine(t,n){const e=t.trim();if(!(!e||e.startsWith(":"))&&e.startsWith("data: ")){const r=e.slice(6);if(r==="[DONE]"){console.info("SSE: Stream completed");return}let a;try{a=JSON.parse(r)}catch(o){console.error(`Failed to parse SSE data: ${r} ${o}`)}n?.(a)}}}const M=new q,re=async(s,t,n,e,r)=>{const{onMessage:a,onToken:o,onComplete:i,onError:c,model:d,signal:h}=n,A={conversationId:s,messages:t,model:d,custom_fields:r};await M.streamChat(G.CHAT,A,{onMessage:P=>D(P,a,o),onComplete:i,onError:c,signal:h},e)},m=s=>s instanceof Error&&s.message.includes("404"),_=s=>`/v1/conversations/${E(s)}`;class oe{constructor(t){this.client=t}async getConversations(t,n,e){const r=`${n?e?`${n}/${e}`:`${n}`:""}`,a=`${u.CONVERSATIONS}/${r}`;try{return(await this.client.getRequest(a+"/?limit=1000&recursive=false",t).then(i=>i.items||[])).map(i=>{const{conversationName:c,modelId:d}=w(i);return{id:i.url?.replace("conversations/","")||i.name,name:c,folderId:r,createdAt:i.createdAt,updatedAt:i.updatedAt,model:{id:d,name:d}}})}catch(o){if(m(o))return[];throw o}}async getConversation(t,n){try{return await this.client.getRequest(_(t),n)}catch(e){if(m(e))return null;throw e}}async getFile(t,n){try{const e=`${u.VERSION}/${E(t)}`;return await this.client.getRequest(e,n)}catch(e){if(m(e))return null;throw e}}async putOnboardingFile(t,n,e,r){try{const a=`${u.VERSION}/${E(n)}`,o="----NodeMultipartBoundary",c=[`--${o}`,`Content-Disposition: form-data; name="file"; filename="${t}"`,"Content-Type: application/json","",JSON.stringify(e),`--${o}--`,""].join(`\r
3
+ `);return await this.client.request(a,r,{method:"PUT",body:c,headers:Z(o),isFormData:!0})}catch(a){if(m(a))return null;throw a}}async getOnboardingFile(t,n){try{const e=`${u.VERSION}/${E(t)}`;return await this.client.getRequest(e,n)}catch(e){if(m(e))return null;throw e}}async getFileBlob(t,n){try{const e=`${u.VERSION}/${E(t)}`;return await this.client.requestBlob(e,n,{method:"GET"})}catch(e){if(m(e))return null;throw e}}async deleteFile(t,n){try{const e=`${u.VERSION}/${E(t)}`;await this.client.request(e,n,{method:"DELETE"})}catch(e){if(m(e))return;throw e}}async putFile(t,n,e){try{const r=`${u.VERSION}/${E(t)}`,a=new FormData,o=decodeURIComponent(t.split("/").at(-1)??"file");a.append("attachment",n,o),await this.client.request(r,e,{method:"PUT",body:a,isFormData:!0})}catch(r){if(m(r))return;throw r}}async createConversation(t,n){const e=t?.id||L(t),{name:r,folderId:a,model:o,messages:i,custom_fields:c}=t,d={id:e,name:r,folderId:a,model:o,messages:i||[],selectedAddons:t.selectedAddons||[],prompt:t.prompt||"",temperature:t.temperature||.7,createdAt:Date.now(),updatedAt:Date.now(),custom_fields:c};return await this.client.request(_(e),n,{method:"PUT",body:d}),{id:e,name:r,folderId:a,model:o,createdAt:d.createdAt,updatedAt:d.updatedAt}}async generateConversationLink(t,n){return await this.client.postRequest(u.SHARE_CONVERSATION,t,{body:n})}async getSharedConversations(t,n){return await this.client.postRequest(u.SHARE_CONVERSATION_LIST,t,{body:n})}async revokeSharedConversations(t,n){await this.client.postRequest(u.SHARE_CONVERSATION_REVOKE,t,{body:n})}async updateConversation(t,n,e){const r=await this.getConversation(t,e);if(!r)throw new Error(`Conversation with id ${t} not found`);const a={...r,...n,updatedAt:Date.now()};return await this.client.request(_(t),e,{method:"PUT",body:a})}async deleteConversation(t,n,e){n?.isShared?await this.client.postRequest(u.SHARE_CONVERSATION_DISCARD,e,{body:{resources:[{url:n?.url}]}}):await this.client.request(_(decodeURI(t)),e,{method:"DELETE"})}async streamChat(t,n){const e=t.model.id,r=encodeURIComponent(e),a=`${u.CHAT(r)}?api-version=${this.client.config.version}`,o={messages:t.messages,stream:!0,temperature:.7,max_tokens:4096,custom_fields:t.custom_fields};return await this.client.stream(a,n,{method:"POST",body:o,chatReference:t.conversationId})}async rateResponse(t,n,e,r){return await this.client.postRequest(u.RATE(t),r,{body:{responseId:n,rate:e}})}async renameConversation(t,n,e){return await this.client.postRequest(u.RENAME,e,{body:{sourceUrl:t,destinationUrl:n,overwrite:!0}})}}class ae{constructor(t){this.config=t,console.info("DialApiClient initialized",{host:t.host||"NOT SET",hasApiKey:!!t.apiKey,version:t.version})}async getRequest(t,n,e){return this.request(t,n,{...e,method:"GET"})}async postRequest(t,n,e){return this.request(t,n,{...e,method:"POST"})}async requestBlob(t,n,e){const r=`${this.config.host}${t}`,a={...p(this.config.apiKey,{jwt:n,chatReference:e.chatReference,contentType:e.isFormData?null:void 0}),...e.headers};try{return(await S(r,a,e)).blob()}catch(o){throw console.error("API Request Exception",{method:e.method,url:r,error:o instanceof Error?o.message:String(o)}),o}}async request(t,n,e){const r=Date.now(),a=`${this.config.host}${t}`,o={...p(this.config.apiKey,{jwt:n,chatReference:e.chatReference,contentType:e.isFormData?null:void 0}),...e.headers};this.addInfoRequestLog("API Request",a,e,o);try{const i=await S(a,o,e),c=Date.now()-r;let d;const h=await i.text();try{d=h?JSON.parse(h):{}}catch{if(this.addErrorRequestParsing(a,e,i,c,h),!i.ok)throw new Error(`API request failed: ${i.status} ${i.statusText} - ${h.substring(0,100)}`);d={data:h}}if(!i.ok){this.addErrorRequestLog(a,e,i,c,d);const A=v(d,i);throw new Error(`API request failed: ${A}`)}return d}catch(i){const c=Date.now()-r;throw console.error("API Request Exception",{method:e.method,url:a,duration:`${c}ms`,error:i instanceof Error?i.message:String(i)}),i}}async stream(t,n,e){const r=`${this.config.host}${t}`,a=p(this.config.apiKey,{jwt:n,chatReference:e.chatReference,contentType:e.isFormData?null:void 0},e.headers);this.addInfoRequestLog("Stream Request",r,e,a);const o=await S(r,a,e);if(!o.ok)throw console.error("Stream Request Failed",{method:e.method||"POST",url:r,status:o.status,statusText:o.statusText}),new Error(`Stream request failed: ${o.status} ${o.statusText}`);if(!o.body)throw new Error("No response body for stream");return o.body}addInfoRequestLog(t,n,e,r){const a={method:e.method||"GET",url:n,headers:Q(r)};e.body&&(a.body=e.body),console.info(t,a)}addErrorRequestLog(t,n,e,r,a){console.error("API Request Failed",{method:n.method,url:t,status:e.status,statusText:e.statusText,duration:`${r}ms`,response:a})}addErrorRequestParsing(t,n,e,r,a){console.error("API Response Parse Error",{method:n.method,url:t,status:e.status,statusText:e.statusText,duration:`${r}ms`,responseText:a.substring(0,200),error:"Response is not valid JSON"})}}exports.AttachmentType=y;exports.COMPLETION_FINISH_REASON=H;exports.CUSTOM_VIEW_STATE_KEY=F;exports.ChatStreamSSEClient=q;exports.ConversationApi=oe;exports.DIAL_API_ROUTES=u;exports.DIAL_ERROR_CODES=U;exports.DIAL_ERROR_TYPES=V;exports.DialApiClient=ae;exports.ERROR_CONTEXT_KIND=N;exports.EXCEEDED_LIMIT=R;exports.EXCEEDED_LIMIT_ORDER=x;exports.InvitationType=$;exports.ResourceTypes=O;exports.ShareTarget=g;exports.chatStreamSSEClient=M;exports.decodeApiUrl=te;exports.encodeApiUrl=E;exports.formatDateTime=se;exports.generateConversationId=L;exports.getErrorMessage=v;exports.getRateLimitRestoreDate=b;exports.getSharedConversationsRequest=ee;exports.handleStreamMessage=D;exports.isRateLimitStillActive=ne;exports.mergeMessages=k;exports.parseConversationName=w;exports.sendRequest=S;exports.streamChatResponse=re;
package/index.mjs CHANGED
@@ -2,18 +2,18 @@ const h = "/v1/ops/resource/share", d = {
2
2
  VERSION: "/v1",
3
3
  BUCKET: "/v1/bucket",
4
4
  CONVERSATIONS: "/v1/metadata/conversations",
5
- CONVERSATION_BY_ID: (n) => `/v1/metadata/conversations/${n}`,
6
- CHAT: (n) => `/openai/deployments/${n}/chat/completions`,
5
+ CONVERSATION_BY_ID: (s) => `/v1/metadata/conversations/${s}`,
6
+ CHAT: (s) => `/openai/deployments/${s}/chat/completions`,
7
7
  MODELS: "/openai/models",
8
- CONFIGURATION: (n) => `/v1/deployments/${n}/configuration`,
9
- DATASETS_METADATA: (n) => `/v1/deployments/${n}/route/metadata/datasets`,
8
+ CONFIGURATION: (s) => `/v1/deployments/${s}/configuration`,
9
+ DATASETS_METADATA: (s) => `/v1/deployments/${s}/route/metadata/datasets`,
10
10
  SHARE_CONVERSATION: `${h}/create`,
11
- SHARE_CONVERSATION_ACCEPT: (n) => `/v1/invitations/${n}?accept=true`,
12
- SHARE_CONVERSATION_DETAILS: (n) => `/v1/invitations/${n}`,
11
+ SHARE_CONVERSATION_ACCEPT: (s) => `/v1/invitations/${s}?accept=true`,
12
+ SHARE_CONVERSATION_DETAILS: (s) => `/v1/invitations/${s}`,
13
13
  SHARE_CONVERSATION_LIST: `${h}/list`,
14
14
  SHARE_CONVERSATION_DISCARD: `${h}/discard`,
15
15
  SHARE_CONVERSATION_REVOKE: `${h}/revoke`,
16
- RATE: (n) => `/v1/${n}/rate`,
16
+ RATE: (s) => `/v1/${s}/rate`,
17
17
  RENAME: "/v1/ops/resource/move"
18
18
  }, G = {
19
19
  LENGTH: "length",
@@ -38,93 +38,94 @@ const h = "/v1/ops/resource/share", d = {
38
38
  RATE_LIMIT: "rate_limit",
39
39
  UNKNOWN: "unknown"
40
40
  };
41
- var p = /* @__PURE__ */ ((n) => (n.CONVERSATION = "CONVERSATION", n))(p || {}), g = /* @__PURE__ */ ((n) => (n.ME = "me", n.OTHERS = "others", n))(g || {}), y = /* @__PURE__ */ ((n) => (n.CSV = "text/csv", n.TABLE = "application/dial-ttyd-table", n.PLOTLY = "application/vnd.plotly.v1+json", n.MARKDOWN = "text/markdown", n.JSON = "application/json", n.JPEG = "image/jpeg", n.PNG = "image/png", n.CROSS_DATASET_GRID = "cross_dataset_grid", n.CUSTOM_DATA_GRID = "custom_data_grid", n.CUSTOM_CHART = "custom_chart", n.CUSTOM_CODE_SAMPLE = "custom_code_sample", n))(y || {}), $ = /* @__PURE__ */ ((n) => (n.LINK = "link", n))($ || {});
42
- const w = (n) => n.content ? (console.info(`Using direct content format: ${n.content}`), n.content) : n.choices?.[0]?.delta?.content ? (console.info(`Using OpenAI delta format: ${n.choices[0].delta.content}`), n.choices[0].delta.content) : n.choices?.[0]?.message?.content ? (console.info(
43
- `Using complete message format: ${n.choices[0].message.content}`
44
- ), n.choices[0].message.content) : (console.info("Unknown SSE data format:", n), null), v = (n, t, s) => {
45
- if (t?.(n), s) {
46
- const e = w(n);
47
- e && s(e);
48
- }
49
- }, D = (n, t) => n.error || n.message || `${t.status} ${t.statusText}`, b = (n, t) => {
50
- const s = n?.reduce(
41
+ var A = /* @__PURE__ */ ((s) => (s.CONVERSATION = "CONVERSATION", s))(A || {}), y = /* @__PURE__ */ ((s) => (s.ME = "me", s.OTHERS = "others", s))(y || {}), g = /* @__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.CROSS_DATASET_GRID = "cross_dataset_grid", s.CUSTOM_DATA_GRID = "custom_data_grid", s.CUSTOM_CHART = "custom_chart", s.CUSTOM_CODE_SAMPLE = "custom_code_sample", s))(g || {}), $ = /* @__PURE__ */ ((s) => (s.LINK = "link", s))($ || {});
42
+ const w = (s) => s.content ? (console.info(`Using direct content format: ${s.content}`), s.content) : s.choices?.[0]?.delta?.content ? (console.info(`Using OpenAI delta format: ${s.choices[0].delta.content}`), s.choices[0].delta.content) : s.choices?.[0]?.message?.content ? (console.info(
43
+ `Using complete message format: ${s.choices[0].message.content}`
44
+ ), s.choices[0].message.content) : (console.info("Unknown SSE data format:", s), null), v = (s, t, n) => {
45
+ if (t?.(s), n) {
46
+ const e = w(s);
47
+ e && n(e);
48
+ }
49
+ }, D = (s, t) => s.error || s.message || `${t.status} ${t.statusText}`, b = (s, t) => {
50
+ const n = s?.reduce(
51
51
  (e, r) => (e[r.index] = r, e),
52
52
  {}
53
53
  );
54
54
  return t.forEach((e) => {
55
- s[e.index] ? (e.attachments && (s[e.index].attachments = (s[e.index].attachments || []).concat(e.attachments)), e.content && (s[e.index].content = (s[e.index].content || "") + e.content), e.name && (s[e.index].name = (s[e.index].name || "") + e.name), e.status && (s[e.index].status = e.status)) : s[e.index] = e;
56
- }), Object.values(s);
57
- }, Q = (n, t) => {
58
- const s = structuredClone(n);
55
+ n[e.index] ? (e.attachments && (n[e.index].attachments = (n[e.index].attachments || []).concat(e.attachments)), e.content && (n[e.index].content = (n[e.index].content || "") + e.content), e.name && (n[e.index].name = (n[e.index].name || "") + e.name), e.status && (n[e.index].status = e.status)) : n[e.index] = e;
56
+ }), Object.values(n);
57
+ }, Q = (s, t) => {
58
+ const n = structuredClone(s);
59
59
  return t.forEach((e) => {
60
- e.errorMessage && (s.errorMessage = e.errorMessage), e.role && (s.role = e.role), e.responseId && (s.responseId = e.responseId), e.content && q(s, e), e.custom_content && (s.custom_content || (s.custom_content = {}), e.custom_content.attachments && (s.custom_content.attachments || (s.custom_content.attachments = []), s.custom_content.attachments = s.custom_content.attachments.concat(
60
+ e.errorMessage && (n.errorMessage = e.errorMessage), e.role && (n.role = e.role), e.responseId && (n.responseId = e.responseId), e.content && q(n, e), e.custom_content && (n.custom_content || (n.custom_content = {}), e.custom_content.attachments && (n.custom_content.attachments || (n.custom_content.attachments = []), n.custom_content.attachments = n.custom_content.attachments.concat(
61
61
  e.custom_content.attachments
62
- )), e.custom_content.stages && (s.custom_content.stages || (s.custom_content.stages = []), s.custom_content.stages = b(
63
- s.custom_content.stages,
62
+ )), e.custom_content.stages && (n.custom_content.stages || (n.custom_content.stages = []), n.custom_content.stages = b(
63
+ n.custom_content.stages,
64
64
  e.custom_content.stages
65
- )), e.custom_content.state && (s.custom_content.state = e.custom_content.state), e.custom_content.form_schema && (s.custom_content.form_schema = e.custom_content.form_schema), e.custom_content.form_value && (s.custom_content.form_value = e.custom_content.form_value));
66
- }), s;
65
+ )), e.custom_content.state && (n.custom_content.state = e.custom_content.state), e.custom_content.form_schema && (n.custom_content.form_schema = e.custom_content.form_schema), e.custom_content.form_value && (n.custom_content.form_value = e.custom_content.form_value));
66
+ }), n;
67
67
  };
68
- function q(n, t) {
68
+ function q(s, t) {
69
69
  if (t.content) {
70
- const s = L(t.content);
71
- s != null ? n.content = n.content.slice(0, -s) : n.content = `${n.content || ""}${t.content}`;
70
+ const n = L(t.content);
71
+ n != null ? s.content = s.content.slice(0, -n) : s.content = `${s.content || ""}${t.content}`;
72
72
  }
73
73
  }
74
- function L(n) {
75
- const t = n.match(/delete_chars\((\d+)\)/);
74
+ function L(s) {
75
+ const t = s.match(/delete_chars\((\d+)\)/);
76
76
  return t != null ? parseInt(t[1], 10) : null;
77
77
  }
78
78
  const V = {
79
79
  CHAT: "/api/chat"
80
- }, M = "application/json", P = "Content-Type", S = "Api-Key", H = "X-CONVERSATION-ID", A = "Ocp-Apim-Subscription-Key";
81
- class T extends Error {
80
+ }, M = "application/json", P = "Content-Type", S = "Api-Key", H = "X-CONVERSATION-ID", T = "Ocp-Apim-Subscription-Key";
81
+ class p extends Error {
82
82
  constructor(t) {
83
83
  super(t.message), this.isHttpError = !0, this.name = "HttpError", this.code = t.code, this.status = t.status, this.details = t.details, this.displayMessage = t.displayMessage;
84
84
  }
85
85
  }
86
- const x = (n) => n?.toLowerCase().replace(/[^\p{L}\p{N}]+/gu, "-").replace(/^-+|-+$/g, "").replace(/-/g, " ") || "", _ = (n, t, s) => {
87
- const e = {
88
- [P]: t?.contentType || M
89
- };
90
- return t?.jwt ? e.Authorization = `Bearer ${t.jwt}` : n && (e[S] = n), t?.chatReference && (e[H] = t.chatReference), { ...e, ...s };
91
- }, U = (n) => {
92
- const t = { ...n };
93
- return t[S] && (t[S] = t[S].substring(0, 8) + "...[REDACTED]"), t.Authorization && (t.Authorization = "Bearer [REDACTED]"), t[A] && (t[A] = t[A].substring(0, 8) + "...[REDACTED]"), t;
94
- }, K = (n) => ({
95
- "Content-Type": `multipart/form-data; boundary=${n}`
96
- }), j = (n) => {
97
- const t = n.name?.split("__") || [], s = t.length > 1 ? t.slice(1).join("__") : n.name;
98
- return { modelId: t[0], conversationName: s };
99
- }, k = (n) => {
100
- const t = Date.now(), s = x(n.name);
101
- return `${n.folderId}/${s}-${t}`;
102
- }, Z = (n) => ({ resourceTypes: [p.CONVERSATION], with: n }), I = async (n, t, s) => await fetch(n, {
103
- method: s.method || "GET",
104
- headers: t,
105
- body: s?.isFormData && typeof s?.body == "string" ? s.body : JSON.stringify(s.body),
106
- signal: s?.signal
107
- });
108
- function E(n) {
109
- return n.split("/").map((t) => encodeURIComponent(t)).join("/");
86
+ const x = (s) => s?.toLowerCase().replace(/[^\p{L}\p{N}]+/gu, "-").replace(/^-+|-+$/g, "").replace(/-/g, " ") || "", _ = (s, t, n) => {
87
+ const e = {};
88
+ return t?.contentType !== null && (e[P] = t?.contentType || M), t?.jwt ? e.Authorization = `Bearer ${t.jwt}` : s && (e[S] = s), t?.chatReference && (e[H] = t.chatReference), { ...e, ...n };
89
+ }, U = (s) => {
90
+ const t = { ...s };
91
+ return t[S] && (t[S] = t[S].substring(0, 8) + "...[REDACTED]"), t.Authorization && (t.Authorization = "Bearer [REDACTED]"), t[T] && (t[T] = t[T].substring(0, 8) + "...[REDACTED]"), t;
92
+ }, F = (s) => ({
93
+ "Content-Type": `multipart/form-data; boundary=${s}`
94
+ }), K = (s) => {
95
+ const t = s.name?.split("__") || [], n = t.length > 1 ? t.slice(1).join("__") : s.name;
96
+ return { modelId: t[0], conversationName: n };
97
+ }, j = (s) => {
98
+ const t = Date.now(), n = x(s.name);
99
+ return `${s.folderId}/${n}-${t}`;
100
+ }, Z = (s) => ({ resourceTypes: [A.CONVERSATION], with: s }), I = async (s, t, n) => {
101
+ const e = n?.body === void 0 ? void 0 : n?.isFormData ? n.body : JSON.stringify(n.body);
102
+ return await fetch(s, {
103
+ method: n.method || "GET",
104
+ headers: t,
105
+ body: e,
106
+ signal: n?.signal
107
+ });
108
+ };
109
+ function E(s) {
110
+ return s.split("/").map((t) => encodeURIComponent(t)).join("/");
110
111
  }
111
- function ee(n) {
112
- return n.split("/").map((t) => decodeURIComponent(t)).join("/");
112
+ function ee(s) {
113
+ return s.split("/").map((t) => decodeURIComponent(t)).join("/");
113
114
  }
114
- function F(n) {
115
- if (n?.kind !== C.RATE_LIMIT || typeof n.retryAfterSeconds != "number")
115
+ function k(s) {
116
+ if (s?.kind !== C.RATE_LIMIT || typeof s.retryAfterSeconds != "number")
116
117
  return null;
117
- const t = new Date(n.occurredAt).getTime();
118
- return Number.isNaN(t) ? null : new Date(t + n.retryAfterSeconds * 1e3);
118
+ const t = new Date(s.occurredAt).getTime();
119
+ return Number.isNaN(t) ? null : new Date(t + s.retryAfterSeconds * 1e3);
119
120
  }
120
- function te(n, t = Date.now()) {
121
- const s = F(n);
122
- return s ? s.getTime() > t : !1;
121
+ function te(s, t = Date.now()) {
122
+ const n = k(s);
123
+ return n ? n.getTime() > t : !1;
123
124
  }
124
- function se(n, t = "en-GB") {
125
+ function ne(s, t = "en-GB") {
125
126
  return {
126
- date: n.toLocaleDateString(t),
127
- time: n.toLocaleTimeString(t, {
127
+ date: s.toLocaleDateString(t),
128
+ time: s.toLocaleTimeString(t, {
128
129
  hour: "2-digit",
129
130
  minute: "2-digit"
130
131
  })
@@ -134,12 +135,12 @@ class Y {
134
135
  constructor() {
135
136
  this.decoder = new TextDecoder();
136
137
  }
137
- async streamChat(t, s, e = {}, r) {
138
+ async streamChat(t, n, e = {}, r) {
138
139
  const { onMessage: a, onError: o, onComplete: c, signal: i } = e;
139
140
  try {
140
141
  const u = await this.initializeStreamRequest(
141
142
  t,
142
- s,
143
+ n,
143
144
  i,
144
145
  r
145
146
  );
@@ -148,7 +149,7 @@ class Y {
148
149
  this.handleStreamError(u, o);
149
150
  }
150
151
  }
151
- async initializeStreamRequest(t, s, e, r) {
152
+ async initializeStreamRequest(t, n, e, r) {
152
153
  const a = _(void 0, {
153
154
  jwt: r
154
155
  }), o = await I(
@@ -159,7 +160,7 @@ class Y {
159
160
  },
160
161
  {
161
162
  method: "POST",
162
- body: s,
163
+ body: n,
163
164
  signal: e
164
165
  }
165
166
  );
@@ -171,25 +172,25 @@ class Y {
171
172
  } catch {
172
173
  i.error = "Failed to parse error body";
173
174
  }
174
- throw new T({
175
+ throw new p({
175
176
  status: o.status,
176
177
  message: i.error ?? "No response body"
177
178
  });
178
179
  }
179
180
  if (!o.body)
180
- throw new T({
181
+ throw new p({
181
182
  message: "No response body",
182
183
  status: o.status
183
184
  });
184
185
  return o.body.getReader();
185
186
  }
186
- async processStreamData(t, s) {
187
+ async processStreamData(t, n) {
187
188
  let e = "";
188
189
  try {
189
190
  for (; ; ) {
190
191
  const { done: r, value: a } = await t.read();
191
192
  if (r) {
192
- e.trim() && this.parseSSEDataLine(e, s);
193
+ e.trim() && this.parseSSEDataLine(e, n);
193
194
  break;
194
195
  }
195
196
  const o = this.decoder.decode(a, { stream: !0 });
@@ -198,17 +199,17 @@ class Y {
198
199
  `);
199
200
  e = c.pop() || "";
200
201
  for (const i of c)
201
- this.parseSSEDataLine(i, s);
202
+ this.parseSSEDataLine(i, n);
202
203
  }
203
204
  } finally {
204
205
  t.releaseLock();
205
206
  }
206
207
  }
207
- handleStreamError(t, s) {
208
+ handleStreamError(t, n) {
208
209
  const e = t instanceof Error ? t : new Error(String(t));
209
- throw s?.(e), e;
210
+ throw n?.(e), e;
210
211
  }
211
- parseSSEDataLine(t, s) {
212
+ parseSSEDataLine(t, n) {
212
213
  const e = t.trim();
213
214
  if (!(!e || e.startsWith(":")) && e.startsWith("data: ")) {
214
215
  const r = e.slice(6);
@@ -222,13 +223,13 @@ class Y {
222
223
  } catch (o) {
223
224
  console.error(`Failed to parse SSE data: ${r} ${o}`);
224
225
  }
225
- s?.(a);
226
+ n?.(a);
226
227
  }
227
228
  }
228
229
  }
229
- const B = new Y(), ne = async (n, t, s, e, r) => {
230
- const { onMessage: a, onToken: o, onComplete: c, onError: i, model: u, signal: l } = s, O = {
231
- conversationId: n,
230
+ const B = new Y(), se = async (s, t, n, e, r) => {
231
+ const { onMessage: a, onToken: o, onComplete: c, onError: i, model: u, signal: m } = n, O = {
232
+ conversationId: s,
232
233
  messages: t,
233
234
  model: u,
234
235
  custom_fields: r
@@ -240,20 +241,20 @@ const B = new Y(), ne = async (n, t, s, e, r) => {
240
241
  onMessage: (N) => v(N, a, o),
241
242
  onComplete: c,
242
243
  onError: i,
243
- signal: l
244
+ signal: m
244
245
  },
245
246
  e
246
247
  );
247
- }, m = (n) => n instanceof Error && n.message.includes("404"), f = (n) => `/v1/conversations/${E(n)}`;
248
+ }, l = (s) => s instanceof Error && s.message.includes("404"), f = (s) => `/v1/conversations/${E(s)}`;
248
249
  class re {
249
250
  constructor(t) {
250
251
  this.client = t;
251
252
  }
252
- async getConversations(t, s, e) {
253
- const r = `${s ? e ? `${s}/${e}` : `${s}` : ""}`, a = `${d.CONVERSATIONS}/${r}`;
253
+ async getConversations(t, n, e) {
254
+ const r = `${n ? e ? `${n}/${e}` : `${n}` : ""}`, a = `${d.CONVERSATIONS}/${r}`;
254
255
  try {
255
256
  return (await this.client.getRequest(a + "/?limit=1000&recursive=false", t).then((c) => c.items || [])).map((c) => {
256
- const { conversationName: i, modelId: u } = j(c);
257
+ const { conversationName: i, modelId: u } = K(c);
257
258
  return {
258
259
  id: c.url?.replace("conversations/", "") || c.name,
259
260
  name: i,
@@ -264,36 +265,36 @@ class re {
264
265
  };
265
266
  });
266
267
  } catch (o) {
267
- if (m(o))
268
+ if (l(o))
268
269
  return [];
269
270
  throw o;
270
271
  }
271
272
  }
272
- async getConversation(t, s) {
273
+ async getConversation(t, n) {
273
274
  try {
274
275
  return await this.client.getRequest(
275
276
  f(t),
276
- s
277
+ n
277
278
  );
278
279
  } catch (e) {
279
- if (m(e))
280
+ if (l(e))
280
281
  return null;
281
282
  throw e;
282
283
  }
283
284
  }
284
- async getFile(t, s) {
285
+ async getFile(t, n) {
285
286
  try {
286
287
  const e = `${d.VERSION}/${E(t)}`;
287
- return await this.client.getRequest(e, s);
288
+ return await this.client.getRequest(e, n);
288
289
  } catch (e) {
289
- if (m(e))
290
+ if (l(e))
290
291
  return null;
291
292
  throw e;
292
293
  }
293
294
  }
294
- async putOnboardingFile(t, s, e, r) {
295
+ async putOnboardingFile(t, n, e, r) {
295
296
  try {
296
- const a = `${d.VERSION}/${E(s)}`, o = "----NodeMultipartBoundary", i = [
297
+ const a = `${d.VERSION}/${E(n)}`, o = "----NodeMultipartBoundary", i = [
297
298
  `--${o}`,
298
299
  `Content-Disposition: form-data; name="file"; filename="${t}"`,
299
300
  "Content-Type: application/json",
@@ -306,47 +307,61 @@ class re {
306
307
  return await this.client.request(a, r, {
307
308
  method: "PUT",
308
309
  body: i,
309
- headers: K(o),
310
+ headers: F(o),
310
311
  isFormData: !0
311
312
  });
312
313
  } catch (a) {
313
- if (m(a))
314
+ if (l(a))
314
315
  return null;
315
316
  throw a;
316
317
  }
317
318
  }
318
- async getOnboardingFile(t, s) {
319
+ async getOnboardingFile(t, n) {
319
320
  try {
320
321
  const e = `${d.VERSION}/${E(t)}`;
321
- return await this.client.getRequest(e, s);
322
+ return await this.client.getRequest(e, n);
322
323
  } catch (e) {
323
- if (m(e))
324
+ if (l(e))
324
325
  return null;
325
326
  throw e;
326
327
  }
327
328
  }
328
- async getFileBlob(t, s) {
329
+ async getFileBlob(t, n) {
329
330
  try {
330
331
  const e = `${d.VERSION}/${E(t)}`;
331
- return await this.client.requestBlob(e, s, { method: "GET" });
332
+ return await this.client.requestBlob(e, n, { method: "GET" });
332
333
  } catch (e) {
333
- if (m(e))
334
+ if (l(e))
334
335
  return null;
335
336
  throw e;
336
337
  }
337
338
  }
338
- async deleteFile(t, s) {
339
+ async deleteFile(t, n) {
339
340
  try {
340
341
  const e = `${d.VERSION}/${E(t)}`;
341
- await this.client.request(e, s, { method: "DELETE" });
342
+ await this.client.request(e, n, { method: "DELETE" });
342
343
  } catch (e) {
343
- if (m(e))
344
+ if (l(e))
344
345
  return;
345
346
  throw e;
346
347
  }
347
348
  }
348
- async createConversation(t, s) {
349
- const e = t?.id || k(t), { name: r, folderId: a, model: o, messages: c, custom_fields: i } = t, u = {
349
+ async putFile(t, n, e) {
350
+ try {
351
+ const r = `${d.VERSION}/${E(t)}`, a = new FormData(), o = decodeURIComponent(t.split("/").at(-1) ?? "file");
352
+ a.append("attachment", n, o), await this.client.request(r, e, {
353
+ method: "PUT",
354
+ body: a,
355
+ isFormData: !0
356
+ });
357
+ } catch (r) {
358
+ if (l(r))
359
+ return;
360
+ throw r;
361
+ }
362
+ }
363
+ async createConversation(t, n) {
364
+ const e = t?.id || j(t), { name: r, folderId: a, model: o, messages: c, custom_fields: i } = t, u = {
350
365
  id: e,
351
366
  name: r,
352
367
  folderId: a,
@@ -361,7 +376,7 @@ class re {
361
376
  };
362
377
  return await this.client.request(
363
378
  f(e),
364
- s,
379
+ n,
365
380
  {
366
381
  method: "PUT",
367
382
  body: u
@@ -375,40 +390,40 @@ class re {
375
390
  updatedAt: u.updatedAt
376
391
  };
377
392
  }
378
- async generateConversationLink(t, s) {
393
+ async generateConversationLink(t, n) {
379
394
  return await this.client.postRequest(
380
395
  d.SHARE_CONVERSATION,
381
396
  t,
382
397
  {
383
- body: s
398
+ body: n
384
399
  }
385
400
  );
386
401
  }
387
- async getSharedConversations(t, s) {
402
+ async getSharedConversations(t, n) {
388
403
  return await this.client.postRequest(
389
404
  d.SHARE_CONVERSATION_LIST,
390
405
  t,
391
406
  {
392
- body: s
407
+ body: n
393
408
  }
394
409
  );
395
410
  }
396
- async revokeSharedConversations(t, s) {
411
+ async revokeSharedConversations(t, n) {
397
412
  await this.client.postRequest(
398
413
  d.SHARE_CONVERSATION_REVOKE,
399
414
  t,
400
415
  {
401
- body: s
416
+ body: n
402
417
  }
403
418
  );
404
419
  }
405
- async updateConversation(t, s, e) {
420
+ async updateConversation(t, n, e) {
406
421
  const r = await this.getConversation(t, e);
407
422
  if (!r)
408
423
  throw new Error(`Conversation with id ${t} not found`);
409
424
  const a = {
410
425
  ...r,
411
- ...s,
426
+ ...n,
412
427
  updatedAt: Date.now()
413
428
  };
414
429
  return await this.client.request(
@@ -420,15 +435,15 @@ class re {
420
435
  }
421
436
  );
422
437
  }
423
- async deleteConversation(t, s, e) {
424
- s?.isShared ? await this.client.postRequest(
438
+ async deleteConversation(t, n, e) {
439
+ n?.isShared ? await this.client.postRequest(
425
440
  d.SHARE_CONVERSATION_DISCARD,
426
441
  e,
427
442
  {
428
443
  body: {
429
444
  resources: [
430
445
  {
431
- url: s?.url
446
+ url: n?.url
432
447
  }
433
448
  ]
434
449
  }
@@ -437,7 +452,7 @@ class re {
437
452
  method: "DELETE"
438
453
  });
439
454
  }
440
- async streamChat(t, s) {
455
+ async streamChat(t, n) {
441
456
  const e = t.model.id, r = encodeURIComponent(e), a = `${d.CHAT(r)}?api-version=${this.client.config.version}`, o = {
442
457
  messages: t.messages,
443
458
  stream: !0,
@@ -445,29 +460,29 @@ class re {
445
460
  max_tokens: 4096,
446
461
  custom_fields: t.custom_fields
447
462
  };
448
- return await this.client.stream(a, s, {
463
+ return await this.client.stream(a, n, {
449
464
  method: "POST",
450
465
  body: o,
451
466
  chatReference: t.conversationId
452
467
  });
453
468
  }
454
- async rateResponse(t, s, e, r) {
469
+ async rateResponse(t, n, e, r) {
455
470
  return await this.client.postRequest(
456
471
  d.RATE(t),
457
472
  r,
458
473
  {
459
474
  body: {
460
- responseId: s,
475
+ responseId: n,
461
476
  rate: e
462
477
  }
463
478
  }
464
479
  );
465
480
  }
466
- async renameConversation(t, s, e) {
481
+ async renameConversation(t, n, e) {
467
482
  return await this.client.postRequest(d.RENAME, e, {
468
483
  body: {
469
484
  sourceUrl: t,
470
- destinationUrl: s,
485
+ destinationUrl: n,
471
486
  overwrite: !0
472
487
  }
473
488
  });
@@ -481,17 +496,18 @@ class oe {
481
496
  version: t.version
482
497
  });
483
498
  }
484
- async getRequest(t, s, e) {
485
- return this.request(t, s, { ...e, method: "GET" });
499
+ async getRequest(t, n, e) {
500
+ return this.request(t, n, { ...e, method: "GET" });
486
501
  }
487
- async postRequest(t, s, e) {
488
- return this.request(t, s, { ...e, method: "POST" });
502
+ async postRequest(t, n, e) {
503
+ return this.request(t, n, { ...e, method: "POST" });
489
504
  }
490
- async requestBlob(t, s, e) {
505
+ async requestBlob(t, n, e) {
491
506
  const r = `${this.config.host}${t}`, a = {
492
507
  ..._(this.config.apiKey, {
493
- jwt: s,
494
- chatReference: e.chatReference
508
+ jwt: n,
509
+ chatReference: e.chatReference,
510
+ contentType: e.isFormData ? null : void 0
495
511
  }),
496
512
  ...e.headers
497
513
  };
@@ -505,11 +521,12 @@ class oe {
505
521
  }), o;
506
522
  }
507
523
  }
508
- async request(t, s, e) {
524
+ async request(t, n, e) {
509
525
  const r = Date.now(), a = `${this.config.host}${t}`, o = {
510
526
  ..._(this.config.apiKey, {
511
- jwt: s,
512
- chatReference: e.chatReference
527
+ jwt: n,
528
+ chatReference: e.chatReference,
529
+ contentType: e.isFormData ? null : void 0
513
530
  }),
514
531
  ...e.headers
515
532
  };
@@ -517,21 +534,21 @@ class oe {
517
534
  try {
518
535
  const c = await I(a, o, e), i = Date.now() - r;
519
536
  let u;
520
- const l = await c.text();
537
+ const m = await c.text();
521
538
  try {
522
- u = l ? JSON.parse(l) : {};
539
+ u = m ? JSON.parse(m) : {};
523
540
  } catch {
524
541
  if (this.addErrorRequestParsing(
525
542
  a,
526
543
  e,
527
544
  c,
528
545
  i,
529
- l
546
+ m
530
547
  ), !c.ok)
531
548
  throw new Error(
532
- `API request failed: ${c.status} ${c.statusText} - ${l.substring(0, 100)}`
549
+ `API request failed: ${c.status} ${c.statusText} - ${m.substring(0, 100)}`
533
550
  );
534
- u = { data: l };
551
+ u = { data: m };
535
552
  }
536
553
  if (!c.ok) {
537
554
  this.addErrorRequestLog(a, e, c, i, u);
@@ -549,12 +566,13 @@ class oe {
549
566
  }), c;
550
567
  }
551
568
  }
552
- async stream(t, s, e) {
569
+ async stream(t, n, e) {
553
570
  const r = `${this.config.host}${t}`, a = _(
554
571
  this.config.apiKey,
555
572
  {
556
- jwt: s,
557
- chatReference: e.chatReference
573
+ jwt: n,
574
+ chatReference: e.chatReference,
575
+ contentType: e.isFormData ? null : void 0
558
576
  },
559
577
  e.headers
560
578
  );
@@ -573,17 +591,17 @@ class oe {
573
591
  throw new Error("No response body for stream");
574
592
  return o.body;
575
593
  }
576
- addInfoRequestLog(t, s, e, r) {
594
+ addInfoRequestLog(t, n, e, r) {
577
595
  const a = {
578
596
  method: e.method || "GET",
579
- url: s,
597
+ url: n,
580
598
  headers: U(r)
581
599
  };
582
600
  e.body && (a.body = e.body), console.info(t, a);
583
601
  }
584
- addErrorRequestLog(t, s, e, r, a) {
602
+ addErrorRequestLog(t, n, e, r, a) {
585
603
  console.error("API Request Failed", {
586
- method: s.method,
604
+ method: n.method,
587
605
  url: t,
588
606
  status: e.status,
589
607
  statusText: e.statusText,
@@ -591,9 +609,9 @@ class oe {
591
609
  response: a
592
610
  });
593
611
  }
594
- addErrorRequestParsing(t, s, e, r, a) {
612
+ addErrorRequestParsing(t, n, e, r, a) {
595
613
  console.error("API Response Parse Error", {
596
- method: s.method,
614
+ method: n.method,
597
615
  url: t,
598
616
  status: e.status,
599
617
  statusText: e.statusText,
@@ -605,7 +623,7 @@ class oe {
605
623
  }
606
624
  }
607
625
  export {
608
- y as AttachmentType,
626
+ g as AttachmentType,
609
627
  G as COMPLETION_FINISH_REASON,
610
628
  X as CUSTOM_VIEW_STATE_KEY,
611
629
  Y as ChatStreamSSEClient,
@@ -618,20 +636,20 @@ export {
618
636
  R as EXCEEDED_LIMIT,
619
637
  W as EXCEEDED_LIMIT_ORDER,
620
638
  $ as InvitationType,
621
- p as ResourceTypes,
622
- g as ShareTarget,
639
+ A as ResourceTypes,
640
+ y as ShareTarget,
623
641
  B as chatStreamSSEClient,
624
642
  ee as decodeApiUrl,
625
643
  E as encodeApiUrl,
626
- se as formatDateTime,
627
- k as generateConversationId,
644
+ ne as formatDateTime,
645
+ j as generateConversationId,
628
646
  D as getErrorMessage,
629
- F as getRateLimitRestoreDate,
647
+ k as getRateLimitRestoreDate,
630
648
  Z as getSharedConversationsRequest,
631
649
  v as handleStreamMessage,
632
650
  te as isRateLimitStillActive,
633
651
  Q as mergeMessages,
634
- j as parseConversationName,
652
+ K as parseConversationName,
635
653
  I as sendRequest,
636
- ne as streamChatResponse
654
+ se as streamChatResponse
637
655
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@epam/statgpt-dial-toolkit",
3
- "version": "0.3.0-rc.10",
3
+ "version": "0.3.0-rc.12",
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.3.0-rc.10",
17
+ "@epam/statgpt-shared-toolkit": "0.3.0-rc.12",
18
18
  "@epam/ai-dial-shared": "^0.43.3"
19
19
  }
20
20
  }