@bubblelab/bubble-core 0.1.141 → 0.1.143

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.
Files changed (154) hide show
  1. package/dist/bubble-bundle.d.ts +181 -118
  2. package/dist/bubble-factory.d.ts.map +1 -1
  3. package/dist/bubble-factory.js +9 -1
  4. package/dist/bubble-factory.js.map +1 -1
  5. package/dist/bubble-flow/bubble-flow-class.d.ts +4 -0
  6. package/dist/bubble-flow/bubble-flow-class.d.ts.map +1 -1
  7. package/dist/bubble-flow/bubble-flow-class.js +1 -0
  8. package/dist/bubble-flow/bubble-flow-class.js.map +1 -1
  9. package/dist/bubbles/service-bubble/agi-inc.d.ts +140 -140
  10. package/dist/bubbles/service-bubble/ai-agent.d.ts +4 -4
  11. package/dist/bubbles/service-bubble/ai-agent.d.ts.map +1 -1
  12. package/dist/bubbles/service-bubble/ai-agent.js +7 -0
  13. package/dist/bubbles/service-bubble/ai-agent.js.map +1 -1
  14. package/dist/bubbles/service-bubble/airtable.d.ts +158 -158
  15. package/dist/bubbles/service-bubble/apify/actors/google-maps-scraper.d.ts +6 -6
  16. package/dist/bubbles/service-bubble/apify/actors/linkedin-profile-detail.d.ts +806 -0
  17. package/dist/bubbles/service-bubble/apify/actors/linkedin-profile-detail.d.ts.map +1 -0
  18. package/dist/bubbles/service-bubble/apify/actors/linkedin-profile-detail.js +256 -0
  19. package/dist/bubbles/service-bubble/apify/actors/linkedin-profile-detail.js.map +1 -0
  20. package/dist/bubbles/service-bubble/apify/apify-scraper.schema.d.ts +813 -6
  21. package/dist/bubbles/service-bubble/apify/apify-scraper.schema.d.ts.map +1 -1
  22. package/dist/bubbles/service-bubble/apify/apify-scraper.schema.js +8 -0
  23. package/dist/bubbles/service-bubble/apify/apify-scraper.schema.js.map +1 -1
  24. package/dist/bubbles/service-bubble/apify/apify.d.ts +13 -13
  25. package/dist/bubbles/service-bubble/apify/apify.d.ts.map +1 -1
  26. package/dist/bubbles/service-bubble/apify/apify.js +1 -0
  27. package/dist/bubbles/service-bubble/apify/apify.js.map +1 -1
  28. package/dist/bubbles/service-bubble/ashby/ashby.d.ts +64 -64
  29. package/dist/bubbles/service-bubble/ashby/ashby.schema.d.ts +6 -6
  30. package/dist/bubbles/service-bubble/browserbase/browserbase.d.ts +44 -37
  31. package/dist/bubbles/service-bubble/browserbase/browserbase.d.ts.map +1 -1
  32. package/dist/bubbles/service-bubble/browserbase/browserbase.js +66 -3
  33. package/dist/bubbles/service-bubble/browserbase/browserbase.js.map +1 -1
  34. package/dist/bubbles/service-bubble/browserbase/browserbase.schema.d.ts +59 -16
  35. package/dist/bubbles/service-bubble/browserbase/browserbase.schema.d.ts.map +1 -1
  36. package/dist/bubbles/service-bubble/browserbase/browserbase.schema.js +19 -0
  37. package/dist/bubbles/service-bubble/browserbase/browserbase.schema.js.map +1 -1
  38. package/dist/bubbles/service-bubble/confluence/confluence.d.ts +26 -26
  39. package/dist/bubbles/service-bubble/crustdata/crustdata.d.ts +96 -96
  40. package/dist/bubbles/service-bubble/crustdata/crustdata.schema.d.ts +24 -24
  41. package/dist/bubbles/service-bubble/eleven-labs.d.ts +24 -24
  42. package/dist/bubbles/service-bubble/firecrawl.d.ts +244 -244
  43. package/dist/bubbles/service-bubble/followupboss.d.ts +152 -152
  44. package/dist/bubbles/service-bubble/fullenrich/fullenrich.d.ts +44 -44
  45. package/dist/bubbles/service-bubble/fullenrich/fullenrich.schema.d.ts +62 -62
  46. package/dist/bubbles/service-bubble/github.d.ts +148 -148
  47. package/dist/bubbles/service-bubble/gmail.d.ts +556 -556
  48. package/dist/bubbles/service-bubble/google-calendar.d.ts +34 -34
  49. package/dist/bubbles/service-bubble/google-drive.d.ts +102 -102
  50. package/dist/bubbles/service-bubble/google-sheets/google-sheets.d.ts +30 -30
  51. package/dist/bubbles/service-bubble/http.d.ts +20 -20
  52. package/dist/bubbles/service-bubble/jira/jira.d.ts +92 -92
  53. package/dist/bubbles/service-bubble/jira/jira.schema.d.ts +2 -2
  54. package/dist/bubbles/service-bubble/notion/notion.d.ts +647 -647
  55. package/dist/bubbles/service-bubble/resend.d.ts +32 -32
  56. package/dist/bubbles/service-bubble/slack/slack.d.ts +496 -496
  57. package/dist/bubbles/service-bubble/slack/slack.js +2 -2
  58. package/dist/bubbles/service-bubble/slack/slack.js.map +1 -1
  59. package/dist/bubbles/service-bubble/storage.d.ts +20 -20
  60. package/dist/bubbles/service-bubble/stripe/stripe.d.ts +87 -87
  61. package/dist/bubbles/service-bubble/telegram.d.ts +108 -108
  62. package/dist/bubbles/tool-bubble/amazon-shopping-tool/amazon-shopping-tool.d.ts +18 -18
  63. package/dist/bubbles/tool-bubble/browser-tools/_shared/schema.d.ts +126 -0
  64. package/dist/bubbles/tool-bubble/browser-tools/_shared/schema.d.ts.map +1 -0
  65. package/dist/bubbles/tool-bubble/browser-tools/_shared/schema.js +34 -0
  66. package/dist/bubbles/tool-bubble/browser-tools/_shared/schema.js.map +1 -0
  67. package/dist/bubbles/tool-bubble/browser-tools/_shared/utils.d.ts +22 -0
  68. package/dist/bubbles/tool-bubble/browser-tools/_shared/utils.d.ts.map +1 -0
  69. package/dist/bubbles/tool-bubble/browser-tools/_shared/utils.js +57 -0
  70. package/dist/bubbles/tool-bubble/browser-tools/_shared/utils.js.map +1 -0
  71. package/dist/bubbles/tool-bubble/browser-tools/index.d.ts +5 -0
  72. package/dist/bubbles/tool-bubble/browser-tools/index.d.ts.map +1 -0
  73. package/dist/bubbles/tool-bubble/browser-tools/index.js +5 -0
  74. package/dist/bubbles/tool-bubble/browser-tools/index.js.map +1 -0
  75. package/dist/bubbles/tool-bubble/browser-tools/linkedin-accept-invitations/index.d.ts +3 -0
  76. package/dist/bubbles/tool-bubble/browser-tools/linkedin-accept-invitations/index.d.ts.map +1 -0
  77. package/dist/bubbles/tool-bubble/browser-tools/linkedin-accept-invitations/index.js +3 -0
  78. package/dist/bubbles/tool-bubble/browser-tools/linkedin-accept-invitations/index.js.map +1 -0
  79. package/dist/bubbles/tool-bubble/browser-tools/linkedin-accept-invitations/schema.d.ts +158 -0
  80. package/dist/bubbles/tool-bubble/browser-tools/linkedin-accept-invitations/schema.d.ts.map +1 -0
  81. package/dist/bubbles/tool-bubble/browser-tools/linkedin-accept-invitations/schema.js +33 -0
  82. package/dist/bubbles/tool-bubble/browser-tools/linkedin-accept-invitations/schema.js.map +1 -0
  83. package/dist/bubbles/tool-bubble/browser-tools/linkedin-accept-invitations/tool.d.ts +161 -0
  84. package/dist/bubbles/tool-bubble/browser-tools/linkedin-accept-invitations/tool.d.ts.map +1 -0
  85. package/dist/bubbles/tool-bubble/browser-tools/linkedin-accept-invitations/tool.js +310 -0
  86. package/dist/bubbles/tool-bubble/browser-tools/linkedin-accept-invitations/tool.js.map +1 -0
  87. package/dist/bubbles/tool-bubble/browser-tools/linkedin-connection/index.d.ts +3 -0
  88. package/dist/bubbles/tool-bubble/browser-tools/linkedin-connection/index.d.ts.map +1 -0
  89. package/dist/bubbles/tool-bubble/browser-tools/linkedin-connection/index.js +3 -0
  90. package/dist/bubbles/tool-bubble/browser-tools/linkedin-connection/index.js.map +1 -0
  91. package/dist/bubbles/tool-bubble/browser-tools/linkedin-connection/schema.d.ts +165 -0
  92. package/dist/bubbles/tool-bubble/browser-tools/linkedin-connection/schema.d.ts.map +1 -0
  93. package/dist/bubbles/tool-bubble/browser-tools/linkedin-connection/schema.js +45 -0
  94. package/dist/bubbles/tool-bubble/browser-tools/linkedin-connection/schema.js.map +1 -0
  95. package/dist/bubbles/tool-bubble/browser-tools/linkedin-connection/tool.d.ts +171 -0
  96. package/dist/bubbles/tool-bubble/browser-tools/linkedin-connection/tool.d.ts.map +1 -0
  97. package/dist/bubbles/tool-bubble/browser-tools/linkedin-connection/tool.js +364 -0
  98. package/dist/bubbles/tool-bubble/browser-tools/linkedin-connection/tool.js.map +1 -0
  99. package/dist/bubbles/tool-bubble/browser-tools/linkedin-received-invitations/index.d.ts +3 -0
  100. package/dist/bubbles/tool-bubble/browser-tools/linkedin-received-invitations/index.d.ts.map +1 -0
  101. package/dist/bubbles/tool-bubble/browser-tools/linkedin-received-invitations/index.js +3 -0
  102. package/dist/bubbles/tool-bubble/browser-tools/linkedin-received-invitations/index.js.map +1 -0
  103. package/dist/bubbles/tool-bubble/browser-tools/linkedin-received-invitations/schema.d.ts +160 -0
  104. package/dist/bubbles/tool-bubble/browser-tools/linkedin-received-invitations/schema.d.ts.map +1 -0
  105. package/dist/bubbles/tool-bubble/browser-tools/linkedin-received-invitations/schema.js +24 -0
  106. package/dist/bubbles/tool-bubble/browser-tools/linkedin-received-invitations/schema.js.map +1 -0
  107. package/dist/bubbles/tool-bubble/browser-tools/linkedin-received-invitations/tool.d.ts +160 -0
  108. package/dist/bubbles/tool-bubble/browser-tools/linkedin-received-invitations/tool.d.ts.map +1 -0
  109. package/dist/bubbles/tool-bubble/browser-tools/linkedin-received-invitations/tool.js +334 -0
  110. package/dist/bubbles/tool-bubble/browser-tools/linkedin-received-invitations/tool.js.map +1 -0
  111. package/dist/bubbles/tool-bubble/browser-tools/linkedin-sent-invitations/index.d.ts +3 -0
  112. package/dist/bubbles/tool-bubble/browser-tools/linkedin-sent-invitations/index.d.ts.map +1 -0
  113. package/dist/bubbles/tool-bubble/browser-tools/linkedin-sent-invitations/index.js +3 -0
  114. package/dist/bubbles/tool-bubble/browser-tools/linkedin-sent-invitations/index.js.map +1 -0
  115. package/dist/bubbles/tool-bubble/browser-tools/linkedin-sent-invitations/schema.d.ts +152 -0
  116. package/dist/bubbles/tool-bubble/browser-tools/linkedin-sent-invitations/schema.d.ts.map +1 -0
  117. package/dist/bubbles/tool-bubble/browser-tools/linkedin-sent-invitations/schema.js +23 -0
  118. package/dist/bubbles/tool-bubble/browser-tools/linkedin-sent-invitations/schema.js.map +1 -0
  119. package/dist/bubbles/tool-bubble/browser-tools/linkedin-sent-invitations/tool.d.ts +155 -0
  120. package/dist/bubbles/tool-bubble/browser-tools/linkedin-sent-invitations/tool.d.ts.map +1 -0
  121. package/dist/bubbles/tool-bubble/browser-tools/linkedin-sent-invitations/tool.js +233 -0
  122. package/dist/bubbles/tool-bubble/browser-tools/linkedin-sent-invitations/tool.js.map +1 -0
  123. package/dist/bubbles/tool-bubble/bubbleflow-validation-tool.d.ts +4 -4
  124. package/dist/bubbles/tool-bubble/company-enrichment-tool.d.ts +64 -64
  125. package/dist/bubbles/tool-bubble/google-maps-tool.d.ts +16 -16
  126. package/dist/bubbles/tool-bubble/instagram-tool.d.ts +4 -4
  127. package/dist/bubbles/tool-bubble/linkedin-connection-tool/linkedin-connection-tool.d.ts +2 -2
  128. package/dist/bubbles/tool-bubble/linkedin-tool.d.ts +1634 -196
  129. package/dist/bubbles/tool-bubble/linkedin-tool.d.ts.map +1 -1
  130. package/dist/bubbles/tool-bubble/linkedin-tool.js +300 -56
  131. package/dist/bubbles/tool-bubble/linkedin-tool.js.map +1 -1
  132. package/dist/bubbles/tool-bubble/list-capabilities-tool.d.ts +8 -8
  133. package/dist/bubbles/tool-bubble/people-search-tool.d.ts +108 -108
  134. package/dist/bubbles/tool-bubble/reddit-scrape-tool.d.ts +10 -10
  135. package/dist/bubbles/tool-bubble/research-agent-tool.d.ts +4 -4
  136. package/dist/bubbles/tool-bubble/sql-query-tool.d.ts +4 -4
  137. package/dist/bubbles/tool-bubble/tiktok-tool.d.ts +24 -24
  138. package/dist/bubbles/tool-bubble/twitter-tool.d.ts +14 -14
  139. package/dist/bubbles/tool-bubble/web-crawl-tool.d.ts +4 -4
  140. package/dist/bubbles/tool-bubble/web-extract-tool.d.ts +4 -4
  141. package/dist/bubbles/tool-bubble/web-scrape-tool.d.ts +8 -8
  142. package/dist/bubbles/tool-bubble/web-search-tool.d.ts +2 -2
  143. package/dist/bubbles/tool-bubble/yc-scraper-tool.d.ts +32 -32
  144. package/dist/bubbles/tool-bubble/youtube-tool.d.ts +14 -14
  145. package/dist/bubbles/workflow-bubble/pdf-form-operations.workflow.d.ts +58 -58
  146. package/dist/bubbles/workflow-bubble/pdf-ocr.workflow.d.ts +16 -16
  147. package/dist/bubbles/workflow-bubble/slack-data-assistant.workflow.d.ts +2 -2
  148. package/dist/bubbles/workflow-bubble/slack-formatter-agent.d.ts +46 -46
  149. package/dist/bubbles.json +1148 -75
  150. package/dist/index.d.ts +4 -1
  151. package/dist/index.d.ts.map +1 -1
  152. package/dist/index.js +4 -1
  153. package/dist/index.js.map +1 -1
  154. package/package.json +2 -2
@@ -0,0 +1,155 @@
1
+ import { ToolBubble } from '../../../../types/tool-bubble-class.js';
2
+ import type { BubbleContext } from '../../../../types/bubble.js';
3
+ import { CredentialType } from '@bubblelab/shared-schemas';
4
+ import { type LinkedInSentInvitationsToolParamsInput, type LinkedInSentInvitationsToolResult } from './schema.js';
5
+ export declare class LinkedInSentInvitationsTool<T extends LinkedInSentInvitationsToolParamsInput = LinkedInSentInvitationsToolParamsInput> extends ToolBubble<T, LinkedInSentInvitationsToolResult> {
6
+ static readonly bubbleName: "linkedin-sent-invitations-tool";
7
+ static readonly schema: import("zod").ZodObject<{
8
+ operation: import("zod").ZodLiteral<"get_sent_invitations">;
9
+ credentials: import("zod").ZodOptional<import("zod").ZodRecord<import("zod").ZodNativeEnum<typeof CredentialType>, import("zod").ZodString>>;
10
+ proxy: import("zod").ZodOptional<import("zod").ZodDiscriminatedUnion<"type", [import("zod").ZodObject<{
11
+ type: import("zod").ZodLiteral<"none">;
12
+ }, "strip", import("zod").ZodTypeAny, {
13
+ type: "none";
14
+ }, {
15
+ type: "none";
16
+ }>, import("zod").ZodObject<{
17
+ type: import("zod").ZodLiteral<"browserbase">;
18
+ }, "strip", import("zod").ZodTypeAny, {
19
+ type: "browserbase";
20
+ }, {
21
+ type: "browserbase";
22
+ }>, import("zod").ZodObject<{
23
+ type: import("zod").ZodLiteral<"custom">;
24
+ proxy: import("zod").ZodObject<{
25
+ id: import("zod").ZodString;
26
+ server: import("zod").ZodString;
27
+ username: import("zod").ZodOptional<import("zod").ZodString>;
28
+ password: import("zod").ZodOptional<import("zod").ZodString>;
29
+ }, "strip", import("zod").ZodTypeAny, {
30
+ id: string;
31
+ server: string;
32
+ password?: string | undefined;
33
+ username?: string | undefined;
34
+ }, {
35
+ id: string;
36
+ server: string;
37
+ password?: string | undefined;
38
+ username?: string | undefined;
39
+ }>;
40
+ }, "strip", import("zod").ZodTypeAny, {
41
+ type: "custom";
42
+ proxy: {
43
+ id: string;
44
+ server: string;
45
+ password?: string | undefined;
46
+ username?: string | undefined;
47
+ };
48
+ }, {
49
+ type: "custom";
50
+ proxy: {
51
+ id: string;
52
+ server: string;
53
+ password?: string | undefined;
54
+ username?: string | undefined;
55
+ };
56
+ }>]>>;
57
+ }, "strip", import("zod").ZodTypeAny, {
58
+ operation: "get_sent_invitations";
59
+ credentials?: Partial<Record<CredentialType, string>> | undefined;
60
+ proxy?: {
61
+ type: "none";
62
+ } | {
63
+ type: "browserbase";
64
+ } | {
65
+ type: "custom";
66
+ proxy: {
67
+ id: string;
68
+ server: string;
69
+ password?: string | undefined;
70
+ username?: string | undefined;
71
+ };
72
+ } | undefined;
73
+ }, {
74
+ operation: "get_sent_invitations";
75
+ credentials?: Partial<Record<CredentialType, string>> | undefined;
76
+ proxy?: {
77
+ type: "none";
78
+ } | {
79
+ type: "browserbase";
80
+ } | {
81
+ type: "custom";
82
+ proxy: {
83
+ id: string;
84
+ server: string;
85
+ password?: string | undefined;
86
+ username?: string | undefined;
87
+ };
88
+ } | undefined;
89
+ }>;
90
+ static readonly resultSchema: import("zod").ZodObject<{
91
+ operation: import("zod").ZodLiteral<"get_sent_invitations">;
92
+ success: import("zod").ZodBoolean;
93
+ invitations: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodObject<{
94
+ name: import("zod").ZodString;
95
+ headline: import("zod").ZodOptional<import("zod").ZodString>;
96
+ sent_date: import("zod").ZodString;
97
+ profile_url: import("zod").ZodOptional<import("zod").ZodString>;
98
+ }, "strip", import("zod").ZodTypeAny, {
99
+ name: string;
100
+ sent_date: string;
101
+ headline?: string | undefined;
102
+ profile_url?: string | undefined;
103
+ }, {
104
+ name: string;
105
+ sent_date: string;
106
+ headline?: string | undefined;
107
+ profile_url?: string | undefined;
108
+ }>, "many">>;
109
+ total_count: import("zod").ZodOptional<import("zod").ZodNumber>;
110
+ message: import("zod").ZodOptional<import("zod").ZodString>;
111
+ error: import("zod").ZodString;
112
+ }, "strip", import("zod").ZodTypeAny, {
113
+ operation: "get_sent_invitations";
114
+ error: string;
115
+ success: boolean;
116
+ message?: string | undefined;
117
+ total_count?: number | undefined;
118
+ invitations?: {
119
+ name: string;
120
+ sent_date: string;
121
+ headline?: string | undefined;
122
+ profile_url?: string | undefined;
123
+ }[] | undefined;
124
+ }, {
125
+ operation: "get_sent_invitations";
126
+ error: string;
127
+ success: boolean;
128
+ message?: string | undefined;
129
+ total_count?: number | undefined;
130
+ invitations?: {
131
+ name: string;
132
+ sent_date: string;
133
+ headline?: string | undefined;
134
+ profile_url?: string | undefined;
135
+ }[] | undefined;
136
+ }>;
137
+ static readonly shortDescription = "Extract sent LinkedIn connection invitations";
138
+ static readonly longDescription = "Recordable LinkedIn Sent Invitations Tool for extracting pending sent connection requests.";
139
+ static readonly alias = "linkedin-sent-invitations";
140
+ static readonly type = "tool";
141
+ private sessionId;
142
+ private contextId;
143
+ private cookies;
144
+ constructor(params?: T, context?: BubbleContext);
145
+ protected chooseCredential(): string | undefined;
146
+ private stepStartBrowserSession;
147
+ private stepNavigateToSentInvitations;
148
+ private stepWaitForInvitationsPage;
149
+ private stepExtractInvitations;
150
+ private stepEndBrowserSession;
151
+ private evaluate;
152
+ private detectIPAddress;
153
+ performAction(): Promise<LinkedInSentInvitationsToolResult>;
154
+ }
155
+ //# sourceMappingURL=tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../../../../src/bubbles/tool-bubble/browser-tools/linkedin-sent-invitations/tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,wCAAwC,CAAC;AACpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAKjE,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE3D,OAAO,EAGL,KAAK,sCAAsC,EAC3C,KAAK,iCAAiC,EAEvC,MAAM,aAAa,CAAC;AAErB,qBAAa,2BAA2B,CACtC,CAAC,SACC,sCAAsC,GAAG,sCAAsC,CACjF,SAAQ,UAAU,CAAC,CAAC,EAAE,iCAAiC,CAAC;IACxD,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAG,gCAAgC,CAAU;IACvE,MAAM,CAAC,QAAQ,CAAC,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAA2C;IACjE,MAAM,CAAC,QAAQ,CAAC,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAA2C;IACvE,MAAM,CAAC,QAAQ,CAAC,gBAAgB,kDACiB;IACjD,MAAM,CAAC,QAAQ,CAAC,eAAe,gGACgE;IAC/F,MAAM,CAAC,QAAQ,CAAC,KAAK,+BAA+B;IACpD,MAAM,CAAC,QAAQ,CAAC,IAAI,UAAU;IAE9B,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,OAAO,CAA4B;gBAGzC,MAAM,GAAE,CAA8C,EACtD,OAAO,CAAC,EAAE,aAAa;IAKzB,SAAS,CAAC,gBAAgB,IAAI,MAAM,GAAG,SAAS;YAOlC,uBAAuB;YAiCvB,6BAA6B;YAkB7B,0BAA0B;YAoB1B,sBAAsB;YAsFtB,qBAAqB;YAYrB,QAAQ;YAaR,eAAe;IAiBvB,aAAa,IAAI,OAAO,CAAC,iCAAiC,CAAC;CA4BlE"}
@@ -0,0 +1,233 @@
1
+ import { ToolBubble } from '../../../../types/tool-bubble-class.js';
2
+ import { BrowserBaseBubble, } from '../../../service-bubble/browserbase/index.js';
3
+ import { CredentialType } from '@bubblelab/shared-schemas';
4
+ import { parseBrowserSessionData, buildProxyConfig } from '../_shared/utils.js';
5
+ import { LinkedInSentInvitationsToolParamsSchema, LinkedInSentInvitationsToolResultSchema, } from './schema.js';
6
+ export class LinkedInSentInvitationsTool extends ToolBubble {
7
+ static bubbleName = 'linkedin-sent-invitations-tool';
8
+ static schema = LinkedInSentInvitationsToolParamsSchema;
9
+ static resultSchema = LinkedInSentInvitationsToolResultSchema;
10
+ static shortDescription = 'Extract sent LinkedIn connection invitations';
11
+ static longDescription = 'Recordable LinkedIn Sent Invitations Tool for extracting pending sent connection requests.';
12
+ static alias = 'linkedin-sent-invitations';
13
+ static type = 'tool';
14
+ sessionId = null;
15
+ contextId = null;
16
+ cookies = null;
17
+ constructor(params = { operation: 'get_sent_invitations' }, context) {
18
+ super(params, context);
19
+ }
20
+ chooseCredential() {
21
+ const { credentials } = this.params;
22
+ return credentials?.[CredentialType.LINKEDIN_CRED];
23
+ }
24
+ async stepStartBrowserSession() {
25
+ if (this.sessionId)
26
+ return;
27
+ const sessionData = parseBrowserSessionData(this.chooseCredential());
28
+ if (sessionData) {
29
+ this.contextId = sessionData.contextId;
30
+ this.cookies = sessionData.cookies;
31
+ }
32
+ const proxyConfig = buildProxyConfig(this.params.proxy);
33
+ const browserbase = new BrowserBaseBubble({
34
+ operation: 'start_session',
35
+ context_id: this.contextId || undefined,
36
+ cookies: this.cookies || undefined,
37
+ credentials: this.params.credentials,
38
+ stealth: { solveCaptchas: true },
39
+ ...proxyConfig,
40
+ }, this.context, 'startsession');
41
+ const result = await browserbase.action();
42
+ if (!result.data.success || !result.data.session_id) {
43
+ throw new Error(result.data.error || 'Failed to start browser session');
44
+ }
45
+ this.sessionId = result.data.session_id;
46
+ if (result.data.context_id)
47
+ this.contextId = result.data.context_id;
48
+ console.log(`[RecordableSentInvitations] Session started: ${this.sessionId}`);
49
+ const ip = await this.detectIPAddress();
50
+ if (ip)
51
+ console.log(`[RecordableSentInvitations] Browser IP: ${ip}`);
52
+ }
53
+ async stepNavigateToSentInvitations() {
54
+ if (!this.sessionId)
55
+ throw new Error('No active session');
56
+ const browserbase = new BrowserBaseBubble({
57
+ operation: 'navigate',
58
+ session_id: this.sessionId,
59
+ url: 'https://www.linkedin.com/mynetwork/invitation-manager/sent/',
60
+ wait_until: 'domcontentloaded',
61
+ timeout: 30000,
62
+ }, this.context, 'navigate');
63
+ const result = await browserbase.action();
64
+ if (!result.data.success)
65
+ throw new Error(result.data.error || 'Navigation failed');
66
+ }
67
+ async stepWaitForInvitationsPage() {
68
+ const checkScript = `(() => {
69
+ const buttons = document.querySelectorAll('button');
70
+ let sentTabFound = false, hasInvitations = false;
71
+ for (const btn of buttons) {
72
+ const text = (btn.innerText || btn.textContent || '').trim().toLowerCase();
73
+ if (text === 'sent') sentTabFound = true;
74
+ if (text === 'withdraw') hasInvitations = true;
75
+ }
76
+ const peopleLabel = document.body.innerText.match(/People\\s*\\(\\d+\\)/i);
77
+ return sentTabFound && (hasInvitations || peopleLabel);
78
+ })()`;
79
+ for (let attempt = 1; attempt <= 15; attempt++) {
80
+ const found = await this.evaluate(checkScript);
81
+ if (found)
82
+ return true;
83
+ await new Promise((r) => setTimeout(r, 1000));
84
+ }
85
+ return false;
86
+ }
87
+ async stepExtractInvitations() {
88
+ const result = (await this.evaluate(`
89
+ (() => {
90
+ const invitations = [];
91
+ const withdrawButtons = Array.from(document.querySelectorAll('button')).filter(btn =>
92
+ (btn.innerText || btn.textContent || '').trim().toLowerCase() === 'withdraw'
93
+ );
94
+ for (const withdrawBtn of withdrawButtons) {
95
+ let container = withdrawBtn.parentElement;
96
+ for (let i = 0; i < 10 && container; i++) {
97
+ const text = container.innerText || '';
98
+ if (text.includes('Sent') && container.querySelector('a[href*="/in/"]')) break;
99
+ container = container.parentElement;
100
+ }
101
+ if (!container) continue;
102
+ let name = '';
103
+ const links = container.querySelectorAll('a[href*="/in/"]');
104
+ for (const link of links) {
105
+ const linkText = (link.innerText || link.textContent || '').trim();
106
+ if (linkText && linkText.length > 1 && linkText.length < 100 && !linkText.includes('Sent')) {
107
+ name = linkText;
108
+ break;
109
+ }
110
+ }
111
+ if (!name) {
112
+ const spans = container.querySelectorAll('span');
113
+ for (const span of spans) {
114
+ const spanText = (span.innerText || span.textContent || '').trim();
115
+ if (spanText && spanText.length > 2 && spanText.length < 50 &&
116
+ !spanText.includes('Sent') && !spanText.includes('Withdraw') &&
117
+ !spanText.includes('|') && !spanText.includes('-')) {
118
+ name = spanText;
119
+ break;
120
+ }
121
+ }
122
+ }
123
+ const containerText = container.innerText || '';
124
+ const lines = containerText.split('\\n').map(l => l.trim()).filter(l => l);
125
+ let headline = '';
126
+ let nameLineIdx = -1, sentLineIdx = -1;
127
+ for (let i = 0; i < lines.length; i++) {
128
+ if (lines[i] === name) nameLineIdx = i;
129
+ if (lines[i].match(/^Sent\\s+\\d+/i)) sentLineIdx = i;
130
+ }
131
+ if (nameLineIdx >= 0 && sentLineIdx > nameLineIdx + 1) {
132
+ headline = lines.slice(nameLineIdx + 1, sentLineIdx)
133
+ .filter(l => l.toLowerCase() !== 'withdraw' && l.length > 5)
134
+ .join(' ').trim();
135
+ }
136
+ if (!headline) {
137
+ for (const line of lines) {
138
+ if (line === name || line.toLowerCase() === 'withdraw' ||
139
+ line.match(/^Sent\\s+\\d+/i) || line.match(/^People\\s*\\(/i)) continue;
140
+ if (line.length > 10 && line.length < 300) { headline = line; break; }
141
+ }
142
+ }
143
+ const sentMatch = containerText.match(/Sent\\s+\\d+\\s+\\w+\\s+ago/i);
144
+ let profile_url = '';
145
+ for (const link of links) {
146
+ const href = link.getAttribute('href') || '';
147
+ if (href.includes('/in/')) {
148
+ profile_url = href.startsWith('http') ? href : 'https://www.linkedin.com' + href;
149
+ break;
150
+ }
151
+ }
152
+ if (name) {
153
+ invitations.push({
154
+ name,
155
+ headline: headline || undefined,
156
+ sent_date: sentMatch ? sentMatch[0] : 'Unknown',
157
+ profile_url: profile_url || undefined,
158
+ });
159
+ }
160
+ }
161
+ let total = invitations.length;
162
+ const peopleMatch = document.body.innerText.match(/People\\s*\\((\\d+)\\)/i);
163
+ if (peopleMatch) total = parseInt(peopleMatch[1], 10);
164
+ return { invitations, total };
165
+ })()
166
+ `));
167
+ return result;
168
+ }
169
+ async stepEndBrowserSession() {
170
+ if (!this.sessionId)
171
+ return;
172
+ const browserbase = new BrowserBaseBubble({ operation: 'end_session', session_id: this.sessionId }, this.context, 'endsession');
173
+ await browserbase.action();
174
+ console.log(`[RecordableSentInvitations] Session ended: ${this.sessionId}`);
175
+ this.sessionId = null;
176
+ }
177
+ async evaluate(script) {
178
+ if (!this.sessionId)
179
+ throw new Error('No active session');
180
+ const browserbase = new BrowserBaseBubble({ operation: 'evaluate', session_id: this.sessionId, script }, this.context, 'evaluate');
181
+ const result = await browserbase.action();
182
+ if (!result.data.success)
183
+ throw new Error(result.data.error || 'Evaluation failed');
184
+ return result.data.result;
185
+ }
186
+ async detectIPAddress() {
187
+ if (!this.sessionId)
188
+ return null;
189
+ try {
190
+ return (await this.evaluate(`
191
+ (async () => {
192
+ try {
193
+ const r = await fetch('https://api.ipify.org?format=json');
194
+ const d = await r.json();
195
+ return d.ip;
196
+ } catch { return null; }
197
+ })()
198
+ `));
199
+ }
200
+ catch {
201
+ return null;
202
+ }
203
+ }
204
+ async performAction() {
205
+ try {
206
+ await this.stepStartBrowserSession();
207
+ await this.stepNavigateToSentInvitations();
208
+ const pageReady = await this.stepWaitForInvitationsPage();
209
+ if (!pageReady)
210
+ console.log('[RecordableSentInvitations] Page slow to load, continuing');
211
+ const { invitations, total } = await this.stepExtractInvitations();
212
+ return {
213
+ operation: 'get_sent_invitations',
214
+ success: true,
215
+ invitations,
216
+ total_count: total,
217
+ message: `Found ${invitations.length} sent invitations`,
218
+ error: '',
219
+ };
220
+ }
221
+ catch (error) {
222
+ return {
223
+ operation: 'get_sent_invitations',
224
+ success: false,
225
+ error: error instanceof Error ? error.message : 'Unknown error',
226
+ };
227
+ }
228
+ finally {
229
+ await this.stepEndBrowserSession();
230
+ }
231
+ }
232
+ }
233
+ //# sourceMappingURL=tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool.js","sourceRoot":"","sources":["../../../../../src/bubbles/tool-bubble/browser-tools/linkedin-sent-invitations/tool.ts"],"names":[],"mappings":"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"}
@@ -135,13 +135,13 @@ declare const BubbleFlowValidationToolResultSchema: z.ZodObject<{
135
135
  hasActionCall: boolean;
136
136
  parameterCount: number;
137
137
  }[] | undefined;
138
- bubbleCount?: number | undefined;
139
138
  variableTypes?: {
140
139
  type: string;
141
140
  name: string;
142
141
  column: number;
143
142
  line: number;
144
143
  }[] | undefined;
144
+ bubbleCount?: number | undefined;
145
145
  }, {
146
146
  valid: boolean;
147
147
  error: string;
@@ -160,13 +160,13 @@ declare const BubbleFlowValidationToolResultSchema: z.ZodObject<{
160
160
  hasActionCall: boolean;
161
161
  parameterCount: number;
162
162
  }[] | undefined;
163
- bubbleCount?: number | undefined;
164
163
  variableTypes?: {
165
164
  type: string;
166
165
  name: string;
167
166
  column: number;
168
167
  line: number;
169
168
  }[] | undefined;
169
+ bubbleCount?: number | undefined;
170
170
  }>;
171
171
  /**
172
172
  * BubbleFlow Validation Tool
@@ -284,13 +284,13 @@ export declare class BubbleFlowValidationTool extends ToolBubble<BubbleFlowValid
284
284
  hasActionCall: boolean;
285
285
  parameterCount: number;
286
286
  }[] | undefined;
287
- bubbleCount?: number | undefined;
288
287
  variableTypes?: {
289
288
  type: string;
290
289
  name: string;
291
290
  column: number;
292
291
  line: number;
293
292
  }[] | undefined;
293
+ bubbleCount?: number | undefined;
294
294
  }, {
295
295
  valid: boolean;
296
296
  error: string;
@@ -309,13 +309,13 @@ export declare class BubbleFlowValidationTool extends ToolBubble<BubbleFlowValid
309
309
  hasActionCall: boolean;
310
310
  parameterCount: number;
311
311
  }[] | undefined;
312
- bubbleCount?: number | undefined;
313
312
  variableTypes?: {
314
313
  type: string;
315
314
  name: string;
316
315
  column: number;
317
316
  line: number;
318
317
  }[] | undefined;
318
+ bubbleCount?: number | undefined;
319
319
  }>;
320
320
  static readonly shortDescription = "Validates BubbleFlow TypeScript code for syntax and structure";
321
321
  static readonly longDescription = "\n A comprehensive validation tool for BubbleFlow TypeScript code.\n \n What it does:\n - Validates TypeScript syntax and compilation\n - Checks BubbleFlow class structure and requirements\n - Parses and analyzes bubble instantiations\n - Provides detailed error reporting with line numbers\n - Returns metadata about detected bubbles\n \n How it works:\n - Uses TypeScript compiler API for syntax validation\n - Validates that code extends BubbleFlow and has handle method\n - Parses bubble instantiations using AST analysis\n - Maps bubble class names to registered bubble types\n \n Use cases:\n - When an AI agent needs to validate user-provided BubbleFlow code\n - When checking code before execution or deployment\n - When providing feedback on BubbleFlow implementation\n - When analyzing bubble usage patterns in code\n ";