@lpextend/node-sdk 1.1.2 → 1.1.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.mjs CHANGED
@@ -182,6 +182,37 @@ var DomainResolver = class {
182
182
  account: this.accountId,
183
183
  service: "promptlibrary",
184
184
  baseURI: `${this.geo}.promptlibrary.liveperson.net`
185
+ },
186
+ // Conversation Builder domains (aliases for consistency with CB service naming)
187
+ {
188
+ account: this.accountId,
189
+ service: "cbBotPlatform",
190
+ baseURI: `${this.region}.bc-platform.liveperson.net`
191
+ },
192
+ {
193
+ account: this.accountId,
194
+ service: "cbIbc",
195
+ baseURI: `${this.region}.bc-nlu.liveperson.net`
196
+ },
197
+ {
198
+ account: this.accountId,
199
+ service: "cbKb",
200
+ baseURI: `${this.region}.bc-kb.liveperson.net`
201
+ },
202
+ {
203
+ account: this.accountId,
204
+ service: "cbMonitoring",
205
+ baseURI: `${this.region}.bc-mgmt.liveperson.net`
206
+ },
207
+ {
208
+ account: this.accountId,
209
+ service: "cbExternalIntegrations",
210
+ baseURI: `${this.region}.bc-intg.liveperson.net`
211
+ },
212
+ {
213
+ account: this.accountId,
214
+ service: "cbAiSearch",
215
+ baseURI: `${this.region}.kai.liveperson.net`
185
216
  }
186
217
  ];
187
218
  }
@@ -1686,6 +1717,524 @@ var LPPromptsAPI = class {
1686
1717
  }
1687
1718
  };
1688
1719
 
1720
+ // src/api/conversation-builder.api.ts
1721
+ var ConversationBuilderAPI = class {
1722
+ constructor(accountId, debug = false, timeout = 3e4) {
1723
+ this.accountId = accountId;
1724
+ this.credentials = null;
1725
+ this.domainResolver = new DomainResolver(accountId);
1726
+ this.debug = debug;
1727
+ this.timeout = timeout;
1728
+ this.botGroups = new BotGroupsAPI(this);
1729
+ this.bots = new BotsAPI(this);
1730
+ this.dialogs = new DialogsAPI(this);
1731
+ this.interactions = new InteractionsAPI(this);
1732
+ this.nluDomains = new NLUDomainsAPI(this);
1733
+ this.knowledgeBases = new KnowledgeBasesAPI(this);
1734
+ this.botAgents = new BotAgentsAPI(this);
1735
+ this.integrations = new IntegrationsAPI(this);
1736
+ }
1737
+ /**
1738
+ * Set CB authentication credentials
1739
+ * Must be called before making any CB API calls
1740
+ */
1741
+ setCredentials(credentials) {
1742
+ this.credentials = credentials;
1743
+ this.log("CB credentials set", { organizationId: credentials.organizationId });
1744
+ }
1745
+ /**
1746
+ * Check if credentials are set
1747
+ */
1748
+ hasCredentials() {
1749
+ return this.credentials !== null;
1750
+ }
1751
+ /**
1752
+ * Get the current credentials
1753
+ * @throws If credentials not set
1754
+ */
1755
+ getCredentials() {
1756
+ if (!this.credentials) {
1757
+ throw new LPExtendSDKError(
1758
+ "CB credentials not set. Call setCredentials() first or use sentinel.authenticateCB().",
1759
+ ErrorCodes.UNAUTHORIZED
1760
+ );
1761
+ }
1762
+ return this.credentials;
1763
+ }
1764
+ /**
1765
+ * Get the account ID
1766
+ */
1767
+ getAccountId() {
1768
+ return this.accountId;
1769
+ }
1770
+ /**
1771
+ * Get domain for a CB service
1772
+ */
1773
+ async getDomain(service) {
1774
+ const domain = await this.domainResolver.getDomain(service);
1775
+ if (!domain) {
1776
+ throw new LPExtendSDKError(
1777
+ `Could not resolve domain for CB service: ${service}`,
1778
+ ErrorCodes.API_ERROR
1779
+ );
1780
+ }
1781
+ return domain;
1782
+ }
1783
+ /**
1784
+ * Make authenticated request to CB API
1785
+ */
1786
+ async request(service, path, options = {}) {
1787
+ const { cbToken, organizationId } = this.getCredentials();
1788
+ const domain = await this.getDomain(service);
1789
+ const method = options.method || "GET";
1790
+ let url = `https://${domain}${path}`;
1791
+ if (options.params) {
1792
+ const searchParams = new URLSearchParams();
1793
+ Object.entries(options.params).forEach(([key, value]) => {
1794
+ if (value !== void 0) {
1795
+ searchParams.set(key, String(value));
1796
+ }
1797
+ });
1798
+ const paramString = searchParams.toString();
1799
+ if (paramString) {
1800
+ url += (url.includes("?") ? "&" : "?") + paramString;
1801
+ }
1802
+ }
1803
+ const headers = {
1804
+ "Accept": "application/json",
1805
+ "Content-Type": "application/json; charset=utf-8",
1806
+ "authorization": cbToken,
1807
+ "organizationid": organizationId
1808
+ };
1809
+ this.log(`${method} ${url}`, { service });
1810
+ const controller = new AbortController();
1811
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1812
+ try {
1813
+ const response = await fetch(url, {
1814
+ method,
1815
+ headers,
1816
+ body: options.body ? JSON.stringify(options.body) : void 0,
1817
+ signal: controller.signal
1818
+ });
1819
+ clearTimeout(timeoutId);
1820
+ if (!response.ok) {
1821
+ const errorBody = await response.json().catch(() => ({ message: "Unknown error" }));
1822
+ throw new LPExtendSDKError(
1823
+ `CB API Error: ${response.status} - ${errorBody.message || response.statusText}`,
1824
+ ErrorCodes.API_ERROR,
1825
+ response.status,
1826
+ errorBody
1827
+ );
1828
+ }
1829
+ const contentType = response.headers.get("content-type");
1830
+ if (!contentType?.includes("application/json") || response.status === 204) {
1831
+ return void 0;
1832
+ }
1833
+ return await response.json();
1834
+ } catch (error) {
1835
+ clearTimeout(timeoutId);
1836
+ if (error.name === "AbortError") {
1837
+ throw new LPExtendSDKError("CB API request timeout", ErrorCodes.TIMEOUT);
1838
+ }
1839
+ if (error instanceof LPExtendSDKError) {
1840
+ throw error;
1841
+ }
1842
+ throw new LPExtendSDKError(
1843
+ `CB API request failed: ${error.message}`,
1844
+ ErrorCodes.API_ERROR
1845
+ );
1846
+ }
1847
+ }
1848
+ /**
1849
+ * Debug logging
1850
+ */
1851
+ log(...args) {
1852
+ if (this.debug) {
1853
+ console.log("[LP-Extend-SDK:CB]", ...args);
1854
+ }
1855
+ }
1856
+ };
1857
+ var BotGroupsAPI = class {
1858
+ constructor(cb) {
1859
+ this.cb = cb;
1860
+ }
1861
+ /**
1862
+ * Get all bot groups
1863
+ */
1864
+ async getAll(params) {
1865
+ const queryParams = {};
1866
+ if (params?.expandAll) {
1867
+ queryParams["expand-all"] = true;
1868
+ } else {
1869
+ queryParams.page = params?.page ?? 1;
1870
+ queryParams.size = params?.size ?? 100;
1871
+ }
1872
+ return this.cb.request("cbBotPlatform", "/bot-groups", { params: queryParams });
1873
+ }
1874
+ /**
1875
+ * Get bots by group
1876
+ */
1877
+ async getBots(params) {
1878
+ const queryParams = {
1879
+ "sort-by": params?.sortBy ?? "botName:asc",
1880
+ page: params?.page ?? 1,
1881
+ size: params?.size ?? 10,
1882
+ "bot-group-id": params?.botGroupId ?? "un_assigned"
1883
+ };
1884
+ return this.cb.request("cbBotPlatform", "/bot-groups/bots", { params: queryParams });
1885
+ }
1886
+ };
1887
+ var BotsAPI = class {
1888
+ constructor(cb) {
1889
+ this.cb = cb;
1890
+ }
1891
+ /**
1892
+ * Get all bots (legacy chatbots endpoint)
1893
+ */
1894
+ async getAll() {
1895
+ return this.cb.request("botPlatform", "/bot-platform-manager-0.1/chatbots");
1896
+ }
1897
+ /**
1898
+ * Get chatbot by ID
1899
+ */
1900
+ async getById(chatBotId) {
1901
+ return this.cb.request("cbBotPlatform", "/chatbots", {
1902
+ params: { chatBotId }
1903
+ });
1904
+ }
1905
+ /**
1906
+ * Get global functions for a bot
1907
+ */
1908
+ async getGlobalFunctions(botId) {
1909
+ return this.cb.request("cbBotPlatform", `/bot/${botId}/globalFunctions`);
1910
+ }
1911
+ /**
1912
+ * Get LP app credentials for a bot
1913
+ */
1914
+ async getLPAppCredentials(chatBotId) {
1915
+ return this.cb.request("cbBotPlatform", "/auth/liveperson/app", {
1916
+ params: { chatBotId }
1917
+ });
1918
+ }
1919
+ /**
1920
+ * Get bot environment variables
1921
+ */
1922
+ async getEnvironment() {
1923
+ const data = await this.cb.request("cbBotPlatform", "/auth/botenvironment/");
1924
+ if (Array.isArray(data)) {
1925
+ return { success: true, successResult: data };
1926
+ }
1927
+ return data;
1928
+ }
1929
+ };
1930
+ var DialogsAPI = class {
1931
+ constructor(cb) {
1932
+ this.cb = cb;
1933
+ }
1934
+ /**
1935
+ * Get all dialogs for a bot
1936
+ */
1937
+ async getByBotId(botId) {
1938
+ return this.cb.request("cbBotPlatform", `/bots/${botId}/dialog/`);
1939
+ }
1940
+ /**
1941
+ * Get dialog template summaries
1942
+ */
1943
+ async getTemplateSummary() {
1944
+ return this.cb.request("cbBotPlatform", "/dialog/template/summary");
1945
+ }
1946
+ };
1947
+ var InteractionsAPI = class {
1948
+ constructor(cb) {
1949
+ this.cb = cb;
1950
+ }
1951
+ /**
1952
+ * Get all interactions for a bot
1953
+ */
1954
+ async getByBotId(botId) {
1955
+ return this.cb.request("cbBotPlatform", `/chat/${botId}/interaction/`);
1956
+ }
1957
+ };
1958
+ var NLUDomainsAPI = class {
1959
+ constructor(cb) {
1960
+ this.cb = cb;
1961
+ }
1962
+ /**
1963
+ * Get all NLU domains for the organization
1964
+ */
1965
+ async getAll() {
1966
+ return this.cb.request("cbIbc", "/api/cb/nlu/v1/domains/getByOrgId");
1967
+ }
1968
+ /**
1969
+ * Get intents for a domain
1970
+ */
1971
+ async getIntents(domainId) {
1972
+ const data = await this.cb.request("cbIbc", `/api/cb/nlu/v1/domains/${domainId}/intents`);
1973
+ if (Array.isArray(data)) {
1974
+ return { success: true, successResult: data };
1975
+ }
1976
+ return data;
1977
+ }
1978
+ };
1979
+ var KnowledgeBasesAPI = class {
1980
+ constructor(cb) {
1981
+ this.cb = cb;
1982
+ }
1983
+ /**
1984
+ * Get all knowledge bases
1985
+ */
1986
+ async getAll(includeMetrics = true) {
1987
+ return this.cb.request("cbKb", "/knowledgeDataSource", {
1988
+ params: { includeMetrics }
1989
+ });
1990
+ }
1991
+ /**
1992
+ * Get knowledge base by ID
1993
+ */
1994
+ async getById(kbId, includeMetrics = true) {
1995
+ return this.cb.request("cbKb", `/knowledgeDataSource/${kbId}`, {
1996
+ params: { includeMetrics }
1997
+ });
1998
+ }
1999
+ /**
2000
+ * Get content sources for a knowledge base
2001
+ */
2002
+ async getContentSources(kbId, includeKmsRecipeDetails = true) {
2003
+ return this.cb.request("cbKb", `/kb/${kbId}/content_sources`, {
2004
+ params: { includeKmsRecipeDetails }
2005
+ });
2006
+ }
2007
+ /**
2008
+ * Get articles for a knowledge base
2009
+ */
2010
+ async getArticles(kbId, params) {
2011
+ const body = {
2012
+ page: params?.page ?? 1,
2013
+ size: params?.size ?? 20,
2014
+ sortAscByLastModificationTime: params?.sortAscByLastModificationTime ?? false,
2015
+ articleIds: params?.articleIds ?? []
2016
+ };
2017
+ return this.cb.request("cbKb", `/kb/${kbId}/articles`, {
2018
+ method: "POST",
2019
+ body,
2020
+ params: { includeConflictingDetails: params?.includeConflictingDetails ?? true }
2021
+ });
2022
+ }
2023
+ /**
2024
+ * Search knowledge base using KAI
2025
+ */
2026
+ async search(kbId, searchRequest) {
2027
+ try {
2028
+ return await this.cb.request("cbAiSearch", `/v1/account/${this.cb.getAccountId()}/kb/${kbId}/search`, {
2029
+ method: "POST",
2030
+ body: searchRequest
2031
+ });
2032
+ } catch {
2033
+ return this.cb.request("cbKb", `/kb/${kbId}/search`, {
2034
+ method: "POST",
2035
+ body: searchRequest
2036
+ });
2037
+ }
2038
+ }
2039
+ /**
2040
+ * Get KAI On-Demand configurations
2041
+ */
2042
+ async getOnDemandConfigs() {
2043
+ return this.cb.request("cbKb", "/on-demand/configs");
2044
+ }
2045
+ /**
2046
+ * Get default prompt for KAI
2047
+ */
2048
+ async getDefaultPrompt() {
2049
+ return this.cb.request("cbKb", "/default-prompt");
2050
+ }
2051
+ /**
2052
+ * Get consumer query metrics for a knowledge base
2053
+ *
2054
+ * Retrieves answered and/or unanswered query metrics within a date range.
2055
+ * Note: The API only supports 7-day ranges. For longer ranges, use getConsumerQueryMetricsExtended().
2056
+ *
2057
+ * @param params - Query parameters including kbId, startTime, endTime, and eventType
2058
+ * @returns Promise resolving to consumer query metrics
2059
+ *
2060
+ * @example
2061
+ * ```typescript
2062
+ * const metrics = await sdk.conversationBuilder.knowledgeBases.getConsumerQueryMetrics({
2063
+ * kbId: 'kb-123',
2064
+ * startTime: Date.now() - 7 * 24 * 60 * 60 * 1000, // 7 days ago
2065
+ * endTime: Date.now(),
2066
+ * eventType: ['EVENT_KB_UN_ANSWERED'],
2067
+ * });
2068
+ * ```
2069
+ */
2070
+ async getConsumerQueryMetrics(params) {
2071
+ const body = {
2072
+ startTime: String(params.startTime),
2073
+ endTime: String(params.endTime),
2074
+ eventType: params.eventType,
2075
+ kbId: params.kbId
2076
+ };
2077
+ return this.cb.request("cbKb", "/kb/consumerQueryMetrics", {
2078
+ method: "POST",
2079
+ body
2080
+ });
2081
+ }
2082
+ /**
2083
+ * Get consumer query metrics for extended date ranges (up to 3 months)
2084
+ *
2085
+ * Automatically iterates through 7-day chunks to retrieve all metrics within
2086
+ * the specified date range. Useful for historical analysis beyond the 7-day API limit.
2087
+ *
2088
+ * @param params - Extended query parameters including startDate, endDate, kbId, and eventType
2089
+ * @returns Promise resolving to aggregated consumer query metrics from all chunks
2090
+ *
2091
+ * @example
2092
+ * ```typescript
2093
+ * const metrics = await sdk.conversationBuilder.knowledgeBases.getConsumerQueryMetricsExtended({
2094
+ * kbId: 'kb-123',
2095
+ * startDate: new Date('2024-01-01'),
2096
+ * endDate: new Date('2024-03-01'),
2097
+ * eventType: ['EVENT_KB_ANSWERED', 'EVENT_KB_UN_ANSWERED'],
2098
+ * onProgress: (completed, total) => console.log(`${completed}/${total} chunks processed`),
2099
+ * });
2100
+ * ```
2101
+ */
2102
+ async getConsumerQueryMetricsExtended(params) {
2103
+ const { startDate, endDate, eventType, kbId, onProgress } = params;
2104
+ const startMs = typeof startDate === "number" ? startDate : startDate.getTime();
2105
+ const endMs = typeof endDate === "number" ? endDate : endDate.getTime();
2106
+ const maxRangeMs = 90 * 24 * 60 * 60 * 1e3;
2107
+ if (endMs - startMs > maxRangeMs) {
2108
+ throw new LPExtendSDKError(
2109
+ "Date range exceeds maximum of 90 days. Please use a smaller range.",
2110
+ ErrorCodes.INVALID_CONFIG
2111
+ );
2112
+ }
2113
+ const chunkSizeMs = 7 * 24 * 60 * 60 * 1e3;
2114
+ const chunks = [];
2115
+ let chunkStart = startMs;
2116
+ while (chunkStart < endMs) {
2117
+ const chunkEnd = Math.min(chunkStart + chunkSizeMs, endMs);
2118
+ chunks.push({ start: chunkStart, end: chunkEnd });
2119
+ chunkStart = chunkEnd;
2120
+ }
2121
+ const allMetrics = [];
2122
+ for (let i = 0; i < chunks.length; i++) {
2123
+ const chunk = chunks[i];
2124
+ try {
2125
+ const response = await this.getConsumerQueryMetrics({
2126
+ kbId,
2127
+ startTime: chunk.start,
2128
+ endTime: chunk.end,
2129
+ eventType
2130
+ });
2131
+ if (response.data && Array.isArray(response.data)) {
2132
+ allMetrics.push(...response.data);
2133
+ }
2134
+ } catch (error) {
2135
+ console.warn(`Failed to fetch metrics for chunk ${i + 1}/${chunks.length}:`, error);
2136
+ }
2137
+ if (onProgress) {
2138
+ onProgress(i + 1, chunks.length);
2139
+ }
2140
+ }
2141
+ const seen = /* @__PURE__ */ new Set();
2142
+ const uniqueMetrics = allMetrics.filter((metric) => {
2143
+ const key = metric.id || `${metric.consumerQuery}-${metric.timestamp}`;
2144
+ if (seen.has(key)) return false;
2145
+ seen.add(key);
2146
+ return true;
2147
+ });
2148
+ return uniqueMetrics;
2149
+ }
2150
+ };
2151
+ var BotAgentsAPI = class {
2152
+ constructor(cb) {
2153
+ this.cb = cb;
2154
+ }
2155
+ /**
2156
+ * Get bot instance status
2157
+ */
2158
+ async getInstanceStatus(botId) {
2159
+ return this.cb.request("cbMonitoring", `/sysadmin/nodejs/instance/status-v2/${botId}`);
2160
+ }
2161
+ /**
2162
+ * Start a bot agent
2163
+ */
2164
+ async start(botId, lpAccountId, lpAccountUser) {
2165
+ return this.cb.request("cbMonitoring", `/sysadmin/nodejs/instance/start/${botId}`, {
2166
+ method: "PUT",
2167
+ body: { lpAccountId, lpAccountUser }
2168
+ });
2169
+ }
2170
+ /**
2171
+ * Stop a bot agent
2172
+ */
2173
+ async stop(botId, lpAccountId, lpAccountUser) {
2174
+ return this.cb.request("cbMonitoring", `/sysadmin/nodejs/instance/stop/${botId}`, {
2175
+ method: "PUT",
2176
+ body: { lpAccountId, lpAccountUser }
2177
+ });
2178
+ }
2179
+ /**
2180
+ * Get all bot agents status
2181
+ */
2182
+ async getAllStatus(params) {
2183
+ return this.cb.request("cbMonitoring", "/sysadmin/nodejs/instance/status", {
2184
+ params: { environment: params?.environment ?? "PRODUCTION" }
2185
+ });
2186
+ }
2187
+ /**
2188
+ * Get PCS bots status
2189
+ */
2190
+ async getPCSStatus(params) {
2191
+ return this.cb.request("cbMonitoring", "/sysadmin/nodejs/instance/pcs/status", {
2192
+ params: { showBotsData: params?.showBotsData ?? true }
2193
+ });
2194
+ }
2195
+ /**
2196
+ * Get bot users
2197
+ */
2198
+ async getBotUsers() {
2199
+ return this.cb.request("cbExternalIntegrations", `/live-engage-service-0.1/le/accounts/${this.cb.getAccountId()}/bot_users`);
2200
+ }
2201
+ /**
2202
+ * Add a bot agent
2203
+ */
2204
+ async addAgent(lpUserId, chatBotId, request) {
2205
+ return this.cb.request("cbExternalIntegrations", `/live-engage-service-0.1/le/accounts/${this.cb.getAccountId()}/bot_users/${lpUserId}`, {
2206
+ method: "POST",
2207
+ body: request,
2208
+ params: { chatBotId }
2209
+ });
2210
+ }
2211
+ };
2212
+ var IntegrationsAPI = class {
2213
+ constructor(cb) {
2214
+ this.cb = cb;
2215
+ }
2216
+ /**
2217
+ * Get responders for a chatbot
2218
+ */
2219
+ async getResponders(chatBotId) {
2220
+ return this.cb.request("cbBotPlatform", "/responder", {
2221
+ params: { chatBotId }
2222
+ });
2223
+ }
2224
+ /**
2225
+ * Get LP skills
2226
+ */
2227
+ async getLPSkills() {
2228
+ return this.cb.request("cbExternalIntegrations", `/live-engage-service-0.1/le/accounts/${this.cb.getAccountId()}/skills`);
2229
+ }
2230
+ /**
2231
+ * Get credentials
2232
+ */
2233
+ async getCredentials() {
2234
+ return this.cb.request("cbExternalIntegrations", "/auth-service-0.1/credentials");
2235
+ }
2236
+ };
2237
+
1689
2238
  // src/sdk.ts
1690
2239
  var LPExtendSDK = class {
1691
2240
  /**
@@ -1718,6 +2267,7 @@ var LPExtendSDK = class {
1718
2267
  this.messaging = new MessagingAPI(this.http);
1719
2268
  this.sentinel = new SentinelAPI(this.http);
1720
2269
  this.prompts = new LPPromptsAPI(this.http);
2270
+ this.conversationBuilder = new ConversationBuilderAPI(config.accountId, this.debug, timeout);
1721
2271
  this.log("SDK initialized with scopes:", this.grantedScopes);
1722
2272
  }
1723
2273
  /**
@@ -1766,9 +2316,9 @@ async function createSDK(config) {
1766
2316
  if (!config.accountId) {
1767
2317
  throw new LPExtendSDKError("accountId is required", ErrorCodes.INVALID_CONFIG);
1768
2318
  }
1769
- if (!config.accessToken && !config.extendToken && !config.shellToken) {
2319
+ if (!config.accessToken && !config.extendToken && !config.shellToken && !config.apiKey) {
1770
2320
  throw new LPExtendSDKError(
1771
- "Either accessToken, extendToken, or shellToken is required",
2321
+ "Either accessToken, apiKey, extendToken, or shellToken is required",
1772
2322
  ErrorCodes.INVALID_CONFIG
1773
2323
  );
1774
2324
  }
@@ -1776,7 +2326,9 @@ async function createSDK(config) {
1776
2326
  const timeout = config.timeout ?? 3e4;
1777
2327
  let shellBaseUrl = config.shellBaseUrl;
1778
2328
  if (!shellBaseUrl) {
1779
- if (typeof window !== "undefined") {
2329
+ if (typeof process !== "undefined" && process.env?.LPEXTEND_SHELL_URL) {
2330
+ shellBaseUrl = process.env.LPEXTEND_SHELL_URL;
2331
+ } else if (typeof window !== "undefined") {
1780
2332
  try {
1781
2333
  if (window.self !== window.top && document.referrer) {
1782
2334
  const url = new URL(document.referrer);
@@ -1785,15 +2337,109 @@ async function createSDK(config) {
1785
2337
  } catch {
1786
2338
  }
1787
2339
  shellBaseUrl = shellBaseUrl || window.location.origin;
1788
- } else {
2340
+ } else if (config.apiKey || config.extendToken || config.shellToken) {
1789
2341
  throw new LPExtendSDKError(
1790
- "shellBaseUrl is required in non-browser environments",
2342
+ "shellBaseUrl is required when using apiKey, extendToken, or shellToken in non-browser environments. Set LPEXTEND_SHELL_URL environment variable or pass shellBaseUrl in config.",
1791
2343
  ErrorCodes.INVALID_CONFIG
1792
2344
  );
1793
2345
  }
1794
2346
  }
1795
2347
  let accessToken = config.accessToken;
1796
- if (!accessToken && config.extendToken) {
2348
+ if (!accessToken && config.apiKey && config.extendToken) {
2349
+ const verifyUrl = `${shellBaseUrl}/api/v1/apps/verify`;
2350
+ if (debug) {
2351
+ console.log("[LP-Extend-SDK] Verifying ExtendJWT with API key");
2352
+ console.log("[LP-Extend-SDK] Shell URL:", shellBaseUrl);
2353
+ console.log("[LP-Extend-SDK] Verify URL:", verifyUrl);
2354
+ console.log("[LP-Extend-SDK] API Key:", config.apiKey.substring(0, 20) + "...");
2355
+ console.log("[LP-Extend-SDK] ExtendToken length:", config.extendToken.length);
2356
+ }
2357
+ const authController = new AbortController();
2358
+ const authTimeoutId = setTimeout(() => authController.abort(), timeout);
2359
+ try {
2360
+ const authResponse = await fetch(verifyUrl, {
2361
+ method: "POST",
2362
+ headers: {
2363
+ "Content-Type": "application/json",
2364
+ "X-LPExtend-API-Key": config.apiKey
2365
+ },
2366
+ body: JSON.stringify({
2367
+ token: config.extendToken
2368
+ }),
2369
+ signal: authController.signal
2370
+ });
2371
+ clearTimeout(authTimeoutId);
2372
+ if (!authResponse.ok) {
2373
+ const errorData = await authResponse.json().catch(() => ({}));
2374
+ if (authResponse.status === 401) {
2375
+ throw new LPExtendSDKError(
2376
+ errorData.message || "Invalid API key or ExtendJWT",
2377
+ ErrorCodes.UNAUTHORIZED,
2378
+ authResponse.status,
2379
+ errorData
2380
+ );
2381
+ }
2382
+ if (authResponse.status === 403) {
2383
+ throw new LPExtendSDKError(
2384
+ errorData.message || "App not authorized for this account",
2385
+ ErrorCodes.APP_NOT_REGISTERED,
2386
+ authResponse.status,
2387
+ errorData
2388
+ );
2389
+ }
2390
+ throw new LPExtendSDKError(
2391
+ errorData.message || `Token verification failed: ${authResponse.status}`,
2392
+ ErrorCodes.API_ERROR,
2393
+ authResponse.status,
2394
+ errorData
2395
+ );
2396
+ }
2397
+ const authData = await authResponse.json();
2398
+ accessToken = authData.lpAccessToken;
2399
+ if (debug) {
2400
+ console.log("[LP-Extend-SDK] ExtendJWT verified with API key");
2401
+ console.log("[LP-Extend-SDK] User:", authData.user?.lpUserId, "Account:", authData.user?.lpAccountId);
2402
+ console.log("[LP-Extend-SDK] Allowed APIs:", authData.allowedApis);
2403
+ }
2404
+ const resolvedConfig = { ...config, accessToken };
2405
+ const initResult = {
2406
+ appId: config.appId,
2407
+ accountId: authData.user?.lpAccountId || config.accountId,
2408
+ grantedScopes: authData.allowedApis || [],
2409
+ appName: config.appId,
2410
+ version: "1.0.0"
2411
+ };
2412
+ return new LPExtendSDK(resolvedConfig, initResult);
2413
+ } catch (error) {
2414
+ clearTimeout(authTimeoutId);
2415
+ if (debug) {
2416
+ console.error("[LP-Extend-SDK] ExtendJWT verification error:", {
2417
+ name: error.name,
2418
+ message: error.message,
2419
+ cause: error.cause?.message || error.cause,
2420
+ verifyUrl
2421
+ });
2422
+ }
2423
+ if (error instanceof LPExtendSDKError) {
2424
+ throw error;
2425
+ }
2426
+ if (error.name === "AbortError") {
2427
+ throw new LPExtendSDKError("Token verification timeout", ErrorCodes.TIMEOUT);
2428
+ }
2429
+ const errorMessage = error.cause?.message || error.message;
2430
+ throw new LPExtendSDKError(
2431
+ `ExtendJWT verification failed: ${errorMessage}`,
2432
+ ErrorCodes.INIT_FAILED
2433
+ );
2434
+ }
2435
+ }
2436
+ if (!accessToken && config.apiKey && !config.extendToken) {
2437
+ throw new LPExtendSDKError(
2438
+ "API key authentication requires extendToken. The ExtendJWT is passed from the shell to your app when opened in an iframe.",
2439
+ ErrorCodes.INVALID_CONFIG
2440
+ );
2441
+ }
2442
+ if (!accessToken && config.extendToken && !config.apiKey) {
1797
2443
  if (debug) {
1798
2444
  console.log("[LP-Extend-SDK] Verifying ExtendJWT with shell");
1799
2445
  }
@@ -1836,6 +2482,20 @@ async function createSDK(config) {
1836
2482
  console.log("[LP-Extend-SDK] ExtendJWT verified, got LP access token");
1837
2483
  console.log("[LP-Extend-SDK] User:", authData.lpUserId, "Account:", authData.lpAccountId);
1838
2484
  }
2485
+ const grantedScopes = config.scopes || ["*"];
2486
+ if (debug) {
2487
+ console.log("[LP-Extend-SDK] ExtendJWT auth grants all scopes:", grantedScopes);
2488
+ console.log("[LP-Extend-SDK] SDK will call LP APIs directly");
2489
+ }
2490
+ const resolvedConfig = { ...config, accessToken };
2491
+ const initResult = {
2492
+ appId: config.appId,
2493
+ accountId: config.accountId,
2494
+ grantedScopes,
2495
+ appName: config.appId,
2496
+ version: "1.0.0"
2497
+ };
2498
+ return new LPExtendSDK(resolvedConfig, initResult);
1839
2499
  } catch (error) {
1840
2500
  clearTimeout(extendTimeoutId);
1841
2501
  if (error instanceof LPExtendSDKError) {
@@ -2000,6 +2660,51 @@ async function createSDK(config) {
2000
2660
  async function initializeSDK(config) {
2001
2661
  return createSDK(config);
2002
2662
  }
2663
+ async function createSDKFromEnv(extendToken) {
2664
+ const apiKey = process.env.LPEXTEND_API_KEY;
2665
+ const appId = process.env.APP_ID;
2666
+ const accountId = process.env.LP_ACCOUNT_ID;
2667
+ const shellBaseUrl = process.env.LPEXTEND_SHELL_URL;
2668
+ const debug = process.env.LPEXTEND_DEBUG === "true";
2669
+ if (!apiKey) {
2670
+ throw new LPExtendSDKError(
2671
+ "LPEXTEND_API_KEY environment variable is required",
2672
+ ErrorCodes.INVALID_CONFIG
2673
+ );
2674
+ }
2675
+ if (!appId) {
2676
+ throw new LPExtendSDKError(
2677
+ "APP_ID environment variable is required",
2678
+ ErrorCodes.INVALID_CONFIG
2679
+ );
2680
+ }
2681
+ if (!accountId) {
2682
+ throw new LPExtendSDKError(
2683
+ "LP_ACCOUNT_ID environment variable is required",
2684
+ ErrorCodes.INVALID_CONFIG
2685
+ );
2686
+ }
2687
+ if (!shellBaseUrl) {
2688
+ throw new LPExtendSDKError(
2689
+ "LPEXTEND_SHELL_URL environment variable is required",
2690
+ ErrorCodes.INVALID_CONFIG
2691
+ );
2692
+ }
2693
+ if (!extendToken) {
2694
+ throw new LPExtendSDKError(
2695
+ "extendToken is required. This is passed from the shell to your app when opened.",
2696
+ ErrorCodes.INVALID_CONFIG
2697
+ );
2698
+ }
2699
+ return createSDK({
2700
+ appId,
2701
+ accountId,
2702
+ apiKey,
2703
+ extendToken,
2704
+ shellBaseUrl,
2705
+ debug
2706
+ });
2707
+ }
2003
2708
  var VERSION = "1.0.0";
2004
2709
  var Scopes = {
2005
2710
  // Account Configuration
@@ -2115,6 +2820,6 @@ async function getShellToken(config) {
2115
2820
  }
2116
2821
  }
2117
2822
 
2118
- export { AIStudioAPI, AIStudioUsersAPI, AgentActivityAPI, AgentGroupsAPI, AgentMetricsAPI, AutomaticMessagesAPI, CampaignsAPI, CategoriesAPI, ConnectToMessagingAPI, ConversationsAPI, EngagementsAPI, ErrorCodes, EvaluatorsAPI, FlowsAPI, GeneratorsAPI, KnowledgebasesAPI, LOBsAPI, LPExtendSDK, LPExtendSDKError, LPPromptsAPI, MessagingAPI, MessagingHistoryAPI, MessagingOperationsAPI, OutboundReportingAPI, PredefinedContentAPI, ProfilesAPI, PromptLibraryAPI, QueryAPI, Scopes, SentinelAPI, SimulationsAPI, SkillsAPI, SpecialOccasionsAPI, SummaryAPI, TranscriptAnalysisAPI, UsersAPI, VERSION, WorkingHoursAPI, createSDK, getShellToken, initializeSDK };
2823
+ export { AIStudioAPI, AIStudioUsersAPI, AgentActivityAPI, AgentGroupsAPI, AgentMetricsAPI, AutomaticMessagesAPI, BotAgentsAPI, BotGroupsAPI, BotsAPI, CampaignsAPI, CategoriesAPI, ConnectToMessagingAPI, ConversationBuilderAPI, ConversationsAPI, DialogsAPI, EngagementsAPI, ErrorCodes, EvaluatorsAPI, FlowsAPI, GeneratorsAPI, IntegrationsAPI, InteractionsAPI, KnowledgeBasesAPI, KnowledgebasesAPI, LOBsAPI, LPExtendSDK, LPExtendSDKError, LPPromptsAPI, MessagingAPI, MessagingHistoryAPI, MessagingOperationsAPI, NLUDomainsAPI, OutboundReportingAPI, PredefinedContentAPI, ProfilesAPI, PromptLibraryAPI, QueryAPI, Scopes, SentinelAPI, SimulationsAPI, SkillsAPI, SpecialOccasionsAPI, SummaryAPI, TranscriptAnalysisAPI, UsersAPI, VERSION, WorkingHoursAPI, createSDK, createSDKFromEnv, getShellToken, initializeSDK };
2119
2824
  //# sourceMappingURL=index.mjs.map
2120
2825
  //# sourceMappingURL=index.mjs.map