@epam/statgpt-dial-toolkit 0.1.0-rc.1 → 0.1.0-rc.3

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.
@@ -1,5 +1,5 @@
1
- import { Message } from '../models/message';
2
1
  import { CustomFields, MessageStreamResponse, RequestStreamBody } from '../models/chat-stream';
2
+ import { Message } from '../models/message';
3
3
  import { ModelInfo } from '../models/model';
4
4
  interface SSEOptions {
5
5
  signal?: AbortSignal;
@@ -5,7 +5,7 @@ import { ConversationData, CreateConversationRequest, GeneratedLinkResponse, Sha
5
5
  import { ModelInfo } from '../models/model';
6
6
  import { GridAttachmentContent } from '../models/grid-attachment';
7
7
  import { CustomFields } from '../models/chat-stream';
8
- import { OnboardingFileSchema } from '../../../shared-toolkit/src/models/onboarding-schema';
8
+ import { OnboardingFileSchema } from '../../../shared-toolkit/src/index';
9
9
  interface Entity extends DialEntity {
10
10
  url?: string;
11
11
  parentPath: string;
@@ -1,4 +1,4 @@
1
- import { RequestOptions } from '../../../shared-toolkit/src/models/request-options';
1
+ import { RequestOptions } from '../../../shared-toolkit/src/index';
2
2
  import { DialApiConfig } from '../models/dial-config';
3
3
  export declare class DialApiClient {
4
4
  readonly config: DialApiConfig;
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 _=(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))(_||{}),I=(s=>(s.LINK="link",s))(I||{});const q=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)},T=(s,t,r)=>{if(t==null||t(s),r){const e=q(s);e&&r(e)}},$=(s,t)=>s.error||s.message||`${t.status} ${t.statusText}`,b=(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)},v=(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=b(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},P=s=>(s==null?void 0:s.toLowerCase().replace(/[^\p{L}\p{N}]+/gu,"-").replace(/^-+|-+$/g,"").replace(/-/g," "))||"",p=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}},O=s=>{const t=Date.now(),r=P(s.name);return`${s.folderId}/${r}-${t}`},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 x(s){return s.split("/").map(t=>decodeURIComponent(t)).join("/")}const H={CHAT:"/api/chat"},D="application/json",L="Content-Type",A="Api-Key",V="X-CONVERSATION-ID",y=(s,t,r)=>{const e={[L]:(t==null?void 0:t.contentType)||D};return t!=null&&t.jwt?e.Authorization=`Bearer ${t.jwt}`:s&&(e[A]=s),t!=null&&t.chatReference&&(e[V]=t.chatReference),{...e,...r}},U=s=>{const t={...s};return t[A]&&(t[A]=t[A].substring(0,8)+"...[REDACTED]"),t.Authorization&&(t.Authorization="Bearer [REDACTED]"),t},j=s=>({"Content-Type":`multipart/form-data; boundary=${s}`});class g{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=y(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(`HTTP ${a.status}: ${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);console.info(`SSE: Parsed data: ${o}`),r==null||r(o)}catch(o){console.error(`Failed to parse SSE data: ${n} ${o}`)}}}}const N=new g,k=async(s,t,r,e,n)=>{const{onMessage:o,onToken:a,onComplete:c,onError:d,model:i,signal:l}=r,C={conversationId:s,messages:t,model:i,custom_fields:n};await N.streamChat(H.CHAT,C,{onMessage:w=>T(w,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 M{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}=p(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:j(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)||O(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 F{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={...y(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={...y(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 C=$(i,c);throw new Error(`API request failed: ${C}`)}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=y(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:U(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=_;exports.ChatStreamSSEClient=g;exports.ConversationApi=M;exports.DIAL_API_ROUTES=u;exports.DialApiClient=F;exports.InvitationType=I;exports.chatStreamSSEClient=N;exports.decodeApiUrl=x;exports.encodeApiUrl=f;exports.generateConversationId=O;exports.getErrorMessage=$;exports.handleStreamMessage=T;exports.mergeMessages=v;exports.parseConversationName=p;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 T=(s=>(s.CONVERSATION="CONVERSATION",s))(T||{}),_=(s=>(s.ME="me",s.OTHERS="others",s))(_||{}),O=(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))(O||{}),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)},p=(s,t,r)=>{if(t==null||t(s),r){const e=b(s);e&&r(e)}},$=(s,t)=>s.error||s.message||`${t.status} ${t.statusText}`,P=(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)},x=(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=P(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",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)||V};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}`}),g=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:[T.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(`HTTP ${a.status}: ${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);console.info(`SSE: Parsed data: ${o}`),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(H.CHAT,y,{onMessage:v=>p(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}=g(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 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 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=$(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=O;exports.ChatStreamSSEClient=w;exports.ConversationApi=B;exports.DIAL_API_ROUTES=u;exports.DialApiClient=z;exports.InvitationType=I;exports.ResourceTypes=T;exports.ShareTarget=_;exports.chatStreamSSEClient=q;exports.decodeApiUrl=F;exports.encodeApiUrl=f;exports.generateConversationId=N;exports.getErrorMessage=$;exports.getSharedConversationsRequest=k;exports.handleStreamMessage=p;exports.mergeMessages=x;exports.parseConversationName=g;exports.sendRequest=E;exports.streamChatResponse=K;
package/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './constants/api-urls';
2
+ export * from './constants/share-conversation';
2
3
  export * from './models';
3
4
  export * from './types';
4
5
  export * from './utils';
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 _ = /* @__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))(_ || {}), y = /* @__PURE__ */ ((s) => (s.LINK = "link", s))(y || {});
19
- const $ = (s) => {
18
+ var I = /* @__PURE__ */ ((s) => (s.CONVERSATION = "CONVERSATION", s))(I || {}), _ = /* @__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))(y || {}), C = /* @__PURE__ */ ((s) => (s.LINK = "link", s))(C || {});
19
+ const T = (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
- }, C = (s, t, r) => {
24
+ }, $ = (s, t, r) => {
25
25
  if (t == null || t(s), r) {
26
- const e = $(s);
26
+ const e = T(s);
27
27
  e && r(e);
28
28
  }
29
- }, N = (s, t) => s.error || s.message || `${t.status} ${t.statusText}`, T = (s, t) => {
29
+ }, p = (s, t) => s.error || s.message || `${t.status} ${t.statusText}`, g = (s, t) => {
30
30
  const r = s == null ? void 0 : s.reduce(
31
31
  (e, n) => (e[n.index] = n, e),
32
32
  {}
@@ -34,24 +34,36 @@ const $ = (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
- }, D = (s, t) => {
37
+ }, j = (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 = T(
42
+ )), e.custom_content.stages && (r.custom_content.stages || (r.custom_content.stages = []), r.custom_content.stages = g(
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
- }, p = (s) => (s == null ? void 0 : s.toLowerCase().replace(/[^\p{L}\p{N}]+/gu, "-").replace(/^-+|-+$/g, "").replace(/-/g, " ")) || "", g = (s) => {
47
+ }, w = {
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) => {
50
+ const e = {
51
+ [b]: (t == null ? void 0 : t.contentType) || q
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) => {
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) => ({
58
+ "Content-Type": `multipart/form-data; boundary=${s}`
59
+ }), H = (s) => {
48
60
  var n;
49
61
  const t = ((n = s.name) == null ? void 0 : n.split("__")) || [], r = t.length > 1 ? t.slice(1).join("__") : s.name;
50
62
  return { modelId: t[0], conversationName: r };
51
- }, w = (s) => {
52
- const t = Date.now(), r = p(s.name);
63
+ }, L = (s) => {
64
+ const t = Date.now(), r = v(s.name);
53
65
  return `${s.folderId}/${r}-${t}`;
54
- }, R = async (s, t, r) => await fetch(s, {
66
+ }, k = (s) => ({ resourceTypes: [I.CONVERSATION], with: s }), O = async (s, t, r) => await fetch(s, {
55
67
  method: r.method || "GET",
56
68
  headers: t,
57
69
  body: r != null && r.isFormData && typeof (r == null ? void 0 : r.body) == "string" ? r.body : JSON.stringify(r.body),
@@ -60,23 +72,10 @@ const $ = (s) => {
60
72
  function h(s) {
61
73
  return s.split("/").map((t) => encodeURIComponent(t)).join("/");
62
74
  }
63
- function U(s) {
75
+ function F(s) {
64
76
  return s.split("/").map((t) => decodeURIComponent(t)).join("/");
65
77
  }
66
- const q = {
67
- CHAT: "/api/chat"
68
- }, b = "application/json", V = "Content-Type", S = "Api-Key", v = "X-CONVERSATION-ID", A = (s, t, r) => {
69
- const e = {
70
- [V]: (t == null ? void 0 : t.contentType) || b
71
- };
72
- return t != null && t.jwt ? e.Authorization = `Bearer ${t.jwt}` : s && (e[S] = s), t != null && t.chatReference && (e[v] = t.chatReference), { ...e, ...r };
73
- }, x = (s) => {
74
- const t = { ...s };
75
- return t[S] && (t[S] = t[S].substring(0, 8) + "...[REDACTED]"), t.Authorization && (t.Authorization = "Bearer [REDACTED]"), t;
76
- }, P = (s) => ({
77
- "Content-Type": `multipart/form-data; boundary=${s}`
78
- });
79
- class H {
78
+ class D {
80
79
  constructor() {
81
80
  this.decoder = new TextDecoder();
82
81
  }
@@ -95,9 +94,9 @@ class H {
95
94
  }
96
95
  }
97
96
  async initializeStreamRequest(t, r, e, n) {
98
- const o = A(void 0, {
97
+ const o = S(void 0, {
99
98
  jwt: n
100
- }), c = await R(
99
+ }), c = await O(
101
100
  t,
102
101
  {
103
102
  Accept: "text/event-stream",
@@ -159,26 +158,26 @@ class H {
159
158
  }
160
159
  }
161
160
  }
162
- const L = new H(), j = async (s, t, r, e, n) => {
163
- const { onMessage: o, onToken: c, onComplete: a, onError: d, model: i, signal: l } = r, I = {
161
+ const U = new D(), K = async (s, t, r, e, n) => {
162
+ const { onMessage: o, onToken: c, onComplete: a, onError: d, model: i, signal: l } = r, A = {
164
163
  conversationId: s,
165
164
  messages: t,
166
165
  model: i,
167
166
  custom_fields: n
168
167
  };
169
- await L.streamChat(
170
- q.CHAT,
171
- I,
168
+ await U.streamChat(
169
+ w.CHAT,
170
+ A,
172
171
  {
173
- onMessage: (O) => C(O, o, c),
172
+ onMessage: (N) => $(N, o, c),
174
173
  onComplete: a,
175
174
  onError: d,
176
175
  signal: l
177
176
  },
178
177
  e
179
178
  );
180
- }, m = (s) => s instanceof Error && s.message.includes("404"), f = (s) => `/v1/conversations/${h(s)}`;
181
- class k {
179
+ }, m = (s) => s instanceof Error && s.message.includes("404"), R = (s) => `/v1/conversations/${h(s)}`;
180
+ class B {
182
181
  constructor(t) {
183
182
  this.client = t;
184
183
  }
@@ -187,7 +186,7 @@ class k {
187
186
  try {
188
187
  return (await this.client.getRequest(o + "/?limit=1000&recursive=false", t).then((a) => a.items || [])).map((a) => {
189
188
  var l;
190
- const { conversationName: d, modelId: i } = g(a);
189
+ const { conversationName: d, modelId: i } = H(a);
191
190
  return {
192
191
  id: ((l = a.url) == null ? void 0 : l.replace("conversations/", "")) || a.name,
193
192
  name: d,
@@ -206,7 +205,7 @@ class k {
206
205
  async getConversation(t, r) {
207
206
  try {
208
207
  return await this.client.getRequest(
209
- f(t),
208
+ R(t),
210
209
  r
211
210
  );
212
211
  } catch (e) {
@@ -270,7 +269,7 @@ class k {
270
269
  }
271
270
  }
272
271
  async createConversation(t, r) {
273
- const e = (t == null ? void 0 : t.id) || w(t), { name: n, folderId: o, model: c, messages: a, custom_fields: d } = t, i = {
272
+ const e = (t == null ? void 0 : t.id) || L(t), { name: n, folderId: o, model: c, messages: a, custom_fields: d } = t, i = {
274
273
  id: e,
275
274
  name: n,
276
275
  folderId: o,
@@ -284,7 +283,7 @@ class k {
284
283
  custom_fields: d
285
284
  };
286
285
  return await this.client.request(
287
- f(e),
286
+ R(e),
288
287
  r,
289
288
  {
290
289
  method: "PUT",
@@ -336,7 +335,7 @@ class k {
336
335
  updatedAt: Date.now()
337
336
  };
338
337
  return await this.client.request(
339
- f(t),
338
+ R(t),
340
339
  e,
341
340
  {
342
341
  method: "PUT",
@@ -358,7 +357,7 @@ class k {
358
357
  }
359
358
  }
360
359
  ) : await this.client.request(
361
- f(decodeURI(t == null ? void 0 : t.id)),
360
+ R(decodeURI(t == null ? void 0 : t.id)),
362
361
  r,
363
362
  {
364
363
  method: "DELETE"
@@ -397,7 +396,7 @@ class k {
397
396
  });
398
397
  }
399
398
  }
400
- class F {
399
+ class M {
401
400
  constructor(t) {
402
401
  this.config = t, console.info("DialApiClient initialized", {
403
402
  host: t.host || "NOT SET",
@@ -413,14 +412,14 @@ class F {
413
412
  }
414
413
  async requestBlob(t, r, e) {
415
414
  const n = `${this.config.host}${t}`, o = {
416
- ...A(this.config.apiKey, {
415
+ ...S(this.config.apiKey, {
417
416
  jwt: r,
418
417
  chatReference: e.chatReference
419
418
  }),
420
419
  ...e.headers
421
420
  };
422
421
  try {
423
- return (await R(n, o, e)).blob();
422
+ return (await O(n, o, e)).blob();
424
423
  } catch (c) {
425
424
  throw console.error("API Request Exception", {
426
425
  method: e.method,
@@ -431,7 +430,7 @@ class F {
431
430
  }
432
431
  async request(t, r, e) {
433
432
  const n = Date.now(), o = `${this.config.host}${t}`, c = {
434
- ...A(this.config.apiKey, {
433
+ ...S(this.config.apiKey, {
435
434
  jwt: r,
436
435
  chatReference: e.chatReference
437
436
  }),
@@ -439,7 +438,7 @@ class F {
439
438
  };
440
439
  this.addInfoRequestLog("API Request", o, e, c);
441
440
  try {
442
- const a = await R(o, c, e), d = Date.now() - n;
441
+ const a = await O(o, c, e), d = Date.now() - n;
443
442
  let i;
444
443
  const l = await a.text();
445
444
  try {
@@ -459,8 +458,8 @@ class F {
459
458
  }
460
459
  if (!a.ok) {
461
460
  this.addErrorRequestLog(o, e, a, d, i);
462
- const I = N(i, a);
463
- throw new Error(`API request failed: ${I}`);
461
+ const A = p(i, a);
462
+ throw new Error(`API request failed: ${A}`);
464
463
  }
465
464
  return i;
466
465
  } catch (a) {
@@ -474,7 +473,7 @@ class F {
474
473
  }
475
474
  }
476
475
  async stream(t, r, e) {
477
- const n = `${this.config.host}${t}`, o = A(
476
+ const n = `${this.config.host}${t}`, o = S(
478
477
  this.config.apiKey,
479
478
  {
480
479
  jwt: r,
@@ -483,7 +482,7 @@ class F {
483
482
  e.headers
484
483
  );
485
484
  this.addInfoRequestLog("Stream Request", n, e, o);
486
- const c = await R(n, o, e);
485
+ const c = await O(n, o, e);
487
486
  if (!c.ok)
488
487
  throw console.error("Stream Request Failed", {
489
488
  method: e.method || "POST",
@@ -529,20 +528,23 @@ class F {
529
528
  }
530
529
  }
531
530
  export {
532
- _ as AttachmentType,
533
- H as ChatStreamSSEClient,
534
- k as ConversationApi,
531
+ y as AttachmentType,
532
+ D as ChatStreamSSEClient,
533
+ B as ConversationApi,
535
534
  u as DIAL_API_ROUTES,
536
- F as DialApiClient,
537
- y as InvitationType,
538
- L as chatStreamSSEClient,
539
- U as decodeApiUrl,
535
+ M as DialApiClient,
536
+ C as InvitationType,
537
+ I as ResourceTypes,
538
+ _ as ShareTarget,
539
+ U as chatStreamSSEClient,
540
+ F as decodeApiUrl,
540
541
  h as encodeApiUrl,
541
- w as generateConversationId,
542
- N as getErrorMessage,
543
- C as handleStreamMessage,
544
- D as mergeMessages,
545
- g as parseConversationName,
546
- R as sendRequest,
547
- j as streamChatResponse
542
+ L as generateConversationId,
543
+ p as getErrorMessage,
544
+ k as getSharedConversationsRequest,
545
+ $ as handleStreamMessage,
546
+ j as mergeMessages,
547
+ H as parseConversationName,
548
+ O as sendRequest,
549
+ K as streamChatResponse
548
550
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@epam/statgpt-dial-toolkit",
3
- "version": "0.1.0-rc.1",
3
+ "version": "0.1.0-rc.3",
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.1.0-rc.1",
17
+ "@epam/statgpt-shared-toolkit": "0.1.0-rc.3",
18
18
  "@epam/ai-dial-shared": "^0.34.0"
19
19
  }
20
20
  }
package/utils/index.d.ts CHANGED
@@ -2,5 +2,6 @@ export * from './chat-stream-api';
2
2
  export * from './get-error-message';
3
3
  export * from './merge-messages';
4
4
  export * from './parse-conversation-name';
5
+ export * from './shared-conversations-request';
5
6
  export * from './send-request';
6
7
  export * from './url';
@@ -1,2 +1,2 @@
1
- import { RequestOptions } from '../../../shared-toolkit/src/models/request-options';
1
+ import { RequestOptions } from '../../../shared-toolkit/src/index';
2
2
  export declare const sendRequest: (url: string, headers: Record<string, string>, options: RequestOptions) => Promise<Response>;