getpatter 0.5.0 → 0.5.2
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/README.md +25 -1
- package/dist/banner-FLR2HE5Z.mjs +19 -0
- package/dist/{chunk-757NVN4L.mjs → chunk-7SDDK2AO.mjs} +61 -46
- package/dist/{chunk-JO5C35FM.mjs → chunk-AKQFOFLG.mjs} +1 -1
- package/dist/cli.js +7 -2
- package/dist/index.d.mts +363 -56
- package/dist/index.d.ts +363 -56
- package/dist/index.js +728 -870
- package/dist/index.mjs +640 -7
- package/dist/{test-mode-YFOL2HYH.mjs → test-mode-K2TTPRGE.mjs} +1 -1
- package/dist/{tunnel-BL7A7GXW.mjs → tunnel-O7ICMSTP.mjs} +1 -1
- package/package.json +1 -1
- package/dist/lib-4WCAS54J.mjs +0 -830
package/dist/index.js
CHANGED
|
@@ -213,7 +213,7 @@ var init_elevenlabs_convai = __esm({
|
|
|
213
213
|
init_logger();
|
|
214
214
|
ELEVENLABS_CONVAI_URL = "wss://api.elevenlabs.io/v1/convai/conversation";
|
|
215
215
|
ElevenLabsConvAIAdapter = class {
|
|
216
|
-
constructor(apiKey, agentId = "", voiceId = "
|
|
216
|
+
constructor(apiKey, agentId = "", voiceId = "EXAVITQu4vr4xnSDxMaL", _modelId = "eleven_turbo_v2_5", _language = "en", firstMessage = "") {
|
|
217
217
|
this.apiKey = apiKey;
|
|
218
218
|
this.agentId = agentId;
|
|
219
219
|
this.voiceId = voiceId;
|
|
@@ -2748,7 +2748,7 @@ async function queryDeepgramCost(metricsAcc, deepgramKey, deepgramRequestId) {
|
|
|
2748
2748
|
const usd = reqData.response?.details?.usd;
|
|
2749
2749
|
if (usd != null) {
|
|
2750
2750
|
metricsAcc.setActualSttCost(usd);
|
|
2751
|
-
getLogger().
|
|
2751
|
+
getLogger().debug(`Deepgram actual cost: $${usd}`);
|
|
2752
2752
|
}
|
|
2753
2753
|
}
|
|
2754
2754
|
}
|
|
@@ -2816,7 +2816,7 @@ var init_stream_handler = __esm({
|
|
|
2816
2816
|
ttsProvider: ttsProviderName,
|
|
2817
2817
|
pricing: deps.pricing
|
|
2818
2818
|
});
|
|
2819
|
-
getLogger().
|
|
2819
|
+
getLogger().debug(`WebSocket connection opened (${deps.bridge.label})`);
|
|
2820
2820
|
}
|
|
2821
2821
|
// ---------------------------------------------------------------------------
|
|
2822
2822
|
// Public: called by the provider-specific parsers in server.ts
|
|
@@ -2832,9 +2832,12 @@ var init_stream_handler = __esm({
|
|
|
2832
2832
|
this.metricsAcc.callId = callId;
|
|
2833
2833
|
if (customParams.caller && !this.caller) this.caller = customParams.caller;
|
|
2834
2834
|
if (customParams.callee && !this.callee) this.callee = customParams.callee;
|
|
2835
|
-
|
|
2835
|
+
const mode = this.deps.agent.engine ? `engine=${this.deps.agent.engine.kind ?? "unknown"}` : "pipeline";
|
|
2836
|
+
getLogger().info(
|
|
2837
|
+
`Call started: ${callId} (${this.deps.bridge.label}, ${mode}, ${sanitizeLogValue(this.caller || "?")} \u2192 ${sanitizeLogValue(this.callee || "?")})`
|
|
2838
|
+
);
|
|
2836
2839
|
if (Object.keys(customParams).length > 0) {
|
|
2837
|
-
getLogger().
|
|
2840
|
+
getLogger().debug(`Custom params: ${sanitizeLogValue(JSON.stringify(customParams))}`);
|
|
2838
2841
|
}
|
|
2839
2842
|
this.deps.metricsStore.recordCallStart({
|
|
2840
2843
|
call_id: callId,
|
|
@@ -2882,7 +2885,7 @@ var init_stream_handler = __esm({
|
|
|
2882
2885
|
}
|
|
2883
2886
|
});
|
|
2884
2887
|
if (recResp.ok) {
|
|
2885
|
-
getLogger().
|
|
2888
|
+
getLogger().debug(`Recording started for ${callId}`);
|
|
2886
2889
|
} else {
|
|
2887
2890
|
getLogger().warn(`could not start recording: ${await recResp.text()}`);
|
|
2888
2891
|
}
|
|
@@ -2937,7 +2940,7 @@ var init_stream_handler = __esm({
|
|
|
2937
2940
|
}
|
|
2938
2941
|
/** Handle a DTMF keypress event (Twilio only). */
|
|
2939
2942
|
async handleDtmf(digit) {
|
|
2940
|
-
getLogger().
|
|
2943
|
+
getLogger().debug(`DTMF: ${digit}`);
|
|
2941
2944
|
if (this.adapter instanceof OpenAIRealtimeAdapter) {
|
|
2942
2945
|
await this.adapter.sendText(`The user pressed key ${digit} on their phone keypad.`);
|
|
2943
2946
|
}
|
|
@@ -2999,14 +3002,14 @@ var init_stream_handler = __esm({
|
|
|
2999
3002
|
this.stt = await this.deps.bridge.createStt(this.deps.agent);
|
|
3000
3003
|
this.tts = await createTTS(this.deps.agent);
|
|
3001
3004
|
if (!this.stt) {
|
|
3002
|
-
getLogger().
|
|
3005
|
+
getLogger().debug(`Pipeline mode (${label}): no STT configured`);
|
|
3003
3006
|
}
|
|
3004
3007
|
if (!this.tts) {
|
|
3005
|
-
getLogger().
|
|
3008
|
+
getLogger().debug(`Pipeline mode (${label}): no TTS configured`);
|
|
3006
3009
|
}
|
|
3007
3010
|
try {
|
|
3008
3011
|
if (this.stt) await this.stt.connect();
|
|
3009
|
-
getLogger().
|
|
3012
|
+
getLogger().debug(`Pipeline mode (${label}): STT + TTS connected`);
|
|
3010
3013
|
} catch (e) {
|
|
3011
3014
|
getLogger().error(`Pipeline connect FAILED (${label}):`, e);
|
|
3012
3015
|
try {
|
|
@@ -3039,7 +3042,24 @@ var init_stream_handler = __esm({
|
|
|
3039
3042
|
this.history.push({ role: "assistant", text: this.deps.agent.firstMessage, timestamp: Date.now() });
|
|
3040
3043
|
}
|
|
3041
3044
|
}
|
|
3042
|
-
if (
|
|
3045
|
+
if (this.deps.agent.llm) {
|
|
3046
|
+
if (this.deps.onMessage) {
|
|
3047
|
+
throw new Error(
|
|
3048
|
+
"Cannot pass both agent({ llm }) and serve({ onMessage }). Pick one \u2014 `llm` for built-in LLMs, `onMessage` for custom logic."
|
|
3049
|
+
);
|
|
3050
|
+
}
|
|
3051
|
+
this.llmLoop = new LLMLoop(
|
|
3052
|
+
"",
|
|
3053
|
+
// apiKey unused when llmProvider is supplied
|
|
3054
|
+
"",
|
|
3055
|
+
// model unused when llmProvider is supplied
|
|
3056
|
+
resolvedPrompt,
|
|
3057
|
+
this.deps.agent.tools,
|
|
3058
|
+
this.deps.agent.llm
|
|
3059
|
+
);
|
|
3060
|
+
const llmLabel = this.deps.agent.llm.constructor?.name ?? "custom";
|
|
3061
|
+
getLogger().debug(`Built-in LLM loop active (pipeline, ${label}, llm=${llmLabel})`);
|
|
3062
|
+
} else if (!this.deps.onMessage && this.deps.config.openaiKey) {
|
|
3043
3063
|
let llmModel = this.deps.agent.model || "gpt-4o-mini";
|
|
3044
3064
|
if (llmModel.includes("realtime")) llmModel = "gpt-4o-mini";
|
|
3045
3065
|
this.llmLoop = new LLMLoop(
|
|
@@ -3048,7 +3068,7 @@ var init_stream_handler = __esm({
|
|
|
3048
3068
|
resolvedPrompt,
|
|
3049
3069
|
this.deps.agent.tools
|
|
3050
3070
|
);
|
|
3051
|
-
getLogger().
|
|
3071
|
+
getLogger().debug(`Built-in LLM loop active (pipeline, ${label})`);
|
|
3052
3072
|
}
|
|
3053
3073
|
if (this.stt) {
|
|
3054
3074
|
this.stt.onTranscript(async (transcript) => {
|
|
@@ -3109,7 +3129,7 @@ var init_stream_handler = __esm({
|
|
|
3109
3129
|
}
|
|
3110
3130
|
async processTranscript(transcript) {
|
|
3111
3131
|
if (transcript.text && this.isSpeaking) {
|
|
3112
|
-
getLogger().
|
|
3132
|
+
getLogger().debug(
|
|
3113
3133
|
`Barge-in: caller spoke over agent (${sanitizeLogValue(transcript.text.slice(0, 40))})`
|
|
3114
3134
|
);
|
|
3115
3135
|
this.isSpeaking = false;
|
|
@@ -3144,17 +3164,17 @@ var init_stream_handler = __esm({
|
|
|
3144
3164
|
"cool"
|
|
3145
3165
|
]);
|
|
3146
3166
|
if (HALLUCINATIONS.has(stripped) || stripped === "") {
|
|
3147
|
-
getLogger().
|
|
3167
|
+
getLogger().debug(`Dropped likely STT hallucination: ${sanitizeLogValue(normalised.slice(0, 40))}`);
|
|
3148
3168
|
return;
|
|
3149
3169
|
}
|
|
3150
3170
|
if (sinceLastMs < 2e3 && normalised === this.lastCommitText) {
|
|
3151
|
-
getLogger().
|
|
3171
|
+
getLogger().debug(
|
|
3152
3172
|
`Dropped duplicate final transcript (${(sinceLastMs / 1e3).toFixed(1)}s since last): ${sanitizeLogValue(normalised.slice(0, 40))}`
|
|
3153
3173
|
);
|
|
3154
3174
|
return;
|
|
3155
3175
|
}
|
|
3156
3176
|
if (sinceLastMs < 500) {
|
|
3157
|
-
getLogger().
|
|
3177
|
+
getLogger().debug(
|
|
3158
3178
|
`Dropped back-to-back final transcript (${(sinceLastMs / 1e3).toFixed(2)}s since last): ${sanitizeLogValue(normalised.slice(0, 40))}`
|
|
3159
3179
|
);
|
|
3160
3180
|
return;
|
|
@@ -3162,7 +3182,7 @@ var init_stream_handler = __esm({
|
|
|
3162
3182
|
this.lastCommitText = normalised;
|
|
3163
3183
|
this.lastCommitAt = now;
|
|
3164
3184
|
const label = this.deps.bridge.label;
|
|
3165
|
-
getLogger().
|
|
3185
|
+
getLogger().debug(`User (${label} pipeline): ${sanitizeLogValue(transcript.text)}`);
|
|
3166
3186
|
this.metricsAcc.startTurn();
|
|
3167
3187
|
this.metricsAcc.recordSttComplete(transcript.text);
|
|
3168
3188
|
if (this.deps.onTranscript) {
|
|
@@ -3177,7 +3197,7 @@ var init_stream_handler = __esm({
|
|
|
3177
3197
|
const hookCtx = this.buildHookContext();
|
|
3178
3198
|
const filteredTranscript = await hookExecutor.runAfterTranscribe(transcript.text, hookCtx);
|
|
3179
3199
|
if (filteredTranscript === null) {
|
|
3180
|
-
getLogger().
|
|
3200
|
+
getLogger().debug(`afterTranscribe hook vetoed turn (${label})`);
|
|
3181
3201
|
this.metricsAcc.recordTurnInterrupted();
|
|
3182
3202
|
return;
|
|
3183
3203
|
}
|
|
@@ -3265,7 +3285,7 @@ var init_stream_handler = __esm({
|
|
|
3265
3285
|
if (!this.llmLoop) {
|
|
3266
3286
|
const guard = checkGuardrails(responseText, this.deps.agent.guardrails);
|
|
3267
3287
|
if (guard) {
|
|
3268
|
-
getLogger().
|
|
3288
|
+
getLogger().debug(`Guardrail '${guard.name}' triggered (pipeline)`);
|
|
3269
3289
|
responseText = guard.replacement ?? "I'm sorry, I can't respond to that.";
|
|
3270
3290
|
}
|
|
3271
3291
|
this.metricsAcc.recordLlmComplete();
|
|
@@ -3343,7 +3363,7 @@ var init_stream_handler = __esm({
|
|
|
3343
3363
|
this.adapter = this.deps.buildAIAdapter(resolvedPrompt);
|
|
3344
3364
|
try {
|
|
3345
3365
|
await this.adapter.connect();
|
|
3346
|
-
getLogger().
|
|
3366
|
+
getLogger().debug(`AI adapter connected (${label})`);
|
|
3347
3367
|
} catch (e) {
|
|
3348
3368
|
getLogger().error(`AI adapter connect FAILED (${label}):`, e);
|
|
3349
3369
|
try {
|
|
@@ -3385,7 +3405,7 @@ var init_stream_handler = __esm({
|
|
|
3385
3405
|
this.deps.bridge.sendMark(this.ws, `audio_${this.chunkCount}`, this.streamSid);
|
|
3386
3406
|
} else if (type === "transcript_input") {
|
|
3387
3407
|
const inputText = eventData;
|
|
3388
|
-
getLogger().
|
|
3408
|
+
getLogger().debug(`User (${this.deps.bridge.label}): ${sanitizeLogValue(inputText)}`);
|
|
3389
3409
|
this.history.push({ role: "user", text: inputText, timestamp: Date.now() });
|
|
3390
3410
|
this.metricsAcc.startTurn();
|
|
3391
3411
|
this.currentAgentText = "";
|
|
@@ -3403,7 +3423,7 @@ var init_stream_handler = __esm({
|
|
|
3403
3423
|
if (outputText) {
|
|
3404
3424
|
const triggered = checkGuardrails(outputText, this.deps.agent.guardrails);
|
|
3405
3425
|
if (triggered) {
|
|
3406
|
-
getLogger().
|
|
3426
|
+
getLogger().debug(`Guardrail '${triggered.name}' triggered`);
|
|
3407
3427
|
if (this.adapter instanceof OpenAIRealtimeAdapter) {
|
|
3408
3428
|
this.adapter.cancelResponse();
|
|
3409
3429
|
await this.adapter.sendText(triggered.replacement ?? "I'm sorry, I can't respond to that.");
|
|
@@ -3462,7 +3482,7 @@ var init_stream_handler = __esm({
|
|
|
3462
3482
|
await adapter.sendFunctionResult(fc.call_id, JSON.stringify({ error: "Invalid phone number format", status: "rejected" }));
|
|
3463
3483
|
return;
|
|
3464
3484
|
}
|
|
3465
|
-
getLogger().
|
|
3485
|
+
getLogger().debug(`Transferring call to ${transferTo}`);
|
|
3466
3486
|
await adapter.sendFunctionResult(fc.call_id, JSON.stringify({ status: "transferring", to: transferTo }));
|
|
3467
3487
|
await this.deps.bridge.transferCall(this.callId, transferTo);
|
|
3468
3488
|
if (this.deps.onTranscript) {
|
|
@@ -3478,7 +3498,7 @@ var init_stream_handler = __esm({
|
|
|
3478
3498
|
endArgs = {};
|
|
3479
3499
|
}
|
|
3480
3500
|
const reason = endArgs.reason ?? "conversation_complete";
|
|
3481
|
-
getLogger().
|
|
3501
|
+
getLogger().debug(`Ending call (${this.deps.bridge.label}): ${reason}`);
|
|
3482
3502
|
await adapter.sendFunctionResult(fc.call_id, JSON.stringify({ status: "ending", reason }));
|
|
3483
3503
|
await this.deps.bridge.endCall(this.callId, this.ws);
|
|
3484
3504
|
if (this.deps.onTranscript) {
|
|
@@ -3530,6 +3550,11 @@ var init_stream_handler = __esm({
|
|
|
3530
3550
|
transcript: [...this.history.entries],
|
|
3531
3551
|
metrics: finalMetrics
|
|
3532
3552
|
};
|
|
3553
|
+
const cost = finalMetrics.cost?.total ?? 0;
|
|
3554
|
+
const latencyP95 = finalMetrics.latency_p95?.total_ms ?? 0;
|
|
3555
|
+
getLogger().info(
|
|
3556
|
+
`Call ended: ${this.callId} (${finalMetrics.duration_seconds.toFixed(1)}s, ${finalMetrics.turns.length} turns, cost=$${cost.toFixed(4)}, p95=${Math.round(latencyP95)}ms)`
|
|
3557
|
+
);
|
|
3533
3558
|
this.deps.metricsStore.recordCallEnd(
|
|
3534
3559
|
callEndData,
|
|
3535
3560
|
finalMetrics
|
|
@@ -3631,7 +3656,7 @@ function buildAIAdapter(config, agent, resolvedPrompt) {
|
|
|
3631
3656
|
return new ElevenLabsConvAIAdapter(
|
|
3632
3657
|
engine.apiKey,
|
|
3633
3658
|
engine.agentId,
|
|
3634
|
-
agent.voice ?? "
|
|
3659
|
+
agent.voice ?? "EXAVITQu4vr4xnSDxMaL",
|
|
3635
3660
|
"eleven_turbo_v2_5",
|
|
3636
3661
|
agent.language ?? "en",
|
|
3637
3662
|
agent.firstMessage ?? ""
|
|
@@ -3978,14 +4003,8 @@ var init_server = __esm({
|
|
|
3978
4003
|
res.json({ status: "ok", mode: "local" });
|
|
3979
4004
|
});
|
|
3980
4005
|
if (this.dashboard) {
|
|
3981
|
-
if (!this.dashboardToken) {
|
|
3982
|
-
getLogger().warn(
|
|
3983
|
-
"Dashboard is enabled without authentication. Set dashboardToken to protect call data. This is safe for local development but should not be exposed on a public network."
|
|
3984
|
-
);
|
|
3985
|
-
}
|
|
3986
4006
|
mountDashboard(app, this.metricsStore, this.dashboardToken);
|
|
3987
4007
|
mountApi(app, this.metricsStore, this.dashboardToken);
|
|
3988
|
-
getLogger().info("Dashboard: http://127.0.0.1:" + port + "/");
|
|
3989
4008
|
}
|
|
3990
4009
|
app.post("/webhooks/twilio/status", (req, res) => {
|
|
3991
4010
|
if (this.config.twilioToken) {
|
|
@@ -4202,7 +4221,6 @@ var init_server = __esm({
|
|
|
4202
4221
|
socket.destroy();
|
|
4203
4222
|
return;
|
|
4204
4223
|
}
|
|
4205
|
-
getLogger().info(`Upgrade request: ${req.url}`);
|
|
4206
4224
|
this.wss.handleUpgrade(req, socket, head, (ws) => {
|
|
4207
4225
|
wsConnectionsByIp.set(remoteIp, (wsConnectionsByIp.get(remoteIp) ?? 0) + 1);
|
|
4208
4226
|
ws.once("close", () => {
|
|
@@ -4218,7 +4236,6 @@ var init_server = __esm({
|
|
|
4218
4236
|
});
|
|
4219
4237
|
this.wss.on("connection", (ws, req) => {
|
|
4220
4238
|
const url = new URL(req.url ?? "", `http://localhost`);
|
|
4221
|
-
getLogger().info(`WebSocket connected: ${req.url}`);
|
|
4222
4239
|
this.activeConnections.add(ws);
|
|
4223
4240
|
ws.once("close", () => {
|
|
4224
4241
|
this.activeConnections.delete(ws);
|
|
@@ -4232,19 +4249,19 @@ var init_server = __esm({
|
|
|
4232
4249
|
});
|
|
4233
4250
|
await new Promise((resolve) => {
|
|
4234
4251
|
this.server.listen(port, "127.0.0.1", () => {
|
|
4235
|
-
getLogger().info(`
|
|
4236
|
-
\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557
|
|
4237
|
-
\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557
|
|
4238
|
-
\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D
|
|
4239
|
-
\u2588\u2588\u2554\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557
|
|
4240
|
-
\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551
|
|
4241
|
-
\u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D
|
|
4242
|
-
|
|
4243
|
-
Connect AI agents to phone numbers in 4 lines of code
|
|
4244
|
-
`);
|
|
4245
4252
|
getLogger().info(`Server on port ${port}`);
|
|
4246
4253
|
getLogger().info(`Webhook: https://${this.config.webhookUrl}`);
|
|
4247
|
-
getLogger().info(`Phone:
|
|
4254
|
+
getLogger().info(`Phone: ${this.config.phoneNumber}`);
|
|
4255
|
+
if (this.dashboard) {
|
|
4256
|
+
console.log("\n\u2500\u2500\u2500\u2500 Dashboard \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
4257
|
+
getLogger().info(`URL: http://127.0.0.1:${port}/`);
|
|
4258
|
+
if (!this.dashboardToken) {
|
|
4259
|
+
getLogger().warn(
|
|
4260
|
+
"Dashboard is enabled without authentication. Set dashboardToken to protect call data. This is safe for local development but should not be exposed on a public network."
|
|
4261
|
+
);
|
|
4262
|
+
}
|
|
4263
|
+
console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n");
|
|
4264
|
+
}
|
|
4248
4265
|
resolve();
|
|
4249
4266
|
});
|
|
4250
4267
|
});
|
|
@@ -4290,7 +4307,6 @@ Connect AI agents to phone numbers in 4 lines of code
|
|
|
4290
4307
|
return;
|
|
4291
4308
|
}
|
|
4292
4309
|
const event = data.event;
|
|
4293
|
-
getLogger().info(`WS event: ${event}`);
|
|
4294
4310
|
if (event === "start") {
|
|
4295
4311
|
handler.setStreamSid(data.streamSid ?? "");
|
|
4296
4312
|
const callSid = data.start?.callSid ?? "";
|
|
@@ -4336,7 +4352,6 @@ Connect AI agents to phone numbers in 4 lines of code
|
|
|
4336
4352
|
}
|
|
4337
4353
|
const event = data.event ?? "";
|
|
4338
4354
|
if (event === "connected") return;
|
|
4339
|
-
getLogger().info(`Telnyx event: ${event}`);
|
|
4340
4355
|
if (event === "start" && !streamStarted) {
|
|
4341
4356
|
streamStarted = true;
|
|
4342
4357
|
const callControlId = data.start?.call_control_id ?? "";
|
|
@@ -4438,829 +4453,28 @@ Connect AI agents to phone numbers in 4 lines of code
|
|
|
4438
4453
|
}
|
|
4439
4454
|
});
|
|
4440
4455
|
|
|
4441
|
-
//
|
|
4442
|
-
var
|
|
4443
|
-
|
|
4444
|
-
|
|
4445
|
-
var __create2 = Object.create;
|
|
4446
|
-
var __defProp2 = Object.defineProperty;
|
|
4447
|
-
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
4448
|
-
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
4449
|
-
var __getProtoOf2 = Object.getPrototypeOf;
|
|
4450
|
-
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
4451
|
-
var __export2 = (target, all) => {
|
|
4452
|
-
for (var name in all)
|
|
4453
|
-
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
4454
|
-
};
|
|
4455
|
-
var __copyProps2 = (to, from, except, desc) => {
|
|
4456
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
4457
|
-
for (let key of __getOwnPropNames2(from))
|
|
4458
|
-
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
4459
|
-
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
4460
|
-
}
|
|
4461
|
-
return to;
|
|
4462
|
-
};
|
|
4463
|
-
var __toESM2 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__getProtoOf2(mod)) : {}, __copyProps2(
|
|
4464
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
4465
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
4466
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
4467
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
4468
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", { value: mod, enumerable: true }) : target,
|
|
4469
|
-
mod
|
|
4470
|
-
));
|
|
4471
|
-
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
4472
|
-
var constants_exports = {};
|
|
4473
|
-
__export2(constants_exports, {
|
|
4474
|
-
CLOUDFLARED_VERSION: () => CLOUDFLARED_VERSION,
|
|
4475
|
-
DEFAULT_CLOUDFLARED_BIN: () => DEFAULT_CLOUDFLARED_BIN,
|
|
4476
|
-
RELEASE_BASE: () => RELEASE_BASE,
|
|
4477
|
-
bin: () => bin,
|
|
4478
|
-
use: () => use
|
|
4479
|
-
});
|
|
4480
|
-
module2.exports = __toCommonJS2(constants_exports);
|
|
4481
|
-
var import_node_path = __toESM2(require("path"));
|
|
4482
|
-
var DEFAULT_CLOUDFLARED_BIN = import_node_path.default.join(
|
|
4483
|
-
__dirname,
|
|
4484
|
-
"..",
|
|
4485
|
-
"bin",
|
|
4486
|
-
process.platform === "win32" ? "cloudflared.exe" : "cloudflared"
|
|
4487
|
-
);
|
|
4488
|
-
var bin = process.env.CLOUDFLARED_BIN || DEFAULT_CLOUDFLARED_BIN;
|
|
4489
|
-
function use(executable) {
|
|
4490
|
-
bin = executable;
|
|
4491
|
-
}
|
|
4492
|
-
var CLOUDFLARED_VERSION = process.env.CLOUDFLARED_VERSION || "latest";
|
|
4493
|
-
var RELEASE_BASE = "https://github.com/cloudflare/cloudflared/releases/";
|
|
4494
|
-
}
|
|
4495
|
-
});
|
|
4496
|
-
|
|
4497
|
-
// node_modules/cloudflared/lib/error.js
|
|
4498
|
-
var require_error = __commonJS({
|
|
4499
|
-
"node_modules/cloudflared/lib/error.js"(exports2, module2) {
|
|
4500
|
-
"use strict";
|
|
4501
|
-
var __defProp2 = Object.defineProperty;
|
|
4502
|
-
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
4503
|
-
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
4504
|
-
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
4505
|
-
var __export2 = (target, all) => {
|
|
4506
|
-
for (var name in all)
|
|
4507
|
-
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
4508
|
-
};
|
|
4509
|
-
var __copyProps2 = (to, from, except, desc) => {
|
|
4510
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
4511
|
-
for (let key of __getOwnPropNames2(from))
|
|
4512
|
-
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
4513
|
-
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
4514
|
-
}
|
|
4515
|
-
return to;
|
|
4516
|
-
};
|
|
4517
|
-
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
4518
|
-
var error_exports = {};
|
|
4519
|
-
__export2(error_exports, {
|
|
4520
|
-
UnsupportedError: () => UnsupportedError
|
|
4521
|
-
});
|
|
4522
|
-
module2.exports = __toCommonJS2(error_exports);
|
|
4523
|
-
var UnsupportedError = class extends Error {
|
|
4524
|
-
constructor(message) {
|
|
4525
|
-
super(message);
|
|
4526
|
-
}
|
|
4527
|
-
};
|
|
4528
|
-
}
|
|
4456
|
+
// src/banner.ts
|
|
4457
|
+
var banner_exports = {};
|
|
4458
|
+
__export(banner_exports, {
|
|
4459
|
+
showBanner: () => showBanner
|
|
4529
4460
|
});
|
|
4530
|
-
|
|
4531
|
-
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
var __defProp2 = Object.defineProperty;
|
|
4537
|
-
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
4538
|
-
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
4539
|
-
var __getProtoOf2 = Object.getPrototypeOf;
|
|
4540
|
-
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
4541
|
-
var __export2 = (target, all) => {
|
|
4542
|
-
for (var name in all)
|
|
4543
|
-
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
4544
|
-
};
|
|
4545
|
-
var __copyProps2 = (to, from, except, desc) => {
|
|
4546
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
4547
|
-
for (let key of __getOwnPropNames2(from))
|
|
4548
|
-
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
4549
|
-
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
4550
|
-
}
|
|
4551
|
-
return to;
|
|
4552
|
-
};
|
|
4553
|
-
var __toESM2 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__getProtoOf2(mod)) : {}, __copyProps2(
|
|
4554
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
4555
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
4556
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
4557
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
4558
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", { value: mod, enumerable: true }) : target,
|
|
4559
|
-
mod
|
|
4560
|
-
));
|
|
4561
|
-
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
4562
|
-
var install_exports = {};
|
|
4563
|
-
__export2(install_exports, {
|
|
4564
|
-
install: () => install,
|
|
4565
|
-
install_linux: () => install_linux,
|
|
4566
|
-
install_macos: () => install_macos,
|
|
4567
|
-
install_windows: () => install_windows
|
|
4568
|
-
});
|
|
4569
|
-
module2.exports = __toCommonJS2(install_exports);
|
|
4570
|
-
var import_node_fs = __toESM2(require("fs"));
|
|
4571
|
-
var import_node_path = __toESM2(require("path"));
|
|
4572
|
-
var import_node_https = __toESM2(require("https"));
|
|
4573
|
-
var import_node_child_process = require("child_process");
|
|
4574
|
-
var import_constants = require_constants();
|
|
4575
|
-
var import_error = require_error();
|
|
4576
|
-
var LINUX_URL = {
|
|
4577
|
-
arm64: "cloudflared-linux-arm64",
|
|
4578
|
-
arm: "cloudflared-linux-arm",
|
|
4579
|
-
x64: "cloudflared-linux-amd64",
|
|
4580
|
-
ia32: "cloudflared-linux-386"
|
|
4581
|
-
};
|
|
4582
|
-
var MACOS_URL = {
|
|
4583
|
-
arm64: "cloudflared-darwin-arm64.tgz",
|
|
4584
|
-
x64: "cloudflared-darwin-amd64.tgz"
|
|
4585
|
-
};
|
|
4586
|
-
var WINDOWS_URL = {
|
|
4587
|
-
x64: "cloudflared-windows-amd64.exe",
|
|
4588
|
-
ia32: "cloudflared-windows-386.exe"
|
|
4589
|
-
};
|
|
4590
|
-
function resolve_base(version2) {
|
|
4591
|
-
if (version2 === "latest") {
|
|
4592
|
-
return `${import_constants.RELEASE_BASE}latest/download/`;
|
|
4593
|
-
}
|
|
4594
|
-
return `${import_constants.RELEASE_BASE}download/${version2}/`;
|
|
4595
|
-
}
|
|
4596
|
-
async function install(to, version2 = import_constants.CLOUDFLARED_VERSION) {
|
|
4597
|
-
if (process.platform === "linux") {
|
|
4598
|
-
return install_linux(to, version2);
|
|
4599
|
-
} else if (process.platform === "darwin") {
|
|
4600
|
-
return install_macos(to, version2);
|
|
4601
|
-
} else if (process.platform === "win32") {
|
|
4602
|
-
return install_windows(to, version2);
|
|
4603
|
-
} else {
|
|
4604
|
-
throw new import_error.UnsupportedError("Unsupported platform: " + process.platform);
|
|
4605
|
-
}
|
|
4606
|
-
}
|
|
4607
|
-
async function install_linux(to, version2 = import_constants.CLOUDFLARED_VERSION) {
|
|
4608
|
-
const file = LINUX_URL[process.arch];
|
|
4609
|
-
if (file === void 0) {
|
|
4610
|
-
throw new import_error.UnsupportedError("Unsupported architecture: " + process.arch);
|
|
4611
|
-
}
|
|
4612
|
-
await download(resolve_base(version2) + file, to);
|
|
4613
|
-
import_node_fs.default.chmodSync(to, "755");
|
|
4614
|
-
return to;
|
|
4615
|
-
}
|
|
4616
|
-
async function install_macos(to, version2 = import_constants.CLOUDFLARED_VERSION) {
|
|
4617
|
-
let arch = process.arch;
|
|
4618
|
-
if (version2 !== "latest" && version_number(version2) < 20240802) {
|
|
4619
|
-
arch = "x64";
|
|
4620
|
-
}
|
|
4621
|
-
const file = MACOS_URL[arch];
|
|
4622
|
-
if (file === void 0) {
|
|
4623
|
-
throw new import_error.UnsupportedError("Unsupported architecture: " + arch);
|
|
4624
|
-
}
|
|
4625
|
-
await download(resolve_base(version2) + file, `${to}.tgz`);
|
|
4626
|
-
process.env.VERBOSE && console.log(`Extracting to ${to}`);
|
|
4627
|
-
(0, import_node_child_process.execSync)(`tar -xzf ${import_node_path.default.basename(`${to}.tgz`)}`, { cwd: import_node_path.default.dirname(to) });
|
|
4628
|
-
import_node_fs.default.unlinkSync(`${to}.tgz`);
|
|
4629
|
-
import_node_fs.default.renameSync(`${import_node_path.default.dirname(to)}/cloudflared`, to);
|
|
4630
|
-
return to;
|
|
4631
|
-
}
|
|
4632
|
-
async function install_windows(to, version2 = import_constants.CLOUDFLARED_VERSION) {
|
|
4633
|
-
const file = WINDOWS_URL[process.arch];
|
|
4634
|
-
if (file === void 0) {
|
|
4635
|
-
throw new import_error.UnsupportedError("Unsupported architecture: " + process.arch);
|
|
4636
|
-
}
|
|
4637
|
-
await download(resolve_base(version2) + file, to);
|
|
4638
|
-
return to;
|
|
4639
|
-
}
|
|
4640
|
-
function download(url, to, redirect = 0) {
|
|
4641
|
-
if (redirect === 0) {
|
|
4642
|
-
process.env.VERBOSE && console.log(`Downloading ${url} to ${to}`);
|
|
4643
|
-
} else {
|
|
4644
|
-
process.env.VERBOSE && console.log(`Redirecting to ${url}`);
|
|
4645
|
-
}
|
|
4646
|
-
if (!import_node_fs.default.existsSync(import_node_path.default.dirname(to))) {
|
|
4647
|
-
import_node_fs.default.mkdirSync(import_node_path.default.dirname(to), { recursive: true });
|
|
4648
|
-
}
|
|
4649
|
-
return new Promise((resolve, reject) => {
|
|
4650
|
-
const request = import_node_https.default.get(url, (res) => {
|
|
4651
|
-
const redirect_code = [301, 302, 303, 307, 308];
|
|
4652
|
-
if (redirect_code.includes(res.statusCode) && res.headers.location !== void 0) {
|
|
4653
|
-
request.destroy();
|
|
4654
|
-
const redirection = res.headers.location;
|
|
4655
|
-
resolve(download(redirection, to, redirect + 1));
|
|
4656
|
-
return;
|
|
4657
|
-
}
|
|
4658
|
-
if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
|
|
4659
|
-
const file = import_node_fs.default.createWriteStream(to);
|
|
4660
|
-
file.on("finish", () => {
|
|
4661
|
-
file.close(() => resolve(to));
|
|
4662
|
-
});
|
|
4663
|
-
file.on("error", (err) => {
|
|
4664
|
-
import_node_fs.default.unlink(to, () => reject(err));
|
|
4665
|
-
});
|
|
4666
|
-
res.pipe(file);
|
|
4667
|
-
} else {
|
|
4668
|
-
request.destroy();
|
|
4669
|
-
reject(new Error(`HTTP response with status code: ${res.statusCode}`));
|
|
4670
|
-
}
|
|
4671
|
-
});
|
|
4672
|
-
request.on("error", (err) => {
|
|
4673
|
-
reject(err);
|
|
4674
|
-
});
|
|
4675
|
-
request.end();
|
|
4676
|
-
});
|
|
4677
|
-
}
|
|
4678
|
-
function version_number(semver) {
|
|
4679
|
-
const [major, minor, patch] = semver.split(".").map(Number);
|
|
4680
|
-
return major * 1e4 + minor * 100 + patch;
|
|
4681
|
-
}
|
|
4682
|
-
}
|
|
4683
|
-
});
|
|
4684
|
-
|
|
4685
|
-
// node_modules/cloudflared/lib/regex.js
|
|
4686
|
-
var require_regex = __commonJS({
|
|
4687
|
-
"node_modules/cloudflared/lib/regex.js"(exports2, module2) {
|
|
4688
|
-
"use strict";
|
|
4689
|
-
var __defProp2 = Object.defineProperty;
|
|
4690
|
-
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
4691
|
-
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
4692
|
-
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
4693
|
-
var __export2 = (target, all) => {
|
|
4694
|
-
for (var name in all)
|
|
4695
|
-
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
4696
|
-
};
|
|
4697
|
-
var __copyProps2 = (to, from, except, desc) => {
|
|
4698
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
4699
|
-
for (let key of __getOwnPropNames2(from))
|
|
4700
|
-
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
4701
|
-
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
4702
|
-
}
|
|
4703
|
-
return to;
|
|
4704
|
-
};
|
|
4705
|
-
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
4706
|
-
var regex_exports = {};
|
|
4707
|
-
__export2(regex_exports, {
|
|
4708
|
-
config_regex: () => config_regex,
|
|
4709
|
-
conn_regex: () => conn_regex,
|
|
4710
|
-
connectorID_regex: () => connectorID_regex,
|
|
4711
|
-
disconnect_regex: () => disconnect_regex,
|
|
4712
|
-
index_regex: () => index_regex,
|
|
4713
|
-
ip_regex: () => ip_regex,
|
|
4714
|
-
location_regex: () => location_regex,
|
|
4715
|
-
metrics_regex: () => metrics_regex,
|
|
4716
|
-
tunnelID_regex: () => tunnelID_regex
|
|
4717
|
-
});
|
|
4718
|
-
module2.exports = __toCommonJS2(regex_exports);
|
|
4719
|
-
var conn_regex = /connection[= ]([0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12})/i;
|
|
4720
|
-
var ip_regex = /ip=([0-9.]+)/;
|
|
4721
|
-
var location_regex = /location=([A-Za-z0-9]+)/;
|
|
4722
|
-
var index_regex = /connIndex=(\d)/;
|
|
4723
|
-
var disconnect_regex = /Unregistered tunnel connection connIndex=(\d)/i;
|
|
4724
|
-
var tunnelID_regex = /tunnelID=([0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12})/i;
|
|
4725
|
-
var connectorID_regex = /Connector ID: ([0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12})/i;
|
|
4726
|
-
var metrics_regex = /metrics server on ([0-9.:]+\/metrics)/;
|
|
4727
|
-
var config_regex = /config="(.+[^\\])"/;
|
|
4728
|
-
}
|
|
4729
|
-
});
|
|
4730
|
-
|
|
4731
|
-
// node_modules/cloudflared/lib/handler.js
|
|
4732
|
-
var require_handler = __commonJS({
|
|
4733
|
-
"node_modules/cloudflared/lib/handler.js"(exports2, module2) {
|
|
4734
|
-
"use strict";
|
|
4735
|
-
var __defProp2 = Object.defineProperty;
|
|
4736
|
-
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
4737
|
-
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
4738
|
-
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
4739
|
-
var __export2 = (target, all) => {
|
|
4740
|
-
for (var name in all)
|
|
4741
|
-
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
4742
|
-
};
|
|
4743
|
-
var __copyProps2 = (to, from, except, desc) => {
|
|
4744
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
4745
|
-
for (let key of __getOwnPropNames2(from))
|
|
4746
|
-
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
4747
|
-
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
4748
|
-
}
|
|
4749
|
-
return to;
|
|
4750
|
-
};
|
|
4751
|
-
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
4752
|
-
var handler_exports = {};
|
|
4753
|
-
__export2(handler_exports, {
|
|
4754
|
-
ConfigHandler: () => ConfigHandler,
|
|
4755
|
-
ConnectionHandler: () => ConnectionHandler,
|
|
4756
|
-
TryCloudflareHandler: () => TryCloudflareHandler
|
|
4757
|
-
});
|
|
4758
|
-
module2.exports = __toCommonJS2(handler_exports);
|
|
4759
|
-
var import_node_stream = require("stream");
|
|
4760
|
-
var import_regex2 = require_regex();
|
|
4761
|
-
var ConnectionHandler = class {
|
|
4762
|
-
constructor(tunnel) {
|
|
4763
|
-
this.connections = [];
|
|
4764
|
-
this.connected_handler = (output, tunnel2) => {
|
|
4765
|
-
const conn_match = output.match(import_regex2.conn_regex);
|
|
4766
|
-
const ip_match = output.match(import_regex2.ip_regex);
|
|
4767
|
-
const location_match = output.match(import_regex2.location_regex);
|
|
4768
|
-
const index_match = output.match(import_regex2.index_regex);
|
|
4769
|
-
if (conn_match && ip_match && location_match && index_match) {
|
|
4770
|
-
const connection = {
|
|
4771
|
-
id: conn_match[1],
|
|
4772
|
-
ip: ip_match[1],
|
|
4773
|
-
location: location_match[1]
|
|
4774
|
-
};
|
|
4775
|
-
this.connections[Number(index_match[1])] = connection;
|
|
4776
|
-
tunnel2.emit("connected", connection);
|
|
4777
|
-
}
|
|
4778
|
-
};
|
|
4779
|
-
this.disconnected_handler = (output, tunnel2) => {
|
|
4780
|
-
const index_match = output.includes("terminated") ? output.match(import_regex2.index_regex) : null;
|
|
4781
|
-
if (index_match) {
|
|
4782
|
-
const index = Number(index_match[1]);
|
|
4783
|
-
if (this.connections[index]) {
|
|
4784
|
-
tunnel2.emit("disconnected", this.connections[index]);
|
|
4785
|
-
this.connections[index] = void 0;
|
|
4786
|
-
}
|
|
4787
|
-
}
|
|
4788
|
-
};
|
|
4789
|
-
tunnel.addHandler(this.connected_handler.bind(this));
|
|
4790
|
-
tunnel.addHandler(this.disconnected_handler.bind(this));
|
|
4791
|
-
}
|
|
4792
|
-
};
|
|
4793
|
-
var TryCloudflareHandler = class {
|
|
4794
|
-
constructor(tunnel) {
|
|
4795
|
-
this.url_handler = (output, tunnel2) => {
|
|
4796
|
-
const url_match = output.match(/https:\/\/([a-z0-9-]+)\.trycloudflare\.com/);
|
|
4797
|
-
if (url_match) {
|
|
4798
|
-
tunnel2.emit("url", url_match[0]);
|
|
4799
|
-
}
|
|
4800
|
-
};
|
|
4801
|
-
tunnel.addHandler(this.url_handler.bind(this));
|
|
4802
|
-
}
|
|
4803
|
-
};
|
|
4804
|
-
var ConfigHandler = class extends import_node_stream.EventEmitter {
|
|
4805
|
-
constructor(tunnel) {
|
|
4806
|
-
super();
|
|
4807
|
-
this.config_handler = (output, tunnel2) => {
|
|
4808
|
-
const config_match = output.match(/\bconfig="(.+?)" version=(\d+)/);
|
|
4809
|
-
if (config_match) {
|
|
4810
|
-
try {
|
|
4811
|
-
const config_str = config_match[1].replace(/\\"/g, '"');
|
|
4812
|
-
const config = JSON.parse(config_str);
|
|
4813
|
-
const version2 = parseInt(config_match[2], 10);
|
|
4814
|
-
this.emit("config", {
|
|
4815
|
-
config,
|
|
4816
|
-
version: version2
|
|
4817
|
-
});
|
|
4818
|
-
if (config && typeof config === "object" && "ingress" in config && Array.isArray(config.ingress)) {
|
|
4819
|
-
for (const ingress of config.ingress) {
|
|
4820
|
-
if ("hostname" in ingress) {
|
|
4821
|
-
tunnel2.emit("url", ingress.hostname);
|
|
4822
|
-
}
|
|
4823
|
-
}
|
|
4824
|
-
}
|
|
4825
|
-
} catch (error) {
|
|
4826
|
-
this.emit("error", new Error(`Failed to parse config: ${error}`));
|
|
4827
|
-
}
|
|
4828
|
-
}
|
|
4829
|
-
};
|
|
4830
|
-
tunnel.addHandler(this.config_handler.bind(this));
|
|
4831
|
-
}
|
|
4832
|
-
on(event, listener) {
|
|
4833
|
-
return super.on(event, listener);
|
|
4834
|
-
}
|
|
4835
|
-
once(event, listener) {
|
|
4836
|
-
return super.once(event, listener);
|
|
4837
|
-
}
|
|
4838
|
-
off(event, listener) {
|
|
4839
|
-
return super.off(event, listener);
|
|
4840
|
-
}
|
|
4841
|
-
emit(event, ...args) {
|
|
4842
|
-
return super.emit(event, ...args);
|
|
4843
|
-
}
|
|
4844
|
-
};
|
|
4845
|
-
}
|
|
4846
|
-
});
|
|
4847
|
-
|
|
4848
|
-
// node_modules/cloudflared/lib/tunnel.js
|
|
4849
|
-
var require_tunnel = __commonJS({
|
|
4850
|
-
"node_modules/cloudflared/lib/tunnel.js"(exports2, module2) {
|
|
4851
|
-
"use strict";
|
|
4852
|
-
var __defProp2 = Object.defineProperty;
|
|
4853
|
-
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
4854
|
-
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
4855
|
-
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
4856
|
-
var __export2 = (target, all) => {
|
|
4857
|
-
for (var name in all)
|
|
4858
|
-
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
4859
|
-
};
|
|
4860
|
-
var __copyProps2 = (to, from, except, desc) => {
|
|
4861
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
4862
|
-
for (let key of __getOwnPropNames2(from))
|
|
4863
|
-
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
4864
|
-
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
4865
|
-
}
|
|
4866
|
-
return to;
|
|
4867
|
-
};
|
|
4868
|
-
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
4869
|
-
var tunnel_exports2 = {};
|
|
4870
|
-
__export2(tunnel_exports2, {
|
|
4871
|
-
Tunnel: () => Tunnel,
|
|
4872
|
-
build_args: () => build_args,
|
|
4873
|
-
build_options: () => build_options,
|
|
4874
|
-
tunnel: () => tunnel
|
|
4875
|
-
});
|
|
4876
|
-
module2.exports = __toCommonJS2(tunnel_exports2);
|
|
4877
|
-
var import_node_child_process = require("child_process");
|
|
4878
|
-
var import_node_events = require("events");
|
|
4879
|
-
var import_constants = require_constants();
|
|
4880
|
-
var import_handler = require_handler();
|
|
4881
|
-
var Tunnel = class _Tunnel extends import_node_events.EventEmitter {
|
|
4882
|
-
constructor(options = ["tunnel", "--hello-world"]) {
|
|
4883
|
-
super();
|
|
4884
|
-
this.outputHandlers = [];
|
|
4885
|
-
this.stop = this._stop.bind(this);
|
|
4886
|
-
this.setupDefaultHandlers();
|
|
4887
|
-
const args = Array.isArray(options) ? options : build_args(options);
|
|
4888
|
-
this._process = this.createProcess(args);
|
|
4889
|
-
this.setupEventHandlers();
|
|
4890
|
-
}
|
|
4891
|
-
get process() {
|
|
4892
|
-
return this._process;
|
|
4893
|
-
}
|
|
4894
|
-
setupDefaultHandlers() {
|
|
4895
|
-
new import_handler.ConnectionHandler(this);
|
|
4896
|
-
new import_handler.TryCloudflareHandler(this);
|
|
4897
|
-
}
|
|
4898
|
-
/**
|
|
4899
|
-
* Add a custom output handler
|
|
4900
|
-
* @param handler Function to handle cloudflared output
|
|
4901
|
-
*/
|
|
4902
|
-
addHandler(handler) {
|
|
4903
|
-
this.outputHandlers.push(handler);
|
|
4904
|
-
}
|
|
4905
|
-
/**
|
|
4906
|
-
* Remove a previously added output handler
|
|
4907
|
-
* @param handler The handler to remove
|
|
4908
|
-
*/
|
|
4909
|
-
removeHandler(handler) {
|
|
4910
|
-
const index = this.outputHandlers.indexOf(handler);
|
|
4911
|
-
if (index !== -1) {
|
|
4912
|
-
this.outputHandlers.splice(index, 1);
|
|
4913
|
-
}
|
|
4914
|
-
}
|
|
4915
|
-
processOutput(output) {
|
|
4916
|
-
for (const handler of this.outputHandlers) {
|
|
4917
|
-
try {
|
|
4918
|
-
handler(output, this);
|
|
4919
|
-
} catch (error) {
|
|
4920
|
-
this.emit("error", error instanceof Error ? error : new Error(String(error)));
|
|
4921
|
-
}
|
|
4922
|
-
}
|
|
4923
|
-
}
|
|
4924
|
-
setupEventHandlers() {
|
|
4925
|
-
this.on("stdout", (output) => {
|
|
4926
|
-
this.processOutput(output);
|
|
4927
|
-
});
|
|
4928
|
-
this.on("stderr", (output) => {
|
|
4929
|
-
this.processOutput(output);
|
|
4930
|
-
});
|
|
4931
|
-
}
|
|
4932
|
-
createProcess(args) {
|
|
4933
|
-
var _a, _b;
|
|
4934
|
-
const child = (0, import_node_child_process.spawn)(import_constants.bin, args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
4935
|
-
child.on("error", (error) => this.emit("error", error));
|
|
4936
|
-
child.on("exit", (code, signal) => this.emit("exit", code, signal));
|
|
4937
|
-
if (process.env.VERBOSE) {
|
|
4938
|
-
child.stdout.pipe(process.stdout);
|
|
4939
|
-
child.stderr.pipe(process.stderr);
|
|
4940
|
-
}
|
|
4941
|
-
(_a = child.stdout) == null ? void 0 : _a.on("data", (data) => this.emit("stdout", data.toString()));
|
|
4942
|
-
(_b = child.stderr) == null ? void 0 : _b.on("data", (data) => this.emit("stderr", data.toString()));
|
|
4943
|
-
return child;
|
|
4944
|
-
}
|
|
4945
|
-
_stop() {
|
|
4946
|
-
return this.process.kill("SIGINT");
|
|
4947
|
-
}
|
|
4948
|
-
on(event, listener) {
|
|
4949
|
-
return super.on(event, listener);
|
|
4950
|
-
}
|
|
4951
|
-
once(event, listener) {
|
|
4952
|
-
return super.once(event, listener);
|
|
4953
|
-
}
|
|
4954
|
-
off(event, listener) {
|
|
4955
|
-
return super.off(event, listener);
|
|
4956
|
-
}
|
|
4957
|
-
emit(event, ...args) {
|
|
4958
|
-
return super.emit(event, ...args);
|
|
4959
|
-
}
|
|
4960
|
-
/**
|
|
4961
|
-
* Create a quick tunnel without a Cloudflare account.
|
|
4962
|
-
* @param url The local service URL to connect to. If not provided, the hello world mode will be used.
|
|
4963
|
-
* @param options The options to pass to cloudflared.
|
|
4964
|
-
*/
|
|
4965
|
-
static quick(url, options = {}) {
|
|
4966
|
-
const args = ["tunnel"];
|
|
4967
|
-
if (url) {
|
|
4968
|
-
args.push("--url", url);
|
|
4969
|
-
} else {
|
|
4970
|
-
args.push("--hello-world");
|
|
4971
|
-
}
|
|
4972
|
-
args.push(...build_options(options));
|
|
4973
|
-
return new _Tunnel(args);
|
|
4974
|
-
}
|
|
4975
|
-
/**
|
|
4976
|
-
* Create a tunnel with a Cloudflare account.
|
|
4977
|
-
* @param token The Cloudflare Tunnel token.
|
|
4978
|
-
* @param options The options to pass to cloudflared.
|
|
4979
|
-
*/
|
|
4980
|
-
static withToken(token, options = {}) {
|
|
4981
|
-
options["--token"] = token;
|
|
4982
|
-
return new _Tunnel(build_args(options));
|
|
4983
|
-
}
|
|
4984
|
-
};
|
|
4985
|
-
function tunnel(options = {}) {
|
|
4986
|
-
return new Tunnel(options);
|
|
4987
|
-
}
|
|
4988
|
-
function build_args(options) {
|
|
4989
|
-
const args = "--hello-world" in options ? ["tunnel"] : ["tunnel", "run"];
|
|
4990
|
-
args.push(...build_options(options));
|
|
4991
|
-
return args;
|
|
4992
|
-
}
|
|
4993
|
-
function build_options(options) {
|
|
4994
|
-
const opts = [];
|
|
4995
|
-
for (const [key, value] of Object.entries(options)) {
|
|
4996
|
-
if (typeof value === "string") {
|
|
4997
|
-
opts.push(`${key}`, value);
|
|
4998
|
-
} else if (typeof value === "number") {
|
|
4999
|
-
opts.push(`${key}`, value.toString());
|
|
5000
|
-
} else if (typeof value === "boolean") {
|
|
5001
|
-
if (value === true) {
|
|
5002
|
-
opts.push(`${key}`);
|
|
5003
|
-
}
|
|
5004
|
-
}
|
|
5005
|
-
}
|
|
5006
|
-
return opts;
|
|
5007
|
-
}
|
|
5008
|
-
}
|
|
5009
|
-
});
|
|
5010
|
-
|
|
5011
|
-
// node_modules/cloudflared/lib/service.js
|
|
5012
|
-
var require_service = __commonJS({
|
|
5013
|
-
"node_modules/cloudflared/lib/service.js"(exports2, module2) {
|
|
4461
|
+
function showBanner() {
|
|
4462
|
+
console.log("\n" + BANNER);
|
|
4463
|
+
}
|
|
4464
|
+
var BANNER;
|
|
4465
|
+
var init_banner = __esm({
|
|
4466
|
+
"src/banner.ts"() {
|
|
5014
4467
|
"use strict";
|
|
5015
|
-
|
|
5016
|
-
|
|
5017
|
-
|
|
5018
|
-
|
|
5019
|
-
|
|
5020
|
-
|
|
5021
|
-
|
|
5022
|
-
for (var name in all)
|
|
5023
|
-
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
5024
|
-
};
|
|
5025
|
-
var __copyProps2 = (to, from, except, desc) => {
|
|
5026
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
5027
|
-
for (let key of __getOwnPropNames2(from))
|
|
5028
|
-
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
5029
|
-
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
5030
|
-
}
|
|
5031
|
-
return to;
|
|
5032
|
-
};
|
|
5033
|
-
var __toESM2 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__getProtoOf2(mod)) : {}, __copyProps2(
|
|
5034
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
5035
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
5036
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
5037
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
5038
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", { value: mod, enumerable: true }) : target,
|
|
5039
|
-
mod
|
|
5040
|
-
));
|
|
5041
|
-
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
5042
|
-
var service_exports = {};
|
|
5043
|
-
__export2(service_exports, {
|
|
5044
|
-
AlreadyInstalledError: () => AlreadyInstalledError2,
|
|
5045
|
-
LINUX_SERVICE_PATH: () => LINUX_SERVICE_PATH,
|
|
5046
|
-
MACOS_SERVICE_PATH: () => MACOS_SERVICE_PATH2,
|
|
5047
|
-
NotInstalledError: () => NotInstalledError2,
|
|
5048
|
-
clean: () => clean,
|
|
5049
|
-
current: () => current,
|
|
5050
|
-
err: () => err,
|
|
5051
|
-
exists: () => exists,
|
|
5052
|
-
identifier: () => identifier2,
|
|
5053
|
-
install: () => install,
|
|
5054
|
-
journal: () => journal,
|
|
5055
|
-
log: () => log2,
|
|
5056
|
-
service: () => service2,
|
|
5057
|
-
service_name: () => service_name,
|
|
5058
|
-
uninstall: () => uninstall
|
|
5059
|
-
});
|
|
5060
|
-
module2.exports = __toCommonJS2(service_exports);
|
|
5061
|
-
var import_node_os = __toESM2(require("os"));
|
|
5062
|
-
var import_node_fs = __toESM2(require("fs"));
|
|
5063
|
-
var import_node_child_process = require("child_process");
|
|
5064
|
-
var import_constants = require_constants();
|
|
5065
|
-
var import_regex2 = require_regex();
|
|
5066
|
-
var identifier2 = "com.cloudflare.cloudflared";
|
|
5067
|
-
var service_name = "cloudflared.service";
|
|
5068
|
-
var MACOS_SERVICE_PATH2 = {
|
|
5069
|
-
PLIST: is_root() ? `/Library/LaunchDaemons/${identifier2}.plist` : `${import_node_os.default.homedir()}/Library/LaunchAgents/${identifier2}.plist`,
|
|
5070
|
-
OUT: is_root() ? `/Library/Logs/${identifier2}.out.log` : `${import_node_os.default.homedir()}/Library/Logs/${identifier2}.out.log`,
|
|
5071
|
-
ERR: is_root() ? `/Library/Logs/${identifier2}.err.log` : `${import_node_os.default.homedir()}/Library/Logs/${identifier2}.err.log`
|
|
5072
|
-
};
|
|
5073
|
-
var LINUX_SERVICE_PATH = {
|
|
5074
|
-
SYSTEMD: `/etc/systemd/system/${service_name}`,
|
|
5075
|
-
SERVICE: "/etc/init.d/cloudflared",
|
|
5076
|
-
SERVICE_OUT: "/var/log/cloudflared.log",
|
|
5077
|
-
SERVICE_ERR: "/var/log/cloudflared.err"
|
|
5078
|
-
};
|
|
5079
|
-
var service2 = { install, uninstall, exists, log: log2, err, current, clean, journal };
|
|
5080
|
-
var AlreadyInstalledError2 = class extends Error {
|
|
5081
|
-
constructor() {
|
|
5082
|
-
super("service is already installed");
|
|
5083
|
-
}
|
|
5084
|
-
};
|
|
5085
|
-
var NotInstalledError2 = class extends Error {
|
|
5086
|
-
constructor() {
|
|
5087
|
-
super("service is not installed");
|
|
5088
|
-
}
|
|
5089
|
-
};
|
|
5090
|
-
function install(token) {
|
|
5091
|
-
if (!["darwin", "linux"].includes(process.platform)) {
|
|
5092
|
-
throw new Error(`Not Implemented on platform ${process.platform}`);
|
|
5093
|
-
}
|
|
5094
|
-
if (exists()) {
|
|
5095
|
-
throw new AlreadyInstalledError2();
|
|
5096
|
-
}
|
|
5097
|
-
const args = ["service", "install"];
|
|
5098
|
-
if (token) {
|
|
5099
|
-
args.push(token);
|
|
5100
|
-
}
|
|
5101
|
-
const result = (0, import_node_child_process.spawnSync)(import_constants.bin, args);
|
|
5102
|
-
if (result.status !== 0) {
|
|
5103
|
-
throw new Error(`service install failed: ${result.stderr.toString()}`);
|
|
5104
|
-
}
|
|
5105
|
-
}
|
|
5106
|
-
function uninstall() {
|
|
5107
|
-
if (!["darwin", "linux"].includes(process.platform)) {
|
|
5108
|
-
throw new Error(`Not Implemented on platform ${process.platform}`);
|
|
5109
|
-
}
|
|
5110
|
-
if (!exists()) {
|
|
5111
|
-
throw new NotInstalledError2();
|
|
5112
|
-
}
|
|
5113
|
-
const result = (0, import_node_child_process.spawnSync)(import_constants.bin, ["service", "uninstall"]);
|
|
5114
|
-
if (result.status !== 0) {
|
|
5115
|
-
throw new Error(`service uninstall failed: ${result.stderr.toString()}`);
|
|
5116
|
-
}
|
|
5117
|
-
if (process.platform === "darwin") {
|
|
5118
|
-
import_node_fs.default.rmSync(MACOS_SERVICE_PATH2.OUT);
|
|
5119
|
-
import_node_fs.default.rmSync(MACOS_SERVICE_PATH2.ERR);
|
|
5120
|
-
} else if (process.platform === "linux" && !is_systemd()) {
|
|
5121
|
-
import_node_fs.default.rmSync(LINUX_SERVICE_PATH.SERVICE_OUT);
|
|
5122
|
-
import_node_fs.default.rmSync(LINUX_SERVICE_PATH.SERVICE_ERR);
|
|
5123
|
-
}
|
|
5124
|
-
}
|
|
5125
|
-
function log2() {
|
|
5126
|
-
if (!exists()) {
|
|
5127
|
-
throw new NotInstalledError2();
|
|
5128
|
-
}
|
|
5129
|
-
if (process.platform === "darwin") {
|
|
5130
|
-
return import_node_fs.default.readFileSync(MACOS_SERVICE_PATH2.OUT, "utf8");
|
|
5131
|
-
}
|
|
5132
|
-
if (process.platform === "linux" && !is_systemd()) {
|
|
5133
|
-
return import_node_fs.default.readFileSync(LINUX_SERVICE_PATH.SERVICE_OUT, "utf8");
|
|
5134
|
-
}
|
|
5135
|
-
throw new Error(`Not Implemented on platform ${process.platform}`);
|
|
5136
|
-
}
|
|
5137
|
-
function err() {
|
|
5138
|
-
if (!exists()) {
|
|
5139
|
-
throw new NotInstalledError2();
|
|
5140
|
-
}
|
|
5141
|
-
if (process.platform === "darwin") {
|
|
5142
|
-
return import_node_fs.default.readFileSync(MACOS_SERVICE_PATH2.ERR, "utf8");
|
|
5143
|
-
}
|
|
5144
|
-
if (process.platform === "linux" && !is_systemd()) {
|
|
5145
|
-
return import_node_fs.default.readFileSync(LINUX_SERVICE_PATH.SERVICE_ERR, "utf8");
|
|
5146
|
-
}
|
|
5147
|
-
throw new Error(`Not Implemented on platform ${process.platform}`);
|
|
5148
|
-
}
|
|
5149
|
-
function journal(n = 300) {
|
|
5150
|
-
if (process.platform === "linux" && is_systemd()) {
|
|
5151
|
-
const args = ["-u", service_name, "-o", "cat", "-n", n.toString()];
|
|
5152
|
-
return (0, import_node_child_process.spawnSync)("journalctl", args).stdout.toString();
|
|
5153
|
-
}
|
|
5154
|
-
throw new Error(`Not Implemented on platform ${process.platform}`);
|
|
5155
|
-
}
|
|
5156
|
-
function current() {
|
|
5157
|
-
var _a, _b, _c, _d;
|
|
5158
|
-
if (!["darwin", "linux"].includes(process.platform)) {
|
|
5159
|
-
throw new Error(`Not Implemented on platform ${process.platform}`);
|
|
5160
|
-
}
|
|
5161
|
-
if (!exists()) {
|
|
5162
|
-
throw new NotInstalledError2();
|
|
5163
|
-
}
|
|
5164
|
-
const log22 = is_systemd() ? journal() : err();
|
|
5165
|
-
let tunnelID = "";
|
|
5166
|
-
let connectorID = "";
|
|
5167
|
-
const connections = [];
|
|
5168
|
-
let metrics = "";
|
|
5169
|
-
let config = {};
|
|
5170
|
-
for (const line of log22.split("\n")) {
|
|
5171
|
-
try {
|
|
5172
|
-
if (line.match(import_regex2.tunnelID_regex)) {
|
|
5173
|
-
tunnelID = ((_a = line.match(import_regex2.tunnelID_regex)) == null ? void 0 : _a[1]) ?? "";
|
|
5174
|
-
} else if (line.match(import_regex2.connectorID_regex)) {
|
|
5175
|
-
connectorID = ((_b = line.match(import_regex2.connectorID_regex)) == null ? void 0 : _b[1]) ?? "";
|
|
5176
|
-
} else if (line.match(import_regex2.conn_regex) && line.match(import_regex2.location_regex) && line.match(import_regex2.ip_regex) && line.match(import_regex2.index_regex)) {
|
|
5177
|
-
const [, id] = line.match(import_regex2.conn_regex) ?? [];
|
|
5178
|
-
const [, location] = line.match(import_regex2.location_regex) ?? [];
|
|
5179
|
-
const [, ip] = line.match(import_regex2.ip_regex) ?? [];
|
|
5180
|
-
const [, idx] = line.match(import_regex2.index_regex) ?? [];
|
|
5181
|
-
connections[parseInt(idx)] = { id, ip, location };
|
|
5182
|
-
} else if (line.match(import_regex2.disconnect_regex)) {
|
|
5183
|
-
const [, idx] = line.match(import_regex2.disconnect_regex) ?? [];
|
|
5184
|
-
if (parseInt(idx) in connections) {
|
|
5185
|
-
connections[parseInt(idx)] = { id: "", ip: "", location: "" };
|
|
5186
|
-
}
|
|
5187
|
-
} else if (line.match(import_regex2.metrics_regex)) {
|
|
5188
|
-
metrics = ((_c = line.match(import_regex2.metrics_regex)) == null ? void 0 : _c[1]) ?? "";
|
|
5189
|
-
} else if (line.match(import_regex2.config_regex)) {
|
|
5190
|
-
config = JSON.parse(((_d = line.match(import_regex2.config_regex)) == null ? void 0 : _d[1].replace(/\\/g, "")) ?? "{}");
|
|
5191
|
-
}
|
|
5192
|
-
} catch (err2) {
|
|
5193
|
-
if (process.env.VERBOSE) {
|
|
5194
|
-
console.error("log parsing failed", err2);
|
|
5195
|
-
}
|
|
5196
|
-
}
|
|
5197
|
-
}
|
|
5198
|
-
return { tunnelID, connectorID, connections, metrics, config };
|
|
5199
|
-
}
|
|
5200
|
-
function clean() {
|
|
5201
|
-
if (process.platform !== "darwin") {
|
|
5202
|
-
throw new Error(`Not Implemented on platform ${process.platform}`);
|
|
5203
|
-
}
|
|
5204
|
-
if (exists()) {
|
|
5205
|
-
throw new AlreadyInstalledError2();
|
|
5206
|
-
}
|
|
5207
|
-
import_node_fs.default.rmSync(MACOS_SERVICE_PATH2.OUT, { force: true });
|
|
5208
|
-
import_node_fs.default.rmSync(MACOS_SERVICE_PATH2.ERR, { force: true });
|
|
5209
|
-
}
|
|
5210
|
-
function exists() {
|
|
5211
|
-
if (process.platform === "darwin") {
|
|
5212
|
-
return import_node_fs.default.existsSync(MACOS_SERVICE_PATH2.PLIST);
|
|
5213
|
-
} else if (process.platform === "linux") {
|
|
5214
|
-
return is_systemd() ? import_node_fs.default.existsSync(LINUX_SERVICE_PATH.SYSTEMD) : import_node_fs.default.existsSync(LINUX_SERVICE_PATH.SERVICE);
|
|
5215
|
-
}
|
|
5216
|
-
throw new Error(`Not Implemented on platform ${process.platform}`);
|
|
5217
|
-
}
|
|
5218
|
-
function is_root() {
|
|
5219
|
-
var _a;
|
|
5220
|
-
return ((_a = process.getuid) == null ? void 0 : _a.call(process)) === 0;
|
|
5221
|
-
}
|
|
5222
|
-
function is_systemd() {
|
|
5223
|
-
return process.platform === "linux" && import_node_fs.default.existsSync("/run/systemd/system");
|
|
5224
|
-
}
|
|
5225
|
-
}
|
|
5226
|
-
});
|
|
4468
|
+
BANNER = `
|
|
4469
|
+
\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557
|
|
4470
|
+
\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557
|
|
4471
|
+
\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D
|
|
4472
|
+
\u2588\u2588\u2554\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557
|
|
4473
|
+
\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551
|
|
4474
|
+
\u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D
|
|
5227
4475
|
|
|
5228
|
-
|
|
5229
|
-
|
|
5230
|
-
"node_modules/cloudflared/lib/lib.js"(exports2, module2) {
|
|
5231
|
-
"use strict";
|
|
5232
|
-
var __defProp2 = Object.defineProperty;
|
|
5233
|
-
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
5234
|
-
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
5235
|
-
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
5236
|
-
var __export2 = (target, all) => {
|
|
5237
|
-
for (var name in all)
|
|
5238
|
-
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
5239
|
-
};
|
|
5240
|
-
var __copyProps2 = (to, from, except, desc) => {
|
|
5241
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
5242
|
-
for (let key of __getOwnPropNames2(from))
|
|
5243
|
-
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
5244
|
-
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
5245
|
-
}
|
|
5246
|
-
return to;
|
|
5247
|
-
};
|
|
5248
|
-
var __reExport = (target, mod, secondTarget) => (__copyProps2(target, mod, "default"), secondTarget && __copyProps2(secondTarget, mod, "default"));
|
|
5249
|
-
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
5250
|
-
var lib_exports = {};
|
|
5251
|
-
__export2(lib_exports, {
|
|
5252
|
-
AlreadyInstalledError: () => import_service.AlreadyInstalledError,
|
|
5253
|
-
MACOS_SERVICE_PATH: () => import_service.MACOS_SERVICE_PATH,
|
|
5254
|
-
NotInstalledError: () => import_service.NotInstalledError,
|
|
5255
|
-
identifier: () => import_service.identifier,
|
|
5256
|
-
service: () => import_service.service
|
|
5257
|
-
});
|
|
5258
|
-
module2.exports = __toCommonJS2(lib_exports);
|
|
5259
|
-
__reExport(lib_exports, require_constants(), module2.exports);
|
|
5260
|
-
__reExport(lib_exports, require_install(), module2.exports);
|
|
5261
|
-
__reExport(lib_exports, require_tunnel(), module2.exports);
|
|
5262
|
-
var import_service = require_service();
|
|
5263
|
-
__reExport(lib_exports, require_handler(), module2.exports);
|
|
4476
|
+
Connect AI agents to phone numbers in 4 lines of code
|
|
4477
|
+
`;
|
|
5264
4478
|
}
|
|
5265
4479
|
});
|
|
5266
4480
|
|
|
@@ -5272,7 +4486,7 @@ __export(tunnel_exports, {
|
|
|
5272
4486
|
async function startTunnel(port, timeoutMs = 3e4) {
|
|
5273
4487
|
let tunnelMod;
|
|
5274
4488
|
try {
|
|
5275
|
-
tunnelMod = await
|
|
4489
|
+
tunnelMod = await import("cloudflared");
|
|
5276
4490
|
} catch {
|
|
5277
4491
|
throw new Error(
|
|
5278
4492
|
'Built-in tunnel requires the "cloudflared" package. Install it with:\n\n npm install cloudflared\n\nOr provide your own webhookUrl instead of using tunnel: true.'
|
|
@@ -6535,6 +5749,7 @@ var require_node_cron = __commonJS({
|
|
|
6535
5749
|
var index_exports = {};
|
|
6536
5750
|
__export(index_exports, {
|
|
6537
5751
|
AllProvidersFailedError: () => AllProvidersFailedError,
|
|
5752
|
+
AnthropicLLM: () => LLM2,
|
|
6538
5753
|
AssemblyAISTT: () => STT5,
|
|
6539
5754
|
AuthenticationError: () => AuthenticationError,
|
|
6540
5755
|
BackgroundAudioPlayer: () => BackgroundAudioPlayer,
|
|
@@ -6542,6 +5757,7 @@ __export(index_exports, {
|
|
|
6542
5757
|
CallMetricsAccumulator: () => CallMetricsAccumulator,
|
|
6543
5758
|
CartesiaSTT: () => STT3,
|
|
6544
5759
|
CartesiaTTS: () => TTS3,
|
|
5760
|
+
CerebrasLLM: () => LLM4,
|
|
6545
5761
|
ChatContext: () => ChatContext,
|
|
6546
5762
|
CloudflareTunnel: () => CloudflareTunnel,
|
|
6547
5763
|
DEFAULT_MIN_SENTENCE_LEN: () => DEFAULT_MIN_SENTENCE_LEN,
|
|
@@ -6555,11 +5771,14 @@ __export(index_exports, {
|
|
|
6555
5771
|
GEMINI_DEFAULT_INPUT_SR: () => GEMINI_DEFAULT_INPUT_SR,
|
|
6556
5772
|
GEMINI_DEFAULT_OUTPUT_SR: () => GEMINI_DEFAULT_OUTPUT_SR,
|
|
6557
5773
|
GeminiLiveAdapter: () => GeminiLiveAdapter,
|
|
5774
|
+
GoogleLLM: () => LLM5,
|
|
5775
|
+
GroqLLM: () => LLM3,
|
|
6558
5776
|
Guardrail: () => Guardrail,
|
|
6559
5777
|
IVRActivity: () => IVRActivity,
|
|
6560
5778
|
LLMLoop: () => LLMLoop,
|
|
6561
5779
|
LMNTTTS: () => TTS5,
|
|
6562
5780
|
MetricsStore: () => MetricsStore,
|
|
5781
|
+
OpenAILLM: () => LLM,
|
|
6563
5782
|
OpenAILLMProvider: () => OpenAILLMProvider,
|
|
6564
5783
|
OpenAIRealtime: () => Realtime,
|
|
6565
5784
|
OpenAIRealtimeAdapter: () => OpenAIRealtimeAdapter,
|
|
@@ -6830,6 +6049,7 @@ var Static = class {
|
|
|
6830
6049
|
};
|
|
6831
6050
|
|
|
6832
6051
|
// src/client.ts
|
|
6052
|
+
init_logger();
|
|
6833
6053
|
var DEFAULT_BACKEND_URL2 = "wss://api.getpatter.com";
|
|
6834
6054
|
var DEFAULT_REST_URL = "https://api.getpatter.com";
|
|
6835
6055
|
function sttConfigToDict(cfg) {
|
|
@@ -6938,6 +6158,8 @@ var Patter = class {
|
|
|
6938
6158
|
"Unknown engine. Expected OpenAIRealtime or ElevenLabsConvAI instance."
|
|
6939
6159
|
);
|
|
6940
6160
|
}
|
|
6161
|
+
} else if (!working.provider && (working.stt !== void 0 || working.tts !== void 0 || working.llm !== void 0)) {
|
|
6162
|
+
working = { ...working, provider: "pipeline" };
|
|
6941
6163
|
}
|
|
6942
6164
|
if (working.provider) {
|
|
6943
6165
|
const valid = ["openai_realtime", "elevenlabs_convai", "pipeline"];
|
|
@@ -6945,6 +6167,19 @@ var Patter = class {
|
|
|
6945
6167
|
throw new Error(`provider must be one of: ${valid.join(", ")}. Got: '${working.provider}'`);
|
|
6946
6168
|
}
|
|
6947
6169
|
}
|
|
6170
|
+
if (working.llm !== void 0) {
|
|
6171
|
+
const llm = working.llm;
|
|
6172
|
+
if (!llm || typeof llm.stream !== "function") {
|
|
6173
|
+
throw new Error(
|
|
6174
|
+
"`llm` must be an LLMProvider instance (e.g. new AnthropicLLM()). Got a value without a `.stream` method."
|
|
6175
|
+
);
|
|
6176
|
+
}
|
|
6177
|
+
if (working.engine) {
|
|
6178
|
+
getLogger().warn(
|
|
6179
|
+
"agent({ engine, llm }): `llm` is ignored when `engine` is set \u2014 realtime/ConvAI engines run their own model. Remove `llm` or switch to pipeline mode (stt + tts + llm) to silence this warning."
|
|
6180
|
+
);
|
|
6181
|
+
}
|
|
6182
|
+
}
|
|
6948
6183
|
if (working.tools) {
|
|
6949
6184
|
if (!Array.isArray(working.tools)) {
|
|
6950
6185
|
throw new TypeError("tools must be an array");
|
|
@@ -6987,6 +6222,8 @@ var Patter = class {
|
|
|
6987
6222
|
if (wantsCloudflared && webhookUrl) {
|
|
6988
6223
|
throw new Error("Cannot use both tunnel: true and webhookUrl. Pick one.");
|
|
6989
6224
|
}
|
|
6225
|
+
const { showBanner: showBanner2 } = await Promise.resolve().then(() => (init_banner(), banner_exports));
|
|
6226
|
+
showBanner2();
|
|
6990
6227
|
if (wantsCloudflared) {
|
|
6991
6228
|
const { startTunnel: startTunnel2 } = await Promise.resolve().then(() => (init_tunnel(), tunnel_exports));
|
|
6992
6229
|
this.tunnelHandle = await startTunnel2(port);
|
|
@@ -8888,7 +8125,8 @@ var ELEVENLABS_VOICE_ID_BY_NAME = {
|
|
|
8888
8125
|
glinda: "z9fAnlkpzviPz146aGWa",
|
|
8889
8126
|
giovanni: "zcAOhNBS3c14rBihAFp1",
|
|
8890
8127
|
mimi: "zrHiDhphv9ZnVXBqCLjz",
|
|
8891
|
-
|
|
8128
|
+
sarah: "EXAVITQu4vr4xnSDxMaL",
|
|
8129
|
+
alloy: "EXAVITQu4vr4xnSDxMaL"
|
|
8892
8130
|
};
|
|
8893
8131
|
var VOICE_ID_PATTERN = /^[A-Za-z0-9]{20}$/;
|
|
8894
8132
|
function resolveVoiceId(voice) {
|
|
@@ -8897,7 +8135,7 @@ function resolveVoiceId(voice) {
|
|
|
8897
8135
|
return ELEVENLABS_VOICE_ID_BY_NAME[voice.toLowerCase()] ?? voice;
|
|
8898
8136
|
}
|
|
8899
8137
|
var ElevenLabsTTS = class {
|
|
8900
|
-
constructor(apiKey, voiceId = "
|
|
8138
|
+
constructor(apiKey, voiceId = "EXAVITQu4vr4xnSDxMaL", modelId = "eleven_turbo_v2_5", outputFormat = "pcm_16000") {
|
|
8901
8139
|
this.apiKey = apiKey;
|
|
8902
8140
|
this.modelId = modelId;
|
|
8903
8141
|
this.outputFormat = outputFormat;
|
|
@@ -8968,7 +8206,7 @@ var TTS = class extends ElevenLabsTTS {
|
|
|
8968
8206
|
}
|
|
8969
8207
|
super(
|
|
8970
8208
|
key,
|
|
8971
|
-
opts.voiceId ?? "
|
|
8209
|
+
opts.voiceId ?? "EXAVITQu4vr4xnSDxMaL",
|
|
8972
8210
|
opts.modelId ?? "eleven_turbo_v2_5",
|
|
8973
8211
|
opts.outputFormat ?? "pcm_16000"
|
|
8974
8212
|
);
|
|
@@ -9464,6 +8702,621 @@ var TTS5 = class extends LMNTTTS {
|
|
|
9464
8702
|
}
|
|
9465
8703
|
};
|
|
9466
8704
|
|
|
8705
|
+
// src/llm/openai.ts
|
|
8706
|
+
init_llm_loop();
|
|
8707
|
+
var LLM = class extends OpenAILLMProvider {
|
|
8708
|
+
constructor(opts = {}) {
|
|
8709
|
+
const key = opts.apiKey ?? process.env.OPENAI_API_KEY;
|
|
8710
|
+
if (!key) {
|
|
8711
|
+
throw new Error(
|
|
8712
|
+
"OpenAI LLM requires an apiKey. Pass { apiKey: 'sk-...' } or set OPENAI_API_KEY."
|
|
8713
|
+
);
|
|
8714
|
+
}
|
|
8715
|
+
super(key, opts.model ?? "gpt-4o-mini");
|
|
8716
|
+
}
|
|
8717
|
+
};
|
|
8718
|
+
|
|
8719
|
+
// src/providers/anthropic-llm.ts
|
|
8720
|
+
init_logger();
|
|
8721
|
+
var DEFAULT_ANTHROPIC_URL = "https://api.anthropic.com/v1/messages";
|
|
8722
|
+
var DEFAULT_ANTHROPIC_VERSION = "2023-06-01";
|
|
8723
|
+
var DEFAULT_MODEL = "claude-3-5-sonnet-20241022";
|
|
8724
|
+
var DEFAULT_MAX_TOKENS = 1024;
|
|
8725
|
+
var AnthropicLLMProvider = class {
|
|
8726
|
+
apiKey;
|
|
8727
|
+
model;
|
|
8728
|
+
maxTokens;
|
|
8729
|
+
temperature;
|
|
8730
|
+
url;
|
|
8731
|
+
anthropicVersion;
|
|
8732
|
+
constructor(options) {
|
|
8733
|
+
if (!options.apiKey) {
|
|
8734
|
+
throw new Error(
|
|
8735
|
+
"Anthropic API key is required. Pass it via { apiKey } or set the ANTHROPIC_API_KEY environment variable before constructing the provider."
|
|
8736
|
+
);
|
|
8737
|
+
}
|
|
8738
|
+
this.apiKey = options.apiKey;
|
|
8739
|
+
this.model = options.model ?? DEFAULT_MODEL;
|
|
8740
|
+
this.maxTokens = options.maxTokens ?? DEFAULT_MAX_TOKENS;
|
|
8741
|
+
this.temperature = options.temperature;
|
|
8742
|
+
this.url = options.baseUrl ?? DEFAULT_ANTHROPIC_URL;
|
|
8743
|
+
this.anthropicVersion = options.anthropicVersion ?? DEFAULT_ANTHROPIC_VERSION;
|
|
8744
|
+
}
|
|
8745
|
+
async *stream(messages, tools) {
|
|
8746
|
+
const { system, messages: anthropicMessages } = toAnthropicMessages(messages);
|
|
8747
|
+
const anthropicTools = tools ? toAnthropicTools(tools) : null;
|
|
8748
|
+
const body = {
|
|
8749
|
+
model: this.model,
|
|
8750
|
+
messages: anthropicMessages,
|
|
8751
|
+
max_tokens: this.maxTokens,
|
|
8752
|
+
stream: true
|
|
8753
|
+
};
|
|
8754
|
+
if (system) body.system = system;
|
|
8755
|
+
if (anthropicTools && anthropicTools.length > 0) body.tools = anthropicTools;
|
|
8756
|
+
if (this.temperature !== void 0) body.temperature = this.temperature;
|
|
8757
|
+
const response = await fetch(this.url, {
|
|
8758
|
+
method: "POST",
|
|
8759
|
+
headers: {
|
|
8760
|
+
"Content-Type": "application/json",
|
|
8761
|
+
"x-api-key": this.apiKey,
|
|
8762
|
+
"anthropic-version": this.anthropicVersion
|
|
8763
|
+
},
|
|
8764
|
+
body: JSON.stringify(body),
|
|
8765
|
+
signal: AbortSignal.timeout(3e4)
|
|
8766
|
+
});
|
|
8767
|
+
if (!response.ok) {
|
|
8768
|
+
const errText = await response.text();
|
|
8769
|
+
getLogger().error(`Anthropic API error: ${response.status} ${errText}`);
|
|
8770
|
+
return;
|
|
8771
|
+
}
|
|
8772
|
+
const reader = response.body?.getReader();
|
|
8773
|
+
if (!reader) return;
|
|
8774
|
+
const decoder = new TextDecoder();
|
|
8775
|
+
let buffer = "";
|
|
8776
|
+
const toolIndexByBlock = /* @__PURE__ */ new Map();
|
|
8777
|
+
const toolIdByBlock = /* @__PURE__ */ new Map();
|
|
8778
|
+
let nextIndex = 0;
|
|
8779
|
+
while (true) {
|
|
8780
|
+
const { done, value } = await reader.read();
|
|
8781
|
+
if (done) break;
|
|
8782
|
+
buffer += decoder.decode(value, { stream: true });
|
|
8783
|
+
const lines = buffer.split("\n");
|
|
8784
|
+
buffer = lines.pop() || "";
|
|
8785
|
+
for (const line of lines) {
|
|
8786
|
+
const trimmed = line.trim();
|
|
8787
|
+
if (!trimmed.startsWith("data: ")) continue;
|
|
8788
|
+
const data = trimmed.slice(6);
|
|
8789
|
+
if (!data || data === "[DONE]") continue;
|
|
8790
|
+
let event;
|
|
8791
|
+
try {
|
|
8792
|
+
event = JSON.parse(data);
|
|
8793
|
+
} catch {
|
|
8794
|
+
continue;
|
|
8795
|
+
}
|
|
8796
|
+
if (event.type === "content_block_start" && event.content_block?.type === "tool_use") {
|
|
8797
|
+
const blockIdx = event.index ?? 0;
|
|
8798
|
+
const toolId = event.content_block.id ?? "";
|
|
8799
|
+
const toolName = event.content_block.name ?? "";
|
|
8800
|
+
const patterIndex = nextIndex++;
|
|
8801
|
+
toolIndexByBlock.set(blockIdx, patterIndex);
|
|
8802
|
+
toolIdByBlock.set(blockIdx, toolId);
|
|
8803
|
+
yield {
|
|
8804
|
+
type: "tool_call",
|
|
8805
|
+
index: patterIndex,
|
|
8806
|
+
id: toolId,
|
|
8807
|
+
name: toolName,
|
|
8808
|
+
arguments: ""
|
|
8809
|
+
};
|
|
8810
|
+
continue;
|
|
8811
|
+
}
|
|
8812
|
+
if (event.type === "content_block_delta") {
|
|
8813
|
+
if (event.delta?.type === "text_delta" && event.delta.text) {
|
|
8814
|
+
yield { type: "text", content: event.delta.text };
|
|
8815
|
+
continue;
|
|
8816
|
+
}
|
|
8817
|
+
if (event.delta?.type === "input_json_delta" && event.delta.partial_json) {
|
|
8818
|
+
const blockIdx = event.index ?? 0;
|
|
8819
|
+
const patterIndex = toolIndexByBlock.get(blockIdx);
|
|
8820
|
+
if (patterIndex !== void 0) {
|
|
8821
|
+
yield {
|
|
8822
|
+
type: "tool_call",
|
|
8823
|
+
index: patterIndex,
|
|
8824
|
+
id: toolIdByBlock.get(blockIdx),
|
|
8825
|
+
arguments: event.delta.partial_json
|
|
8826
|
+
};
|
|
8827
|
+
}
|
|
8828
|
+
}
|
|
8829
|
+
}
|
|
8830
|
+
}
|
|
8831
|
+
}
|
|
8832
|
+
yield { type: "done" };
|
|
8833
|
+
}
|
|
8834
|
+
};
|
|
8835
|
+
function toAnthropicTools(tools) {
|
|
8836
|
+
return tools.map((t) => {
|
|
8837
|
+
const fn = t.function ?? t;
|
|
8838
|
+
return {
|
|
8839
|
+
name: String(fn.name ?? ""),
|
|
8840
|
+
description: String(fn.description ?? ""),
|
|
8841
|
+
input_schema: fn.parameters ?? { type: "object", properties: {} }
|
|
8842
|
+
};
|
|
8843
|
+
});
|
|
8844
|
+
}
|
|
8845
|
+
function toAnthropicMessages(messages) {
|
|
8846
|
+
const systemParts = [];
|
|
8847
|
+
const out = [];
|
|
8848
|
+
for (const rawMsg of messages) {
|
|
8849
|
+
const role = rawMsg.role;
|
|
8850
|
+
if (role === "system") {
|
|
8851
|
+
if (typeof rawMsg.content === "string" && rawMsg.content) {
|
|
8852
|
+
systemParts.push(rawMsg.content);
|
|
8853
|
+
}
|
|
8854
|
+
continue;
|
|
8855
|
+
}
|
|
8856
|
+
if (role === "user") {
|
|
8857
|
+
if (typeof rawMsg.content === "string") {
|
|
8858
|
+
out.push({ role: "user", content: rawMsg.content });
|
|
8859
|
+
} else if (rawMsg.content) {
|
|
8860
|
+
out.push({ role: "user", content: rawMsg.content });
|
|
8861
|
+
}
|
|
8862
|
+
continue;
|
|
8863
|
+
}
|
|
8864
|
+
if (role === "assistant") {
|
|
8865
|
+
const blocks = [];
|
|
8866
|
+
if (typeof rawMsg.content === "string" && rawMsg.content) {
|
|
8867
|
+
blocks.push({ type: "text", text: rawMsg.content });
|
|
8868
|
+
}
|
|
8869
|
+
for (const tc of rawMsg.tool_calls ?? []) {
|
|
8870
|
+
let args = {};
|
|
8871
|
+
try {
|
|
8872
|
+
args = JSON.parse(tc.function?.arguments ?? "{}");
|
|
8873
|
+
} catch {
|
|
8874
|
+
args = {};
|
|
8875
|
+
}
|
|
8876
|
+
blocks.push({
|
|
8877
|
+
type: "tool_use",
|
|
8878
|
+
id: tc.id ?? "",
|
|
8879
|
+
name: tc.function?.name ?? "",
|
|
8880
|
+
input: args
|
|
8881
|
+
});
|
|
8882
|
+
}
|
|
8883
|
+
if (blocks.length > 0) {
|
|
8884
|
+
out.push({ role: "assistant", content: blocks });
|
|
8885
|
+
}
|
|
8886
|
+
continue;
|
|
8887
|
+
}
|
|
8888
|
+
if (role === "tool") {
|
|
8889
|
+
const contentStr = typeof rawMsg.content === "string" ? rawMsg.content : JSON.stringify(rawMsg.content);
|
|
8890
|
+
out.push({
|
|
8891
|
+
role: "user",
|
|
8892
|
+
content: [
|
|
8893
|
+
{
|
|
8894
|
+
type: "tool_result",
|
|
8895
|
+
tool_use_id: rawMsg.tool_call_id ?? "",
|
|
8896
|
+
content: contentStr
|
|
8897
|
+
}
|
|
8898
|
+
]
|
|
8899
|
+
});
|
|
8900
|
+
continue;
|
|
8901
|
+
}
|
|
8902
|
+
}
|
|
8903
|
+
return { system: systemParts.join("\n\n"), messages: out };
|
|
8904
|
+
}
|
|
8905
|
+
|
|
8906
|
+
// src/llm/anthropic.ts
|
|
8907
|
+
var LLM2 = class extends AnthropicLLMProvider {
|
|
8908
|
+
constructor(opts = {}) {
|
|
8909
|
+
const key = opts.apiKey ?? process.env.ANTHROPIC_API_KEY;
|
|
8910
|
+
if (!key) {
|
|
8911
|
+
throw new Error(
|
|
8912
|
+
"Anthropic LLM requires an apiKey. Pass { apiKey: 'sk-ant-...' } or set ANTHROPIC_API_KEY."
|
|
8913
|
+
);
|
|
8914
|
+
}
|
|
8915
|
+
super({
|
|
8916
|
+
apiKey: key,
|
|
8917
|
+
model: opts.model,
|
|
8918
|
+
maxTokens: opts.maxTokens,
|
|
8919
|
+
temperature: opts.temperature,
|
|
8920
|
+
baseUrl: opts.baseUrl,
|
|
8921
|
+
anthropicVersion: opts.anthropicVersion
|
|
8922
|
+
});
|
|
8923
|
+
}
|
|
8924
|
+
};
|
|
8925
|
+
|
|
8926
|
+
// src/providers/groq-llm.ts
|
|
8927
|
+
init_logger();
|
|
8928
|
+
var GROQ_BASE_URL = "https://api.groq.com/openai/v1";
|
|
8929
|
+
var DEFAULT_MODEL2 = "llama-3.3-70b-versatile";
|
|
8930
|
+
var GroqLLMProvider = class {
|
|
8931
|
+
apiKey;
|
|
8932
|
+
model;
|
|
8933
|
+
baseUrl;
|
|
8934
|
+
constructor(options) {
|
|
8935
|
+
if (!options.apiKey) {
|
|
8936
|
+
throw new Error(
|
|
8937
|
+
"Groq API key is required. Pass it via { apiKey } or read GROQ_API_KEY from the environment."
|
|
8938
|
+
);
|
|
8939
|
+
}
|
|
8940
|
+
this.apiKey = options.apiKey;
|
|
8941
|
+
this.model = options.model ?? DEFAULT_MODEL2;
|
|
8942
|
+
this.baseUrl = options.baseUrl ?? GROQ_BASE_URL;
|
|
8943
|
+
}
|
|
8944
|
+
async *stream(messages, tools) {
|
|
8945
|
+
const body = {
|
|
8946
|
+
model: this.model,
|
|
8947
|
+
messages,
|
|
8948
|
+
stream: true
|
|
8949
|
+
};
|
|
8950
|
+
if (tools) body.tools = tools;
|
|
8951
|
+
const response = await fetch(`${this.baseUrl}/chat/completions`, {
|
|
8952
|
+
method: "POST",
|
|
8953
|
+
headers: {
|
|
8954
|
+
"Content-Type": "application/json",
|
|
8955
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
8956
|
+
},
|
|
8957
|
+
body: JSON.stringify(body),
|
|
8958
|
+
signal: AbortSignal.timeout(3e4)
|
|
8959
|
+
});
|
|
8960
|
+
if (!response.ok) {
|
|
8961
|
+
const errText = await response.text();
|
|
8962
|
+
getLogger().error(`Groq API error: ${response.status} ${errText}`);
|
|
8963
|
+
return;
|
|
8964
|
+
}
|
|
8965
|
+
yield* parseOpenAISseStream(response);
|
|
8966
|
+
}
|
|
8967
|
+
};
|
|
8968
|
+
async function* parseOpenAISseStream(response) {
|
|
8969
|
+
const reader = response.body?.getReader();
|
|
8970
|
+
if (!reader) return;
|
|
8971
|
+
const decoder = new TextDecoder();
|
|
8972
|
+
let buffer = "";
|
|
8973
|
+
while (true) {
|
|
8974
|
+
const { done, value } = await reader.read();
|
|
8975
|
+
if (done) break;
|
|
8976
|
+
buffer += decoder.decode(value, { stream: true });
|
|
8977
|
+
const lines = buffer.split("\n");
|
|
8978
|
+
buffer = lines.pop() || "";
|
|
8979
|
+
for (const line of lines) {
|
|
8980
|
+
const trimmed = line.trim();
|
|
8981
|
+
if (!trimmed || !trimmed.startsWith("data: ")) continue;
|
|
8982
|
+
const data = trimmed.slice(6);
|
|
8983
|
+
if (data === "[DONE]") continue;
|
|
8984
|
+
let chunk;
|
|
8985
|
+
try {
|
|
8986
|
+
chunk = JSON.parse(data);
|
|
8987
|
+
} catch {
|
|
8988
|
+
continue;
|
|
8989
|
+
}
|
|
8990
|
+
const delta = chunk.choices?.[0]?.delta;
|
|
8991
|
+
if (!delta) continue;
|
|
8992
|
+
if (delta.content) {
|
|
8993
|
+
yield { type: "text", content: delta.content };
|
|
8994
|
+
}
|
|
8995
|
+
if (delta.tool_calls) {
|
|
8996
|
+
for (const tc of delta.tool_calls) {
|
|
8997
|
+
yield {
|
|
8998
|
+
type: "tool_call",
|
|
8999
|
+
index: tc.index,
|
|
9000
|
+
id: tc.id,
|
|
9001
|
+
name: tc.function?.name,
|
|
9002
|
+
arguments: tc.function?.arguments
|
|
9003
|
+
};
|
|
9004
|
+
}
|
|
9005
|
+
}
|
|
9006
|
+
}
|
|
9007
|
+
}
|
|
9008
|
+
}
|
|
9009
|
+
|
|
9010
|
+
// src/llm/groq.ts
|
|
9011
|
+
var LLM3 = class extends GroqLLMProvider {
|
|
9012
|
+
constructor(opts = {}) {
|
|
9013
|
+
const key = opts.apiKey ?? process.env.GROQ_API_KEY;
|
|
9014
|
+
if (!key) {
|
|
9015
|
+
throw new Error(
|
|
9016
|
+
"Groq LLM requires an apiKey. Pass { apiKey: 'gsk_...' } or set GROQ_API_KEY."
|
|
9017
|
+
);
|
|
9018
|
+
}
|
|
9019
|
+
super({
|
|
9020
|
+
apiKey: key,
|
|
9021
|
+
model: opts.model,
|
|
9022
|
+
baseUrl: opts.baseUrl
|
|
9023
|
+
});
|
|
9024
|
+
}
|
|
9025
|
+
};
|
|
9026
|
+
|
|
9027
|
+
// src/providers/cerebras-llm.ts
|
|
9028
|
+
init_logger();
|
|
9029
|
+
var CEREBRAS_BASE_URL = "https://api.cerebras.ai/v1";
|
|
9030
|
+
var DEFAULT_MODEL3 = "llama3.1-8b";
|
|
9031
|
+
var CerebrasLLMProvider = class {
|
|
9032
|
+
apiKey;
|
|
9033
|
+
model;
|
|
9034
|
+
baseUrl;
|
|
9035
|
+
gzipCompression;
|
|
9036
|
+
constructor(options) {
|
|
9037
|
+
if (!options.apiKey) {
|
|
9038
|
+
throw new Error(
|
|
9039
|
+
"Cerebras API key is required. Pass it via { apiKey } or read CEREBRAS_API_KEY from the environment."
|
|
9040
|
+
);
|
|
9041
|
+
}
|
|
9042
|
+
this.apiKey = options.apiKey;
|
|
9043
|
+
this.model = options.model ?? DEFAULT_MODEL3;
|
|
9044
|
+
this.baseUrl = options.baseUrl ?? CEREBRAS_BASE_URL;
|
|
9045
|
+
this.gzipCompression = options.gzipCompression ?? false;
|
|
9046
|
+
}
|
|
9047
|
+
async *stream(messages, tools) {
|
|
9048
|
+
const body = {
|
|
9049
|
+
model: this.model,
|
|
9050
|
+
messages,
|
|
9051
|
+
stream: true
|
|
9052
|
+
};
|
|
9053
|
+
if (tools) body.tools = tools;
|
|
9054
|
+
const headers = {
|
|
9055
|
+
"Content-Type": "application/json",
|
|
9056
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
9057
|
+
};
|
|
9058
|
+
let payload = JSON.stringify(body);
|
|
9059
|
+
if (this.gzipCompression) {
|
|
9060
|
+
const compressed = await gzipEncode(payload);
|
|
9061
|
+
if (compressed) {
|
|
9062
|
+
payload = compressed;
|
|
9063
|
+
headers["Content-Encoding"] = "gzip";
|
|
9064
|
+
}
|
|
9065
|
+
}
|
|
9066
|
+
const response = await fetch(`${this.baseUrl}/chat/completions`, {
|
|
9067
|
+
method: "POST",
|
|
9068
|
+
headers,
|
|
9069
|
+
body: payload,
|
|
9070
|
+
signal: AbortSignal.timeout(3e4)
|
|
9071
|
+
});
|
|
9072
|
+
if (!response.ok) {
|
|
9073
|
+
const errText = await response.text();
|
|
9074
|
+
getLogger().error(`Cerebras API error: ${response.status} ${errText}`);
|
|
9075
|
+
return;
|
|
9076
|
+
}
|
|
9077
|
+
yield* parseOpenAISseStream(response);
|
|
9078
|
+
}
|
|
9079
|
+
};
|
|
9080
|
+
async function gzipEncode(data) {
|
|
9081
|
+
const CompressionCtor = globalThis.CompressionStream;
|
|
9082
|
+
if (!CompressionCtor) return null;
|
|
9083
|
+
const stream = new CompressionCtor("gzip");
|
|
9084
|
+
const writer = stream.writable.getWriter();
|
|
9085
|
+
const encoder = new TextEncoder();
|
|
9086
|
+
await writer.write(encoder.encode(data));
|
|
9087
|
+
await writer.close();
|
|
9088
|
+
const chunks = [];
|
|
9089
|
+
const reader = stream.readable.getReader();
|
|
9090
|
+
while (true) {
|
|
9091
|
+
const { done, value } = await reader.read();
|
|
9092
|
+
if (done) break;
|
|
9093
|
+
if (value) chunks.push(value);
|
|
9094
|
+
}
|
|
9095
|
+
const total = chunks.reduce((n, c) => n + c.length, 0);
|
|
9096
|
+
const out = new Uint8Array(total);
|
|
9097
|
+
let offset = 0;
|
|
9098
|
+
for (const c of chunks) {
|
|
9099
|
+
out.set(c, offset);
|
|
9100
|
+
offset += c.length;
|
|
9101
|
+
}
|
|
9102
|
+
return out;
|
|
9103
|
+
}
|
|
9104
|
+
|
|
9105
|
+
// src/llm/cerebras.ts
|
|
9106
|
+
var LLM4 = class extends CerebrasLLMProvider {
|
|
9107
|
+
constructor(opts = {}) {
|
|
9108
|
+
const key = opts.apiKey ?? process.env.CEREBRAS_API_KEY;
|
|
9109
|
+
if (!key) {
|
|
9110
|
+
throw new Error(
|
|
9111
|
+
"Cerebras LLM requires an apiKey. Pass { apiKey: 'csk-...' } or set CEREBRAS_API_KEY."
|
|
9112
|
+
);
|
|
9113
|
+
}
|
|
9114
|
+
super({
|
|
9115
|
+
apiKey: key,
|
|
9116
|
+
model: opts.model,
|
|
9117
|
+
baseUrl: opts.baseUrl,
|
|
9118
|
+
gzipCompression: opts.gzipCompression
|
|
9119
|
+
});
|
|
9120
|
+
}
|
|
9121
|
+
};
|
|
9122
|
+
|
|
9123
|
+
// src/providers/google-llm.ts
|
|
9124
|
+
init_logger();
|
|
9125
|
+
var DEFAULT_MODEL4 = "gemini-2.5-flash";
|
|
9126
|
+
var DEFAULT_BASE_URL3 = "https://generativelanguage.googleapis.com/v1beta";
|
|
9127
|
+
var GoogleLLMProvider = class {
|
|
9128
|
+
apiKey;
|
|
9129
|
+
model;
|
|
9130
|
+
baseUrl;
|
|
9131
|
+
temperature;
|
|
9132
|
+
maxOutputTokens;
|
|
9133
|
+
constructor(options) {
|
|
9134
|
+
if (!options.apiKey) {
|
|
9135
|
+
throw new Error(
|
|
9136
|
+
"Google API key is required. Pass it via { apiKey } or read GOOGLE_API_KEY from the environment."
|
|
9137
|
+
);
|
|
9138
|
+
}
|
|
9139
|
+
this.apiKey = options.apiKey;
|
|
9140
|
+
this.model = options.model ?? DEFAULT_MODEL4;
|
|
9141
|
+
this.baseUrl = options.baseUrl ?? DEFAULT_BASE_URL3;
|
|
9142
|
+
this.temperature = options.temperature;
|
|
9143
|
+
this.maxOutputTokens = options.maxOutputTokens;
|
|
9144
|
+
}
|
|
9145
|
+
async *stream(messages, tools) {
|
|
9146
|
+
const { systemInstruction, contents } = toGeminiContents(messages);
|
|
9147
|
+
const geminiTools = tools ? toGeminiTools(tools) : null;
|
|
9148
|
+
const body = { contents };
|
|
9149
|
+
if (systemInstruction) {
|
|
9150
|
+
body.systemInstruction = { role: "system", parts: [{ text: systemInstruction }] };
|
|
9151
|
+
}
|
|
9152
|
+
if (geminiTools) body.tools = geminiTools;
|
|
9153
|
+
const generationConfig = {};
|
|
9154
|
+
if (this.temperature !== void 0) generationConfig.temperature = this.temperature;
|
|
9155
|
+
if (this.maxOutputTokens !== void 0)
|
|
9156
|
+
generationConfig.maxOutputTokens = this.maxOutputTokens;
|
|
9157
|
+
if (Object.keys(generationConfig).length > 0) body.generationConfig = generationConfig;
|
|
9158
|
+
const url = `${this.baseUrl}/models/${encodeURIComponent(this.model)}:streamGenerateContent?alt=sse&key=${encodeURIComponent(this.apiKey)}`;
|
|
9159
|
+
const response = await fetch(url, {
|
|
9160
|
+
method: "POST",
|
|
9161
|
+
headers: { "Content-Type": "application/json" },
|
|
9162
|
+
body: JSON.stringify(body),
|
|
9163
|
+
signal: AbortSignal.timeout(3e4)
|
|
9164
|
+
});
|
|
9165
|
+
if (!response.ok) {
|
|
9166
|
+
const errText = await response.text();
|
|
9167
|
+
getLogger().error(`Gemini API error: ${response.status} ${errText}`);
|
|
9168
|
+
return;
|
|
9169
|
+
}
|
|
9170
|
+
const reader = response.body?.getReader();
|
|
9171
|
+
if (!reader) return;
|
|
9172
|
+
const decoder = new TextDecoder();
|
|
9173
|
+
let buffer = "";
|
|
9174
|
+
let nextIndex = 0;
|
|
9175
|
+
while (true) {
|
|
9176
|
+
const { done, value } = await reader.read();
|
|
9177
|
+
if (done) break;
|
|
9178
|
+
buffer += decoder.decode(value, { stream: true });
|
|
9179
|
+
const lines = buffer.split("\n");
|
|
9180
|
+
buffer = lines.pop() || "";
|
|
9181
|
+
for (const line of lines) {
|
|
9182
|
+
const trimmed = line.trim();
|
|
9183
|
+
if (!trimmed.startsWith("data: ")) continue;
|
|
9184
|
+
const data = trimmed.slice(6);
|
|
9185
|
+
if (!data) continue;
|
|
9186
|
+
let payload;
|
|
9187
|
+
try {
|
|
9188
|
+
payload = JSON.parse(data);
|
|
9189
|
+
} catch {
|
|
9190
|
+
continue;
|
|
9191
|
+
}
|
|
9192
|
+
const candidate = payload.candidates?.[0];
|
|
9193
|
+
const parts = candidate?.content?.parts ?? [];
|
|
9194
|
+
for (const part of parts) {
|
|
9195
|
+
if (part.functionCall) {
|
|
9196
|
+
const args = part.functionCall.args ?? {};
|
|
9197
|
+
const callId = part.functionCall.id ?? `gemini_call_${nextIndex}`;
|
|
9198
|
+
yield {
|
|
9199
|
+
type: "tool_call",
|
|
9200
|
+
index: nextIndex,
|
|
9201
|
+
id: callId,
|
|
9202
|
+
name: part.functionCall.name ?? "",
|
|
9203
|
+
arguments: JSON.stringify(args)
|
|
9204
|
+
};
|
|
9205
|
+
nextIndex++;
|
|
9206
|
+
continue;
|
|
9207
|
+
}
|
|
9208
|
+
if (part.text) {
|
|
9209
|
+
yield { type: "text", content: part.text };
|
|
9210
|
+
}
|
|
9211
|
+
}
|
|
9212
|
+
}
|
|
9213
|
+
}
|
|
9214
|
+
yield { type: "done" };
|
|
9215
|
+
}
|
|
9216
|
+
};
|
|
9217
|
+
function toGeminiTools(tools) {
|
|
9218
|
+
const functionDeclarations = tools.map((t) => {
|
|
9219
|
+
const fn = t.function ?? t;
|
|
9220
|
+
return {
|
|
9221
|
+
name: String(fn.name ?? ""),
|
|
9222
|
+
description: String(fn.description ?? ""),
|
|
9223
|
+
parameters: fn.parameters ?? { type: "object", properties: {} }
|
|
9224
|
+
};
|
|
9225
|
+
});
|
|
9226
|
+
if (functionDeclarations.length === 0) return [];
|
|
9227
|
+
return [{ functionDeclarations }];
|
|
9228
|
+
}
|
|
9229
|
+
function toGeminiContents(messages) {
|
|
9230
|
+
const systemParts = [];
|
|
9231
|
+
const contents = [];
|
|
9232
|
+
for (const rawMsg of messages) {
|
|
9233
|
+
const role = rawMsg.role;
|
|
9234
|
+
if (role === "system") {
|
|
9235
|
+
if (typeof rawMsg.content === "string" && rawMsg.content) {
|
|
9236
|
+
systemParts.push(rawMsg.content);
|
|
9237
|
+
}
|
|
9238
|
+
continue;
|
|
9239
|
+
}
|
|
9240
|
+
if (role === "user") {
|
|
9241
|
+
if (typeof rawMsg.content === "string" && rawMsg.content) {
|
|
9242
|
+
contents.push({ role: "user", parts: [{ text: rawMsg.content }] });
|
|
9243
|
+
}
|
|
9244
|
+
continue;
|
|
9245
|
+
}
|
|
9246
|
+
if (role === "assistant") {
|
|
9247
|
+
const parts = [];
|
|
9248
|
+
if (typeof rawMsg.content === "string" && rawMsg.content) {
|
|
9249
|
+
parts.push({ text: rawMsg.content });
|
|
9250
|
+
}
|
|
9251
|
+
for (const tc of rawMsg.tool_calls ?? []) {
|
|
9252
|
+
let args = {};
|
|
9253
|
+
try {
|
|
9254
|
+
const parsed = JSON.parse(tc.function?.arguments ?? "{}");
|
|
9255
|
+
if (parsed && typeof parsed === "object") args = parsed;
|
|
9256
|
+
} catch {
|
|
9257
|
+
args = {};
|
|
9258
|
+
}
|
|
9259
|
+
parts.push({
|
|
9260
|
+
functionCall: {
|
|
9261
|
+
name: tc.function?.name ?? "",
|
|
9262
|
+
args,
|
|
9263
|
+
id: tc.id
|
|
9264
|
+
}
|
|
9265
|
+
});
|
|
9266
|
+
}
|
|
9267
|
+
if (parts.length > 0) contents.push({ role: "model", parts });
|
|
9268
|
+
continue;
|
|
9269
|
+
}
|
|
9270
|
+
if (role === "tool") {
|
|
9271
|
+
const raw = rawMsg.content;
|
|
9272
|
+
let response;
|
|
9273
|
+
if (typeof raw === "string") {
|
|
9274
|
+
try {
|
|
9275
|
+
const parsed = JSON.parse(raw);
|
|
9276
|
+
response = parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : { result: parsed };
|
|
9277
|
+
} catch {
|
|
9278
|
+
response = { result: raw };
|
|
9279
|
+
}
|
|
9280
|
+
} else {
|
|
9281
|
+
response = raw ?? {};
|
|
9282
|
+
}
|
|
9283
|
+
contents.push({
|
|
9284
|
+
role: "user",
|
|
9285
|
+
parts: [
|
|
9286
|
+
{
|
|
9287
|
+
functionResponse: {
|
|
9288
|
+
name: rawMsg.name ?? rawMsg.tool_call_id ?? "",
|
|
9289
|
+
response,
|
|
9290
|
+
id: rawMsg.tool_call_id
|
|
9291
|
+
}
|
|
9292
|
+
}
|
|
9293
|
+
]
|
|
9294
|
+
});
|
|
9295
|
+
continue;
|
|
9296
|
+
}
|
|
9297
|
+
}
|
|
9298
|
+
return { systemInstruction: systemParts.join("\n\n"), contents };
|
|
9299
|
+
}
|
|
9300
|
+
|
|
9301
|
+
// src/llm/google.ts
|
|
9302
|
+
var LLM5 = class extends GoogleLLMProvider {
|
|
9303
|
+
constructor(opts = {}) {
|
|
9304
|
+
const key = opts.apiKey ?? process.env.GEMINI_API_KEY ?? process.env.GOOGLE_API_KEY;
|
|
9305
|
+
if (!key) {
|
|
9306
|
+
throw new Error(
|
|
9307
|
+
"Google LLM requires an apiKey. Pass { apiKey: 'AIza...' } or set GEMINI_API_KEY (or GOOGLE_API_KEY)."
|
|
9308
|
+
);
|
|
9309
|
+
}
|
|
9310
|
+
super({
|
|
9311
|
+
apiKey: key,
|
|
9312
|
+
model: opts.model,
|
|
9313
|
+
baseUrl: opts.baseUrl,
|
|
9314
|
+
temperature: opts.temperature,
|
|
9315
|
+
maxOutputTokens: opts.maxOutputTokens
|
|
9316
|
+
});
|
|
9317
|
+
}
|
|
9318
|
+
};
|
|
9319
|
+
|
|
9467
9320
|
// src/carriers/twilio.ts
|
|
9468
9321
|
var Carrier = class {
|
|
9469
9322
|
kind = "twilio";
|
|
@@ -10178,6 +10031,7 @@ function isAudioConfig(value) {
|
|
|
10178
10031
|
// Annotate the CommonJS export names for ESM import in node:
|
|
10179
10032
|
0 && (module.exports = {
|
|
10180
10033
|
AllProvidersFailedError,
|
|
10034
|
+
AnthropicLLM,
|
|
10181
10035
|
AssemblyAISTT,
|
|
10182
10036
|
AuthenticationError,
|
|
10183
10037
|
BackgroundAudioPlayer,
|
|
@@ -10185,6 +10039,7 @@ function isAudioConfig(value) {
|
|
|
10185
10039
|
CallMetricsAccumulator,
|
|
10186
10040
|
CartesiaSTT,
|
|
10187
10041
|
CartesiaTTS,
|
|
10042
|
+
CerebrasLLM,
|
|
10188
10043
|
ChatContext,
|
|
10189
10044
|
CloudflareTunnel,
|
|
10190
10045
|
DEFAULT_MIN_SENTENCE_LEN,
|
|
@@ -10198,11 +10053,14 @@ function isAudioConfig(value) {
|
|
|
10198
10053
|
GEMINI_DEFAULT_INPUT_SR,
|
|
10199
10054
|
GEMINI_DEFAULT_OUTPUT_SR,
|
|
10200
10055
|
GeminiLiveAdapter,
|
|
10056
|
+
GoogleLLM,
|
|
10057
|
+
GroqLLM,
|
|
10201
10058
|
Guardrail,
|
|
10202
10059
|
IVRActivity,
|
|
10203
10060
|
LLMLoop,
|
|
10204
10061
|
LMNTTTS,
|
|
10205
10062
|
MetricsStore,
|
|
10063
|
+
OpenAILLM,
|
|
10206
10064
|
OpenAILLMProvider,
|
|
10207
10065
|
OpenAIRealtime,
|
|
10208
10066
|
OpenAIRealtimeAdapter,
|