@epam/statgpt-dial-toolkit 0.1.0-rc.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/LICENSE +21 -0
- package/README.md +67 -0
- package/api/chat-streaming-api.d.ts +27 -0
- package/api/conversation-api.d.ts +25 -0
- package/api/dial-api-client.d.ts +14 -0
- package/api/index.d.ts +3 -0
- package/constants/api-urls.d.ts +15 -0
- package/constants/share-conversation.d.ts +7 -0
- package/index.cjs +2 -0
- package/index.d.ts +5 -0
- package/index.mjs +484 -0
- package/models/chat-stream.d.ts +24 -0
- package/models/conversation.d.ts +50 -0
- package/models/dial-config.d.ts +6 -0
- package/models/grid-attachment.d.ts +28 -0
- package/models/index.d.ts +6 -0
- package/models/message.d.ts +5 -0
- package/models/model.d.ts +4 -0
- package/package.json +20 -0
- package/types/attachment-type.d.ts +11 -0
- package/types/index.d.ts +2 -0
- package/types/invitation-type.d.ts +3 -0
- package/utils/chat-stream-api.d.ts +2 -0
- package/utils/get-error-message.d.ts +5 -0
- package/utils/index.d.ts +6 -0
- package/utils/is-error.d.ts +1 -0
- package/utils/merge-messages.d.ts +2 -0
- package/utils/parse-conversation-name.d.ts +7 -0
- package/utils/send-request.d.ts +2 -0
- package/utils/shared-conversations-request.d.ts +5 -0
- package/utils/url.d.ts +2 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 EPAM Systems
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# DIAL Toolkit
|
|
2
|
+
|
|
3
|
+
This is StatGpt portals library,
|
|
4
|
+
provides utilities and helpers for working with DIAL Api in the StatGPT ecosystem.
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
[](https://opensource.org/licenses/mit)
|
|
8
|
+
[](https://www.typescriptlang.org/)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
## Table of Contents
|
|
12
|
+
|
|
13
|
+
- [Features](#features)
|
|
14
|
+
- [Installation](#installation)
|
|
15
|
+
- [Usage](#usage)
|
|
16
|
+
- [Contributing](#contributing)
|
|
17
|
+
- [Security](#security)
|
|
18
|
+
- [License](#license)
|
|
19
|
+
|
|
20
|
+
## Features
|
|
21
|
+
|
|
22
|
+
- Pre-configured API clients for easy access to DIAL services
|
|
23
|
+
- Type definitions for DIAL concepts
|
|
24
|
+
- Utility functions for DIAL data processing
|
|
25
|
+
- Streaming data support
|
|
26
|
+
- Attachment handling and processing
|
|
27
|
+
- Support for authorization
|
|
28
|
+
- Integration with StatGPT ecosystem
|
|
29
|
+
- Lightweight and minimal dependencies
|
|
30
|
+
|
|
31
|
+
## Installation
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm install @epam/statgpt-dial-toolkit
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Usage
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
import { DialApiClient, ConversationApi } from '@epam/statgpt-dial-toolkit';
|
|
41
|
+
|
|
42
|
+
const config = {
|
|
43
|
+
host: yuor_dial_api_host,
|
|
44
|
+
version: your_dial_api_version,
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// Example usage
|
|
48
|
+
export const dialApiClient = new DialApiClient(config);
|
|
49
|
+
export const conversationApi = new ConversationApi(dialApiClient);
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Contributing
|
|
53
|
+
|
|
54
|
+
We welcome contributions! Please see our [Contributing Guide](https://github.com/epam/statgpt-portal-frontend/blob/development/CONTRIBUTING.md) for details on:
|
|
55
|
+
|
|
56
|
+
- Testing requirements
|
|
57
|
+
- Pull request process
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
## Security
|
|
61
|
+
|
|
62
|
+
If you discover a security vulnerability, please refer to our [Security Policy](https://github.com/epam/statgpt-portal-frontend/blob/development/SECURITY.md).
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
## License
|
|
66
|
+
|
|
67
|
+
[MIT](https://github.com/epam/statgpt-portal-frontend/blob/development/LICENSE) - see the [LICENSE](https://github.com/epam/statgpt-portal-frontend/blob/development/LICENSE) file for details.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Message } from '../models/message';
|
|
2
|
+
import { MessageStreamResponse, RequestStreamBody } from '../models/chat-stream';
|
|
3
|
+
import { ModelInfo } from '../models/model';
|
|
4
|
+
interface SSEOptions {
|
|
5
|
+
signal?: AbortSignal;
|
|
6
|
+
onMessage?: (data: MessageStreamResponse) => void;
|
|
7
|
+
onError?: (error: Error) => void;
|
|
8
|
+
onComplete?: () => void;
|
|
9
|
+
}
|
|
10
|
+
export declare class ChatStreamSSEClient {
|
|
11
|
+
private decoder;
|
|
12
|
+
streamChat(url: string, body: RequestStreamBody, options?: SSEOptions, token?: string): Promise<void>;
|
|
13
|
+
private initializeStreamRequest;
|
|
14
|
+
private processStreamData;
|
|
15
|
+
private handleStreamError;
|
|
16
|
+
private parseSSEDataLine;
|
|
17
|
+
}
|
|
18
|
+
export declare const chatStreamSSEClient: ChatStreamSSEClient;
|
|
19
|
+
export declare const streamChatResponse: (conversationId: string, messages: Message[], options: {
|
|
20
|
+
onMessage?: (data: MessageStreamResponse) => void;
|
|
21
|
+
onToken?: (token: string) => void;
|
|
22
|
+
onComplete?: () => void;
|
|
23
|
+
onError?: (error: Error) => void;
|
|
24
|
+
model: ModelInfo;
|
|
25
|
+
signal?: AbortSignal;
|
|
26
|
+
}, token?: string | null) => Promise<void>;
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Conversation, ConversationInfo } from '@epam/ai-dial-shared';
|
|
2
|
+
import { Message } from '../models/message';
|
|
3
|
+
import { DialApiClient } from './dial-api-client';
|
|
4
|
+
import { ConversationData, CreateConversationRequest, GeneratedLinkResponse, SharedConversationsRequest, SharedConversations, UpdateConversationRequest } from '../models/conversation';
|
|
5
|
+
import { ModelInfo } from '../models/model';
|
|
6
|
+
import { GridAttachmentContent } from '../models/grid-attachment';
|
|
7
|
+
export declare class ConversationApi {
|
|
8
|
+
private client;
|
|
9
|
+
constructor(client: DialApiClient);
|
|
10
|
+
getConversations(token: string, bucket?: string, locale?: string): Promise<ConversationInfo[]>;
|
|
11
|
+
getConversation(id: string, token: string): Promise<Conversation | null>;
|
|
12
|
+
getFile(filePath: string, token: string): Promise<GridAttachmentContent | null>;
|
|
13
|
+
getFileBlob(filePath: string, token: string): Promise<Blob | null>;
|
|
14
|
+
createConversation(data: CreateConversationRequest, token: string): Promise<ConversationInfo>;
|
|
15
|
+
generateConversationLink(token: string, conversationData?: ConversationData): Promise<GeneratedLinkResponse>;
|
|
16
|
+
getSharedConversations(token: string, requestData?: SharedConversationsRequest): Promise<SharedConversations>;
|
|
17
|
+
revokeSharedConversations(token: string, sharedConversations?: SharedConversations): Promise<void>;
|
|
18
|
+
updateConversation(id: string, data: UpdateConversationRequest, token: string): Promise<ConversationInfo>;
|
|
19
|
+
deleteConversation(conversation: ConversationInfo, token: string): Promise<void>;
|
|
20
|
+
streamChat(params: {
|
|
21
|
+
conversationId: string;
|
|
22
|
+
messages: Message[];
|
|
23
|
+
model: ModelInfo;
|
|
24
|
+
}, token: string): Promise<ReadableStream>;
|
|
25
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { RequestOptions } from '../../../shared-toolkit/src/models/request-options';
|
|
2
|
+
import { DialApiConfig } from '../models/dial-config';
|
|
3
|
+
export declare class DialApiClient {
|
|
4
|
+
readonly config: DialApiConfig;
|
|
5
|
+
constructor(config: DialApiConfig);
|
|
6
|
+
getRequest<T>(endpoint: string, token: string, options?: RequestOptions): Promise<T>;
|
|
7
|
+
postRequest<T>(endpoint: string, token: string, options?: RequestOptions): Promise<T>;
|
|
8
|
+
requestBlob(endpoint: string, token: string, options: RequestOptions): Promise<Blob>;
|
|
9
|
+
request<T>(endpoint: string, token: string, options: RequestOptions): Promise<T>;
|
|
10
|
+
stream(endpoint: string, token: string, options: RequestOptions): Promise<ReadableStream>;
|
|
11
|
+
private addInfoRequestLog;
|
|
12
|
+
private addErrorRequestLog;
|
|
13
|
+
private addErrorRequestParsing;
|
|
14
|
+
}
|
package/api/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare const DIAL_API_ROUTES: {
|
|
2
|
+
readonly VERSION: "/v1";
|
|
3
|
+
readonly BUCKET: "/v1/bucket";
|
|
4
|
+
readonly CONVERSATIONS: "/v1/metadata/conversations";
|
|
5
|
+
readonly CONVERSATION_BY_ID: (id: string) => string;
|
|
6
|
+
readonly CHAT: (modelId: string) => string;
|
|
7
|
+
readonly MODELS: "/openai/models";
|
|
8
|
+
readonly CONFIGURATION: (modelId: string) => string;
|
|
9
|
+
readonly SHARE_CONVERSATION: "/v1/ops/resource/share/create";
|
|
10
|
+
readonly SHARE_CONVERSATION_ACCEPT: (invitationId: string) => string;
|
|
11
|
+
readonly SHARE_CONVERSATION_DETAILS: (invitationId: string) => string;
|
|
12
|
+
readonly SHARE_CONVERSATION_LIST: "/v1/ops/resource/share/list";
|
|
13
|
+
readonly SHARE_CONVERSATION_DISCARD: "/v1/ops/resource/share/discard";
|
|
14
|
+
readonly SHARE_CONVERSATION_REVOKE: "/v1/ops/resource/share/revoke";
|
|
15
|
+
};
|
package/index.cjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l="v1",f=`/${l}/ops/resource/share`,m={VERSION:`/${l}`,BUCKET:`/${l}/bucket`,CONVERSATIONS:`/${l}/metadata/conversations`,CONVERSATION_BY_ID:r=>`/${l}/metadata/conversations/${r}`,CHAT:r=>`/openai/deployments/${r}/chat/completions`,MODELS:"/openai/models",CONFIGURATION:r=>`/${l}/deployments/${r}/configuration`,SHARE_CONVERSATION:`${f}/create`,SHARE_CONVERSATION_ACCEPT:r=>`/${l}/invitations/${r}?accept=true`,SHARE_CONVERSATION_DETAILS:r=>`/${l}/invitations/${r}`,SHARE_CONVERSATION_LIST:`${f}/list`,SHARE_CONVERSATION_DISCARD:`${f}/discard`,SHARE_CONVERSATION_REVOKE:`${f}/revoke`};var p=(r=>(r.CSV="text/csv",r.TABLE="application/dial-ttyd-table",r.PLOTLY="application/vnd.plotly.v1+json",r.MARKDOWN="text/markdown",r.JSON="application/json",r.JPEG="image/jpeg",r.PNG="image/png",r.CUSTOM_DATA_GRID="custom_data_grid",r.CUSTOM_CHART="custom_chart",r))(p||{}),I=(r=>(r.LINK="link",r))(I||{});const w=r=>{var t,s,e,n,o,c;return r.content?(console.info(`Using direct content format: ${r.content}`),r.content):(e=(s=(t=r.choices)==null?void 0:t[0])==null?void 0:s.delta)!=null&&e.content?(console.info(`Using OpenAI delta format: ${r.choices[0].delta.content}`),r.choices[0].delta.content):(c=(o=(n=r.choices)==null?void 0:n[0])==null?void 0:o.message)!=null&&c.content?(console.info(`Using complete message format: ${r.choices[0].message.content}`),r.choices[0].message.content):(console.info("Unknown SSE data format:",r),null)},T=(r,t,s)=>{if(t==null||t(r),s){const e=w(r);e&&s(e)}},O=(r,t)=>r.error||r.message||`${t.status} ${t.statusText}`,q=(r,t)=>{const s=r==null?void 0:r.reduce((e,n)=>(e[n.index]=n,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)},v=(r,t)=>{const s=structuredClone(r);return t.forEach(e=>{e.errorMessage&&(s.errorMessage=e.errorMessage),e.role&&(s.role=e.role),e.responseId&&(s.responseId=e.responseId),e.content&&(s.content=`${s.content||""}${e.content}`),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=q(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},x=r=>(r==null?void 0:r.toLowerCase().replace(/[^\p{L}\p{N}]+/gu,"-").replace(/^-+|-+$/g,"").replace(/-/g," "))||"",$=r=>{var n;const t=((n=r.name)==null?void 0:n.split("__"))||[],s=t.length>1?t.slice(1).join("__"):r.name;return{modelId:t[0],conversationName:s}},g=r=>{const t=Date.now(),s=x(r.name);return`${r.folderId}/${s}-${t}`},h=async(r,t,s)=>await fetch(r,{method:s.method||"GET",headers:t,body:s.body?JSON.stringify(s.body):void 0});function _(r){return r.split("/").map(t=>encodeURIComponent(t)).join("/")}function b(r){return r.split("/").map(t=>decodeURIComponent(t)).join("/")}const P={CHAT:"/api/chat"},H="application/json",L="Content-Type",R="Api-Key",D="X-CONVERSATION-ID",A=(r,t,s)=>{const e={[L]:(t==null?void 0:t.contentType)||H};return t!=null&&t.jwt?e.Authorization=`Bearer ${t.jwt}`:r&&(e[R]=r),t!=null&&t.chatReference&&(e[D]=t.chatReference),{...e,...s}},U=r=>{const t={...r};return t[R]&&(t[R]=t[R].substring(0,8)+"...[REDACTED]"),t.Authorization&&(t.Authorization="Bearer [REDACTED]"),t};class y{constructor(){this.decoder=new TextDecoder}async streamChat(t,s,e={},n){const{onMessage:o,onError:c,onComplete:a,signal:i}=e;try{const d=await this.initializeStreamRequest(t,s,i,n);await this.processStreamData(d,o),a==null||a()}catch(d){this.handleStreamError(d,c)}}async initializeStreamRequest(t,s,e,n){const o=A(void 0,{jwt:n}),c=await h(t,{Accept:"text/event-stream",...o},{method:"POST",body:s});if(!c.ok){const a=await c.text();throw new Error(`HTTP ${c.status}: ${a}`)}if(!c.body)throw new Error("No response body");return c.body.getReader()}async processStreamData(t,s){let e="";try{for(;;){const{done:n,value:o}=await t.read();if(n){e.trim()&&this.parseSSEDataLine(e,s);break}const c=this.decoder.decode(o,{stream:!0});e+=c;const a=e.split(`
|
|
2
|
+
`);e=a.pop()||"";for(const i of a)this.parseSSEDataLine(i,s)}}finally{t.releaseLock()}}handleStreamError(t,s){const e=t instanceof Error?t:new Error(String(t));throw s==null||s(e),e}parseSSEDataLine(t,s){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}`),s==null||s(o)}catch(o){console.error(`Failed to parse SSE data: ${n} ${o}`)}}}}const N=new y,V=async(r,t,s,e)=>{const{onMessage:n,onToken:o,onComplete:c,onError:a,model:i,signal:d}=s,u={conversationId:r,messages:t,model:i};await N.streamChat(P.CHAT,u,{onMessage:C=>T(C,n,o),onComplete:c,onError:a,signal:d},e)},E=r=>r instanceof Error&&r.message.includes("404"),S=r=>`/v1/conversations/${_(r)}`;class j{constructor(t){this.client=t}async getConversations(t,s,e){const n=`${s?e?`${s}/${e}`:`${s}`:""}`,o=`${m.CONVERSATIONS}/${n}`;try{return(await this.client.getRequest(o+"/?limit=1000&recursive=false",t).then(a=>a.items||[])).map(a=>{var u;const{conversationName:i,modelId:d}=$(a);return{id:((u=a.url)==null?void 0:u.replace("conversations/",""))||a.name,name:i,folderId:n,createdAt:a.createdAt,updatedAt:a.updatedAt,model:{id:d,name:d}}})}catch(c){if(E(c))return[];throw c}}async getConversation(t,s){try{return await this.client.getRequest(S(t),s)}catch(e){if(E(e))return null;throw e}}async getFile(t,s){try{const e=`${m.VERSION}/${_(t)}`;return await this.client.getRequest(e,s)}catch(e){if(E(e))return null;throw e}}async getFileBlob(t,s){try{const e=`${m.VERSION}/${_(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==null?void 0:t.id)||g(t),{name:n,folderId:o,model:c,messages:a}=t,i={id:e,name:n,folderId:o,model:c,messages:a||[],selectedAddons:t.selectedAddons||[],prompt:t.prompt||"",temperature:t.temperature||.7,createdAt:Date.now(),updatedAt:Date.now()};return await this.client.request(S(e),s,{method:"PUT",body:i}),{id:e,name:n,folderId:o,model:c,createdAt:i.createdAt,updatedAt:i.updatedAt}}async generateConversationLink(t,s){return await this.client.postRequest(m.SHARE_CONVERSATION,t,{body:s})}async getSharedConversations(t,s){return await this.client.postRequest(m.SHARE_CONVERSATION_LIST,t,{body:s})}async revokeSharedConversations(t,s){await this.client.postRequest(m.SHARE_CONVERSATION_REVOKE,t,{body:s})}async updateConversation(t,s,e){const n=await this.getConversation(t,e);if(!n)throw new Error(`Conversation with id ${t} not found`);const o={...n,...s,updatedAt:Date.now()};return await this.client.request(S(t),e,{method:"PUT",body:o})}async deleteConversation(t,s){t!=null&&t.isShared?await this.client.postRequest(m.SHARE_CONVERSATION_DISCARD,s,{body:{resources:[{url:t==null?void 0:t.url}]}}):await this.client.request(S(decodeURI(t==null?void 0:t.id)),s,{method:"DELETE"})}async streamChat(t,s){const e=t.model.id,n=encodeURIComponent(e),o=`${m.CHAT(n)}?api-version=${this.client.config.version}`,c={messages:t.messages,stream:!0,temperature:.7,max_tokens:4096};return await this.client.stream(o,s,{method:"POST",body:c,chatReference:t.conversationId})}}class k{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 n=`${this.config.host}${t}`,o={...A(this.config.apiKey,{jwt:s,chatReference:e.chatReference}),...e.headers};try{return(await h(n,o,e)).blob()}catch(c){throw console.error("API Request Exception",{method:e.method,url:n,error:c instanceof Error?c.message:String(c)}),c}}async request(t,s,e){const n=Date.now(),o=`${this.config.host}${t}`,c={...A(this.config.apiKey,{jwt:s,chatReference:e.chatReference}),...e.headers};this.addInfoRequestLog("API Request",o,e,c);try{const a=await h(o,c,e),i=Date.now()-n;let d;const u=await a.text();try{d=u?JSON.parse(u):{}}catch{if(this.addErrorRequestParsing(o,e,a,i,u),!a.ok)throw new Error(`API request failed: ${a.status} ${a.statusText} - ${u.substring(0,100)}`);d={data:u}}if(!a.ok){this.addErrorRequestLog(o,e,a,i,d);const C=O(d,a);throw new Error(`API request failed: ${C}`)}return d}catch(a){const i=Date.now()-n;throw console.error("API Request Exception",{method:e.method,url:o,duration:`${i}ms`,error:a instanceof Error?a.message:String(a)}),a}}async stream(t,s,e){const n=`${this.config.host}${t}`,o=A(this.config.apiKey,{jwt:s,chatReference:e.chatReference},e.headers);this.addInfoRequestLog("Stream Request",n,e,o);const c=await h(n,o,e);if(!c.ok)throw console.error("Stream Request Failed",{method:e.method||"POST",url:n,status:c.status,statusText:c.statusText}),new Error(`Stream request failed: ${c.status} ${c.statusText}`);if(!c.body)throw new Error("No response body for stream");return c.body}addInfoRequestLog(t,s,e,n){const o={method:e.method||"GET",url:s,headers:U(n)};e.body&&(o.body=e.body),console.info(t,o)}addErrorRequestLog(t,s,e,n,o){console.error("API Request Failed",{method:s.method,url:t,status:e.status,statusText:e.statusText,duration:`${n}ms`,response:o})}addErrorRequestParsing(t,s,e,n,o){console.error("API Response Parse Error",{method:s.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=p;exports.ChatStreamSSEClient=y;exports.ConversationApi=j;exports.DIAL_API_ROUTES=m;exports.DialApiClient=k;exports.InvitationType=I;exports.chatStreamSSEClient=N;exports.decodeApiUrl=b;exports.encodeApiUrl=_;exports.generateConversationId=g;exports.getErrorMessage=O;exports.handleStreamMessage=T;exports.mergeMessages=v;exports.parseConversationName=$;exports.sendRequest=h;exports.streamChatResponse=V;
|
package/index.d.ts
ADDED
package/index.mjs
ADDED
|
@@ -0,0 +1,484 @@
|
|
|
1
|
+
const l = "/v1/ops/resource/share", m = {
|
|
2
|
+
VERSION: "/v1",
|
|
3
|
+
BUCKET: "/v1/bucket",
|
|
4
|
+
CONVERSATIONS: "/v1/metadata/conversations",
|
|
5
|
+
CONVERSATION_BY_ID: (r) => `/v1/metadata/conversations/${r}`,
|
|
6
|
+
CHAT: (r) => `/openai/deployments/${r}/chat/completions`,
|
|
7
|
+
MODELS: "/openai/models",
|
|
8
|
+
CONFIGURATION: (r) => `/v1/deployments/${r}/configuration`,
|
|
9
|
+
SHARE_CONVERSATION: `${l}/create`,
|
|
10
|
+
SHARE_CONVERSATION_ACCEPT: (r) => `/v1/invitations/${r}?accept=true`,
|
|
11
|
+
SHARE_CONVERSATION_DETAILS: (r) => `/v1/invitations/${r}`,
|
|
12
|
+
SHARE_CONVERSATION_LIST: `${l}/list`,
|
|
13
|
+
SHARE_CONVERSATION_DISCARD: `${l}/discard`,
|
|
14
|
+
SHARE_CONVERSATION_REVOKE: `${l}/revoke`
|
|
15
|
+
};
|
|
16
|
+
var _ = /* @__PURE__ */ ((r) => (r.CSV = "text/csv", r.TABLE = "application/dial-ttyd-table", r.PLOTLY = "application/vnd.plotly.v1+json", r.MARKDOWN = "text/markdown", r.JSON = "application/json", r.JPEG = "image/jpeg", r.PNG = "image/png", r.CUSTOM_DATA_GRID = "custom_data_grid", r.CUSTOM_CHART = "custom_chart", r))(_ || {}), O = /* @__PURE__ */ ((r) => (r.LINK = "link", r))(O || {});
|
|
17
|
+
const C = (r) => {
|
|
18
|
+
var t, s, e, n, o, c;
|
|
19
|
+
return r.content ? (console.info(`Using direct content format: ${r.content}`), r.content) : (e = (s = (t = r.choices) == null ? void 0 : t[0]) == null ? void 0 : s.delta) != null && e.content ? (console.info(`Using OpenAI delta format: ${r.choices[0].delta.content}`), r.choices[0].delta.content) : (c = (o = (n = r.choices) == null ? void 0 : n[0]) == null ? void 0 : o.message) != null && c.content ? (console.info(
|
|
20
|
+
`Using complete message format: ${r.choices[0].message.content}`
|
|
21
|
+
), r.choices[0].message.content) : (console.info("Unknown SSE data format:", r), null);
|
|
22
|
+
}, p = (r, t, s) => {
|
|
23
|
+
if (t == null || t(r), s) {
|
|
24
|
+
const e = C(r);
|
|
25
|
+
e && s(e);
|
|
26
|
+
}
|
|
27
|
+
}, T = (r, t) => r.error || r.message || `${t.status} ${t.statusText}`, N = (r, t) => {
|
|
28
|
+
const s = r == null ? void 0 : r.reduce(
|
|
29
|
+
(e, n) => (e[n.index] = n, e),
|
|
30
|
+
{}
|
|
31
|
+
);
|
|
32
|
+
return t.forEach((e) => {
|
|
33
|
+
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;
|
|
34
|
+
}), Object.values(s);
|
|
35
|
+
}, H = (r, t) => {
|
|
36
|
+
const s = structuredClone(r);
|
|
37
|
+
return t.forEach((e) => {
|
|
38
|
+
e.errorMessage && (s.errorMessage = e.errorMessage), e.role && (s.role = e.role), e.responseId && (s.responseId = e.responseId), e.content && (s.content = `${s.content || ""}${e.content}`), 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(
|
|
39
|
+
e.custom_content.attachments
|
|
40
|
+
)), e.custom_content.stages && (s.custom_content.stages || (s.custom_content.stages = []), s.custom_content.stages = N(
|
|
41
|
+
s.custom_content.stages,
|
|
42
|
+
e.custom_content.stages
|
|
43
|
+
)), 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));
|
|
44
|
+
}), s;
|
|
45
|
+
}, $ = (r) => (r == null ? void 0 : r.toLowerCase().replace(/[^\p{L}\p{N}]+/gu, "-").replace(/^-+|-+$/g, "").replace(/-/g, " ")) || "", y = (r) => {
|
|
46
|
+
var n;
|
|
47
|
+
const t = ((n = r.name) == null ? void 0 : n.split("__")) || [], s = t.length > 1 ? t.slice(1).join("__") : r.name;
|
|
48
|
+
return { modelId: t[0], conversationName: s };
|
|
49
|
+
}, g = (r) => {
|
|
50
|
+
const t = Date.now(), s = $(r.name);
|
|
51
|
+
return `${r.folderId}/${s}-${t}`;
|
|
52
|
+
}, f = async (r, t, s) => await fetch(r, {
|
|
53
|
+
method: s.method || "GET",
|
|
54
|
+
headers: t,
|
|
55
|
+
body: s.body ? JSON.stringify(s.body) : void 0
|
|
56
|
+
});
|
|
57
|
+
function I(r) {
|
|
58
|
+
return r.split("/").map((t) => encodeURIComponent(t)).join("/");
|
|
59
|
+
}
|
|
60
|
+
function L(r) {
|
|
61
|
+
return r.split("/").map((t) => decodeURIComponent(t)).join("/");
|
|
62
|
+
}
|
|
63
|
+
const w = {
|
|
64
|
+
CHAT: "/api/chat"
|
|
65
|
+
}, q = "application/json", x = "Content-Type", R = "Api-Key", v = "X-CONVERSATION-ID", S = (r, t, s) => {
|
|
66
|
+
const e = {
|
|
67
|
+
[x]: (t == null ? void 0 : t.contentType) || q
|
|
68
|
+
};
|
|
69
|
+
return t != null && t.jwt ? e.Authorization = `Bearer ${t.jwt}` : r && (e[R] = r), t != null && t.chatReference && (e[v] = t.chatReference), { ...e, ...s };
|
|
70
|
+
}, V = (r) => {
|
|
71
|
+
const t = { ...r };
|
|
72
|
+
return t[R] && (t[R] = t[R].substring(0, 8) + "...[REDACTED]"), t.Authorization && (t.Authorization = "Bearer [REDACTED]"), t;
|
|
73
|
+
};
|
|
74
|
+
class b {
|
|
75
|
+
constructor() {
|
|
76
|
+
this.decoder = new TextDecoder();
|
|
77
|
+
}
|
|
78
|
+
async streamChat(t, s, e = {}, n) {
|
|
79
|
+
const { onMessage: o, onError: c, onComplete: a, signal: i } = e;
|
|
80
|
+
try {
|
|
81
|
+
const d = await this.initializeStreamRequest(
|
|
82
|
+
t,
|
|
83
|
+
s,
|
|
84
|
+
i,
|
|
85
|
+
n
|
|
86
|
+
);
|
|
87
|
+
await this.processStreamData(d, o), a == null || a();
|
|
88
|
+
} catch (d) {
|
|
89
|
+
this.handleStreamError(d, c);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
async initializeStreamRequest(t, s, e, n) {
|
|
93
|
+
const o = S(void 0, {
|
|
94
|
+
jwt: n
|
|
95
|
+
}), c = await f(
|
|
96
|
+
t,
|
|
97
|
+
{
|
|
98
|
+
Accept: "text/event-stream",
|
|
99
|
+
...o
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
method: "POST",
|
|
103
|
+
body: s
|
|
104
|
+
}
|
|
105
|
+
);
|
|
106
|
+
if (!c.ok) {
|
|
107
|
+
const a = await c.text();
|
|
108
|
+
throw new Error(`HTTP ${c.status}: ${a}`);
|
|
109
|
+
}
|
|
110
|
+
if (!c.body)
|
|
111
|
+
throw new Error("No response body");
|
|
112
|
+
return c.body.getReader();
|
|
113
|
+
}
|
|
114
|
+
async processStreamData(t, s) {
|
|
115
|
+
let e = "";
|
|
116
|
+
try {
|
|
117
|
+
for (; ; ) {
|
|
118
|
+
const { done: n, value: o } = await t.read();
|
|
119
|
+
if (n) {
|
|
120
|
+
e.trim() && this.parseSSEDataLine(e, s);
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
const c = this.decoder.decode(o, { stream: !0 });
|
|
124
|
+
e += c;
|
|
125
|
+
const a = e.split(`
|
|
126
|
+
`);
|
|
127
|
+
e = a.pop() || "";
|
|
128
|
+
for (const i of a)
|
|
129
|
+
this.parseSSEDataLine(i, s);
|
|
130
|
+
}
|
|
131
|
+
} finally {
|
|
132
|
+
t.releaseLock();
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
handleStreamError(t, s) {
|
|
136
|
+
const e = t instanceof Error ? t : new Error(String(t));
|
|
137
|
+
throw s == null || s(e), e;
|
|
138
|
+
}
|
|
139
|
+
parseSSEDataLine(t, s) {
|
|
140
|
+
const e = t.trim();
|
|
141
|
+
if (!(!e || e.startsWith(":")) && e.startsWith("data: ")) {
|
|
142
|
+
const n = e.slice(6);
|
|
143
|
+
if (n === "[DONE]") {
|
|
144
|
+
console.info("SSE: Stream completed");
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
try {
|
|
148
|
+
const o = JSON.parse(n);
|
|
149
|
+
console.info(`SSE: Parsed data: ${o}`), s == null || s(o);
|
|
150
|
+
} catch (o) {
|
|
151
|
+
console.error(`Failed to parse SSE data: ${n} ${o}`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
const P = new b(), D = async (r, t, s, e) => {
|
|
157
|
+
const { onMessage: n, onToken: o, onComplete: c, onError: a, model: i, signal: d } = s, u = { conversationId: r, messages: t, model: i };
|
|
158
|
+
await P.streamChat(
|
|
159
|
+
w.CHAT,
|
|
160
|
+
u,
|
|
161
|
+
{
|
|
162
|
+
onMessage: (A) => p(A, n, o),
|
|
163
|
+
onComplete: c,
|
|
164
|
+
onError: a,
|
|
165
|
+
signal: d
|
|
166
|
+
},
|
|
167
|
+
e
|
|
168
|
+
);
|
|
169
|
+
}, h = (r) => r instanceof Error && r.message.includes("404"), E = (r) => `/v1/conversations/${I(r)}`;
|
|
170
|
+
class U {
|
|
171
|
+
constructor(t) {
|
|
172
|
+
this.client = t;
|
|
173
|
+
}
|
|
174
|
+
async getConversations(t, s, e) {
|
|
175
|
+
const n = `${s ? e ? `${s}/${e}` : `${s}` : ""}`, o = `${m.CONVERSATIONS}/${n}`;
|
|
176
|
+
try {
|
|
177
|
+
return (await this.client.getRequest(o + "/?limit=1000&recursive=false", t).then((a) => a.items || [])).map((a) => {
|
|
178
|
+
var u;
|
|
179
|
+
const { conversationName: i, modelId: d } = y(a);
|
|
180
|
+
return {
|
|
181
|
+
id: ((u = a.url) == null ? void 0 : u.replace("conversations/", "")) || a.name,
|
|
182
|
+
name: i,
|
|
183
|
+
folderId: n,
|
|
184
|
+
createdAt: a.createdAt,
|
|
185
|
+
updatedAt: a.updatedAt,
|
|
186
|
+
model: { id: d, name: d }
|
|
187
|
+
};
|
|
188
|
+
});
|
|
189
|
+
} catch (c) {
|
|
190
|
+
if (h(c))
|
|
191
|
+
return [];
|
|
192
|
+
throw c;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
async getConversation(t, s) {
|
|
196
|
+
try {
|
|
197
|
+
return await this.client.getRequest(
|
|
198
|
+
E(t),
|
|
199
|
+
s
|
|
200
|
+
);
|
|
201
|
+
} catch (e) {
|
|
202
|
+
if (h(e))
|
|
203
|
+
return null;
|
|
204
|
+
throw e;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
async getFile(t, s) {
|
|
208
|
+
try {
|
|
209
|
+
const e = `${m.VERSION}/${I(t)}`;
|
|
210
|
+
return await this.client.getRequest(e, s);
|
|
211
|
+
} catch (e) {
|
|
212
|
+
if (h(e))
|
|
213
|
+
return null;
|
|
214
|
+
throw e;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
async getFileBlob(t, s) {
|
|
218
|
+
try {
|
|
219
|
+
const e = `${m.VERSION}/${I(t)}`;
|
|
220
|
+
return await this.client.requestBlob(e, s, { method: "GET" });
|
|
221
|
+
} catch (e) {
|
|
222
|
+
if (h(e))
|
|
223
|
+
return null;
|
|
224
|
+
throw e;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
async createConversation(t, s) {
|
|
228
|
+
const e = (t == null ? void 0 : t.id) || g(t), { name: n, folderId: o, model: c, messages: a } = t, i = {
|
|
229
|
+
id: e,
|
|
230
|
+
name: n,
|
|
231
|
+
folderId: o,
|
|
232
|
+
model: c,
|
|
233
|
+
messages: a || [],
|
|
234
|
+
selectedAddons: t.selectedAddons || [],
|
|
235
|
+
prompt: t.prompt || "",
|
|
236
|
+
temperature: t.temperature || 0.7,
|
|
237
|
+
createdAt: Date.now(),
|
|
238
|
+
updatedAt: Date.now()
|
|
239
|
+
};
|
|
240
|
+
return await this.client.request(
|
|
241
|
+
E(e),
|
|
242
|
+
s,
|
|
243
|
+
{
|
|
244
|
+
method: "PUT",
|
|
245
|
+
body: i
|
|
246
|
+
}
|
|
247
|
+
), {
|
|
248
|
+
id: e,
|
|
249
|
+
name: n,
|
|
250
|
+
folderId: o,
|
|
251
|
+
model: c,
|
|
252
|
+
createdAt: i.createdAt,
|
|
253
|
+
updatedAt: i.updatedAt
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
async generateConversationLink(t, s) {
|
|
257
|
+
return await this.client.postRequest(
|
|
258
|
+
m.SHARE_CONVERSATION,
|
|
259
|
+
t,
|
|
260
|
+
{
|
|
261
|
+
body: s
|
|
262
|
+
}
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
async getSharedConversations(t, s) {
|
|
266
|
+
return await this.client.postRequest(
|
|
267
|
+
m.SHARE_CONVERSATION_LIST,
|
|
268
|
+
t,
|
|
269
|
+
{
|
|
270
|
+
body: s
|
|
271
|
+
}
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
async revokeSharedConversations(t, s) {
|
|
275
|
+
await this.client.postRequest(
|
|
276
|
+
m.SHARE_CONVERSATION_REVOKE,
|
|
277
|
+
t,
|
|
278
|
+
{
|
|
279
|
+
body: s
|
|
280
|
+
}
|
|
281
|
+
);
|
|
282
|
+
}
|
|
283
|
+
async updateConversation(t, s, e) {
|
|
284
|
+
const n = await this.getConversation(t, e);
|
|
285
|
+
if (!n)
|
|
286
|
+
throw new Error(`Conversation with id ${t} not found`);
|
|
287
|
+
const o = {
|
|
288
|
+
...n,
|
|
289
|
+
...s,
|
|
290
|
+
updatedAt: Date.now()
|
|
291
|
+
};
|
|
292
|
+
return await this.client.request(
|
|
293
|
+
E(t),
|
|
294
|
+
e,
|
|
295
|
+
{
|
|
296
|
+
method: "PUT",
|
|
297
|
+
body: o
|
|
298
|
+
}
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
async deleteConversation(t, s) {
|
|
302
|
+
t != null && t.isShared ? await this.client.postRequest(
|
|
303
|
+
m.SHARE_CONVERSATION_DISCARD,
|
|
304
|
+
s,
|
|
305
|
+
{
|
|
306
|
+
body: {
|
|
307
|
+
resources: [
|
|
308
|
+
{
|
|
309
|
+
url: t == null ? void 0 : t.url
|
|
310
|
+
}
|
|
311
|
+
]
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
) : await this.client.request(
|
|
315
|
+
E(decodeURI(t == null ? void 0 : t.id)),
|
|
316
|
+
s,
|
|
317
|
+
{
|
|
318
|
+
method: "DELETE"
|
|
319
|
+
}
|
|
320
|
+
);
|
|
321
|
+
}
|
|
322
|
+
async streamChat(t, s) {
|
|
323
|
+
const e = t.model.id, n = encodeURIComponent(e), o = `${m.CHAT(n)}?api-version=${this.client.config.version}`, c = {
|
|
324
|
+
messages: t.messages,
|
|
325
|
+
stream: !0,
|
|
326
|
+
temperature: 0.7,
|
|
327
|
+
max_tokens: 4096
|
|
328
|
+
};
|
|
329
|
+
return await this.client.stream(o, s, {
|
|
330
|
+
method: "POST",
|
|
331
|
+
body: c,
|
|
332
|
+
chatReference: t.conversationId
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
class j {
|
|
337
|
+
constructor(t) {
|
|
338
|
+
this.config = t, console.info("DialApiClient initialized", {
|
|
339
|
+
host: t.host || "NOT SET",
|
|
340
|
+
hasApiKey: !!t.apiKey,
|
|
341
|
+
version: t.version
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
async getRequest(t, s, e) {
|
|
345
|
+
return this.request(t, s, { ...e, method: "GET" });
|
|
346
|
+
}
|
|
347
|
+
async postRequest(t, s, e) {
|
|
348
|
+
return this.request(t, s, { ...e, method: "POST" });
|
|
349
|
+
}
|
|
350
|
+
async requestBlob(t, s, e) {
|
|
351
|
+
const n = `${this.config.host}${t}`, o = {
|
|
352
|
+
...S(this.config.apiKey, {
|
|
353
|
+
jwt: s,
|
|
354
|
+
chatReference: e.chatReference
|
|
355
|
+
}),
|
|
356
|
+
...e.headers
|
|
357
|
+
};
|
|
358
|
+
try {
|
|
359
|
+
return (await f(n, o, e)).blob();
|
|
360
|
+
} catch (c) {
|
|
361
|
+
throw console.error("API Request Exception", {
|
|
362
|
+
method: e.method,
|
|
363
|
+
url: n,
|
|
364
|
+
error: c instanceof Error ? c.message : String(c)
|
|
365
|
+
}), c;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
async request(t, s, e) {
|
|
369
|
+
const n = Date.now(), o = `${this.config.host}${t}`, c = {
|
|
370
|
+
...S(this.config.apiKey, {
|
|
371
|
+
jwt: s,
|
|
372
|
+
chatReference: e.chatReference
|
|
373
|
+
}),
|
|
374
|
+
...e.headers
|
|
375
|
+
};
|
|
376
|
+
this.addInfoRequestLog("API Request", o, e, c);
|
|
377
|
+
try {
|
|
378
|
+
const a = await f(o, c, e), i = Date.now() - n;
|
|
379
|
+
let d;
|
|
380
|
+
const u = await a.text();
|
|
381
|
+
try {
|
|
382
|
+
d = u ? JSON.parse(u) : {};
|
|
383
|
+
} catch {
|
|
384
|
+
if (this.addErrorRequestParsing(
|
|
385
|
+
o,
|
|
386
|
+
e,
|
|
387
|
+
a,
|
|
388
|
+
i,
|
|
389
|
+
u
|
|
390
|
+
), !a.ok)
|
|
391
|
+
throw new Error(
|
|
392
|
+
`API request failed: ${a.status} ${a.statusText} - ${u.substring(0, 100)}`
|
|
393
|
+
);
|
|
394
|
+
d = { data: u };
|
|
395
|
+
}
|
|
396
|
+
if (!a.ok) {
|
|
397
|
+
this.addErrorRequestLog(o, e, a, i, d);
|
|
398
|
+
const A = T(d, a);
|
|
399
|
+
throw new Error(`API request failed: ${A}`);
|
|
400
|
+
}
|
|
401
|
+
return d;
|
|
402
|
+
} catch (a) {
|
|
403
|
+
const i = Date.now() - n;
|
|
404
|
+
throw console.error("API Request Exception", {
|
|
405
|
+
method: e.method,
|
|
406
|
+
url: o,
|
|
407
|
+
duration: `${i}ms`,
|
|
408
|
+
error: a instanceof Error ? a.message : String(a)
|
|
409
|
+
}), a;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
async stream(t, s, e) {
|
|
413
|
+
const n = `${this.config.host}${t}`, o = S(
|
|
414
|
+
this.config.apiKey,
|
|
415
|
+
{
|
|
416
|
+
jwt: s,
|
|
417
|
+
chatReference: e.chatReference
|
|
418
|
+
},
|
|
419
|
+
e.headers
|
|
420
|
+
);
|
|
421
|
+
this.addInfoRequestLog("Stream Request", n, e, o);
|
|
422
|
+
const c = await f(n, o, e);
|
|
423
|
+
if (!c.ok)
|
|
424
|
+
throw console.error("Stream Request Failed", {
|
|
425
|
+
method: e.method || "POST",
|
|
426
|
+
url: n,
|
|
427
|
+
status: c.status,
|
|
428
|
+
statusText: c.statusText
|
|
429
|
+
}), new Error(
|
|
430
|
+
`Stream request failed: ${c.status} ${c.statusText}`
|
|
431
|
+
);
|
|
432
|
+
if (!c.body)
|
|
433
|
+
throw new Error("No response body for stream");
|
|
434
|
+
return c.body;
|
|
435
|
+
}
|
|
436
|
+
addInfoRequestLog(t, s, e, n) {
|
|
437
|
+
const o = {
|
|
438
|
+
method: e.method || "GET",
|
|
439
|
+
url: s,
|
|
440
|
+
headers: V(n)
|
|
441
|
+
};
|
|
442
|
+
e.body && (o.body = e.body), console.info(t, o);
|
|
443
|
+
}
|
|
444
|
+
addErrorRequestLog(t, s, e, n, o) {
|
|
445
|
+
console.error("API Request Failed", {
|
|
446
|
+
method: s.method,
|
|
447
|
+
url: t,
|
|
448
|
+
status: e.status,
|
|
449
|
+
statusText: e.statusText,
|
|
450
|
+
duration: `${n}ms`,
|
|
451
|
+
response: o
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
addErrorRequestParsing(t, s, e, n, o) {
|
|
455
|
+
console.error("API Response Parse Error", {
|
|
456
|
+
method: s.method,
|
|
457
|
+
url: t,
|
|
458
|
+
status: e.status,
|
|
459
|
+
statusText: e.statusText,
|
|
460
|
+
duration: `${n}ms`,
|
|
461
|
+
responseText: o.substring(0, 200),
|
|
462
|
+
// First 200 chars
|
|
463
|
+
error: "Response is not valid JSON"
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
export {
|
|
468
|
+
_ as AttachmentType,
|
|
469
|
+
b as ChatStreamSSEClient,
|
|
470
|
+
U as ConversationApi,
|
|
471
|
+
m as DIAL_API_ROUTES,
|
|
472
|
+
j as DialApiClient,
|
|
473
|
+
O as InvitationType,
|
|
474
|
+
P as chatStreamSSEClient,
|
|
475
|
+
L as decodeApiUrl,
|
|
476
|
+
I as encodeApiUrl,
|
|
477
|
+
g as generateConversationId,
|
|
478
|
+
T as getErrorMessage,
|
|
479
|
+
p as handleStreamMessage,
|
|
480
|
+
H as mergeMessages,
|
|
481
|
+
y as parseConversationName,
|
|
482
|
+
f as sendRequest,
|
|
483
|
+
D as streamChatResponse
|
|
484
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Role, Message } from '@epam/ai-dial-shared';
|
|
2
|
+
import { ModelInfo } from './model';
|
|
3
|
+
export interface RequestStreamBody {
|
|
4
|
+
conversationId: string;
|
|
5
|
+
messages: Message[];
|
|
6
|
+
model: ModelInfo;
|
|
7
|
+
content?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface MessageStreamResponse {
|
|
10
|
+
id?: string;
|
|
11
|
+
content?: string;
|
|
12
|
+
choices: MessageChoices[];
|
|
13
|
+
}
|
|
14
|
+
export interface MessageChoices {
|
|
15
|
+
delta: {
|
|
16
|
+
content?: string;
|
|
17
|
+
role?: Role;
|
|
18
|
+
custom_content?: unknown;
|
|
19
|
+
};
|
|
20
|
+
message: {
|
|
21
|
+
content?: string;
|
|
22
|
+
};
|
|
23
|
+
finish_reason?: string;
|
|
24
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { ConversationInfo } from '@epam/ai-dial-shared';
|
|
2
|
+
import { Message } from './message';
|
|
3
|
+
import { ModelInfo } from './model';
|
|
4
|
+
import { InvitationType } from '../types/invitation-type';
|
|
5
|
+
import { ResourceTypes, ShareTarget } from '../constants/share-conversation';
|
|
6
|
+
export interface CreateConversationRequest {
|
|
7
|
+
name: string;
|
|
8
|
+
folderId: string;
|
|
9
|
+
model?: ModelInfo;
|
|
10
|
+
messages?: Message[];
|
|
11
|
+
id?: string;
|
|
12
|
+
prompt?: string;
|
|
13
|
+
temperature?: number;
|
|
14
|
+
selectedAddons?: string[];
|
|
15
|
+
}
|
|
16
|
+
export interface UpdateConversationRequest {
|
|
17
|
+
name?: string;
|
|
18
|
+
folderId?: string;
|
|
19
|
+
model?: ModelInfo;
|
|
20
|
+
prompt?: string;
|
|
21
|
+
temperature?: number;
|
|
22
|
+
messages: Message[];
|
|
23
|
+
}
|
|
24
|
+
export interface ConversationListResponse {
|
|
25
|
+
conversations: ConversationInfo[];
|
|
26
|
+
total?: number;
|
|
27
|
+
hasMore?: boolean;
|
|
28
|
+
}
|
|
29
|
+
export interface ConversationResource {
|
|
30
|
+
url: string;
|
|
31
|
+
}
|
|
32
|
+
export interface ConversationData {
|
|
33
|
+
invitationType?: InvitationType;
|
|
34
|
+
resources: ConversationResource[];
|
|
35
|
+
}
|
|
36
|
+
export interface GeneratedLinkResponse {
|
|
37
|
+
invitationLink: string;
|
|
38
|
+
}
|
|
39
|
+
export interface SharedConversationsRequest {
|
|
40
|
+
resourceTypes: ResourceTypes[];
|
|
41
|
+
with: ShareTarget;
|
|
42
|
+
}
|
|
43
|
+
export interface SharedConversationInfo extends ConversationInfo {
|
|
44
|
+
bucket: string;
|
|
45
|
+
url: string;
|
|
46
|
+
parentPath?: string;
|
|
47
|
+
}
|
|
48
|
+
export interface SharedConversations {
|
|
49
|
+
resources: SharedConversationInfo[];
|
|
50
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface GridAttachmentContent {
|
|
2
|
+
data: {
|
|
3
|
+
schema: Schema;
|
|
4
|
+
data: RowData[];
|
|
5
|
+
};
|
|
6
|
+
metadata: Metadata;
|
|
7
|
+
layout: Layout;
|
|
8
|
+
}
|
|
9
|
+
export interface Schema {
|
|
10
|
+
fields: SchemaField[];
|
|
11
|
+
}
|
|
12
|
+
export interface SchemaField {
|
|
13
|
+
name: string;
|
|
14
|
+
type: string;
|
|
15
|
+
}
|
|
16
|
+
export interface RowData {
|
|
17
|
+
index: number;
|
|
18
|
+
value: number;
|
|
19
|
+
[key: string]: unknown;
|
|
20
|
+
}
|
|
21
|
+
export interface Metadata {
|
|
22
|
+
time_column: string;
|
|
23
|
+
pinned_columns?: string[];
|
|
24
|
+
}
|
|
25
|
+
export interface Layout {
|
|
26
|
+
height: number;
|
|
27
|
+
width: number;
|
|
28
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@epam/statgpt-dial-toolkit",
|
|
3
|
+
"version": "0.1.0-rc.0",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"exports": {
|
|
6
|
+
".": {
|
|
7
|
+
"import": "./index.mjs",
|
|
8
|
+
"require": "./index.cjs",
|
|
9
|
+
"types": "./index.d.ts"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"main": "./index.cjs",
|
|
13
|
+
"browser": "./index.mjs",
|
|
14
|
+
"module": "./index.mjs",
|
|
15
|
+
"types": "./index.d.ts",
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@epam/statgpt-shared-toolkit": "0.1.0-rc.0",
|
|
18
|
+
"@epam/ai-dial-shared": "^0.34.0"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare enum AttachmentType {
|
|
2
|
+
CSV = "text/csv",
|
|
3
|
+
TABLE = "application/dial-ttyd-table",
|
|
4
|
+
PLOTLY = "application/vnd.plotly.v1+json",
|
|
5
|
+
MARKDOWN = "text/markdown",
|
|
6
|
+
JSON = "application/json",
|
|
7
|
+
JPEG = "image/jpeg",
|
|
8
|
+
PNG = "image/png",
|
|
9
|
+
CUSTOM_DATA_GRID = "custom_data_grid",
|
|
10
|
+
CUSTOM_CHART = "custom_chart"
|
|
11
|
+
}
|
package/types/index.d.ts
ADDED
package/utils/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const isError: (error: unknown) => boolean;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Entity } from '@epam/ai-dial-shared';
|
|
2
|
+
import { CreateConversationRequest } from '../models/conversation';
|
|
3
|
+
export declare const parseConversationName: (item: Entity) => {
|
|
4
|
+
modelId: string;
|
|
5
|
+
conversationName: string;
|
|
6
|
+
};
|
|
7
|
+
export declare const generateConversationId: (data: CreateConversationRequest) => string;
|
package/utils/url.d.ts
ADDED