lumnisai 0.1.13 → 0.1.14

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.cjs CHANGED
@@ -416,6 +416,42 @@ class MCPServersResource {
416
416
  }
417
417
  }
418
418
 
419
+ const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
420
+ function isUUID(s) {
421
+ return UUID_PATTERN.test(s);
422
+ }
423
+ function toCamel(s) {
424
+ if (isUUID(s))
425
+ return s;
426
+ return s.replace(/([-_][a-z])/gi, ($1) => {
427
+ return $1.toUpperCase().replace("-", "").replace("_", "");
428
+ });
429
+ }
430
+ function toSnake(s) {
431
+ if (isUUID(s))
432
+ return s;
433
+ return s.replace(/[A-Z]/g, (letter, index) => {
434
+ return index === 0 ? letter.toLowerCase() : `_${letter.toLowerCase()}`;
435
+ });
436
+ }
437
+ function convertCase(obj, converter) {
438
+ if (Array.isArray(obj)) {
439
+ return obj.map((v) => convertCase(v, converter));
440
+ } else if (obj !== null && typeof obj === "object") {
441
+ return Object.keys(obj).reduce((acc, key) => {
442
+ acc[converter(key)] = convertCase(obj[key], converter);
443
+ return acc;
444
+ }, {});
445
+ }
446
+ return obj;
447
+ }
448
+ function toCamelCase(obj) {
449
+ return convertCase(obj, toCamel);
450
+ }
451
+ function toSnakeCase(obj) {
452
+ return convertCase(obj, toSnake);
453
+ }
454
+
419
455
  class LumnisError extends Error {
420
456
  code;
421
457
  statusCode;
@@ -736,6 +772,293 @@ class MessagingResource {
736
772
  request
737
773
  );
738
774
  }
775
+ /**
776
+ * Create drafts for multiple prospects with real-time progress updates via Server-Sent Events (SSE).
777
+ *
778
+ * This method provides real-time progress updates as drafts are being created, significantly
779
+ * improving user experience for large batch operations (30+ prospects).
780
+ *
781
+ * **Event Types:**
782
+ * - `progress`: Progress update with percentage and current prospect
783
+ * - `draft_created`: Draft successfully created
784
+ * - `error`: Error occurred for a specific prospect
785
+ * - `complete`: Batch processing completed
786
+ *
787
+ * **Example:**
788
+ * ```typescript
789
+ * const result = await client.messaging.createBatchDraftsStream(
790
+ * 'user@example.com',
791
+ * {
792
+ * prospects: [...],
793
+ * channel: 'linkedin',
794
+ * useAiGeneration: true
795
+ * },
796
+ * {
797
+ * onProgress: (processed, total, percentage, prospectName) => {
798
+ * console.log(`${percentage}% - ${prospectName}`)
799
+ * },
800
+ * onDraftCreated: (draft) => {
801
+ * console.log(`Draft created: ${draft.id}`)
802
+ * },
803
+ * onError: (prospect, error) => {
804
+ * console.error(`Error for ${prospect}: ${error}`)
805
+ * },
806
+ * onComplete: (result) => {
807
+ * console.log(`Complete! Created: ${result.created}, Errors: ${result.errors}`)
808
+ * }
809
+ * }
810
+ * )
811
+ * ```
812
+ *
813
+ * @param userId - User ID or email
814
+ * @param request - Batch draft creation request
815
+ * @param callbacks - Optional callbacks for stream events
816
+ * @returns Final result with created drafts and error details
817
+ */
818
+ async createBatchDraftsStream(userId, request, callbacks) {
819
+ const queryParams = new URLSearchParams();
820
+ queryParams.append("user_id", userId);
821
+ const baseUrl = this.http.options.baseUrl;
822
+ const apiPrefix = this.http.options.apiPrefix || "";
823
+ const path = `/messaging/drafts/batch/stream?${queryParams.toString()}`;
824
+ const url = `${baseUrl}${apiPrefix}${path}`;
825
+ const headers = {
826
+ "Content-Type": "application/json",
827
+ "Accept": "text/event-stream",
828
+ ...this.http.options.headers
829
+ };
830
+ const body = JSON.stringify(toSnakeCase(request));
831
+ const response = await fetch(url, {
832
+ method: "POST",
833
+ headers,
834
+ body
835
+ });
836
+ if (!response.ok) {
837
+ const requestId = response.headers.get("x-request-id");
838
+ const contentType = response.headers.get("content-type") || "";
839
+ let detail = { raw: await response.text() };
840
+ try {
841
+ if (contentType.includes("application/json"))
842
+ detail = JSON.parse(detail.raw);
843
+ } catch {
844
+ }
845
+ const errorMsg = detail?.error?.message || `Server error: ${response.status}`;
846
+ if (response.status === 401) {
847
+ throw new AuthenticationError("Invalid or missing API key", { requestId, statusCode: 401, details: detail });
848
+ }
849
+ if (response.status === 403) {
850
+ throw new AuthenticationError("Forbidden - insufficient permissions", { requestId, statusCode: 403, details: detail });
851
+ }
852
+ if (response.status === 404) {
853
+ throw new NotFoundError("Resource not found", { requestId, statusCode: 404, details: detail });
854
+ }
855
+ if (response.status === 429) {
856
+ const retryAfter = response.headers.get("Retry-After");
857
+ throw new RateLimitError({ requestId, statusCode: 429, details: detail, retryAfter });
858
+ }
859
+ if (response.status >= 400 && response.status < 500) {
860
+ throw new ValidationError(errorMsg, { requestId, statusCode: response.status, details: detail });
861
+ }
862
+ throw new LumnisError(`Server error: ${response.status}`, { requestId, statusCode: response.status, details: detail });
863
+ }
864
+ const reader = response.body?.getReader();
865
+ if (!reader) {
866
+ throw new Error("Response body reader not available");
867
+ }
868
+ const decoder = new TextDecoder();
869
+ let buffer = "";
870
+ let finalResult = null;
871
+ try {
872
+ while (true) {
873
+ const { done, value } = await reader.read();
874
+ if (done)
875
+ break;
876
+ buffer += decoder.decode(value, { stream: true });
877
+ const lines = buffer.split("\n");
878
+ buffer = lines.pop() || "";
879
+ for (const line of lines) {
880
+ if (!line.startsWith("data: "))
881
+ continue;
882
+ try {
883
+ const eventData = JSON.parse(line.slice(6));
884
+ const { event, data } = eventData;
885
+ switch (event) {
886
+ case "progress": {
887
+ const progressData = toCamelCase(data);
888
+ callbacks?.onProgress?.(
889
+ progressData.processed || 0,
890
+ progressData.total || 0,
891
+ progressData.percentage || 0,
892
+ progressData.currentProspect || ""
893
+ );
894
+ break;
895
+ }
896
+ case "draft_created": {
897
+ const draftData = toCamelCase(data);
898
+ const draft = draftData.draft;
899
+ if (draft) {
900
+ const convertedDraft = toCamelCase(draft);
901
+ callbacks?.onDraftCreated?.(convertedDraft);
902
+ }
903
+ break;
904
+ }
905
+ case "error": {
906
+ const errorData = toCamelCase(data);
907
+ callbacks?.onError?.(
908
+ errorData.prospect || "Unknown",
909
+ errorData.error || ""
910
+ );
911
+ break;
912
+ }
913
+ case "complete": {
914
+ const completeData = toCamelCase(data);
915
+ finalResult = {
916
+ created: completeData.created || 0,
917
+ errors: completeData.errors || 0,
918
+ drafts: (completeData.drafts || []).map((d) => toCamelCase(d)),
919
+ errorDetails: completeData.errorDetails || []
920
+ };
921
+ callbacks?.onComplete?.(finalResult);
922
+ break;
923
+ }
924
+ }
925
+ } catch (parseError) {
926
+ continue;
927
+ }
928
+ }
929
+ }
930
+ } finally {
931
+ reader.releaseLock();
932
+ }
933
+ return finalResult || { created: 0, errors: 0, drafts: [], errorDetails: [] };
934
+ }
935
+ /**
936
+ * Create drafts with streaming events as an async generator.
937
+ *
938
+ * This method yields events as they arrive, providing more control over event handling.
939
+ *
940
+ * **Example:**
941
+ * ```typescript
942
+ * for await (const event of client.messaging.createBatchDraftsStreamGenerator(
943
+ * 'user@example.com',
944
+ * {
945
+ * prospects: [...],
946
+ * channel: 'linkedin',
947
+ * useAiGeneration: true
948
+ * }
949
+ * )) {
950
+ * switch (event.event) {
951
+ * case 'progress':
952
+ * console.log(`Progress: ${event.data.percentage}%`)
953
+ * break
954
+ * case 'draft_created':
955
+ * console.log(`Draft: ${event.data.draft.id}`)
956
+ * break
957
+ * case 'error':
958
+ * console.error(`Error: ${event.data.error}`)
959
+ * break
960
+ * case 'complete':
961
+ * console.log(`Done! ${event.data.created} drafts created`)
962
+ * break
963
+ * }
964
+ * }
965
+ * ```
966
+ *
967
+ * @param userId - User ID or email
968
+ * @param request - Batch draft creation request
969
+ * @yields Stream events with 'event' and 'data' keys
970
+ * @returns Final result with created drafts and error details
971
+ */
972
+ async *createBatchDraftsStreamGenerator(userId, request) {
973
+ const queryParams = new URLSearchParams();
974
+ queryParams.append("user_id", userId);
975
+ const baseUrl = this.http.options.baseUrl;
976
+ const apiPrefix = this.http.options.apiPrefix || "";
977
+ const path = `/messaging/drafts/batch/stream?${queryParams.toString()}`;
978
+ const url = `${baseUrl}${apiPrefix}${path}`;
979
+ const headers = {
980
+ "Content-Type": "application/json",
981
+ "Accept": "text/event-stream",
982
+ ...this.http.options.headers
983
+ };
984
+ const body = JSON.stringify(toSnakeCase(request));
985
+ const response = await fetch(url, {
986
+ method: "POST",
987
+ headers,
988
+ body
989
+ });
990
+ if (!response.ok) {
991
+ const requestId = response.headers.get("x-request-id");
992
+ const contentType = response.headers.get("content-type") || "";
993
+ let detail = { raw: await response.text() };
994
+ try {
995
+ if (contentType.includes("application/json"))
996
+ detail = JSON.parse(detail.raw);
997
+ } catch {
998
+ }
999
+ const errorMsg = detail?.error?.message || `Server error: ${response.status}`;
1000
+ if (response.status === 401) {
1001
+ throw new AuthenticationError("Invalid or missing API key", { requestId, statusCode: 401, details: detail });
1002
+ }
1003
+ if (response.status === 403) {
1004
+ throw new AuthenticationError("Forbidden - insufficient permissions", { requestId, statusCode: 403, details: detail });
1005
+ }
1006
+ if (response.status === 404) {
1007
+ throw new NotFoundError("Resource not found", { requestId, statusCode: 404, details: detail });
1008
+ }
1009
+ if (response.status === 429) {
1010
+ const retryAfter = response.headers.get("Retry-After");
1011
+ throw new RateLimitError({ requestId, statusCode: 429, details: detail, retryAfter });
1012
+ }
1013
+ if (response.status >= 400 && response.status < 500) {
1014
+ throw new ValidationError(errorMsg, { requestId, statusCode: response.status, details: detail });
1015
+ }
1016
+ throw new LumnisError(`Server error: ${response.status}`, { requestId, statusCode: response.status, details: detail });
1017
+ }
1018
+ const reader = response.body?.getReader();
1019
+ if (!reader) {
1020
+ throw new Error("Response body reader not available");
1021
+ }
1022
+ const decoder = new TextDecoder();
1023
+ let buffer = "";
1024
+ let finalResult = null;
1025
+ try {
1026
+ while (true) {
1027
+ const { done, value } = await reader.read();
1028
+ if (done)
1029
+ break;
1030
+ buffer += decoder.decode(value, { stream: true });
1031
+ const lines = buffer.split("\n");
1032
+ buffer = lines.pop() || "";
1033
+ for (const line of lines) {
1034
+ if (!line.startsWith("data: "))
1035
+ continue;
1036
+ try {
1037
+ const eventData = JSON.parse(line.slice(6));
1038
+ const camelEventData = {
1039
+ event: eventData.event,
1040
+ data: toCamelCase(eventData.data)
1041
+ };
1042
+ yield camelEventData;
1043
+ if (eventData.event === "complete") {
1044
+ const completeData = camelEventData.data;
1045
+ finalResult = {
1046
+ created: completeData.created || 0,
1047
+ errors: completeData.errors || 0,
1048
+ drafts: (completeData.drafts || []).map((d) => toCamelCase(d)),
1049
+ errorDetails: completeData.errorDetails || []
1050
+ };
1051
+ }
1052
+ } catch (parseError) {
1053
+ continue;
1054
+ }
1055
+ }
1056
+ }
1057
+ } finally {
1058
+ reader.releaseLock();
1059
+ }
1060
+ return finalResult || { created: 0, errors: 0, drafts: [], errorDetails: [] };
1061
+ }
739
1062
  /**
740
1063
  * Approve and send a single draft
741
1064
  */
@@ -1464,42 +1787,6 @@ class UsersResource {
1464
1787
  }
1465
1788
  }
1466
1789
 
1467
- const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
1468
- function isUUID(s) {
1469
- return UUID_PATTERN.test(s);
1470
- }
1471
- function toCamel(s) {
1472
- if (isUUID(s))
1473
- return s;
1474
- return s.replace(/([-_][a-z])/gi, ($1) => {
1475
- return $1.toUpperCase().replace("-", "").replace("_", "");
1476
- });
1477
- }
1478
- function toSnake(s) {
1479
- if (isUUID(s))
1480
- return s;
1481
- return s.replace(/[A-Z]/g, (letter, index) => {
1482
- return index === 0 ? letter.toLowerCase() : `_${letter.toLowerCase()}`;
1483
- });
1484
- }
1485
- function convertCase(obj, converter) {
1486
- if (Array.isArray(obj)) {
1487
- return obj.map((v) => convertCase(v, converter));
1488
- } else if (obj !== null && typeof obj === "object") {
1489
- return Object.keys(obj).reduce((acc, key) => {
1490
- acc[converter(key)] = convertCase(obj[key], converter);
1491
- return acc;
1492
- }, {});
1493
- }
1494
- return obj;
1495
- }
1496
- function toCamelCase(obj) {
1497
- return convertCase(obj, toCamel);
1498
- }
1499
- function toSnakeCase(obj) {
1500
- return convertCase(obj, toSnake);
1501
- }
1502
-
1503
1790
  class Http {
1504
1791
  options;
1505
1792
  constructor(options) {
package/dist/index.d.cts CHANGED
@@ -1598,6 +1598,65 @@ interface BatchDraftResponse {
1598
1598
  errors: number;
1599
1599
  errorDetails?: Array<Record<string, any>> | null;
1600
1600
  }
1601
+ /**
1602
+ * Progress event data from streaming batch draft creation
1603
+ */
1604
+ interface BatchDraftProgressData {
1605
+ processed: number;
1606
+ total: number;
1607
+ percentage: number;
1608
+ currentProspect: string;
1609
+ }
1610
+ /**
1611
+ * Draft created event data from streaming batch draft creation
1612
+ */
1613
+ interface BatchDraftCreatedData {
1614
+ draft: DraftResponse;
1615
+ prospectExternalId?: string | null;
1616
+ }
1617
+ /**
1618
+ * Error event data from streaming batch draft creation
1619
+ */
1620
+ interface BatchDraftErrorData {
1621
+ prospect: string;
1622
+ error: string;
1623
+ }
1624
+ /**
1625
+ * Complete event data from streaming batch draft creation
1626
+ */
1627
+ interface BatchDraftCompleteData {
1628
+ created: number;
1629
+ errors: number;
1630
+ drafts: DraftResponse[];
1631
+ errorDetails: Array<{
1632
+ prospect: string;
1633
+ error: string;
1634
+ }>;
1635
+ }
1636
+ /**
1637
+ * Stream event types for batch draft creation
1638
+ */
1639
+ type BatchDraftStreamEventType = 'progress' | 'draft_created' | 'error' | 'complete';
1640
+ /**
1641
+ * Stream event from batch draft creation
1642
+ */
1643
+ interface BatchDraftStreamEvent {
1644
+ event: BatchDraftStreamEventType;
1645
+ data: BatchDraftProgressData | BatchDraftCreatedData | BatchDraftErrorData | BatchDraftCompleteData;
1646
+ }
1647
+ /**
1648
+ * Callbacks for batch draft streaming
1649
+ */
1650
+ interface BatchDraftStreamCallbacks {
1651
+ /** Callback for progress updates */
1652
+ onProgress?: (processed: number, total: number, percentage: number, prospectName: string) => void;
1653
+ /** Callback when a draft is created */
1654
+ onDraftCreated?: (draft: DraftResponse) => void;
1655
+ /** Callback when an error occurs for a prospect */
1656
+ onError?: (prospect: string, error: string) => void;
1657
+ /** Callback when batch processing completes */
1658
+ onComplete?: (result: BatchDraftResponse) => void;
1659
+ }
1601
1660
  /**
1602
1661
  * Send result (returned by reply, linkedin/send, drafts endpoints)
1603
1662
  */
@@ -1864,6 +1923,88 @@ declare class MessagingResource {
1864
1923
  * Create drafts for multiple prospects with AI generation
1865
1924
  */
1866
1925
  createBatchDrafts(userId: string, request: BatchDraftRequest): Promise<BatchDraftResponse>;
1926
+ /**
1927
+ * Create drafts for multiple prospects with real-time progress updates via Server-Sent Events (SSE).
1928
+ *
1929
+ * This method provides real-time progress updates as drafts are being created, significantly
1930
+ * improving user experience for large batch operations (30+ prospects).
1931
+ *
1932
+ * **Event Types:**
1933
+ * - `progress`: Progress update with percentage and current prospect
1934
+ * - `draft_created`: Draft successfully created
1935
+ * - `error`: Error occurred for a specific prospect
1936
+ * - `complete`: Batch processing completed
1937
+ *
1938
+ * **Example:**
1939
+ * ```typescript
1940
+ * const result = await client.messaging.createBatchDraftsStream(
1941
+ * 'user@example.com',
1942
+ * {
1943
+ * prospects: [...],
1944
+ * channel: 'linkedin',
1945
+ * useAiGeneration: true
1946
+ * },
1947
+ * {
1948
+ * onProgress: (processed, total, percentage, prospectName) => {
1949
+ * console.log(`${percentage}% - ${prospectName}`)
1950
+ * },
1951
+ * onDraftCreated: (draft) => {
1952
+ * console.log(`Draft created: ${draft.id}`)
1953
+ * },
1954
+ * onError: (prospect, error) => {
1955
+ * console.error(`Error for ${prospect}: ${error}`)
1956
+ * },
1957
+ * onComplete: (result) => {
1958
+ * console.log(`Complete! Created: ${result.created}, Errors: ${result.errors}`)
1959
+ * }
1960
+ * }
1961
+ * )
1962
+ * ```
1963
+ *
1964
+ * @param userId - User ID or email
1965
+ * @param request - Batch draft creation request
1966
+ * @param callbacks - Optional callbacks for stream events
1967
+ * @returns Final result with created drafts and error details
1968
+ */
1969
+ createBatchDraftsStream(userId: string, request: BatchDraftRequest, callbacks?: BatchDraftStreamCallbacks): Promise<BatchDraftResponse>;
1970
+ /**
1971
+ * Create drafts with streaming events as an async generator.
1972
+ *
1973
+ * This method yields events as they arrive, providing more control over event handling.
1974
+ *
1975
+ * **Example:**
1976
+ * ```typescript
1977
+ * for await (const event of client.messaging.createBatchDraftsStreamGenerator(
1978
+ * 'user@example.com',
1979
+ * {
1980
+ * prospects: [...],
1981
+ * channel: 'linkedin',
1982
+ * useAiGeneration: true
1983
+ * }
1984
+ * )) {
1985
+ * switch (event.event) {
1986
+ * case 'progress':
1987
+ * console.log(`Progress: ${event.data.percentage}%`)
1988
+ * break
1989
+ * case 'draft_created':
1990
+ * console.log(`Draft: ${event.data.draft.id}`)
1991
+ * break
1992
+ * case 'error':
1993
+ * console.error(`Error: ${event.data.error}`)
1994
+ * break
1995
+ * case 'complete':
1996
+ * console.log(`Done! ${event.data.created} drafts created`)
1997
+ * break
1998
+ * }
1999
+ * }
2000
+ * ```
2001
+ *
2002
+ * @param userId - User ID or email
2003
+ * @param request - Batch draft creation request
2004
+ * @yields Stream events with 'event' and 'data' keys
2005
+ * @returns Final result with created drafts and error details
2006
+ */
2007
+ createBatchDraftsStreamGenerator(userId: string, request: BatchDraftRequest): AsyncGenerator<BatchDraftStreamEvent, BatchDraftResponse>;
1867
2008
  /**
1868
2009
  * Approve and send a single draft
1869
2010
  */
@@ -2574,4 +2715,4 @@ declare class ProgressTracker {
2574
2715
  declare function verifyWebhookSignature(payload: string, signature: string, secret: string): boolean;
2575
2716
 
2576
2717
  export = LumnisClient;
2577
- export { type AgentConfig, type ApiKeyMode, type ApiKeyModeRequest, type ApiKeyModeResponse, type ApiProvider, type AppEnabledResponse, type AppliedFilters, type AppsListResponse, type ArtifactObject, type ArtifactsListResponse, AuthenticationError, type BaseResource, type BatchCheckConnectionRequest, type BatchCheckPriorContactRequest, type BatchCheckPriorContactResponse, type BatchConnectionRequest, type BatchConnectionResponse, type BatchConnectionStatus, type BatchConnectionStatusResponse, type BatchDraftRequest, type BatchDraftResponse, type BatchProspectIdentifier, type BatchSendRequest, type BatchSendResponse, type BillingStatus, type BulkDeleteRequest, type BulkDeleteResponse, type BulkUploadResponse, type CancelResponseResponse, type ChannelContactHistory, ChannelType, type CheckAppEnabledParams, type CheckLinkedInConnectionRequest, type CheckPriorContactRequest, type CheckPriorContactResponse, type ChunkingStrategy, type ConnectionAcceptedData, type ConnectionCallbackRequest, type ConnectionCallbackResponse, type ConnectionInfo, type ConnectionStatus, type ConnectionStatusResponse, type ConnectionSummary, type ContentType, type ConversationDetail, ConversationStatus, type ConversationSummary, type CreateDraftRequest, type CreateFeedbackRequest, type CreateFeedbackResponse, type CreateResponseRequest, type CreateResponseResponse, type CreateThreadRequest, type DatabaseStatus, type DeleteApiKeyResponse, type DeleteConversationResponse, type DeleteConversationsByProjectResponse, type DisconnectRequest, type DisconnectResponse, type DraftResponse, DraftStatus, type DuplicateHandling, type Email, type EmailThreadSummary, type ErrorResponse, ExternalAPIKeysResource, type ExternalApiKeyResponse, type FeedbackListResponse, type FeedbackObject, type FeedbackType, type FileAttachment, type FileChunk, type FileContentResponse, type FileListResponse, type FileMetadata, type FileScope, type FileScopeUpdateRequest, type FileSearchRequest, type FileSearchResponse, type FileSearchResult, type FileStatisticsResponse, type FileUploadResponse, FilesResource, type FilterLogic, type FilterValue, type GetConnectionStatusParams, type GetToolsRequest, type GetToolsResponse, type GetUserConnectionsParams, type InitiateConnectionRequest, type InitiateConnectionResponse, IntegrationsResource, InternalServerError, type LinkedInConnectionStatus, type LinkedInCreditsResponse, type LinkedInSendRequest, LinkedInSubscriptionType, type ListProvidersResponse, LocalFileNotSupportedError, LumnisClient, type LumnisClientOptions, LumnisError, type LumnisErrorOptions, type MCPScope, type MCPServerCreateRequest, type MCPServerListResponse, type MCPServerResponse, type MCPServerUpdateRequest, MCPServersResource, type MCPToolListResponse, type MCPToolResponse, type MCPTransport, type Message, type MessageReceivedData, type MessageResponse, type MessageSentData, MessageType, MessagingAPIError, MessagingConnectionError, MessagingNotFoundError, MessagingResource, MessagingSendError, MessagingValidationError, type ModelAvailability, type ModelOverrides, type ModelPreferenceCreate, type ModelPreferencesBulkUpdate, ModelPreferencesResource, type ModelProvider, type ModelType, NetworkDistance, NoDataSourcesError, NotFoundError, OutreachMethod, type PaginationInfo, type PaginationParams, PeopleDataSource, PeopleResource, type PeopleSearchRequest, type PeopleSearchResponse, type PersonResult, type Plan, type PriorContactMessage, type ProcessingStatus, type ProcessingStatusResponse, type ProgressEntry, ProgressTracker, type ProspectConnectionCheck, type ProspectInfo, type ProspectPriorContactResult, type ProspectSyncIdentifier, type ProspectSyncResult, ProviderType, QueueItemStatus, type QuickPeopleSearchOutput, RateLimitError, type RateLimitErrorOptions, type ResponseArtifact, type ResponseListResponse, type ResponseObject, type ResponseStatus, ResponsesResource, type SalaryRange, type Scope, type SelectedSkill, type SendMessageRequest, type SendMessageResponse, type SendReplyRequest, type SendResult, type SkillAnalyticsRequest, type SkillEffectivenessMetrics, type SkillGuidelineBase, type SkillGuidelineCreate, type SkillGuidelineListResponse, type SkillGuidelineResponse, type SkillGuidelineUpdate, type SkillRetrievalMetadata, type SkillUsageBase, type SkillUsageCreate, type SkillUsageListResponse, type SkillUsageResponse, type SkillUsageUpdate, SkillsResource, SourcesNotAvailableError, type SpecializedAgentParams, type SpecializedAgentType, type StoreApiKeyRequest, type SyncJobResponse, SyncJobStatus, type SyncProspectRequest, type SyncProspectResponse, type SyncRequest, type SyncStats, type TenantDetailsResponse, TenantInfoResource, type TenantModelPreference, type TenantModelPreferencesResponse, type TestConnectionResponse, type ThreadListResponse, type ThreadObject, type ThreadResponsesParams, ThreadsResource, type ToolInfo, type UUID, type UnlinkConversationsResponse, type UpdateAppStatusParams, type UpdateAppStatusResponse, type UpdateLinkedInSubscriptionRequest, type UpdateThreadRequest, type UserConnectionsResponse, type UserCreateRequest, type UserDeleteResponse, type UserIdentifier, type UserListResponse, type UserResponse, type UserUpdateRequest, UsersResource, ValidationError, type WebhookEvent, type WebhookPayload, displayProgress, formatProgressEntry, verifyWebhookSignature };
2718
+ export { type AgentConfig, type ApiKeyMode, type ApiKeyModeRequest, type ApiKeyModeResponse, type ApiProvider, type AppEnabledResponse, type AppliedFilters, type AppsListResponse, type ArtifactObject, type ArtifactsListResponse, AuthenticationError, type BaseResource, type BatchCheckConnectionRequest, type BatchCheckPriorContactRequest, type BatchCheckPriorContactResponse, type BatchConnectionRequest, type BatchConnectionResponse, type BatchConnectionStatus, type BatchConnectionStatusResponse, type BatchDraftCompleteData, type BatchDraftCreatedData, type BatchDraftErrorData, type BatchDraftProgressData, type BatchDraftRequest, type BatchDraftResponse, type BatchDraftStreamCallbacks, type BatchDraftStreamEvent, type BatchDraftStreamEventType, type BatchProspectIdentifier, type BatchSendRequest, type BatchSendResponse, type BillingStatus, type BulkDeleteRequest, type BulkDeleteResponse, type BulkUploadResponse, type CancelResponseResponse, type ChannelContactHistory, ChannelType, type CheckAppEnabledParams, type CheckLinkedInConnectionRequest, type CheckPriorContactRequest, type CheckPriorContactResponse, type ChunkingStrategy, type ConnectionAcceptedData, type ConnectionCallbackRequest, type ConnectionCallbackResponse, type ConnectionInfo, type ConnectionStatus, type ConnectionStatusResponse, type ConnectionSummary, type ContentType, type ConversationDetail, ConversationStatus, type ConversationSummary, type CreateDraftRequest, type CreateFeedbackRequest, type CreateFeedbackResponse, type CreateResponseRequest, type CreateResponseResponse, type CreateThreadRequest, type DatabaseStatus, type DeleteApiKeyResponse, type DeleteConversationResponse, type DeleteConversationsByProjectResponse, type DisconnectRequest, type DisconnectResponse, type DraftResponse, DraftStatus, type DuplicateHandling, type Email, type EmailThreadSummary, type ErrorResponse, ExternalAPIKeysResource, type ExternalApiKeyResponse, type FeedbackListResponse, type FeedbackObject, type FeedbackType, type FileAttachment, type FileChunk, type FileContentResponse, type FileListResponse, type FileMetadata, type FileScope, type FileScopeUpdateRequest, type FileSearchRequest, type FileSearchResponse, type FileSearchResult, type FileStatisticsResponse, type FileUploadResponse, FilesResource, type FilterLogic, type FilterValue, type GetConnectionStatusParams, type GetToolsRequest, type GetToolsResponse, type GetUserConnectionsParams, type InitiateConnectionRequest, type InitiateConnectionResponse, IntegrationsResource, InternalServerError, type LinkedInConnectionStatus, type LinkedInCreditsResponse, type LinkedInSendRequest, LinkedInSubscriptionType, type ListProvidersResponse, LocalFileNotSupportedError, LumnisClient, type LumnisClientOptions, LumnisError, type LumnisErrorOptions, type MCPScope, type MCPServerCreateRequest, type MCPServerListResponse, type MCPServerResponse, type MCPServerUpdateRequest, MCPServersResource, type MCPToolListResponse, type MCPToolResponse, type MCPTransport, type Message, type MessageReceivedData, type MessageResponse, type MessageSentData, MessageType, MessagingAPIError, MessagingConnectionError, MessagingNotFoundError, MessagingResource, MessagingSendError, MessagingValidationError, type ModelAvailability, type ModelOverrides, type ModelPreferenceCreate, type ModelPreferencesBulkUpdate, ModelPreferencesResource, type ModelProvider, type ModelType, NetworkDistance, NoDataSourcesError, NotFoundError, OutreachMethod, type PaginationInfo, type PaginationParams, PeopleDataSource, PeopleResource, type PeopleSearchRequest, type PeopleSearchResponse, type PersonResult, type Plan, type PriorContactMessage, type ProcessingStatus, type ProcessingStatusResponse, type ProgressEntry, ProgressTracker, type ProspectConnectionCheck, type ProspectInfo, type ProspectPriorContactResult, type ProspectSyncIdentifier, type ProspectSyncResult, ProviderType, QueueItemStatus, type QuickPeopleSearchOutput, RateLimitError, type RateLimitErrorOptions, type ResponseArtifact, type ResponseListResponse, type ResponseObject, type ResponseStatus, ResponsesResource, type SalaryRange, type Scope, type SelectedSkill, type SendMessageRequest, type SendMessageResponse, type SendReplyRequest, type SendResult, type SkillAnalyticsRequest, type SkillEffectivenessMetrics, type SkillGuidelineBase, type SkillGuidelineCreate, type SkillGuidelineListResponse, type SkillGuidelineResponse, type SkillGuidelineUpdate, type SkillRetrievalMetadata, type SkillUsageBase, type SkillUsageCreate, type SkillUsageListResponse, type SkillUsageResponse, type SkillUsageUpdate, SkillsResource, SourcesNotAvailableError, type SpecializedAgentParams, type SpecializedAgentType, type StoreApiKeyRequest, type SyncJobResponse, SyncJobStatus, type SyncProspectRequest, type SyncProspectResponse, type SyncRequest, type SyncStats, type TenantDetailsResponse, TenantInfoResource, type TenantModelPreference, type TenantModelPreferencesResponse, type TestConnectionResponse, type ThreadListResponse, type ThreadObject, type ThreadResponsesParams, ThreadsResource, type ToolInfo, type UUID, type UnlinkConversationsResponse, type UpdateAppStatusParams, type UpdateAppStatusResponse, type UpdateLinkedInSubscriptionRequest, type UpdateThreadRequest, type UserConnectionsResponse, type UserCreateRequest, type UserDeleteResponse, type UserIdentifier, type UserListResponse, type UserResponse, type UserUpdateRequest, UsersResource, ValidationError, type WebhookEvent, type WebhookPayload, displayProgress, formatProgressEntry, verifyWebhookSignature };
package/dist/index.d.mts CHANGED
@@ -1598,6 +1598,65 @@ interface BatchDraftResponse {
1598
1598
  errors: number;
1599
1599
  errorDetails?: Array<Record<string, any>> | null;
1600
1600
  }
1601
+ /**
1602
+ * Progress event data from streaming batch draft creation
1603
+ */
1604
+ interface BatchDraftProgressData {
1605
+ processed: number;
1606
+ total: number;
1607
+ percentage: number;
1608
+ currentProspect: string;
1609
+ }
1610
+ /**
1611
+ * Draft created event data from streaming batch draft creation
1612
+ */
1613
+ interface BatchDraftCreatedData {
1614
+ draft: DraftResponse;
1615
+ prospectExternalId?: string | null;
1616
+ }
1617
+ /**
1618
+ * Error event data from streaming batch draft creation
1619
+ */
1620
+ interface BatchDraftErrorData {
1621
+ prospect: string;
1622
+ error: string;
1623
+ }
1624
+ /**
1625
+ * Complete event data from streaming batch draft creation
1626
+ */
1627
+ interface BatchDraftCompleteData {
1628
+ created: number;
1629
+ errors: number;
1630
+ drafts: DraftResponse[];
1631
+ errorDetails: Array<{
1632
+ prospect: string;
1633
+ error: string;
1634
+ }>;
1635
+ }
1636
+ /**
1637
+ * Stream event types for batch draft creation
1638
+ */
1639
+ type BatchDraftStreamEventType = 'progress' | 'draft_created' | 'error' | 'complete';
1640
+ /**
1641
+ * Stream event from batch draft creation
1642
+ */
1643
+ interface BatchDraftStreamEvent {
1644
+ event: BatchDraftStreamEventType;
1645
+ data: BatchDraftProgressData | BatchDraftCreatedData | BatchDraftErrorData | BatchDraftCompleteData;
1646
+ }
1647
+ /**
1648
+ * Callbacks for batch draft streaming
1649
+ */
1650
+ interface BatchDraftStreamCallbacks {
1651
+ /** Callback for progress updates */
1652
+ onProgress?: (processed: number, total: number, percentage: number, prospectName: string) => void;
1653
+ /** Callback when a draft is created */
1654
+ onDraftCreated?: (draft: DraftResponse) => void;
1655
+ /** Callback when an error occurs for a prospect */
1656
+ onError?: (prospect: string, error: string) => void;
1657
+ /** Callback when batch processing completes */
1658
+ onComplete?: (result: BatchDraftResponse) => void;
1659
+ }
1601
1660
  /**
1602
1661
  * Send result (returned by reply, linkedin/send, drafts endpoints)
1603
1662
  */
@@ -1864,6 +1923,88 @@ declare class MessagingResource {
1864
1923
  * Create drafts for multiple prospects with AI generation
1865
1924
  */
1866
1925
  createBatchDrafts(userId: string, request: BatchDraftRequest): Promise<BatchDraftResponse>;
1926
+ /**
1927
+ * Create drafts for multiple prospects with real-time progress updates via Server-Sent Events (SSE).
1928
+ *
1929
+ * This method provides real-time progress updates as drafts are being created, significantly
1930
+ * improving user experience for large batch operations (30+ prospects).
1931
+ *
1932
+ * **Event Types:**
1933
+ * - `progress`: Progress update with percentage and current prospect
1934
+ * - `draft_created`: Draft successfully created
1935
+ * - `error`: Error occurred for a specific prospect
1936
+ * - `complete`: Batch processing completed
1937
+ *
1938
+ * **Example:**
1939
+ * ```typescript
1940
+ * const result = await client.messaging.createBatchDraftsStream(
1941
+ * 'user@example.com',
1942
+ * {
1943
+ * prospects: [...],
1944
+ * channel: 'linkedin',
1945
+ * useAiGeneration: true
1946
+ * },
1947
+ * {
1948
+ * onProgress: (processed, total, percentage, prospectName) => {
1949
+ * console.log(`${percentage}% - ${prospectName}`)
1950
+ * },
1951
+ * onDraftCreated: (draft) => {
1952
+ * console.log(`Draft created: ${draft.id}`)
1953
+ * },
1954
+ * onError: (prospect, error) => {
1955
+ * console.error(`Error for ${prospect}: ${error}`)
1956
+ * },
1957
+ * onComplete: (result) => {
1958
+ * console.log(`Complete! Created: ${result.created}, Errors: ${result.errors}`)
1959
+ * }
1960
+ * }
1961
+ * )
1962
+ * ```
1963
+ *
1964
+ * @param userId - User ID or email
1965
+ * @param request - Batch draft creation request
1966
+ * @param callbacks - Optional callbacks for stream events
1967
+ * @returns Final result with created drafts and error details
1968
+ */
1969
+ createBatchDraftsStream(userId: string, request: BatchDraftRequest, callbacks?: BatchDraftStreamCallbacks): Promise<BatchDraftResponse>;
1970
+ /**
1971
+ * Create drafts with streaming events as an async generator.
1972
+ *
1973
+ * This method yields events as they arrive, providing more control over event handling.
1974
+ *
1975
+ * **Example:**
1976
+ * ```typescript
1977
+ * for await (const event of client.messaging.createBatchDraftsStreamGenerator(
1978
+ * 'user@example.com',
1979
+ * {
1980
+ * prospects: [...],
1981
+ * channel: 'linkedin',
1982
+ * useAiGeneration: true
1983
+ * }
1984
+ * )) {
1985
+ * switch (event.event) {
1986
+ * case 'progress':
1987
+ * console.log(`Progress: ${event.data.percentage}%`)
1988
+ * break
1989
+ * case 'draft_created':
1990
+ * console.log(`Draft: ${event.data.draft.id}`)
1991
+ * break
1992
+ * case 'error':
1993
+ * console.error(`Error: ${event.data.error}`)
1994
+ * break
1995
+ * case 'complete':
1996
+ * console.log(`Done! ${event.data.created} drafts created`)
1997
+ * break
1998
+ * }
1999
+ * }
2000
+ * ```
2001
+ *
2002
+ * @param userId - User ID or email
2003
+ * @param request - Batch draft creation request
2004
+ * @yields Stream events with 'event' and 'data' keys
2005
+ * @returns Final result with created drafts and error details
2006
+ */
2007
+ createBatchDraftsStreamGenerator(userId: string, request: BatchDraftRequest): AsyncGenerator<BatchDraftStreamEvent, BatchDraftResponse>;
1867
2008
  /**
1868
2009
  * Approve and send a single draft
1869
2010
  */
@@ -2573,4 +2714,4 @@ declare class ProgressTracker {
2573
2714
  */
2574
2715
  declare function verifyWebhookSignature(payload: string, signature: string, secret: string): boolean;
2575
2716
 
2576
- export { type AgentConfig, type ApiKeyMode, type ApiKeyModeRequest, type ApiKeyModeResponse, type ApiProvider, type AppEnabledResponse, type AppliedFilters, type AppsListResponse, type ArtifactObject, type ArtifactsListResponse, AuthenticationError, type BaseResource, type BatchCheckConnectionRequest, type BatchCheckPriorContactRequest, type BatchCheckPriorContactResponse, type BatchConnectionRequest, type BatchConnectionResponse, type BatchConnectionStatus, type BatchConnectionStatusResponse, type BatchDraftRequest, type BatchDraftResponse, type BatchProspectIdentifier, type BatchSendRequest, type BatchSendResponse, type BillingStatus, type BulkDeleteRequest, type BulkDeleteResponse, type BulkUploadResponse, type CancelResponseResponse, type ChannelContactHistory, ChannelType, type CheckAppEnabledParams, type CheckLinkedInConnectionRequest, type CheckPriorContactRequest, type CheckPriorContactResponse, type ChunkingStrategy, type ConnectionAcceptedData, type ConnectionCallbackRequest, type ConnectionCallbackResponse, type ConnectionInfo, type ConnectionStatus, type ConnectionStatusResponse, type ConnectionSummary, type ContentType, type ConversationDetail, ConversationStatus, type ConversationSummary, type CreateDraftRequest, type CreateFeedbackRequest, type CreateFeedbackResponse, type CreateResponseRequest, type CreateResponseResponse, type CreateThreadRequest, type DatabaseStatus, type DeleteApiKeyResponse, type DeleteConversationResponse, type DeleteConversationsByProjectResponse, type DisconnectRequest, type DisconnectResponse, type DraftResponse, DraftStatus, type DuplicateHandling, type Email, type EmailThreadSummary, type ErrorResponse, ExternalAPIKeysResource, type ExternalApiKeyResponse, type FeedbackListResponse, type FeedbackObject, type FeedbackType, type FileAttachment, type FileChunk, type FileContentResponse, type FileListResponse, type FileMetadata, type FileScope, type FileScopeUpdateRequest, type FileSearchRequest, type FileSearchResponse, type FileSearchResult, type FileStatisticsResponse, type FileUploadResponse, FilesResource, type FilterLogic, type FilterValue, type GetConnectionStatusParams, type GetToolsRequest, type GetToolsResponse, type GetUserConnectionsParams, type InitiateConnectionRequest, type InitiateConnectionResponse, IntegrationsResource, InternalServerError, type LinkedInConnectionStatus, type LinkedInCreditsResponse, type LinkedInSendRequest, LinkedInSubscriptionType, type ListProvidersResponse, LocalFileNotSupportedError, LumnisClient, type LumnisClientOptions, LumnisError, type LumnisErrorOptions, type MCPScope, type MCPServerCreateRequest, type MCPServerListResponse, type MCPServerResponse, type MCPServerUpdateRequest, MCPServersResource, type MCPToolListResponse, type MCPToolResponse, type MCPTransport, type Message, type MessageReceivedData, type MessageResponse, type MessageSentData, MessageType, MessagingAPIError, MessagingConnectionError, MessagingNotFoundError, MessagingResource, MessagingSendError, MessagingValidationError, type ModelAvailability, type ModelOverrides, type ModelPreferenceCreate, type ModelPreferencesBulkUpdate, ModelPreferencesResource, type ModelProvider, type ModelType, NetworkDistance, NoDataSourcesError, NotFoundError, OutreachMethod, type PaginationInfo, type PaginationParams, PeopleDataSource, PeopleResource, type PeopleSearchRequest, type PeopleSearchResponse, type PersonResult, type Plan, type PriorContactMessage, type ProcessingStatus, type ProcessingStatusResponse, type ProgressEntry, ProgressTracker, type ProspectConnectionCheck, type ProspectInfo, type ProspectPriorContactResult, type ProspectSyncIdentifier, type ProspectSyncResult, ProviderType, QueueItemStatus, type QuickPeopleSearchOutput, RateLimitError, type RateLimitErrorOptions, type ResponseArtifact, type ResponseListResponse, type ResponseObject, type ResponseStatus, ResponsesResource, type SalaryRange, type Scope, type SelectedSkill, type SendMessageRequest, type SendMessageResponse, type SendReplyRequest, type SendResult, type SkillAnalyticsRequest, type SkillEffectivenessMetrics, type SkillGuidelineBase, type SkillGuidelineCreate, type SkillGuidelineListResponse, type SkillGuidelineResponse, type SkillGuidelineUpdate, type SkillRetrievalMetadata, type SkillUsageBase, type SkillUsageCreate, type SkillUsageListResponse, type SkillUsageResponse, type SkillUsageUpdate, SkillsResource, SourcesNotAvailableError, type SpecializedAgentParams, type SpecializedAgentType, type StoreApiKeyRequest, type SyncJobResponse, SyncJobStatus, type SyncProspectRequest, type SyncProspectResponse, type SyncRequest, type SyncStats, type TenantDetailsResponse, TenantInfoResource, type TenantModelPreference, type TenantModelPreferencesResponse, type TestConnectionResponse, type ThreadListResponse, type ThreadObject, type ThreadResponsesParams, ThreadsResource, type ToolInfo, type UUID, type UnlinkConversationsResponse, type UpdateAppStatusParams, type UpdateAppStatusResponse, type UpdateLinkedInSubscriptionRequest, type UpdateThreadRequest, type UserConnectionsResponse, type UserCreateRequest, type UserDeleteResponse, type UserIdentifier, type UserListResponse, type UserResponse, type UserUpdateRequest, UsersResource, ValidationError, type WebhookEvent, type WebhookPayload, LumnisClient as default, displayProgress, formatProgressEntry, verifyWebhookSignature };
2717
+ export { type AgentConfig, type ApiKeyMode, type ApiKeyModeRequest, type ApiKeyModeResponse, type ApiProvider, type AppEnabledResponse, type AppliedFilters, type AppsListResponse, type ArtifactObject, type ArtifactsListResponse, AuthenticationError, type BaseResource, type BatchCheckConnectionRequest, type BatchCheckPriorContactRequest, type BatchCheckPriorContactResponse, type BatchConnectionRequest, type BatchConnectionResponse, type BatchConnectionStatus, type BatchConnectionStatusResponse, type BatchDraftCompleteData, type BatchDraftCreatedData, type BatchDraftErrorData, type BatchDraftProgressData, type BatchDraftRequest, type BatchDraftResponse, type BatchDraftStreamCallbacks, type BatchDraftStreamEvent, type BatchDraftStreamEventType, type BatchProspectIdentifier, type BatchSendRequest, type BatchSendResponse, type BillingStatus, type BulkDeleteRequest, type BulkDeleteResponse, type BulkUploadResponse, type CancelResponseResponse, type ChannelContactHistory, ChannelType, type CheckAppEnabledParams, type CheckLinkedInConnectionRequest, type CheckPriorContactRequest, type CheckPriorContactResponse, type ChunkingStrategy, type ConnectionAcceptedData, type ConnectionCallbackRequest, type ConnectionCallbackResponse, type ConnectionInfo, type ConnectionStatus, type ConnectionStatusResponse, type ConnectionSummary, type ContentType, type ConversationDetail, ConversationStatus, type ConversationSummary, type CreateDraftRequest, type CreateFeedbackRequest, type CreateFeedbackResponse, type CreateResponseRequest, type CreateResponseResponse, type CreateThreadRequest, type DatabaseStatus, type DeleteApiKeyResponse, type DeleteConversationResponse, type DeleteConversationsByProjectResponse, type DisconnectRequest, type DisconnectResponse, type DraftResponse, DraftStatus, type DuplicateHandling, type Email, type EmailThreadSummary, type ErrorResponse, ExternalAPIKeysResource, type ExternalApiKeyResponse, type FeedbackListResponse, type FeedbackObject, type FeedbackType, type FileAttachment, type FileChunk, type FileContentResponse, type FileListResponse, type FileMetadata, type FileScope, type FileScopeUpdateRequest, type FileSearchRequest, type FileSearchResponse, type FileSearchResult, type FileStatisticsResponse, type FileUploadResponse, FilesResource, type FilterLogic, type FilterValue, type GetConnectionStatusParams, type GetToolsRequest, type GetToolsResponse, type GetUserConnectionsParams, type InitiateConnectionRequest, type InitiateConnectionResponse, IntegrationsResource, InternalServerError, type LinkedInConnectionStatus, type LinkedInCreditsResponse, type LinkedInSendRequest, LinkedInSubscriptionType, type ListProvidersResponse, LocalFileNotSupportedError, LumnisClient, type LumnisClientOptions, LumnisError, type LumnisErrorOptions, type MCPScope, type MCPServerCreateRequest, type MCPServerListResponse, type MCPServerResponse, type MCPServerUpdateRequest, MCPServersResource, type MCPToolListResponse, type MCPToolResponse, type MCPTransport, type Message, type MessageReceivedData, type MessageResponse, type MessageSentData, MessageType, MessagingAPIError, MessagingConnectionError, MessagingNotFoundError, MessagingResource, MessagingSendError, MessagingValidationError, type ModelAvailability, type ModelOverrides, type ModelPreferenceCreate, type ModelPreferencesBulkUpdate, ModelPreferencesResource, type ModelProvider, type ModelType, NetworkDistance, NoDataSourcesError, NotFoundError, OutreachMethod, type PaginationInfo, type PaginationParams, PeopleDataSource, PeopleResource, type PeopleSearchRequest, type PeopleSearchResponse, type PersonResult, type Plan, type PriorContactMessage, type ProcessingStatus, type ProcessingStatusResponse, type ProgressEntry, ProgressTracker, type ProspectConnectionCheck, type ProspectInfo, type ProspectPriorContactResult, type ProspectSyncIdentifier, type ProspectSyncResult, ProviderType, QueueItemStatus, type QuickPeopleSearchOutput, RateLimitError, type RateLimitErrorOptions, type ResponseArtifact, type ResponseListResponse, type ResponseObject, type ResponseStatus, ResponsesResource, type SalaryRange, type Scope, type SelectedSkill, type SendMessageRequest, type SendMessageResponse, type SendReplyRequest, type SendResult, type SkillAnalyticsRequest, type SkillEffectivenessMetrics, type SkillGuidelineBase, type SkillGuidelineCreate, type SkillGuidelineListResponse, type SkillGuidelineResponse, type SkillGuidelineUpdate, type SkillRetrievalMetadata, type SkillUsageBase, type SkillUsageCreate, type SkillUsageListResponse, type SkillUsageResponse, type SkillUsageUpdate, SkillsResource, SourcesNotAvailableError, type SpecializedAgentParams, type SpecializedAgentType, type StoreApiKeyRequest, type SyncJobResponse, SyncJobStatus, type SyncProspectRequest, type SyncProspectResponse, type SyncRequest, type SyncStats, type TenantDetailsResponse, TenantInfoResource, type TenantModelPreference, type TenantModelPreferencesResponse, type TestConnectionResponse, type ThreadListResponse, type ThreadObject, type ThreadResponsesParams, ThreadsResource, type ToolInfo, type UUID, type UnlinkConversationsResponse, type UpdateAppStatusParams, type UpdateAppStatusResponse, type UpdateLinkedInSubscriptionRequest, type UpdateThreadRequest, type UserConnectionsResponse, type UserCreateRequest, type UserDeleteResponse, type UserIdentifier, type UserListResponse, type UserResponse, type UserUpdateRequest, UsersResource, ValidationError, type WebhookEvent, type WebhookPayload, LumnisClient as default, displayProgress, formatProgressEntry, verifyWebhookSignature };
package/dist/index.d.ts CHANGED
@@ -1598,6 +1598,65 @@ interface BatchDraftResponse {
1598
1598
  errors: number;
1599
1599
  errorDetails?: Array<Record<string, any>> | null;
1600
1600
  }
1601
+ /**
1602
+ * Progress event data from streaming batch draft creation
1603
+ */
1604
+ interface BatchDraftProgressData {
1605
+ processed: number;
1606
+ total: number;
1607
+ percentage: number;
1608
+ currentProspect: string;
1609
+ }
1610
+ /**
1611
+ * Draft created event data from streaming batch draft creation
1612
+ */
1613
+ interface BatchDraftCreatedData {
1614
+ draft: DraftResponse;
1615
+ prospectExternalId?: string | null;
1616
+ }
1617
+ /**
1618
+ * Error event data from streaming batch draft creation
1619
+ */
1620
+ interface BatchDraftErrorData {
1621
+ prospect: string;
1622
+ error: string;
1623
+ }
1624
+ /**
1625
+ * Complete event data from streaming batch draft creation
1626
+ */
1627
+ interface BatchDraftCompleteData {
1628
+ created: number;
1629
+ errors: number;
1630
+ drafts: DraftResponse[];
1631
+ errorDetails: Array<{
1632
+ prospect: string;
1633
+ error: string;
1634
+ }>;
1635
+ }
1636
+ /**
1637
+ * Stream event types for batch draft creation
1638
+ */
1639
+ type BatchDraftStreamEventType = 'progress' | 'draft_created' | 'error' | 'complete';
1640
+ /**
1641
+ * Stream event from batch draft creation
1642
+ */
1643
+ interface BatchDraftStreamEvent {
1644
+ event: BatchDraftStreamEventType;
1645
+ data: BatchDraftProgressData | BatchDraftCreatedData | BatchDraftErrorData | BatchDraftCompleteData;
1646
+ }
1647
+ /**
1648
+ * Callbacks for batch draft streaming
1649
+ */
1650
+ interface BatchDraftStreamCallbacks {
1651
+ /** Callback for progress updates */
1652
+ onProgress?: (processed: number, total: number, percentage: number, prospectName: string) => void;
1653
+ /** Callback when a draft is created */
1654
+ onDraftCreated?: (draft: DraftResponse) => void;
1655
+ /** Callback when an error occurs for a prospect */
1656
+ onError?: (prospect: string, error: string) => void;
1657
+ /** Callback when batch processing completes */
1658
+ onComplete?: (result: BatchDraftResponse) => void;
1659
+ }
1601
1660
  /**
1602
1661
  * Send result (returned by reply, linkedin/send, drafts endpoints)
1603
1662
  */
@@ -1864,6 +1923,88 @@ declare class MessagingResource {
1864
1923
  * Create drafts for multiple prospects with AI generation
1865
1924
  */
1866
1925
  createBatchDrafts(userId: string, request: BatchDraftRequest): Promise<BatchDraftResponse>;
1926
+ /**
1927
+ * Create drafts for multiple prospects with real-time progress updates via Server-Sent Events (SSE).
1928
+ *
1929
+ * This method provides real-time progress updates as drafts are being created, significantly
1930
+ * improving user experience for large batch operations (30+ prospects).
1931
+ *
1932
+ * **Event Types:**
1933
+ * - `progress`: Progress update with percentage and current prospect
1934
+ * - `draft_created`: Draft successfully created
1935
+ * - `error`: Error occurred for a specific prospect
1936
+ * - `complete`: Batch processing completed
1937
+ *
1938
+ * **Example:**
1939
+ * ```typescript
1940
+ * const result = await client.messaging.createBatchDraftsStream(
1941
+ * 'user@example.com',
1942
+ * {
1943
+ * prospects: [...],
1944
+ * channel: 'linkedin',
1945
+ * useAiGeneration: true
1946
+ * },
1947
+ * {
1948
+ * onProgress: (processed, total, percentage, prospectName) => {
1949
+ * console.log(`${percentage}% - ${prospectName}`)
1950
+ * },
1951
+ * onDraftCreated: (draft) => {
1952
+ * console.log(`Draft created: ${draft.id}`)
1953
+ * },
1954
+ * onError: (prospect, error) => {
1955
+ * console.error(`Error for ${prospect}: ${error}`)
1956
+ * },
1957
+ * onComplete: (result) => {
1958
+ * console.log(`Complete! Created: ${result.created}, Errors: ${result.errors}`)
1959
+ * }
1960
+ * }
1961
+ * )
1962
+ * ```
1963
+ *
1964
+ * @param userId - User ID or email
1965
+ * @param request - Batch draft creation request
1966
+ * @param callbacks - Optional callbacks for stream events
1967
+ * @returns Final result with created drafts and error details
1968
+ */
1969
+ createBatchDraftsStream(userId: string, request: BatchDraftRequest, callbacks?: BatchDraftStreamCallbacks): Promise<BatchDraftResponse>;
1970
+ /**
1971
+ * Create drafts with streaming events as an async generator.
1972
+ *
1973
+ * This method yields events as they arrive, providing more control over event handling.
1974
+ *
1975
+ * **Example:**
1976
+ * ```typescript
1977
+ * for await (const event of client.messaging.createBatchDraftsStreamGenerator(
1978
+ * 'user@example.com',
1979
+ * {
1980
+ * prospects: [...],
1981
+ * channel: 'linkedin',
1982
+ * useAiGeneration: true
1983
+ * }
1984
+ * )) {
1985
+ * switch (event.event) {
1986
+ * case 'progress':
1987
+ * console.log(`Progress: ${event.data.percentage}%`)
1988
+ * break
1989
+ * case 'draft_created':
1990
+ * console.log(`Draft: ${event.data.draft.id}`)
1991
+ * break
1992
+ * case 'error':
1993
+ * console.error(`Error: ${event.data.error}`)
1994
+ * break
1995
+ * case 'complete':
1996
+ * console.log(`Done! ${event.data.created} drafts created`)
1997
+ * break
1998
+ * }
1999
+ * }
2000
+ * ```
2001
+ *
2002
+ * @param userId - User ID or email
2003
+ * @param request - Batch draft creation request
2004
+ * @yields Stream events with 'event' and 'data' keys
2005
+ * @returns Final result with created drafts and error details
2006
+ */
2007
+ createBatchDraftsStreamGenerator(userId: string, request: BatchDraftRequest): AsyncGenerator<BatchDraftStreamEvent, BatchDraftResponse>;
1867
2008
  /**
1868
2009
  * Approve and send a single draft
1869
2010
  */
@@ -2574,4 +2715,4 @@ declare class ProgressTracker {
2574
2715
  declare function verifyWebhookSignature(payload: string, signature: string, secret: string): boolean;
2575
2716
 
2576
2717
  export = LumnisClient;
2577
- export { type AgentConfig, type ApiKeyMode, type ApiKeyModeRequest, type ApiKeyModeResponse, type ApiProvider, type AppEnabledResponse, type AppliedFilters, type AppsListResponse, type ArtifactObject, type ArtifactsListResponse, AuthenticationError, type BaseResource, type BatchCheckConnectionRequest, type BatchCheckPriorContactRequest, type BatchCheckPriorContactResponse, type BatchConnectionRequest, type BatchConnectionResponse, type BatchConnectionStatus, type BatchConnectionStatusResponse, type BatchDraftRequest, type BatchDraftResponse, type BatchProspectIdentifier, type BatchSendRequest, type BatchSendResponse, type BillingStatus, type BulkDeleteRequest, type BulkDeleteResponse, type BulkUploadResponse, type CancelResponseResponse, type ChannelContactHistory, ChannelType, type CheckAppEnabledParams, type CheckLinkedInConnectionRequest, type CheckPriorContactRequest, type CheckPriorContactResponse, type ChunkingStrategy, type ConnectionAcceptedData, type ConnectionCallbackRequest, type ConnectionCallbackResponse, type ConnectionInfo, type ConnectionStatus, type ConnectionStatusResponse, type ConnectionSummary, type ContentType, type ConversationDetail, ConversationStatus, type ConversationSummary, type CreateDraftRequest, type CreateFeedbackRequest, type CreateFeedbackResponse, type CreateResponseRequest, type CreateResponseResponse, type CreateThreadRequest, type DatabaseStatus, type DeleteApiKeyResponse, type DeleteConversationResponse, type DeleteConversationsByProjectResponse, type DisconnectRequest, type DisconnectResponse, type DraftResponse, DraftStatus, type DuplicateHandling, type Email, type EmailThreadSummary, type ErrorResponse, ExternalAPIKeysResource, type ExternalApiKeyResponse, type FeedbackListResponse, type FeedbackObject, type FeedbackType, type FileAttachment, type FileChunk, type FileContentResponse, type FileListResponse, type FileMetadata, type FileScope, type FileScopeUpdateRequest, type FileSearchRequest, type FileSearchResponse, type FileSearchResult, type FileStatisticsResponse, type FileUploadResponse, FilesResource, type FilterLogic, type FilterValue, type GetConnectionStatusParams, type GetToolsRequest, type GetToolsResponse, type GetUserConnectionsParams, type InitiateConnectionRequest, type InitiateConnectionResponse, IntegrationsResource, InternalServerError, type LinkedInConnectionStatus, type LinkedInCreditsResponse, type LinkedInSendRequest, LinkedInSubscriptionType, type ListProvidersResponse, LocalFileNotSupportedError, LumnisClient, type LumnisClientOptions, LumnisError, type LumnisErrorOptions, type MCPScope, type MCPServerCreateRequest, type MCPServerListResponse, type MCPServerResponse, type MCPServerUpdateRequest, MCPServersResource, type MCPToolListResponse, type MCPToolResponse, type MCPTransport, type Message, type MessageReceivedData, type MessageResponse, type MessageSentData, MessageType, MessagingAPIError, MessagingConnectionError, MessagingNotFoundError, MessagingResource, MessagingSendError, MessagingValidationError, type ModelAvailability, type ModelOverrides, type ModelPreferenceCreate, type ModelPreferencesBulkUpdate, ModelPreferencesResource, type ModelProvider, type ModelType, NetworkDistance, NoDataSourcesError, NotFoundError, OutreachMethod, type PaginationInfo, type PaginationParams, PeopleDataSource, PeopleResource, type PeopleSearchRequest, type PeopleSearchResponse, type PersonResult, type Plan, type PriorContactMessage, type ProcessingStatus, type ProcessingStatusResponse, type ProgressEntry, ProgressTracker, type ProspectConnectionCheck, type ProspectInfo, type ProspectPriorContactResult, type ProspectSyncIdentifier, type ProspectSyncResult, ProviderType, QueueItemStatus, type QuickPeopleSearchOutput, RateLimitError, type RateLimitErrorOptions, type ResponseArtifact, type ResponseListResponse, type ResponseObject, type ResponseStatus, ResponsesResource, type SalaryRange, type Scope, type SelectedSkill, type SendMessageRequest, type SendMessageResponse, type SendReplyRequest, type SendResult, type SkillAnalyticsRequest, type SkillEffectivenessMetrics, type SkillGuidelineBase, type SkillGuidelineCreate, type SkillGuidelineListResponse, type SkillGuidelineResponse, type SkillGuidelineUpdate, type SkillRetrievalMetadata, type SkillUsageBase, type SkillUsageCreate, type SkillUsageListResponse, type SkillUsageResponse, type SkillUsageUpdate, SkillsResource, SourcesNotAvailableError, type SpecializedAgentParams, type SpecializedAgentType, type StoreApiKeyRequest, type SyncJobResponse, SyncJobStatus, type SyncProspectRequest, type SyncProspectResponse, type SyncRequest, type SyncStats, type TenantDetailsResponse, TenantInfoResource, type TenantModelPreference, type TenantModelPreferencesResponse, type TestConnectionResponse, type ThreadListResponse, type ThreadObject, type ThreadResponsesParams, ThreadsResource, type ToolInfo, type UUID, type UnlinkConversationsResponse, type UpdateAppStatusParams, type UpdateAppStatusResponse, type UpdateLinkedInSubscriptionRequest, type UpdateThreadRequest, type UserConnectionsResponse, type UserCreateRequest, type UserDeleteResponse, type UserIdentifier, type UserListResponse, type UserResponse, type UserUpdateRequest, UsersResource, ValidationError, type WebhookEvent, type WebhookPayload, displayProgress, formatProgressEntry, verifyWebhookSignature };
2718
+ export { type AgentConfig, type ApiKeyMode, type ApiKeyModeRequest, type ApiKeyModeResponse, type ApiProvider, type AppEnabledResponse, type AppliedFilters, type AppsListResponse, type ArtifactObject, type ArtifactsListResponse, AuthenticationError, type BaseResource, type BatchCheckConnectionRequest, type BatchCheckPriorContactRequest, type BatchCheckPriorContactResponse, type BatchConnectionRequest, type BatchConnectionResponse, type BatchConnectionStatus, type BatchConnectionStatusResponse, type BatchDraftCompleteData, type BatchDraftCreatedData, type BatchDraftErrorData, type BatchDraftProgressData, type BatchDraftRequest, type BatchDraftResponse, type BatchDraftStreamCallbacks, type BatchDraftStreamEvent, type BatchDraftStreamEventType, type BatchProspectIdentifier, type BatchSendRequest, type BatchSendResponse, type BillingStatus, type BulkDeleteRequest, type BulkDeleteResponse, type BulkUploadResponse, type CancelResponseResponse, type ChannelContactHistory, ChannelType, type CheckAppEnabledParams, type CheckLinkedInConnectionRequest, type CheckPriorContactRequest, type CheckPriorContactResponse, type ChunkingStrategy, type ConnectionAcceptedData, type ConnectionCallbackRequest, type ConnectionCallbackResponse, type ConnectionInfo, type ConnectionStatus, type ConnectionStatusResponse, type ConnectionSummary, type ContentType, type ConversationDetail, ConversationStatus, type ConversationSummary, type CreateDraftRequest, type CreateFeedbackRequest, type CreateFeedbackResponse, type CreateResponseRequest, type CreateResponseResponse, type CreateThreadRequest, type DatabaseStatus, type DeleteApiKeyResponse, type DeleteConversationResponse, type DeleteConversationsByProjectResponse, type DisconnectRequest, type DisconnectResponse, type DraftResponse, DraftStatus, type DuplicateHandling, type Email, type EmailThreadSummary, type ErrorResponse, ExternalAPIKeysResource, type ExternalApiKeyResponse, type FeedbackListResponse, type FeedbackObject, type FeedbackType, type FileAttachment, type FileChunk, type FileContentResponse, type FileListResponse, type FileMetadata, type FileScope, type FileScopeUpdateRequest, type FileSearchRequest, type FileSearchResponse, type FileSearchResult, type FileStatisticsResponse, type FileUploadResponse, FilesResource, type FilterLogic, type FilterValue, type GetConnectionStatusParams, type GetToolsRequest, type GetToolsResponse, type GetUserConnectionsParams, type InitiateConnectionRequest, type InitiateConnectionResponse, IntegrationsResource, InternalServerError, type LinkedInConnectionStatus, type LinkedInCreditsResponse, type LinkedInSendRequest, LinkedInSubscriptionType, type ListProvidersResponse, LocalFileNotSupportedError, LumnisClient, type LumnisClientOptions, LumnisError, type LumnisErrorOptions, type MCPScope, type MCPServerCreateRequest, type MCPServerListResponse, type MCPServerResponse, type MCPServerUpdateRequest, MCPServersResource, type MCPToolListResponse, type MCPToolResponse, type MCPTransport, type Message, type MessageReceivedData, type MessageResponse, type MessageSentData, MessageType, MessagingAPIError, MessagingConnectionError, MessagingNotFoundError, MessagingResource, MessagingSendError, MessagingValidationError, type ModelAvailability, type ModelOverrides, type ModelPreferenceCreate, type ModelPreferencesBulkUpdate, ModelPreferencesResource, type ModelProvider, type ModelType, NetworkDistance, NoDataSourcesError, NotFoundError, OutreachMethod, type PaginationInfo, type PaginationParams, PeopleDataSource, PeopleResource, type PeopleSearchRequest, type PeopleSearchResponse, type PersonResult, type Plan, type PriorContactMessage, type ProcessingStatus, type ProcessingStatusResponse, type ProgressEntry, ProgressTracker, type ProspectConnectionCheck, type ProspectInfo, type ProspectPriorContactResult, type ProspectSyncIdentifier, type ProspectSyncResult, ProviderType, QueueItemStatus, type QuickPeopleSearchOutput, RateLimitError, type RateLimitErrorOptions, type ResponseArtifact, type ResponseListResponse, type ResponseObject, type ResponseStatus, ResponsesResource, type SalaryRange, type Scope, type SelectedSkill, type SendMessageRequest, type SendMessageResponse, type SendReplyRequest, type SendResult, type SkillAnalyticsRequest, type SkillEffectivenessMetrics, type SkillGuidelineBase, type SkillGuidelineCreate, type SkillGuidelineListResponse, type SkillGuidelineResponse, type SkillGuidelineUpdate, type SkillRetrievalMetadata, type SkillUsageBase, type SkillUsageCreate, type SkillUsageListResponse, type SkillUsageResponse, type SkillUsageUpdate, SkillsResource, SourcesNotAvailableError, type SpecializedAgentParams, type SpecializedAgentType, type StoreApiKeyRequest, type SyncJobResponse, SyncJobStatus, type SyncProspectRequest, type SyncProspectResponse, type SyncRequest, type SyncStats, type TenantDetailsResponse, TenantInfoResource, type TenantModelPreference, type TenantModelPreferencesResponse, type TestConnectionResponse, type ThreadListResponse, type ThreadObject, type ThreadResponsesParams, ThreadsResource, type ToolInfo, type UUID, type UnlinkConversationsResponse, type UpdateAppStatusParams, type UpdateAppStatusResponse, type UpdateLinkedInSubscriptionRequest, type UpdateThreadRequest, type UserConnectionsResponse, type UserCreateRequest, type UserDeleteResponse, type UserIdentifier, type UserListResponse, type UserResponse, type UserUpdateRequest, UsersResource, ValidationError, type WebhookEvent, type WebhookPayload, displayProgress, formatProgressEntry, verifyWebhookSignature };
package/dist/index.mjs CHANGED
@@ -408,6 +408,42 @@ class MCPServersResource {
408
408
  }
409
409
  }
410
410
 
411
+ const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
412
+ function isUUID(s) {
413
+ return UUID_PATTERN.test(s);
414
+ }
415
+ function toCamel(s) {
416
+ if (isUUID(s))
417
+ return s;
418
+ return s.replace(/([-_][a-z])/gi, ($1) => {
419
+ return $1.toUpperCase().replace("-", "").replace("_", "");
420
+ });
421
+ }
422
+ function toSnake(s) {
423
+ if (isUUID(s))
424
+ return s;
425
+ return s.replace(/[A-Z]/g, (letter, index) => {
426
+ return index === 0 ? letter.toLowerCase() : `_${letter.toLowerCase()}`;
427
+ });
428
+ }
429
+ function convertCase(obj, converter) {
430
+ if (Array.isArray(obj)) {
431
+ return obj.map((v) => convertCase(v, converter));
432
+ } else if (obj !== null && typeof obj === "object") {
433
+ return Object.keys(obj).reduce((acc, key) => {
434
+ acc[converter(key)] = convertCase(obj[key], converter);
435
+ return acc;
436
+ }, {});
437
+ }
438
+ return obj;
439
+ }
440
+ function toCamelCase(obj) {
441
+ return convertCase(obj, toCamel);
442
+ }
443
+ function toSnakeCase(obj) {
444
+ return convertCase(obj, toSnake);
445
+ }
446
+
411
447
  class LumnisError extends Error {
412
448
  code;
413
449
  statusCode;
@@ -728,6 +764,293 @@ class MessagingResource {
728
764
  request
729
765
  );
730
766
  }
767
+ /**
768
+ * Create drafts for multiple prospects with real-time progress updates via Server-Sent Events (SSE).
769
+ *
770
+ * This method provides real-time progress updates as drafts are being created, significantly
771
+ * improving user experience for large batch operations (30+ prospects).
772
+ *
773
+ * **Event Types:**
774
+ * - `progress`: Progress update with percentage and current prospect
775
+ * - `draft_created`: Draft successfully created
776
+ * - `error`: Error occurred for a specific prospect
777
+ * - `complete`: Batch processing completed
778
+ *
779
+ * **Example:**
780
+ * ```typescript
781
+ * const result = await client.messaging.createBatchDraftsStream(
782
+ * 'user@example.com',
783
+ * {
784
+ * prospects: [...],
785
+ * channel: 'linkedin',
786
+ * useAiGeneration: true
787
+ * },
788
+ * {
789
+ * onProgress: (processed, total, percentage, prospectName) => {
790
+ * console.log(`${percentage}% - ${prospectName}`)
791
+ * },
792
+ * onDraftCreated: (draft) => {
793
+ * console.log(`Draft created: ${draft.id}`)
794
+ * },
795
+ * onError: (prospect, error) => {
796
+ * console.error(`Error for ${prospect}: ${error}`)
797
+ * },
798
+ * onComplete: (result) => {
799
+ * console.log(`Complete! Created: ${result.created}, Errors: ${result.errors}`)
800
+ * }
801
+ * }
802
+ * )
803
+ * ```
804
+ *
805
+ * @param userId - User ID or email
806
+ * @param request - Batch draft creation request
807
+ * @param callbacks - Optional callbacks for stream events
808
+ * @returns Final result with created drafts and error details
809
+ */
810
+ async createBatchDraftsStream(userId, request, callbacks) {
811
+ const queryParams = new URLSearchParams();
812
+ queryParams.append("user_id", userId);
813
+ const baseUrl = this.http.options.baseUrl;
814
+ const apiPrefix = this.http.options.apiPrefix || "";
815
+ const path = `/messaging/drafts/batch/stream?${queryParams.toString()}`;
816
+ const url = `${baseUrl}${apiPrefix}${path}`;
817
+ const headers = {
818
+ "Content-Type": "application/json",
819
+ "Accept": "text/event-stream",
820
+ ...this.http.options.headers
821
+ };
822
+ const body = JSON.stringify(toSnakeCase(request));
823
+ const response = await fetch(url, {
824
+ method: "POST",
825
+ headers,
826
+ body
827
+ });
828
+ if (!response.ok) {
829
+ const requestId = response.headers.get("x-request-id");
830
+ const contentType = response.headers.get("content-type") || "";
831
+ let detail = { raw: await response.text() };
832
+ try {
833
+ if (contentType.includes("application/json"))
834
+ detail = JSON.parse(detail.raw);
835
+ } catch {
836
+ }
837
+ const errorMsg = detail?.error?.message || `Server error: ${response.status}`;
838
+ if (response.status === 401) {
839
+ throw new AuthenticationError("Invalid or missing API key", { requestId, statusCode: 401, details: detail });
840
+ }
841
+ if (response.status === 403) {
842
+ throw new AuthenticationError("Forbidden - insufficient permissions", { requestId, statusCode: 403, details: detail });
843
+ }
844
+ if (response.status === 404) {
845
+ throw new NotFoundError("Resource not found", { requestId, statusCode: 404, details: detail });
846
+ }
847
+ if (response.status === 429) {
848
+ const retryAfter = response.headers.get("Retry-After");
849
+ throw new RateLimitError({ requestId, statusCode: 429, details: detail, retryAfter });
850
+ }
851
+ if (response.status >= 400 && response.status < 500) {
852
+ throw new ValidationError(errorMsg, { requestId, statusCode: response.status, details: detail });
853
+ }
854
+ throw new LumnisError(`Server error: ${response.status}`, { requestId, statusCode: response.status, details: detail });
855
+ }
856
+ const reader = response.body?.getReader();
857
+ if (!reader) {
858
+ throw new Error("Response body reader not available");
859
+ }
860
+ const decoder = new TextDecoder();
861
+ let buffer = "";
862
+ let finalResult = null;
863
+ try {
864
+ while (true) {
865
+ const { done, value } = await reader.read();
866
+ if (done)
867
+ break;
868
+ buffer += decoder.decode(value, { stream: true });
869
+ const lines = buffer.split("\n");
870
+ buffer = lines.pop() || "";
871
+ for (const line of lines) {
872
+ if (!line.startsWith("data: "))
873
+ continue;
874
+ try {
875
+ const eventData = JSON.parse(line.slice(6));
876
+ const { event, data } = eventData;
877
+ switch (event) {
878
+ case "progress": {
879
+ const progressData = toCamelCase(data);
880
+ callbacks?.onProgress?.(
881
+ progressData.processed || 0,
882
+ progressData.total || 0,
883
+ progressData.percentage || 0,
884
+ progressData.currentProspect || ""
885
+ );
886
+ break;
887
+ }
888
+ case "draft_created": {
889
+ const draftData = toCamelCase(data);
890
+ const draft = draftData.draft;
891
+ if (draft) {
892
+ const convertedDraft = toCamelCase(draft);
893
+ callbacks?.onDraftCreated?.(convertedDraft);
894
+ }
895
+ break;
896
+ }
897
+ case "error": {
898
+ const errorData = toCamelCase(data);
899
+ callbacks?.onError?.(
900
+ errorData.prospect || "Unknown",
901
+ errorData.error || ""
902
+ );
903
+ break;
904
+ }
905
+ case "complete": {
906
+ const completeData = toCamelCase(data);
907
+ finalResult = {
908
+ created: completeData.created || 0,
909
+ errors: completeData.errors || 0,
910
+ drafts: (completeData.drafts || []).map((d) => toCamelCase(d)),
911
+ errorDetails: completeData.errorDetails || []
912
+ };
913
+ callbacks?.onComplete?.(finalResult);
914
+ break;
915
+ }
916
+ }
917
+ } catch (parseError) {
918
+ continue;
919
+ }
920
+ }
921
+ }
922
+ } finally {
923
+ reader.releaseLock();
924
+ }
925
+ return finalResult || { created: 0, errors: 0, drafts: [], errorDetails: [] };
926
+ }
927
+ /**
928
+ * Create drafts with streaming events as an async generator.
929
+ *
930
+ * This method yields events as they arrive, providing more control over event handling.
931
+ *
932
+ * **Example:**
933
+ * ```typescript
934
+ * for await (const event of client.messaging.createBatchDraftsStreamGenerator(
935
+ * 'user@example.com',
936
+ * {
937
+ * prospects: [...],
938
+ * channel: 'linkedin',
939
+ * useAiGeneration: true
940
+ * }
941
+ * )) {
942
+ * switch (event.event) {
943
+ * case 'progress':
944
+ * console.log(`Progress: ${event.data.percentage}%`)
945
+ * break
946
+ * case 'draft_created':
947
+ * console.log(`Draft: ${event.data.draft.id}`)
948
+ * break
949
+ * case 'error':
950
+ * console.error(`Error: ${event.data.error}`)
951
+ * break
952
+ * case 'complete':
953
+ * console.log(`Done! ${event.data.created} drafts created`)
954
+ * break
955
+ * }
956
+ * }
957
+ * ```
958
+ *
959
+ * @param userId - User ID or email
960
+ * @param request - Batch draft creation request
961
+ * @yields Stream events with 'event' and 'data' keys
962
+ * @returns Final result with created drafts and error details
963
+ */
964
+ async *createBatchDraftsStreamGenerator(userId, request) {
965
+ const queryParams = new URLSearchParams();
966
+ queryParams.append("user_id", userId);
967
+ const baseUrl = this.http.options.baseUrl;
968
+ const apiPrefix = this.http.options.apiPrefix || "";
969
+ const path = `/messaging/drafts/batch/stream?${queryParams.toString()}`;
970
+ const url = `${baseUrl}${apiPrefix}${path}`;
971
+ const headers = {
972
+ "Content-Type": "application/json",
973
+ "Accept": "text/event-stream",
974
+ ...this.http.options.headers
975
+ };
976
+ const body = JSON.stringify(toSnakeCase(request));
977
+ const response = await fetch(url, {
978
+ method: "POST",
979
+ headers,
980
+ body
981
+ });
982
+ if (!response.ok) {
983
+ const requestId = response.headers.get("x-request-id");
984
+ const contentType = response.headers.get("content-type") || "";
985
+ let detail = { raw: await response.text() };
986
+ try {
987
+ if (contentType.includes("application/json"))
988
+ detail = JSON.parse(detail.raw);
989
+ } catch {
990
+ }
991
+ const errorMsg = detail?.error?.message || `Server error: ${response.status}`;
992
+ if (response.status === 401) {
993
+ throw new AuthenticationError("Invalid or missing API key", { requestId, statusCode: 401, details: detail });
994
+ }
995
+ if (response.status === 403) {
996
+ throw new AuthenticationError("Forbidden - insufficient permissions", { requestId, statusCode: 403, details: detail });
997
+ }
998
+ if (response.status === 404) {
999
+ throw new NotFoundError("Resource not found", { requestId, statusCode: 404, details: detail });
1000
+ }
1001
+ if (response.status === 429) {
1002
+ const retryAfter = response.headers.get("Retry-After");
1003
+ throw new RateLimitError({ requestId, statusCode: 429, details: detail, retryAfter });
1004
+ }
1005
+ if (response.status >= 400 && response.status < 500) {
1006
+ throw new ValidationError(errorMsg, { requestId, statusCode: response.status, details: detail });
1007
+ }
1008
+ throw new LumnisError(`Server error: ${response.status}`, { requestId, statusCode: response.status, details: detail });
1009
+ }
1010
+ const reader = response.body?.getReader();
1011
+ if (!reader) {
1012
+ throw new Error("Response body reader not available");
1013
+ }
1014
+ const decoder = new TextDecoder();
1015
+ let buffer = "";
1016
+ let finalResult = null;
1017
+ try {
1018
+ while (true) {
1019
+ const { done, value } = await reader.read();
1020
+ if (done)
1021
+ break;
1022
+ buffer += decoder.decode(value, { stream: true });
1023
+ const lines = buffer.split("\n");
1024
+ buffer = lines.pop() || "";
1025
+ for (const line of lines) {
1026
+ if (!line.startsWith("data: "))
1027
+ continue;
1028
+ try {
1029
+ const eventData = JSON.parse(line.slice(6));
1030
+ const camelEventData = {
1031
+ event: eventData.event,
1032
+ data: toCamelCase(eventData.data)
1033
+ };
1034
+ yield camelEventData;
1035
+ if (eventData.event === "complete") {
1036
+ const completeData = camelEventData.data;
1037
+ finalResult = {
1038
+ created: completeData.created || 0,
1039
+ errors: completeData.errors || 0,
1040
+ drafts: (completeData.drafts || []).map((d) => toCamelCase(d)),
1041
+ errorDetails: completeData.errorDetails || []
1042
+ };
1043
+ }
1044
+ } catch (parseError) {
1045
+ continue;
1046
+ }
1047
+ }
1048
+ }
1049
+ } finally {
1050
+ reader.releaseLock();
1051
+ }
1052
+ return finalResult || { created: 0, errors: 0, drafts: [], errorDetails: [] };
1053
+ }
731
1054
  /**
732
1055
  * Approve and send a single draft
733
1056
  */
@@ -1456,42 +1779,6 @@ class UsersResource {
1456
1779
  }
1457
1780
  }
1458
1781
 
1459
- const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
1460
- function isUUID(s) {
1461
- return UUID_PATTERN.test(s);
1462
- }
1463
- function toCamel(s) {
1464
- if (isUUID(s))
1465
- return s;
1466
- return s.replace(/([-_][a-z])/gi, ($1) => {
1467
- return $1.toUpperCase().replace("-", "").replace("_", "");
1468
- });
1469
- }
1470
- function toSnake(s) {
1471
- if (isUUID(s))
1472
- return s;
1473
- return s.replace(/[A-Z]/g, (letter, index) => {
1474
- return index === 0 ? letter.toLowerCase() : `_${letter.toLowerCase()}`;
1475
- });
1476
- }
1477
- function convertCase(obj, converter) {
1478
- if (Array.isArray(obj)) {
1479
- return obj.map((v) => convertCase(v, converter));
1480
- } else if (obj !== null && typeof obj === "object") {
1481
- return Object.keys(obj).reduce((acc, key) => {
1482
- acc[converter(key)] = convertCase(obj[key], converter);
1483
- return acc;
1484
- }, {});
1485
- }
1486
- return obj;
1487
- }
1488
- function toCamelCase(obj) {
1489
- return convertCase(obj, toCamel);
1490
- }
1491
- function toSnakeCase(obj) {
1492
- return convertCase(obj, toSnake);
1493
- }
1494
-
1495
1782
  class Http {
1496
1783
  options;
1497
1784
  constructor(options) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "lumnisai",
3
3
  "type": "module",
4
- "version": "0.1.13",
4
+ "version": "0.1.14",
5
5
  "description": "Official Node.js SDK for the Lumnis AI API",
6
6
  "author": "Lumnis AI",
7
7
  "license": "MIT",