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