@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 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
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/mit)
8
+ [![Typescript](https://img.shields.io/badge/Typescript-5+-61dafb.svg)](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,3 @@
1
+ export * from './chat-streaming-api';
2
+ export * from './conversation-api';
3
+ export * from './dial-api-client';
@@ -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
+ };
@@ -0,0 +1,7 @@
1
+ export declare enum ResourceTypes {
2
+ CONVERSATION = "CONVERSATION"
3
+ }
4
+ export declare enum ShareTarget {
5
+ ME = "me",
6
+ OTHERS = "others"
7
+ }
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
@@ -0,0 +1,5 @@
1
+ export * from './constants/api-urls';
2
+ export * from './models';
3
+ export * from './types';
4
+ export * from './utils';
5
+ export * from './api';
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,6 @@
1
+ export interface DialApiConfig {
2
+ host: string;
3
+ version: string;
4
+ apiKey?: string;
5
+ jwt?: string;
6
+ }
@@ -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
+ }
@@ -0,0 +1,6 @@
1
+ export * from './chat-stream';
2
+ export * from './conversation';
3
+ export * from './dial-config';
4
+ export * from './grid-attachment';
5
+ export * from './message';
6
+ export * from './model';
@@ -0,0 +1,5 @@
1
+ import { Message as DialMessage } from '@epam/ai-dial-shared';
2
+ export interface Message extends DialMessage {
3
+ id?: string;
4
+ timestamp?: number;
5
+ }
@@ -0,0 +1,4 @@
1
+ export interface ModelInfo {
2
+ id: string;
3
+ name?: string;
4
+ }
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
+ }
@@ -0,0 +1,2 @@
1
+ export * from './attachment-type';
2
+ export * from './invitation-type';
@@ -0,0 +1,3 @@
1
+ export declare enum InvitationType {
2
+ LINK = "link"
3
+ }
@@ -0,0 +1,2 @@
1
+ import { MessageStreamResponse } from '../models/chat-stream';
2
+ export declare const handleStreamMessage: (data: MessageStreamResponse, onMessage?: (data: MessageStreamResponse) => void, onToken?: (token: string) => void) => void;
@@ -0,0 +1,5 @@
1
+ export declare const getErrorMessage: (responseData: {
2
+ data: unknown;
3
+ error?: string;
4
+ message?: string;
5
+ }, response: Response) => string;
@@ -0,0 +1,6 @@
1
+ export * from './chat-stream-api';
2
+ export * from './get-error-message';
3
+ export * from './merge-messages';
4
+ export * from './parse-conversation-name';
5
+ export * from './send-request';
6
+ export * from './url';
@@ -0,0 +1 @@
1
+ export declare const isError: (error: unknown) => boolean;
@@ -0,0 +1,2 @@
1
+ import { Message } from '../models/message';
2
+ export declare const mergeMessages: (source: Message, newMessages: Partial<Message>[]) => Message;
@@ -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;
@@ -0,0 +1,2 @@
1
+ import { RequestOptions } from '../../../shared-toolkit/src/models/request-options';
2
+ export declare const sendRequest: (url: string, headers: Record<string, string>, options: RequestOptions) => Promise<Response>;
@@ -0,0 +1,5 @@
1
+ import { ResourceTypes, ShareTarget } from '../constants/share-conversation';
2
+ export declare const getSharedConversationsRequest: (shareTarget: ShareTarget) => {
3
+ resourceTypes: ResourceTypes[];
4
+ with: ShareTarget;
5
+ };
package/utils/url.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export declare function encodeApiUrl(path: string): string;
2
+ export declare function decodeApiUrl(path: string): string;