@radaros/core 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +174 -1
- package/dist/index.js +822 -37
- package/package.json +6 -2
- package/src/index.ts +14 -1
- package/src/models/providers/vertex.ts +400 -0
- package/src/models/registry.ts +17 -0
- package/src/toolkits/base.ts +15 -0
- package/src/toolkits/gmail.ts +226 -0
- package/src/toolkits/hackernews.ts +121 -0
- package/src/toolkits/websearch.ts +158 -0
- package/src/toolkits/whatsapp.ts +209 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { ToolDef } from "../tools/types.js";
|
|
3
|
+
import type { RunContext } from "../agent/run-context.js";
|
|
4
|
+
import { Toolkit } from "./base.js";
|
|
5
|
+
|
|
6
|
+
export interface WhatsAppConfig {
|
|
7
|
+
/** WhatsApp Business API access token. Falls back to WHATSAPP_ACCESS_TOKEN env var. */
|
|
8
|
+
accessToken?: string;
|
|
9
|
+
/** WhatsApp Business phone number ID. Falls back to WHATSAPP_PHONE_NUMBER_ID env var. */
|
|
10
|
+
phoneNumberId?: string;
|
|
11
|
+
/** API version (default "v22.0"). Falls back to WHATSAPP_VERSION env var. */
|
|
12
|
+
version?: string;
|
|
13
|
+
/** Default recipient WhatsApp ID. Falls back to WHATSAPP_RECIPIENT_WAID env var. */
|
|
14
|
+
recipientWaid?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* WhatsApp Toolkit — send messages via WhatsApp Business Cloud API (Meta).
|
|
19
|
+
*
|
|
20
|
+
* Uses the WhatsApp Cloud API directly (no Twilio).
|
|
21
|
+
* Setup: https://developers.facebook.com/docs/whatsapp/cloud-api/get-started
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* const whatsapp = new WhatsAppToolkit({
|
|
26
|
+
* accessToken: "...",
|
|
27
|
+
* phoneNumberId: "...",
|
|
28
|
+
* });
|
|
29
|
+
* const agent = new Agent({ tools: [...whatsapp.getTools()] });
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export class WhatsAppToolkit extends Toolkit {
|
|
33
|
+
readonly name = "whatsapp";
|
|
34
|
+
private accessToken: string;
|
|
35
|
+
private phoneNumberId: string;
|
|
36
|
+
private version: string;
|
|
37
|
+
private recipientWaid: string | undefined;
|
|
38
|
+
|
|
39
|
+
constructor(config: WhatsAppConfig = {}) {
|
|
40
|
+
super();
|
|
41
|
+
this.accessToken =
|
|
42
|
+
config.accessToken ?? process.env.WHATSAPP_ACCESS_TOKEN ?? "";
|
|
43
|
+
this.phoneNumberId =
|
|
44
|
+
config.phoneNumberId ?? process.env.WHATSAPP_PHONE_NUMBER_ID ?? "";
|
|
45
|
+
this.version =
|
|
46
|
+
config.version ?? process.env.WHATSAPP_VERSION ?? "v22.0";
|
|
47
|
+
this.recipientWaid =
|
|
48
|
+
config.recipientWaid ?? process.env.WHATSAPP_RECIPIENT_WAID;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
private getBaseUrl(): string {
|
|
52
|
+
return `https://graph.facebook.com/${this.version}/${this.phoneNumberId}/messages`;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
private validate(): void {
|
|
56
|
+
if (!this.accessToken) {
|
|
57
|
+
throw new Error(
|
|
58
|
+
"WhatsAppToolkit: accessToken is required. Set WHATSAPP_ACCESS_TOKEN env var or pass in config."
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
if (!this.phoneNumberId) {
|
|
62
|
+
throw new Error(
|
|
63
|
+
"WhatsAppToolkit: phoneNumberId is required. Set WHATSAPP_PHONE_NUMBER_ID env var or pass in config."
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
private resolveRecipient(recipient?: string): string {
|
|
69
|
+
const r = recipient ?? this.recipientWaid;
|
|
70
|
+
if (!r) {
|
|
71
|
+
throw new Error(
|
|
72
|
+
"WhatsAppToolkit: recipient is required. Provide it in the tool call or set WHATSAPP_RECIPIENT_WAID env var."
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
return r.replace(/[^0-9]/g, "");
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
getTools(): ToolDef[] {
|
|
79
|
+
const self = this;
|
|
80
|
+
|
|
81
|
+
return [
|
|
82
|
+
{
|
|
83
|
+
name: "whatsapp_send_text",
|
|
84
|
+
description:
|
|
85
|
+
"Send a text message to a WhatsApp user via WhatsApp Business Cloud API.",
|
|
86
|
+
parameters: z.object({
|
|
87
|
+
text: z.string().describe("The text message to send"),
|
|
88
|
+
recipient: z
|
|
89
|
+
.string()
|
|
90
|
+
.optional()
|
|
91
|
+
.describe(
|
|
92
|
+
"Recipient WhatsApp number with country code (e.g. 919876543210). Uses default if omitted."
|
|
93
|
+
),
|
|
94
|
+
previewUrl: z
|
|
95
|
+
.boolean()
|
|
96
|
+
.optional()
|
|
97
|
+
.describe("Enable URL previews in the message (default false)"),
|
|
98
|
+
}),
|
|
99
|
+
execute: async (
|
|
100
|
+
args: Record<string, unknown>,
|
|
101
|
+
_ctx: RunContext
|
|
102
|
+
): Promise<string> => {
|
|
103
|
+
self.validate();
|
|
104
|
+
const recipient = self.resolveRecipient(args.recipient as string);
|
|
105
|
+
|
|
106
|
+
const res = await fetch(self.getBaseUrl(), {
|
|
107
|
+
method: "POST",
|
|
108
|
+
headers: {
|
|
109
|
+
Authorization: `Bearer ${self.accessToken}`,
|
|
110
|
+
"Content-Type": "application/json",
|
|
111
|
+
},
|
|
112
|
+
body: JSON.stringify({
|
|
113
|
+
messaging_product: "whatsapp",
|
|
114
|
+
recipient_type: "individual",
|
|
115
|
+
to: recipient,
|
|
116
|
+
type: "text",
|
|
117
|
+
text: {
|
|
118
|
+
preview_url: (args.previewUrl as boolean) ?? false,
|
|
119
|
+
body: args.text as string,
|
|
120
|
+
},
|
|
121
|
+
}),
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
if (!res.ok) {
|
|
125
|
+
const err = await res.text();
|
|
126
|
+
throw new Error(
|
|
127
|
+
`WhatsApp send failed: ${res.status} ${err}`
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const data = (await res.json()) as any;
|
|
132
|
+
const msgId = data.messages?.[0]?.id ?? "unknown";
|
|
133
|
+
return `Message sent successfully to ${recipient}. Message ID: ${msgId}`;
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
name: "whatsapp_send_template",
|
|
138
|
+
description:
|
|
139
|
+
"Send a template message to a WhatsApp user. Required for first-time outreach (24-hour messaging window).",
|
|
140
|
+
parameters: z.object({
|
|
141
|
+
templateName: z
|
|
142
|
+
.string()
|
|
143
|
+
.describe(
|
|
144
|
+
'The pre-approved template name (e.g. "hello_world")'
|
|
145
|
+
),
|
|
146
|
+
recipient: z
|
|
147
|
+
.string()
|
|
148
|
+
.optional()
|
|
149
|
+
.describe(
|
|
150
|
+
"Recipient WhatsApp number with country code. Uses default if omitted."
|
|
151
|
+
),
|
|
152
|
+
languageCode: z
|
|
153
|
+
.string()
|
|
154
|
+
.optional()
|
|
155
|
+
.describe('Template language code (default "en_US")'),
|
|
156
|
+
components: z
|
|
157
|
+
.array(z.record(z.any()))
|
|
158
|
+
.optional()
|
|
159
|
+
.describe(
|
|
160
|
+
"Template components for dynamic content (header, body, button parameters)"
|
|
161
|
+
),
|
|
162
|
+
}),
|
|
163
|
+
execute: async (
|
|
164
|
+
args: Record<string, unknown>,
|
|
165
|
+
_ctx: RunContext
|
|
166
|
+
): Promise<string> => {
|
|
167
|
+
self.validate();
|
|
168
|
+
const recipient = self.resolveRecipient(args.recipient as string);
|
|
169
|
+
const langCode = (args.languageCode as string) ?? "en_US";
|
|
170
|
+
|
|
171
|
+
const template: Record<string, unknown> = {
|
|
172
|
+
name: args.templateName as string,
|
|
173
|
+
language: { code: langCode },
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
if (args.components) {
|
|
177
|
+
template.components = args.components;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const res = await fetch(self.getBaseUrl(), {
|
|
181
|
+
method: "POST",
|
|
182
|
+
headers: {
|
|
183
|
+
Authorization: `Bearer ${self.accessToken}`,
|
|
184
|
+
"Content-Type": "application/json",
|
|
185
|
+
},
|
|
186
|
+
body: JSON.stringify({
|
|
187
|
+
messaging_product: "whatsapp",
|
|
188
|
+
recipient_type: "individual",
|
|
189
|
+
to: recipient,
|
|
190
|
+
type: "template",
|
|
191
|
+
template,
|
|
192
|
+
}),
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
if (!res.ok) {
|
|
196
|
+
const err = await res.text();
|
|
197
|
+
throw new Error(
|
|
198
|
+
`WhatsApp template send failed: ${res.status} ${err}`
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const data = (await res.json()) as any;
|
|
203
|
+
const msgId = data.messages?.[0]?.id ?? "unknown";
|
|
204
|
+
return `Template message "${args.templateName}" sent to ${recipient}. Message ID: ${msgId}`;
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
];
|
|
208
|
+
}
|
|
209
|
+
}
|