llmasaservice-client 0.9.2 → 0.9.4
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/dist/index.d.mts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +12 -16
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +12 -16
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -11,6 +11,7 @@ interface LLMServiceType {
|
|
|
11
11
|
customer?: LLMAsAServiceCustomer;
|
|
12
12
|
url?: string | null;
|
|
13
13
|
agent?: string | null;
|
|
14
|
+
tools?: [] | null;
|
|
14
15
|
}
|
|
15
16
|
declare const LLMService: React.Context<LLMServiceType | undefined>;
|
|
16
17
|
interface UserProviderProps {
|
|
@@ -19,6 +20,7 @@ interface UserProviderProps {
|
|
|
19
20
|
customer?: LLMAsAServiceCustomer;
|
|
20
21
|
url?: string | null;
|
|
21
22
|
agent?: string | null;
|
|
23
|
+
tools?: [] | null;
|
|
22
24
|
}
|
|
23
25
|
declare const LLMServiceProvider: React.FC<UserProviderProps>;
|
|
24
26
|
|
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ interface LLMServiceType {
|
|
|
11
11
|
customer?: LLMAsAServiceCustomer;
|
|
12
12
|
url?: string | null;
|
|
13
13
|
agent?: string | null;
|
|
14
|
+
tools?: [] | null;
|
|
14
15
|
}
|
|
15
16
|
declare const LLMService: React.Context<LLMServiceType | undefined>;
|
|
16
17
|
interface UserProviderProps {
|
|
@@ -19,6 +20,7 @@ interface UserProviderProps {
|
|
|
19
20
|
customer?: LLMAsAServiceCustomer;
|
|
20
21
|
url?: string | null;
|
|
21
22
|
agent?: string | null;
|
|
23
|
+
tools?: [] | null;
|
|
22
24
|
}
|
|
23
25
|
declare const LLMServiceProvider: React.FC<UserProviderProps>;
|
|
24
26
|
|
package/dist/index.js
CHANGED
|
@@ -93,7 +93,7 @@ var useLLM = (options) => {
|
|
|
93
93
|
};
|
|
94
94
|
function send(_0) {
|
|
95
95
|
return __async(this, arguments, function* (prompt, messages = [], data = [], stream = true, allowCaching = true, service = null, conversation = null, abortController = new AbortController(), onComplete, onError) {
|
|
96
|
-
var _a, _b, _c, _d, _e;
|
|
96
|
+
var _a, _b, _c, _d, _e, _f;
|
|
97
97
|
setResponse("");
|
|
98
98
|
setIdle(false);
|
|
99
99
|
let errorInFetch = "";
|
|
@@ -107,7 +107,8 @@ var useLLM = (options) => {
|
|
|
107
107
|
customer: (_b = context == null ? void 0 : context.customer) != null ? _b : {},
|
|
108
108
|
// if no customer, use the projectId as the customer_id
|
|
109
109
|
allowCaching,
|
|
110
|
-
conversationId: conversation
|
|
110
|
+
conversationId: conversation,
|
|
111
|
+
tools: (_c = context == null ? void 0 : context.tools) != null ? _c : []
|
|
111
112
|
});
|
|
112
113
|
const options2 = {
|
|
113
114
|
method: "POST",
|
|
@@ -119,13 +120,13 @@ var useLLM = (options) => {
|
|
|
119
120
|
body: responseBody
|
|
120
121
|
};
|
|
121
122
|
try {
|
|
122
|
-
const url = (
|
|
123
|
+
const url = (_d = context == null ? void 0 : context.url) != null ? _d : "https://chat.llmasaservice.io/";
|
|
123
124
|
const response2 = yield fetch(url, options2);
|
|
124
125
|
if (!response2.ok) {
|
|
125
126
|
errorInFetch = `Error: Network error for service. (${response2.status} ${response2.statusText})`;
|
|
126
127
|
} else {
|
|
127
|
-
setLastCallId((
|
|
128
|
-
const reader = (
|
|
128
|
+
setLastCallId((_e = response2.headers.get("x-callId")) != null ? _e : "");
|
|
129
|
+
const reader = (_f = response2 == null ? void 0 : response2.body) == null ? void 0 : _f.getReader();
|
|
129
130
|
const decoder = new TextDecoder("utf-8");
|
|
130
131
|
setIdle(false);
|
|
131
132
|
if (!stream) {
|
|
@@ -173,7 +174,6 @@ var useLLM = (options) => {
|
|
|
173
174
|
try {
|
|
174
175
|
if (signal.aborted) {
|
|
175
176
|
reader.cancel();
|
|
176
|
-
setIdle(true);
|
|
177
177
|
break;
|
|
178
178
|
}
|
|
179
179
|
const { value, done } = yield reader.read();
|
|
@@ -182,28 +182,24 @@ var useLLM = (options) => {
|
|
|
182
182
|
break;
|
|
183
183
|
}
|
|
184
184
|
if (done) {
|
|
185
|
-
setIdle(true);
|
|
186
185
|
break;
|
|
187
186
|
}
|
|
188
187
|
result += decoder.decode(value);
|
|
189
|
-
if (stream) setResponse(
|
|
188
|
+
if (stream) setResponse(result);
|
|
190
189
|
} catch (error2) {
|
|
191
|
-
if (error2.name
|
|
192
|
-
|
|
190
|
+
if (error2.name !== "AbortError") {
|
|
191
|
+
errorInRead = `Reading error ${error2.message}`;
|
|
193
192
|
}
|
|
194
|
-
errorInRead = `Reading error ${error2.message}`;
|
|
195
193
|
break;
|
|
196
194
|
} finally {
|
|
197
|
-
if (signal.aborted)
|
|
198
|
-
reader.releaseLock();
|
|
199
|
-
}
|
|
195
|
+
if (signal.aborted) reader.releaseLock();
|
|
200
196
|
}
|
|
201
197
|
}
|
|
202
|
-
|
|
198
|
+
setIdle(true);
|
|
199
|
+
if (errorInRead) {
|
|
203
200
|
setError(errorInRead);
|
|
204
201
|
reader.cancel();
|
|
205
202
|
if (onError) onError(errorInRead);
|
|
206
|
-
setIdle(true);
|
|
207
203
|
}
|
|
208
204
|
if (onComplete) {
|
|
209
205
|
onComplete(result);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../index.ts","../src/useLLM.ts","../src/LLMAsAService.tsx"],"sourcesContent":["\r\nexport { useLLM, UseLLMReturnType } from \"./src/useLLM\";\r\nexport * from './src/LLMAsAService';","import { useContext, useState } from \"react\";\r\nimport { LLMService, LLMServiceType } from \"./LLMAsAService\";\r\n\r\nexport interface Message {\r\n role: string;\r\n content: string;\r\n}\r\n\r\nexport interface DataItem {\r\n key: string;\r\n data: string;\r\n}\r\n\r\nexport interface UseLLMReturnType {\r\n send: (\r\n prompt: string,\r\n messages?: Message[],\r\n data?: DataItem[],\r\n stream?: boolean,\r\n allowCaching?: boolean,\r\n service?: string | null,\r\n conversation?: string | null,\r\n abortController?: AbortController,\r\n onComplete?: (result: string) => void,\r\n onError?: (error: string) => void\r\n ) => Promise<ReadableStreamDefaultReader<any> | string | undefined>;\r\n stop: (controller: AbortController | null) => void;\r\n response: string;\r\n idle: boolean;\r\n error: string;\r\n setResponse: (response: string) => void;\r\n lastCallId: string;\r\n}\r\n\r\nexport const useLLM = (options?: LLMServiceType): UseLLMReturnType => {\r\n const [response, setResponse] = useState<string>(\"\");\r\n const [idle, setIdle] = useState<boolean>(true);\r\n const [error, setError] = useState<string>(\"\");\r\n const [lastCallId, setLastCallId] = useState<string>(\"\");\r\n\r\n let context = useContext(LLMService);\r\n if (!context) {\r\n context = options;\r\n }\r\n\r\n if (!context) {\r\n throw new Error(\r\n \"useLLM must be used within a LLMServiceProvider or constructed with options in your useLLM() call.\"\r\n );\r\n }\r\n\r\n /**\r\n * Stops the fetch request and returns the hook to an idle state. Use this to add abort functionality to your UI.\r\n *\r\n * @param controller An AbortController object to stop the fetch request and return this hook to an idle state, the controller should be the same one passed to the send function.\r\n */\r\n const stop = (controller: AbortController | null) => {\r\n if (controller) controller.abort();\r\n setIdle(true);\r\n };\r\n\r\n /**\r\n * Calls the LLM as a service with the given prompt and messages. The response is returned in the response property of the hook.\r\n *\r\n * @param {string} prompt - The prompt to send to the LLM service.\r\n * @param {Message[]} messages - The history and context messages to send to the LLM service, as an array of {role: string, content: string} objects. For example, [{ role: \"system\", content: \"You are a useful assistant.\" }]\r\n * @param {DataItem[]} data - The data to send to the LLM service, as an array of {key: string, data: string} objects. For example, [{ key: \"name\", value: \"John\" }]\r\n * @param {boolean} stream - Determines whether to stream results back in the response property as they return from the service or batch them up and return them all at once in the response property as a string.\r\n * @param {boolean} allowCaching - Determines whether the service can use cached results or not.\r\n * @param {string | null} service - The service to use for the request. If null, load balancing will be applied. This is typically only used for testing.\r\n * @param {string | null} conversation - The conversation of this request. If null, this is a one off call with no conversation history\r\n * @param {AbortController} abortController - The AbortController used to abort this request once it's started. This allows you to add a stop button to your UI.\r\n * @param {(result: string) => void} onComplete - The callback function to be called once the stream completes, with the final result string.\r\n * @param {(error: string) => void} onError - The callback function to be called if an error occurs, with the error string.\r\n * @returns {Promise<ReadableStreamDefaultReader<any> | string | undefined>} - A StreamReader object if stream is true, otherwise a string of the response. Typically this isn't used when streaming, the stream is exposed in the response property.\r\n */\r\n async function send(\r\n prompt: string,\r\n messages: Message[] = [],\r\n data: DataItem[] = [],\r\n stream: boolean = true,\r\n allowCaching: boolean = true,\r\n service: string | null = null, // null means use the default service and apply services load balancing\r\n conversation: string | null = null,\r\n abortController: AbortController = new AbortController(),\r\n onComplete?: (result: string) => void,\r\n onError?: (error: string) => void\r\n ): Promise<ReadableStreamDefaultReader<any> | string | undefined> {\r\n setResponse(\"\");\r\n setIdle(false);\r\n\r\n let errorInFetch = \"\";\r\n\r\n const responseBody = JSON.stringify({\r\n projectId: context?.project_id ?? \"\",\r\n serviceId: service,\r\n agentId: context?.agent,\r\n prompt: prompt,\r\n messages: messages,\r\n data: data,\r\n customer: context?.customer ?? {}, // if no customer, use the projectId as the customer_id\r\n allowCaching: allowCaching,\r\n conversationId: conversation,\r\n });\r\n\r\n // trying to get cloudfront oac going. posts need to be signed, but when i add this the call fails...\r\n const options = {\r\n method: \"POST\",\r\n signal: abortController.signal,\r\n mode: \"cors\" as RequestMode,\r\n headers: {\r\n \"Content-Type\": \"text/plain\",\r\n },\r\n body: responseBody,\r\n };\r\n\r\n try {\r\n const url = context?.url ?? \"https://chat.llmasaservice.io/\";\r\n const response = await fetch(url, options);\r\n if (!response.ok) {\r\n errorInFetch = `Error: Network error for service. (${response.status} ${response.statusText})`;\r\n } else {\r\n setLastCallId(response.headers.get(\"x-callId\") ?? \"\");\r\n const reader =\r\n response?.body?.getReader() as ReadableStreamDefaultReader;\r\n const decoder = new TextDecoder(\"utf-8\");\r\n setIdle(false);\r\n\r\n if (!stream) {\r\n return await readStream(\r\n reader,\r\n decoder,\r\n stream,\r\n {\r\n signal: options.signal,\r\n },\r\n onComplete,\r\n onError\r\n );\r\n } else {\r\n readStream(\r\n reader,\r\n decoder,\r\n stream,\r\n {\r\n signal: options.signal,\r\n },\r\n onComplete,\r\n onError\r\n );\r\n\r\n return reader;\r\n }\r\n }\r\n } catch (errorObject: any) {\r\n errorInFetch = `Error: Having trouble connecting to chat service. (${errorObject.message})`;\r\n }\r\n\r\n if (errorInFetch !== \"\") {\r\n setError(errorInFetch);\r\n if (onError) {\r\n onError(errorInFetch);\r\n }\r\n console.error(`Error: Error in fetch. (${errorInFetch})`);\r\n }\r\n }\r\n\r\n async function readStream(\r\n reader: ReadableStreamDefaultReader,\r\n decoder: TextDecoder,\r\n stream: Boolean = true,\r\n { signal: signal }: { signal: AbortSignal },\r\n onComplete?: (result: string) => void,\r\n onError?: (error: string) => void\r\n ): Promise<string> {\r\n let errorInRead = \"\";\r\n let result = \"\";\r\n\r\n while (true) {\r\n try {\r\n // Check if the stream has been aborted\r\n if (signal.aborted) {\r\n reader.cancel();\r\n setIdle(true);\r\n break;\r\n }\r\n\r\n // Read a chunk of data from the stream\r\n const { value, done } = await reader.read();\r\n\r\n if (decoder.decode(value).startsWith(\"Error:\")) {\r\n errorInRead = decoder.decode(value).substring(6);\r\n break;\r\n }\r\n\r\n // If the stream has been read to the end, exit the loop\r\n if (done) {\r\n setIdle(true);\r\n break;\r\n }\r\n\r\n // Process the chunk of data\r\n result += decoder.decode(value);\r\n if (stream) setResponse((prevState: any) => result);\r\n } catch (error: any) {\r\n if (error.name === \"AbortError\") {\r\n break;\r\n }\r\n\r\n errorInRead = `Reading error ${error.message}`;\r\n break;\r\n } finally {\r\n if (signal.aborted) {\r\n reader.releaseLock();\r\n }\r\n }\r\n }\r\n\r\n if (errorInRead !== \"\") {\r\n setError(errorInRead);\r\n reader.cancel();\r\n if (onError) onError(errorInRead);\r\n setIdle(true);\r\n }\r\n\r\n if (onComplete) {\r\n onComplete(result);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n return { response, send, stop, idle, error, setResponse, lastCallId };\r\n};\r\n\r\nexport default useLLM;\r\n","import React, { createContext, ReactNode } from \"react\";\r\n\r\nexport type LLMAsAServiceCustomer = {\r\n customer_id: string;\r\n customer_name?: string;\r\n customer_user_id?: string;\r\n customer_user_email?: string;\r\n};\r\n\r\nexport interface LLMServiceType {\r\n project_id: string | undefined;\r\n customer?: LLMAsAServiceCustomer;\r\n url?: string | null;\r\n agent?: string | null;\r\n}\r\n\r\nexport const LLMService = createContext<LLMServiceType | undefined>(undefined);\r\n\r\ninterface UserProviderProps {\r\n children: ReactNode;\r\n project_id: string | undefined;\r\n customer?: LLMAsAServiceCustomer;\r\n url?: string | null;\r\n agent?: string | null;\r\n}\r\n\r\nexport const LLMServiceProvider: React.FC<UserProviderProps> = ({\r\n children,\r\n project_id,\r\n customer,\r\n url = \"https://chat.llmasaservice.io/\",\r\n agent = null,\r\n}) => {\r\n return (\r\n <LLMService.Provider value={{ project_id, customer, url, agent }}>\r\n {children}\r\n </LLMService.Provider>\r\n );\r\n};\r\n\r\nexport default LLMServiceProvider;"],"mappings":"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","names":["import_react","React","options","response","error"]}
|
|
1
|
+
{"version":3,"sources":["../index.ts","../src/useLLM.ts","../src/LLMAsAService.tsx"],"sourcesContent":["\r\nexport { useLLM, UseLLMReturnType } from \"./src/useLLM\";\r\nexport * from './src/LLMAsAService';","import { useContext, useState } from \"react\";\r\nimport { LLMService, LLMServiceType } from \"./LLMAsAService\";\r\n\r\nexport interface Message {\r\n role: string;\r\n content: string;\r\n}\r\n\r\nexport interface DataItem {\r\n key: string;\r\n data: string;\r\n}\r\n\r\nexport interface UseLLMReturnType {\r\n send: (\r\n prompt: string,\r\n messages?: Message[],\r\n data?: DataItem[],\r\n stream?: boolean,\r\n allowCaching?: boolean,\r\n service?: string | null,\r\n conversation?: string | null,\r\n abortController?: AbortController,\r\n onComplete?: (result: string) => void,\r\n onError?: (error: string) => void\r\n ) => Promise<ReadableStreamDefaultReader<any> | string | undefined>;\r\n stop: (controller: AbortController | null) => void;\r\n response: string;\r\n idle: boolean;\r\n error: string;\r\n setResponse: (response: string) => void;\r\n lastCallId: string;\r\n}\r\n\r\nexport const useLLM = (options?: LLMServiceType): UseLLMReturnType => {\r\n const [response, setResponse] = useState<string>(\"\");\r\n const [idle, setIdle] = useState<boolean>(true);\r\n const [error, setError] = useState<string>(\"\");\r\n const [lastCallId, setLastCallId] = useState<string>(\"\");\r\n\r\n let context = useContext(LLMService);\r\n if (!context) {\r\n context = options;\r\n }\r\n\r\n if (!context) {\r\n throw new Error(\r\n \"useLLM must be used within a LLMServiceProvider or constructed with options in your useLLM() call.\"\r\n );\r\n }\r\n\r\n /**\r\n * Stops the fetch request and returns the hook to an idle state. Use this to add abort functionality to your UI.\r\n *\r\n * @param controller An AbortController object to stop the fetch request and return this hook to an idle state, the controller should be the same one passed to the send function.\r\n */\r\n const stop = (controller: AbortController | null) => {\r\n if (controller) controller.abort();\r\n setIdle(true);\r\n };\r\n\r\n /**\r\n * Calls the LLM as a service with the given prompt and messages. The response is returned in the response property of the hook.\r\n *\r\n * @param {string} prompt - The prompt to send to the LLM service.\r\n * @param {Message[]} messages - The history and context messages to send to the LLM service, as an array of {role: string, content: string} objects. For example, [{ role: \"system\", content: \"You are a useful assistant.\" }]\r\n * @param {DataItem[]} data - The data to send to the LLM service, as an array of {key: string, data: string} objects. For example, [{ key: \"name\", value: \"John\" }]\r\n * @param {boolean} stream - Determines whether to stream results back in the response property as they return from the service or batch them up and return them all at once in the response property as a string.\r\n * @param {boolean} allowCaching - Determines whether the service can use cached results or not.\r\n * @param {string | null} service - The service to use for the request. If null, load balancing will be applied. This is typically only used for testing.\r\n * @param {string | null} conversation - The conversation of this request. If null, this is a one off call with no conversation history\r\n * @param {AbortController} abortController - The AbortController used to abort this request once it's started. This allows you to add a stop button to your UI.\r\n * @param {(result: string) => void} onComplete - The callback function to be called once the stream completes, with the final result string.\r\n * @param {(error: string) => void} onError - The callback function to be called if an error occurs, with the error string.\r\n * @returns {Promise<ReadableStreamDefaultReader<any> | string | undefined>} - A StreamReader object if stream is true, otherwise a string of the response. Typically this isn't used when streaming, the stream is exposed in the response property.\r\n */\r\n async function send(\r\n prompt: string,\r\n messages: Message[] = [],\r\n data: DataItem[] = [],\r\n stream: boolean = true,\r\n allowCaching: boolean = true,\r\n service: string | null = null, // null means use the default service and apply services load balancing\r\n conversation: string | null = null,\r\n abortController: AbortController = new AbortController(),\r\n onComplete?: (result: string) => void,\r\n onError?: (error: string) => void\r\n ): Promise<ReadableStreamDefaultReader<any> | string | undefined> {\r\n setResponse(\"\");\r\n setIdle(false);\r\n\r\n let errorInFetch = \"\";\r\n\r\n const responseBody = JSON.stringify({\r\n projectId: context?.project_id ?? \"\",\r\n serviceId: service,\r\n agentId: context?.agent,\r\n prompt: prompt,\r\n messages: messages,\r\n data: data,\r\n customer: context?.customer ?? {}, // if no customer, use the projectId as the customer_id\r\n allowCaching: allowCaching,\r\n conversationId: conversation,\r\n tools: context?.tools ?? [],\r\n });\r\n\r\n // trying to get cloudfront oac going. posts need to be signed, but when i add this the call fails...\r\n const options = {\r\n method: \"POST\",\r\n signal: abortController.signal,\r\n mode: \"cors\" as RequestMode,\r\n headers: {\r\n \"Content-Type\": \"text/plain\",\r\n },\r\n body: responseBody,\r\n };\r\n\r\n try {\r\n const url = context?.url ?? \"https://chat.llmasaservice.io/\";\r\n const response = await fetch(url, options);\r\n if (!response.ok) {\r\n errorInFetch = `Error: Network error for service. (${response.status} ${response.statusText})`;\r\n } else {\r\n setLastCallId(response.headers.get(\"x-callId\") ?? \"\");\r\n const reader =\r\n response?.body?.getReader() as ReadableStreamDefaultReader;\r\n const decoder = new TextDecoder(\"utf-8\");\r\n setIdle(false);\r\n\r\n if (!stream) {\r\n return await readStream(\r\n reader,\r\n decoder,\r\n stream,\r\n {\r\n signal: options.signal,\r\n },\r\n onComplete,\r\n onError\r\n );\r\n } else {\r\n readStream(\r\n reader,\r\n decoder,\r\n stream,\r\n {\r\n signal: options.signal,\r\n },\r\n onComplete,\r\n onError\r\n );\r\n\r\n return reader;\r\n }\r\n }\r\n } catch (errorObject: any) {\r\n errorInFetch = `Error: Having trouble connecting to chat service. (${errorObject.message})`;\r\n }\r\n\r\n if (errorInFetch !== \"\") {\r\n setError(errorInFetch);\r\n if (onError) {\r\n onError(errorInFetch);\r\n }\r\n console.error(`Error: Error in fetch. (${errorInFetch})`);\r\n }\r\n }\r\n async function readStream(\r\n reader: ReadableStreamDefaultReader,\r\n decoder: TextDecoder,\r\n stream: Boolean = true,\r\n { signal }: { signal: AbortSignal },\r\n onComplete?: (result: string) => void,\r\n onError?: (error: string) => void\r\n ): Promise<string> {\r\n let errorInRead = \"\";\r\n let result = \"\";\r\n\r\n while (true) {\r\n try {\r\n if (signal.aborted) {\r\n reader.cancel();\r\n break;\r\n }\r\n\r\n const { value, done } = await reader.read();\r\n\r\n if (decoder.decode(value).startsWith(\"Error:\")) {\r\n errorInRead = decoder.decode(value).substring(6);\r\n break;\r\n }\r\n\r\n if (done) {\r\n break;\r\n }\r\n\r\n result += decoder.decode(value);\r\n if (stream) setResponse(result);\r\n } catch (error: any) {\r\n if (error.name !== \"AbortError\") {\r\n errorInRead = `Reading error ${error.message}`;\r\n }\r\n break;\r\n } finally {\r\n if (signal.aborted) reader.releaseLock();\r\n }\r\n }\r\n\r\n // once the loop is fully done, flip idle = true exactly once\r\n setIdle(true);\r\n\r\n if (errorInRead) {\r\n setError(errorInRead);\r\n reader.cancel();\r\n if (onError) onError(errorInRead);\r\n }\r\n\r\n if (onComplete) {\r\n onComplete(result);\r\n }\r\n \r\n return result;\r\n }\r\n\r\n return { response, send, stop, idle, error, setResponse, lastCallId };\r\n};\r\n\r\nexport default useLLM;\r\n","import React, { createContext, ReactNode } from \"react\";\r\n\r\nexport type LLMAsAServiceCustomer = {\r\n customer_id: string;\r\n customer_name?: string;\r\n customer_user_id?: string;\r\n customer_user_email?: string;\r\n};\r\n\r\nexport interface LLMServiceType {\r\n project_id: string | undefined;\r\n customer?: LLMAsAServiceCustomer;\r\n url?: string | null;\r\n agent?: string | null;\r\n tools?: [] | null;\r\n}\r\n\r\nexport const LLMService = createContext<LLMServiceType | undefined>(undefined);\r\n\r\ninterface UserProviderProps {\r\n children: ReactNode;\r\n project_id: string | undefined;\r\n customer?: LLMAsAServiceCustomer;\r\n url?: string | null;\r\n agent?: string | null;\r\n tools?: [] | null;\r\n}\r\n\r\nexport const LLMServiceProvider: React.FC<UserProviderProps> = ({\r\n children,\r\n project_id,\r\n customer,\r\n url = \"https://chat.llmasaservice.io/\",\r\n agent = null,\r\n}) => {\r\n return (\r\n <LLMService.Provider value={{ project_id, customer, url, agent }}>\r\n {children}\r\n </LLMService.Provider>\r\n );\r\n};\r\n\r\nexport default LLMServiceProvider;"],"mappings":"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","names":["import_react","React","options","response","error"]}
|
package/dist/index.mjs
CHANGED
|
@@ -56,7 +56,7 @@ var useLLM = (options) => {
|
|
|
56
56
|
};
|
|
57
57
|
function send(_0) {
|
|
58
58
|
return __async(this, arguments, function* (prompt, messages = [], data = [], stream = true, allowCaching = true, service = null, conversation = null, abortController = new AbortController(), onComplete, onError) {
|
|
59
|
-
var _a, _b, _c, _d, _e;
|
|
59
|
+
var _a, _b, _c, _d, _e, _f;
|
|
60
60
|
setResponse("");
|
|
61
61
|
setIdle(false);
|
|
62
62
|
let errorInFetch = "";
|
|
@@ -70,7 +70,8 @@ var useLLM = (options) => {
|
|
|
70
70
|
customer: (_b = context == null ? void 0 : context.customer) != null ? _b : {},
|
|
71
71
|
// if no customer, use the projectId as the customer_id
|
|
72
72
|
allowCaching,
|
|
73
|
-
conversationId: conversation
|
|
73
|
+
conversationId: conversation,
|
|
74
|
+
tools: (_c = context == null ? void 0 : context.tools) != null ? _c : []
|
|
74
75
|
});
|
|
75
76
|
const options2 = {
|
|
76
77
|
method: "POST",
|
|
@@ -82,13 +83,13 @@ var useLLM = (options) => {
|
|
|
82
83
|
body: responseBody
|
|
83
84
|
};
|
|
84
85
|
try {
|
|
85
|
-
const url = (
|
|
86
|
+
const url = (_d = context == null ? void 0 : context.url) != null ? _d : "https://chat.llmasaservice.io/";
|
|
86
87
|
const response2 = yield fetch(url, options2);
|
|
87
88
|
if (!response2.ok) {
|
|
88
89
|
errorInFetch = `Error: Network error for service. (${response2.status} ${response2.statusText})`;
|
|
89
90
|
} else {
|
|
90
|
-
setLastCallId((
|
|
91
|
-
const reader = (
|
|
91
|
+
setLastCallId((_e = response2.headers.get("x-callId")) != null ? _e : "");
|
|
92
|
+
const reader = (_f = response2 == null ? void 0 : response2.body) == null ? void 0 : _f.getReader();
|
|
92
93
|
const decoder = new TextDecoder("utf-8");
|
|
93
94
|
setIdle(false);
|
|
94
95
|
if (!stream) {
|
|
@@ -136,7 +137,6 @@ var useLLM = (options) => {
|
|
|
136
137
|
try {
|
|
137
138
|
if (signal.aborted) {
|
|
138
139
|
reader.cancel();
|
|
139
|
-
setIdle(true);
|
|
140
140
|
break;
|
|
141
141
|
}
|
|
142
142
|
const { value, done } = yield reader.read();
|
|
@@ -145,28 +145,24 @@ var useLLM = (options) => {
|
|
|
145
145
|
break;
|
|
146
146
|
}
|
|
147
147
|
if (done) {
|
|
148
|
-
setIdle(true);
|
|
149
148
|
break;
|
|
150
149
|
}
|
|
151
150
|
result += decoder.decode(value);
|
|
152
|
-
if (stream) setResponse(
|
|
151
|
+
if (stream) setResponse(result);
|
|
153
152
|
} catch (error2) {
|
|
154
|
-
if (error2.name
|
|
155
|
-
|
|
153
|
+
if (error2.name !== "AbortError") {
|
|
154
|
+
errorInRead = `Reading error ${error2.message}`;
|
|
156
155
|
}
|
|
157
|
-
errorInRead = `Reading error ${error2.message}`;
|
|
158
156
|
break;
|
|
159
157
|
} finally {
|
|
160
|
-
if (signal.aborted)
|
|
161
|
-
reader.releaseLock();
|
|
162
|
-
}
|
|
158
|
+
if (signal.aborted) reader.releaseLock();
|
|
163
159
|
}
|
|
164
160
|
}
|
|
165
|
-
|
|
161
|
+
setIdle(true);
|
|
162
|
+
if (errorInRead) {
|
|
166
163
|
setError(errorInRead);
|
|
167
164
|
reader.cancel();
|
|
168
165
|
if (onError) onError(errorInRead);
|
|
169
|
-
setIdle(true);
|
|
170
166
|
}
|
|
171
167
|
if (onComplete) {
|
|
172
168
|
onComplete(result);
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/useLLM.ts","../src/LLMAsAService.tsx"],"sourcesContent":["import { useContext, useState } from \"react\";\r\nimport { LLMService, LLMServiceType } from \"./LLMAsAService\";\r\n\r\nexport interface Message {\r\n role: string;\r\n content: string;\r\n}\r\n\r\nexport interface DataItem {\r\n key: string;\r\n data: string;\r\n}\r\n\r\nexport interface UseLLMReturnType {\r\n send: (\r\n prompt: string,\r\n messages?: Message[],\r\n data?: DataItem[],\r\n stream?: boolean,\r\n allowCaching?: boolean,\r\n service?: string | null,\r\n conversation?: string | null,\r\n abortController?: AbortController,\r\n onComplete?: (result: string) => void,\r\n onError?: (error: string) => void\r\n ) => Promise<ReadableStreamDefaultReader<any> | string | undefined>;\r\n stop: (controller: AbortController | null) => void;\r\n response: string;\r\n idle: boolean;\r\n error: string;\r\n setResponse: (response: string) => void;\r\n lastCallId: string;\r\n}\r\n\r\nexport const useLLM = (options?: LLMServiceType): UseLLMReturnType => {\r\n const [response, setResponse] = useState<string>(\"\");\r\n const [idle, setIdle] = useState<boolean>(true);\r\n const [error, setError] = useState<string>(\"\");\r\n const [lastCallId, setLastCallId] = useState<string>(\"\");\r\n\r\n let context = useContext(LLMService);\r\n if (!context) {\r\n context = options;\r\n }\r\n\r\n if (!context) {\r\n throw new Error(\r\n \"useLLM must be used within a LLMServiceProvider or constructed with options in your useLLM() call.\"\r\n );\r\n }\r\n\r\n /**\r\n * Stops the fetch request and returns the hook to an idle state. Use this to add abort functionality to your UI.\r\n *\r\n * @param controller An AbortController object to stop the fetch request and return this hook to an idle state, the controller should be the same one passed to the send function.\r\n */\r\n const stop = (controller: AbortController | null) => {\r\n if (controller) controller.abort();\r\n setIdle(true);\r\n };\r\n\r\n /**\r\n * Calls the LLM as a service with the given prompt and messages. The response is returned in the response property of the hook.\r\n *\r\n * @param {string} prompt - The prompt to send to the LLM service.\r\n * @param {Message[]} messages - The history and context messages to send to the LLM service, as an array of {role: string, content: string} objects. For example, [{ role: \"system\", content: \"You are a useful assistant.\" }]\r\n * @param {DataItem[]} data - The data to send to the LLM service, as an array of {key: string, data: string} objects. For example, [{ key: \"name\", value: \"John\" }]\r\n * @param {boolean} stream - Determines whether to stream results back in the response property as they return from the service or batch them up and return them all at once in the response property as a string.\r\n * @param {boolean} allowCaching - Determines whether the service can use cached results or not.\r\n * @param {string | null} service - The service to use for the request. If null, load balancing will be applied. This is typically only used for testing.\r\n * @param {string | null} conversation - The conversation of this request. If null, this is a one off call with no conversation history\r\n * @param {AbortController} abortController - The AbortController used to abort this request once it's started. This allows you to add a stop button to your UI.\r\n * @param {(result: string) => void} onComplete - The callback function to be called once the stream completes, with the final result string.\r\n * @param {(error: string) => void} onError - The callback function to be called if an error occurs, with the error string.\r\n * @returns {Promise<ReadableStreamDefaultReader<any> | string | undefined>} - A StreamReader object if stream is true, otherwise a string of the response. Typically this isn't used when streaming, the stream is exposed in the response property.\r\n */\r\n async function send(\r\n prompt: string,\r\n messages: Message[] = [],\r\n data: DataItem[] = [],\r\n stream: boolean = true,\r\n allowCaching: boolean = true,\r\n service: string | null = null, // null means use the default service and apply services load balancing\r\n conversation: string | null = null,\r\n abortController: AbortController = new AbortController(),\r\n onComplete?: (result: string) => void,\r\n onError?: (error: string) => void\r\n ): Promise<ReadableStreamDefaultReader<any> | string | undefined> {\r\n setResponse(\"\");\r\n setIdle(false);\r\n\r\n let errorInFetch = \"\";\r\n\r\n const responseBody = JSON.stringify({\r\n projectId: context?.project_id ?? \"\",\r\n serviceId: service,\r\n agentId: context?.agent,\r\n prompt: prompt,\r\n messages: messages,\r\n data: data,\r\n customer: context?.customer ?? {}, // if no customer, use the projectId as the customer_id\r\n allowCaching: allowCaching,\r\n conversationId: conversation,\r\n });\r\n\r\n // trying to get cloudfront oac going. posts need to be signed, but when i add this the call fails...\r\n const options = {\r\n method: \"POST\",\r\n signal: abortController.signal,\r\n mode: \"cors\" as RequestMode,\r\n headers: {\r\n \"Content-Type\": \"text/plain\",\r\n },\r\n body: responseBody,\r\n };\r\n\r\n try {\r\n const url = context?.url ?? \"https://chat.llmasaservice.io/\";\r\n const response = await fetch(url, options);\r\n if (!response.ok) {\r\n errorInFetch = `Error: Network error for service. (${response.status} ${response.statusText})`;\r\n } else {\r\n setLastCallId(response.headers.get(\"x-callId\") ?? \"\");\r\n const reader =\r\n response?.body?.getReader() as ReadableStreamDefaultReader;\r\n const decoder = new TextDecoder(\"utf-8\");\r\n setIdle(false);\r\n\r\n if (!stream) {\r\n return await readStream(\r\n reader,\r\n decoder,\r\n stream,\r\n {\r\n signal: options.signal,\r\n },\r\n onComplete,\r\n onError\r\n );\r\n } else {\r\n readStream(\r\n reader,\r\n decoder,\r\n stream,\r\n {\r\n signal: options.signal,\r\n },\r\n onComplete,\r\n onError\r\n );\r\n\r\n return reader;\r\n }\r\n }\r\n } catch (errorObject: any) {\r\n errorInFetch = `Error: Having trouble connecting to chat service. (${errorObject.message})`;\r\n }\r\n\r\n if (errorInFetch !== \"\") {\r\n setError(errorInFetch);\r\n if (onError) {\r\n onError(errorInFetch);\r\n }\r\n console.error(`Error: Error in fetch. (${errorInFetch})`);\r\n }\r\n }\r\n\r\n async function readStream(\r\n reader: ReadableStreamDefaultReader,\r\n decoder: TextDecoder,\r\n stream: Boolean = true,\r\n { signal: signal }: { signal: AbortSignal },\r\n onComplete?: (result: string) => void,\r\n onError?: (error: string) => void\r\n ): Promise<string> {\r\n let errorInRead = \"\";\r\n let result = \"\";\r\n\r\n while (true) {\r\n try {\r\n // Check if the stream has been aborted\r\n if (signal.aborted) {\r\n reader.cancel();\r\n setIdle(true);\r\n break;\r\n }\r\n\r\n // Read a chunk of data from the stream\r\n const { value, done } = await reader.read();\r\n\r\n if (decoder.decode(value).startsWith(\"Error:\")) {\r\n errorInRead = decoder.decode(value).substring(6);\r\n break;\r\n }\r\n\r\n // If the stream has been read to the end, exit the loop\r\n if (done) {\r\n setIdle(true);\r\n break;\r\n }\r\n\r\n // Process the chunk of data\r\n result += decoder.decode(value);\r\n if (stream) setResponse((prevState: any) => result);\r\n } catch (error: any) {\r\n if (error.name === \"AbortError\") {\r\n break;\r\n }\r\n\r\n errorInRead = `Reading error ${error.message}`;\r\n break;\r\n } finally {\r\n if (signal.aborted) {\r\n reader.releaseLock();\r\n }\r\n }\r\n }\r\n\r\n if (errorInRead !== \"\") {\r\n setError(errorInRead);\r\n reader.cancel();\r\n if (onError) onError(errorInRead);\r\n setIdle(true);\r\n }\r\n\r\n if (onComplete) {\r\n onComplete(result);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n return { response, send, stop, idle, error, setResponse, lastCallId };\r\n};\r\n\r\nexport default useLLM;\r\n","import React, { createContext, ReactNode } from \"react\";\r\n\r\nexport type LLMAsAServiceCustomer = {\r\n customer_id: string;\r\n customer_name?: string;\r\n customer_user_id?: string;\r\n customer_user_email?: string;\r\n};\r\n\r\nexport interface LLMServiceType {\r\n project_id: string | undefined;\r\n customer?: LLMAsAServiceCustomer;\r\n url?: string | null;\r\n agent?: string | null;\r\n}\r\n\r\nexport const LLMService = createContext<LLMServiceType | undefined>(undefined);\r\n\r\ninterface UserProviderProps {\r\n children: ReactNode;\r\n project_id: string | undefined;\r\n customer?: LLMAsAServiceCustomer;\r\n url?: string | null;\r\n agent?: string | null;\r\n}\r\n\r\nexport const LLMServiceProvider: React.FC<UserProviderProps> = ({\r\n children,\r\n project_id,\r\n customer,\r\n url = \"https://chat.llmasaservice.io/\",\r\n agent = null,\r\n}) => {\r\n return (\r\n <LLMService.Provider value={{ project_id, customer, url, agent }}>\r\n {children}\r\n </LLMService.Provider>\r\n );\r\n};\r\n\r\nexport default LLMServiceProvider;"],"mappings":"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","names":["options","response","error"]}
|
|
1
|
+
{"version":3,"sources":["../src/useLLM.ts","../src/LLMAsAService.tsx"],"sourcesContent":["import { useContext, useState } from \"react\";\r\nimport { LLMService, LLMServiceType } from \"./LLMAsAService\";\r\n\r\nexport interface Message {\r\n role: string;\r\n content: string;\r\n}\r\n\r\nexport interface DataItem {\r\n key: string;\r\n data: string;\r\n}\r\n\r\nexport interface UseLLMReturnType {\r\n send: (\r\n prompt: string,\r\n messages?: Message[],\r\n data?: DataItem[],\r\n stream?: boolean,\r\n allowCaching?: boolean,\r\n service?: string | null,\r\n conversation?: string | null,\r\n abortController?: AbortController,\r\n onComplete?: (result: string) => void,\r\n onError?: (error: string) => void\r\n ) => Promise<ReadableStreamDefaultReader<any> | string | undefined>;\r\n stop: (controller: AbortController | null) => void;\r\n response: string;\r\n idle: boolean;\r\n error: string;\r\n setResponse: (response: string) => void;\r\n lastCallId: string;\r\n}\r\n\r\nexport const useLLM = (options?: LLMServiceType): UseLLMReturnType => {\r\n const [response, setResponse] = useState<string>(\"\");\r\n const [idle, setIdle] = useState<boolean>(true);\r\n const [error, setError] = useState<string>(\"\");\r\n const [lastCallId, setLastCallId] = useState<string>(\"\");\r\n\r\n let context = useContext(LLMService);\r\n if (!context) {\r\n context = options;\r\n }\r\n\r\n if (!context) {\r\n throw new Error(\r\n \"useLLM must be used within a LLMServiceProvider or constructed with options in your useLLM() call.\"\r\n );\r\n }\r\n\r\n /**\r\n * Stops the fetch request and returns the hook to an idle state. Use this to add abort functionality to your UI.\r\n *\r\n * @param controller An AbortController object to stop the fetch request and return this hook to an idle state, the controller should be the same one passed to the send function.\r\n */\r\n const stop = (controller: AbortController | null) => {\r\n if (controller) controller.abort();\r\n setIdle(true);\r\n };\r\n\r\n /**\r\n * Calls the LLM as a service with the given prompt and messages. The response is returned in the response property of the hook.\r\n *\r\n * @param {string} prompt - The prompt to send to the LLM service.\r\n * @param {Message[]} messages - The history and context messages to send to the LLM service, as an array of {role: string, content: string} objects. For example, [{ role: \"system\", content: \"You are a useful assistant.\" }]\r\n * @param {DataItem[]} data - The data to send to the LLM service, as an array of {key: string, data: string} objects. For example, [{ key: \"name\", value: \"John\" }]\r\n * @param {boolean} stream - Determines whether to stream results back in the response property as they return from the service or batch them up and return them all at once in the response property as a string.\r\n * @param {boolean} allowCaching - Determines whether the service can use cached results or not.\r\n * @param {string | null} service - The service to use for the request. If null, load balancing will be applied. This is typically only used for testing.\r\n * @param {string | null} conversation - The conversation of this request. If null, this is a one off call with no conversation history\r\n * @param {AbortController} abortController - The AbortController used to abort this request once it's started. This allows you to add a stop button to your UI.\r\n * @param {(result: string) => void} onComplete - The callback function to be called once the stream completes, with the final result string.\r\n * @param {(error: string) => void} onError - The callback function to be called if an error occurs, with the error string.\r\n * @returns {Promise<ReadableStreamDefaultReader<any> | string | undefined>} - A StreamReader object if stream is true, otherwise a string of the response. Typically this isn't used when streaming, the stream is exposed in the response property.\r\n */\r\n async function send(\r\n prompt: string,\r\n messages: Message[] = [],\r\n data: DataItem[] = [],\r\n stream: boolean = true,\r\n allowCaching: boolean = true,\r\n service: string | null = null, // null means use the default service and apply services load balancing\r\n conversation: string | null = null,\r\n abortController: AbortController = new AbortController(),\r\n onComplete?: (result: string) => void,\r\n onError?: (error: string) => void\r\n ): Promise<ReadableStreamDefaultReader<any> | string | undefined> {\r\n setResponse(\"\");\r\n setIdle(false);\r\n\r\n let errorInFetch = \"\";\r\n\r\n const responseBody = JSON.stringify({\r\n projectId: context?.project_id ?? \"\",\r\n serviceId: service,\r\n agentId: context?.agent,\r\n prompt: prompt,\r\n messages: messages,\r\n data: data,\r\n customer: context?.customer ?? {}, // if no customer, use the projectId as the customer_id\r\n allowCaching: allowCaching,\r\n conversationId: conversation,\r\n tools: context?.tools ?? [],\r\n });\r\n\r\n // trying to get cloudfront oac going. posts need to be signed, but when i add this the call fails...\r\n const options = {\r\n method: \"POST\",\r\n signal: abortController.signal,\r\n mode: \"cors\" as RequestMode,\r\n headers: {\r\n \"Content-Type\": \"text/plain\",\r\n },\r\n body: responseBody,\r\n };\r\n\r\n try {\r\n const url = context?.url ?? \"https://chat.llmasaservice.io/\";\r\n const response = await fetch(url, options);\r\n if (!response.ok) {\r\n errorInFetch = `Error: Network error for service. (${response.status} ${response.statusText})`;\r\n } else {\r\n setLastCallId(response.headers.get(\"x-callId\") ?? \"\");\r\n const reader =\r\n response?.body?.getReader() as ReadableStreamDefaultReader;\r\n const decoder = new TextDecoder(\"utf-8\");\r\n setIdle(false);\r\n\r\n if (!stream) {\r\n return await readStream(\r\n reader,\r\n decoder,\r\n stream,\r\n {\r\n signal: options.signal,\r\n },\r\n onComplete,\r\n onError\r\n );\r\n } else {\r\n readStream(\r\n reader,\r\n decoder,\r\n stream,\r\n {\r\n signal: options.signal,\r\n },\r\n onComplete,\r\n onError\r\n );\r\n\r\n return reader;\r\n }\r\n }\r\n } catch (errorObject: any) {\r\n errorInFetch = `Error: Having trouble connecting to chat service. (${errorObject.message})`;\r\n }\r\n\r\n if (errorInFetch !== \"\") {\r\n setError(errorInFetch);\r\n if (onError) {\r\n onError(errorInFetch);\r\n }\r\n console.error(`Error: Error in fetch. (${errorInFetch})`);\r\n }\r\n }\r\n async function readStream(\r\n reader: ReadableStreamDefaultReader,\r\n decoder: TextDecoder,\r\n stream: Boolean = true,\r\n { signal }: { signal: AbortSignal },\r\n onComplete?: (result: string) => void,\r\n onError?: (error: string) => void\r\n ): Promise<string> {\r\n let errorInRead = \"\";\r\n let result = \"\";\r\n\r\n while (true) {\r\n try {\r\n if (signal.aborted) {\r\n reader.cancel();\r\n break;\r\n }\r\n\r\n const { value, done } = await reader.read();\r\n\r\n if (decoder.decode(value).startsWith(\"Error:\")) {\r\n errorInRead = decoder.decode(value).substring(6);\r\n break;\r\n }\r\n\r\n if (done) {\r\n break;\r\n }\r\n\r\n result += decoder.decode(value);\r\n if (stream) setResponse(result);\r\n } catch (error: any) {\r\n if (error.name !== \"AbortError\") {\r\n errorInRead = `Reading error ${error.message}`;\r\n }\r\n break;\r\n } finally {\r\n if (signal.aborted) reader.releaseLock();\r\n }\r\n }\r\n\r\n // once the loop is fully done, flip idle = true exactly once\r\n setIdle(true);\r\n\r\n if (errorInRead) {\r\n setError(errorInRead);\r\n reader.cancel();\r\n if (onError) onError(errorInRead);\r\n }\r\n\r\n if (onComplete) {\r\n onComplete(result);\r\n }\r\n \r\n return result;\r\n }\r\n\r\n return { response, send, stop, idle, error, setResponse, lastCallId };\r\n};\r\n\r\nexport default useLLM;\r\n","import React, { createContext, ReactNode } from \"react\";\r\n\r\nexport type LLMAsAServiceCustomer = {\r\n customer_id: string;\r\n customer_name?: string;\r\n customer_user_id?: string;\r\n customer_user_email?: string;\r\n};\r\n\r\nexport interface LLMServiceType {\r\n project_id: string | undefined;\r\n customer?: LLMAsAServiceCustomer;\r\n url?: string | null;\r\n agent?: string | null;\r\n tools?: [] | null;\r\n}\r\n\r\nexport const LLMService = createContext<LLMServiceType | undefined>(undefined);\r\n\r\ninterface UserProviderProps {\r\n children: ReactNode;\r\n project_id: string | undefined;\r\n customer?: LLMAsAServiceCustomer;\r\n url?: string | null;\r\n agent?: string | null;\r\n tools?: [] | null;\r\n}\r\n\r\nexport const LLMServiceProvider: React.FC<UserProviderProps> = ({\r\n children,\r\n project_id,\r\n customer,\r\n url = \"https://chat.llmasaservice.io/\",\r\n agent = null,\r\n}) => {\r\n return (\r\n <LLMService.Provider value={{ project_id, customer, url, agent }}>\r\n {children}\r\n </LLMService.Provider>\r\n );\r\n};\r\n\r\nexport default LLMServiceProvider;"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,YAAY,gBAAgB;;;ACArC,OAAO,SAAS,qBAAgC;AAiBzC,IAAM,aAAa,cAA0C,MAAS;AAWtE,IAAM,qBAAkD,CAAC;AAAA,EAC9D;AAAA,EACA;AAAA,EACA;AAAA,EACA,MAAM;AAAA,EACN,QAAQ;AACV,MAAM;AACJ,SACE,oCAAC,WAAW,UAAX,EAAoB,OAAO,EAAE,YAAY,UAAU,KAAK,MAAM,KAC5D,QACH;AAEJ;;;ADNO,IAAM,SAAS,CAAC,YAA+C;AACpE,QAAM,CAAC,UAAU,WAAW,IAAI,SAAiB,EAAE;AACnD,QAAM,CAAC,MAAM,OAAO,IAAI,SAAkB,IAAI;AAC9C,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAiB,EAAE;AAC7C,QAAM,CAAC,YAAY,aAAa,IAAI,SAAiB,EAAE;AAEvD,MAAI,UAAU,WAAW,UAAU;AACnC,MAAI,CAAC,SAAS;AACZ,cAAU;AAAA,EACZ;AAEA,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAOA,QAAM,OAAO,CAAC,eAAuC;AACnD,QAAI,WAAY,YAAW,MAAM;AACjC,YAAQ,IAAI;AAAA,EACd;AAiBA,WAAe,KACb,IAUgE;AAAA,+CAVhE,QACA,WAAsB,CAAC,GACvB,OAAmB,CAAC,GACpB,SAAkB,MAClB,eAAwB,MACxB,UAAyB,MACzB,eAA8B,MAC9B,kBAAmC,IAAI,gBAAgB,GACvD,YACA,SACgE;AAvFpE;AAwFI,kBAAY,EAAE;AACd,cAAQ,KAAK;AAEb,UAAI,eAAe;AAEnB,YAAM,eAAe,KAAK,UAAU;AAAA,QAClC,YAAW,wCAAS,eAAT,YAAuB;AAAA,QAClC,WAAW;AAAA,QACX,SAAS,mCAAS;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,QACA,WAAU,wCAAS,aAAT,YAAqB,CAAC;AAAA;AAAA,QAChC;AAAA,QACA,gBAAgB;AAAA,QAChB,QAAO,wCAAS,UAAT,YAAkB,CAAC;AAAA,MAC5B,CAAC;AAGD,YAAMA,WAAU;AAAA,QACd,QAAQ;AAAA,QACR,QAAQ,gBAAgB;AAAA,QACxB,MAAM;AAAA,QACN,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM;AAAA,MACR;AAEA,UAAI;AACF,cAAM,OAAM,wCAAS,QAAT,YAAgB;AAC5B,cAAMC,YAAW,MAAM,MAAM,KAAKD,QAAO;AACzC,YAAI,CAACC,UAAS,IAAI;AAChB,yBAAe,sCAAsCA,UAAS,MAAM,IAAIA,UAAS,UAAU;AAAA,QAC7F,OAAO;AACL,yBAAc,KAAAA,UAAS,QAAQ,IAAI,UAAU,MAA/B,YAAoC,EAAE;AACpD,gBAAM,UACJ,KAAAA,aAAA,gBAAAA,UAAU,SAAV,mBAAgB;AAClB,gBAAM,UAAU,IAAI,YAAY,OAAO;AACvC,kBAAQ,KAAK;AAEb,cAAI,CAAC,QAAQ;AACX,mBAAO,MAAM;AAAA,cACX;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,gBACE,QAAQD,SAAQ;AAAA,cAClB;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,UACF,OAAO;AACL;AAAA,cACE;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,gBACE,QAAQA,SAAQ;AAAA,cAClB;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAEA,mBAAO;AAAA,UACT;AAAA,QACF;AAAA,MACF,SAAS,aAAkB;AACzB,uBAAe,sDAAsD,YAAY,OAAO;AAAA,MAC1F;AAEA,UAAI,iBAAiB,IAAI;AACvB,iBAAS,YAAY;AACrB,YAAI,SAAS;AACX,kBAAQ,YAAY;AAAA,QACtB;AACA,gBAAQ,MAAM,2BAA2B,YAAY,GAAG;AAAA,MAC1D;AAAA,IACF;AAAA;AACA,WAAe,WACb,IACA,IAKiB;AAAA,+CANjB,QACA,SACA,SAAkB,MAClB,EAAE,OAAO,GACT,YACA,SACiB;AACjB,UAAI,cAAc;AAClB,UAAI,SAAS;AAEb,aAAO,MAAM;AACX,YAAI;AACF,cAAI,OAAO,SAAS;AAClB,mBAAO,OAAO;AACd;AAAA,UACF;AAEA,gBAAM,EAAE,OAAO,KAAK,IAAI,MAAM,OAAO,KAAK;AAE1C,cAAI,QAAQ,OAAO,KAAK,EAAE,WAAW,QAAQ,GAAG;AAC9C,0BAAc,QAAQ,OAAO,KAAK,EAAE,UAAU,CAAC;AAC/C;AAAA,UACF;AAEA,cAAI,MAAM;AACR;AAAA,UACF;AAEA,oBAAU,QAAQ,OAAO,KAAK;AAC9B,cAAI,OAAQ,aAAY,MAAM;AAAA,QAChC,SAASE,QAAY;AACnB,cAAIA,OAAM,SAAS,cAAc;AAC/B,0BAAc,kBAAkBA,OAAM,OAAO;AAAA,UAC/C;AACA;AAAA,QACF,UAAE;AACA,cAAI,OAAO,QAAS,QAAO,YAAY;AAAA,QACzC;AAAA,MACF;AAGA,cAAQ,IAAI;AAEZ,UAAI,aAAa;AACf,iBAAS,WAAW;AACpB,eAAO,OAAO;AACd,YAAI,QAAS,SAAQ,WAAW;AAAA,MAClC;AAEA,UAAI,YAAY;AACd,mBAAW,MAAM;AAAA,MACnB;AAEA,aAAO;AAAA,IACT;AAAA;AAEA,SAAO,EAAE,UAAU,MAAM,MAAM,MAAM,OAAO,aAAa,WAAW;AACtE;","names":["options","response","error"]}
|