getpatter 0.5.0 → 0.5.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/README.md +25 -1
- package/dist/{chunk-JO5C35FM.mjs → chunk-AKQFOFLG.mjs} +1 -1
- package/dist/{chunk-757NVN4L.mjs → chunk-B6C3KIBG.mjs} +48 -23
- package/dist/index.d.mts +363 -56
- package/dist/index.d.ts +363 -56
- package/dist/index.js +690 -850
- package/dist/index.mjs +634 -4
- package/dist/{test-mode-YFOL2HYH.mjs → test-mode-JZMYE5HY.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
|
@@ -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
|
|
@@ -4438,832 +4463,6 @@ Connect AI agents to phone numbers in 4 lines of code
|
|
|
4438
4463
|
}
|
|
4439
4464
|
});
|
|
4440
4465
|
|
|
4441
|
-
// node_modules/cloudflared/lib/constants.js
|
|
4442
|
-
var require_constants = __commonJS({
|
|
4443
|
-
"node_modules/cloudflared/lib/constants.js"(exports2, module2) {
|
|
4444
|
-
"use strict";
|
|
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
|
-
}
|
|
4529
|
-
});
|
|
4530
|
-
|
|
4531
|
-
// node_modules/cloudflared/lib/install.js
|
|
4532
|
-
var require_install = __commonJS({
|
|
4533
|
-
"node_modules/cloudflared/lib/install.js"(exports2, module2) {
|
|
4534
|
-
"use strict";
|
|
4535
|
-
var __create2 = Object.create;
|
|
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) {
|
|
5014
|
-
"use strict";
|
|
5015
|
-
var __create2 = Object.create;
|
|
5016
|
-
var __defProp2 = Object.defineProperty;
|
|
5017
|
-
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
5018
|
-
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
5019
|
-
var __getProtoOf2 = Object.getPrototypeOf;
|
|
5020
|
-
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
5021
|
-
var __export2 = (target, all) => {
|
|
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
|
-
});
|
|
5227
|
-
|
|
5228
|
-
// node_modules/cloudflared/lib/lib.js
|
|
5229
|
-
var require_lib = __commonJS({
|
|
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);
|
|
5264
|
-
}
|
|
5265
|
-
});
|
|
5266
|
-
|
|
5267
4466
|
// src/tunnel.ts
|
|
5268
4467
|
var tunnel_exports = {};
|
|
5269
4468
|
__export(tunnel_exports, {
|
|
@@ -5272,7 +4471,7 @@ __export(tunnel_exports, {
|
|
|
5272
4471
|
async function startTunnel(port, timeoutMs = 3e4) {
|
|
5273
4472
|
let tunnelMod;
|
|
5274
4473
|
try {
|
|
5275
|
-
tunnelMod = await
|
|
4474
|
+
tunnelMod = await import("cloudflared");
|
|
5276
4475
|
} catch {
|
|
5277
4476
|
throw new Error(
|
|
5278
4477
|
'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 +5734,7 @@ var require_node_cron = __commonJS({
|
|
|
6535
5734
|
var index_exports = {};
|
|
6536
5735
|
__export(index_exports, {
|
|
6537
5736
|
AllProvidersFailedError: () => AllProvidersFailedError,
|
|
5737
|
+
AnthropicLLM: () => LLM2,
|
|
6538
5738
|
AssemblyAISTT: () => STT5,
|
|
6539
5739
|
AuthenticationError: () => AuthenticationError,
|
|
6540
5740
|
BackgroundAudioPlayer: () => BackgroundAudioPlayer,
|
|
@@ -6542,6 +5742,7 @@ __export(index_exports, {
|
|
|
6542
5742
|
CallMetricsAccumulator: () => CallMetricsAccumulator,
|
|
6543
5743
|
CartesiaSTT: () => STT3,
|
|
6544
5744
|
CartesiaTTS: () => TTS3,
|
|
5745
|
+
CerebrasLLM: () => LLM4,
|
|
6545
5746
|
ChatContext: () => ChatContext,
|
|
6546
5747
|
CloudflareTunnel: () => CloudflareTunnel,
|
|
6547
5748
|
DEFAULT_MIN_SENTENCE_LEN: () => DEFAULT_MIN_SENTENCE_LEN,
|
|
@@ -6555,11 +5756,14 @@ __export(index_exports, {
|
|
|
6555
5756
|
GEMINI_DEFAULT_INPUT_SR: () => GEMINI_DEFAULT_INPUT_SR,
|
|
6556
5757
|
GEMINI_DEFAULT_OUTPUT_SR: () => GEMINI_DEFAULT_OUTPUT_SR,
|
|
6557
5758
|
GeminiLiveAdapter: () => GeminiLiveAdapter,
|
|
5759
|
+
GoogleLLM: () => LLM5,
|
|
5760
|
+
GroqLLM: () => LLM3,
|
|
6558
5761
|
Guardrail: () => Guardrail,
|
|
6559
5762
|
IVRActivity: () => IVRActivity,
|
|
6560
5763
|
LLMLoop: () => LLMLoop,
|
|
6561
5764
|
LMNTTTS: () => TTS5,
|
|
6562
5765
|
MetricsStore: () => MetricsStore,
|
|
5766
|
+
OpenAILLM: () => LLM,
|
|
6563
5767
|
OpenAILLMProvider: () => OpenAILLMProvider,
|
|
6564
5768
|
OpenAIRealtime: () => Realtime,
|
|
6565
5769
|
OpenAIRealtimeAdapter: () => OpenAIRealtimeAdapter,
|
|
@@ -6830,6 +6034,7 @@ var Static = class {
|
|
|
6830
6034
|
};
|
|
6831
6035
|
|
|
6832
6036
|
// src/client.ts
|
|
6037
|
+
init_logger();
|
|
6833
6038
|
var DEFAULT_BACKEND_URL2 = "wss://api.getpatter.com";
|
|
6834
6039
|
var DEFAULT_REST_URL = "https://api.getpatter.com";
|
|
6835
6040
|
function sttConfigToDict(cfg) {
|
|
@@ -6938,6 +6143,8 @@ var Patter = class {
|
|
|
6938
6143
|
"Unknown engine. Expected OpenAIRealtime or ElevenLabsConvAI instance."
|
|
6939
6144
|
);
|
|
6940
6145
|
}
|
|
6146
|
+
} else if (!working.provider && (working.stt !== void 0 || working.tts !== void 0 || working.llm !== void 0)) {
|
|
6147
|
+
working = { ...working, provider: "pipeline" };
|
|
6941
6148
|
}
|
|
6942
6149
|
if (working.provider) {
|
|
6943
6150
|
const valid = ["openai_realtime", "elevenlabs_convai", "pipeline"];
|
|
@@ -6945,6 +6152,19 @@ var Patter = class {
|
|
|
6945
6152
|
throw new Error(`provider must be one of: ${valid.join(", ")}. Got: '${working.provider}'`);
|
|
6946
6153
|
}
|
|
6947
6154
|
}
|
|
6155
|
+
if (working.llm !== void 0) {
|
|
6156
|
+
const llm = working.llm;
|
|
6157
|
+
if (!llm || typeof llm.stream !== "function") {
|
|
6158
|
+
throw new Error(
|
|
6159
|
+
"`llm` must be an LLMProvider instance (e.g. new AnthropicLLM()). Got a value without a `.stream` method."
|
|
6160
|
+
);
|
|
6161
|
+
}
|
|
6162
|
+
if (working.engine) {
|
|
6163
|
+
getLogger().warn(
|
|
6164
|
+
"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."
|
|
6165
|
+
);
|
|
6166
|
+
}
|
|
6167
|
+
}
|
|
6948
6168
|
if (working.tools) {
|
|
6949
6169
|
if (!Array.isArray(working.tools)) {
|
|
6950
6170
|
throw new TypeError("tools must be an array");
|
|
@@ -9464,6 +8684,621 @@ var TTS5 = class extends LMNTTTS {
|
|
|
9464
8684
|
}
|
|
9465
8685
|
};
|
|
9466
8686
|
|
|
8687
|
+
// src/llm/openai.ts
|
|
8688
|
+
init_llm_loop();
|
|
8689
|
+
var LLM = class extends OpenAILLMProvider {
|
|
8690
|
+
constructor(opts = {}) {
|
|
8691
|
+
const key = opts.apiKey ?? process.env.OPENAI_API_KEY;
|
|
8692
|
+
if (!key) {
|
|
8693
|
+
throw new Error(
|
|
8694
|
+
"OpenAI LLM requires an apiKey. Pass { apiKey: 'sk-...' } or set OPENAI_API_KEY."
|
|
8695
|
+
);
|
|
8696
|
+
}
|
|
8697
|
+
super(key, opts.model ?? "gpt-4o-mini");
|
|
8698
|
+
}
|
|
8699
|
+
};
|
|
8700
|
+
|
|
8701
|
+
// src/providers/anthropic-llm.ts
|
|
8702
|
+
init_logger();
|
|
8703
|
+
var DEFAULT_ANTHROPIC_URL = "https://api.anthropic.com/v1/messages";
|
|
8704
|
+
var DEFAULT_ANTHROPIC_VERSION = "2023-06-01";
|
|
8705
|
+
var DEFAULT_MODEL = "claude-3-5-sonnet-20241022";
|
|
8706
|
+
var DEFAULT_MAX_TOKENS = 1024;
|
|
8707
|
+
var AnthropicLLMProvider = class {
|
|
8708
|
+
apiKey;
|
|
8709
|
+
model;
|
|
8710
|
+
maxTokens;
|
|
8711
|
+
temperature;
|
|
8712
|
+
url;
|
|
8713
|
+
anthropicVersion;
|
|
8714
|
+
constructor(options) {
|
|
8715
|
+
if (!options.apiKey) {
|
|
8716
|
+
throw new Error(
|
|
8717
|
+
"Anthropic API key is required. Pass it via { apiKey } or set the ANTHROPIC_API_KEY environment variable before constructing the provider."
|
|
8718
|
+
);
|
|
8719
|
+
}
|
|
8720
|
+
this.apiKey = options.apiKey;
|
|
8721
|
+
this.model = options.model ?? DEFAULT_MODEL;
|
|
8722
|
+
this.maxTokens = options.maxTokens ?? DEFAULT_MAX_TOKENS;
|
|
8723
|
+
this.temperature = options.temperature;
|
|
8724
|
+
this.url = options.baseUrl ?? DEFAULT_ANTHROPIC_URL;
|
|
8725
|
+
this.anthropicVersion = options.anthropicVersion ?? DEFAULT_ANTHROPIC_VERSION;
|
|
8726
|
+
}
|
|
8727
|
+
async *stream(messages, tools) {
|
|
8728
|
+
const { system, messages: anthropicMessages } = toAnthropicMessages(messages);
|
|
8729
|
+
const anthropicTools = tools ? toAnthropicTools(tools) : null;
|
|
8730
|
+
const body = {
|
|
8731
|
+
model: this.model,
|
|
8732
|
+
messages: anthropicMessages,
|
|
8733
|
+
max_tokens: this.maxTokens,
|
|
8734
|
+
stream: true
|
|
8735
|
+
};
|
|
8736
|
+
if (system) body.system = system;
|
|
8737
|
+
if (anthropicTools && anthropicTools.length > 0) body.tools = anthropicTools;
|
|
8738
|
+
if (this.temperature !== void 0) body.temperature = this.temperature;
|
|
8739
|
+
const response = await fetch(this.url, {
|
|
8740
|
+
method: "POST",
|
|
8741
|
+
headers: {
|
|
8742
|
+
"Content-Type": "application/json",
|
|
8743
|
+
"x-api-key": this.apiKey,
|
|
8744
|
+
"anthropic-version": this.anthropicVersion
|
|
8745
|
+
},
|
|
8746
|
+
body: JSON.stringify(body),
|
|
8747
|
+
signal: AbortSignal.timeout(3e4)
|
|
8748
|
+
});
|
|
8749
|
+
if (!response.ok) {
|
|
8750
|
+
const errText = await response.text();
|
|
8751
|
+
getLogger().error(`Anthropic API error: ${response.status} ${errText}`);
|
|
8752
|
+
return;
|
|
8753
|
+
}
|
|
8754
|
+
const reader = response.body?.getReader();
|
|
8755
|
+
if (!reader) return;
|
|
8756
|
+
const decoder = new TextDecoder();
|
|
8757
|
+
let buffer = "";
|
|
8758
|
+
const toolIndexByBlock = /* @__PURE__ */ new Map();
|
|
8759
|
+
const toolIdByBlock = /* @__PURE__ */ new Map();
|
|
8760
|
+
let nextIndex = 0;
|
|
8761
|
+
while (true) {
|
|
8762
|
+
const { done, value } = await reader.read();
|
|
8763
|
+
if (done) break;
|
|
8764
|
+
buffer += decoder.decode(value, { stream: true });
|
|
8765
|
+
const lines = buffer.split("\n");
|
|
8766
|
+
buffer = lines.pop() || "";
|
|
8767
|
+
for (const line of lines) {
|
|
8768
|
+
const trimmed = line.trim();
|
|
8769
|
+
if (!trimmed.startsWith("data: ")) continue;
|
|
8770
|
+
const data = trimmed.slice(6);
|
|
8771
|
+
if (!data || data === "[DONE]") continue;
|
|
8772
|
+
let event;
|
|
8773
|
+
try {
|
|
8774
|
+
event = JSON.parse(data);
|
|
8775
|
+
} catch {
|
|
8776
|
+
continue;
|
|
8777
|
+
}
|
|
8778
|
+
if (event.type === "content_block_start" && event.content_block?.type === "tool_use") {
|
|
8779
|
+
const blockIdx = event.index ?? 0;
|
|
8780
|
+
const toolId = event.content_block.id ?? "";
|
|
8781
|
+
const toolName = event.content_block.name ?? "";
|
|
8782
|
+
const patterIndex = nextIndex++;
|
|
8783
|
+
toolIndexByBlock.set(blockIdx, patterIndex);
|
|
8784
|
+
toolIdByBlock.set(blockIdx, toolId);
|
|
8785
|
+
yield {
|
|
8786
|
+
type: "tool_call",
|
|
8787
|
+
index: patterIndex,
|
|
8788
|
+
id: toolId,
|
|
8789
|
+
name: toolName,
|
|
8790
|
+
arguments: ""
|
|
8791
|
+
};
|
|
8792
|
+
continue;
|
|
8793
|
+
}
|
|
8794
|
+
if (event.type === "content_block_delta") {
|
|
8795
|
+
if (event.delta?.type === "text_delta" && event.delta.text) {
|
|
8796
|
+
yield { type: "text", content: event.delta.text };
|
|
8797
|
+
continue;
|
|
8798
|
+
}
|
|
8799
|
+
if (event.delta?.type === "input_json_delta" && event.delta.partial_json) {
|
|
8800
|
+
const blockIdx = event.index ?? 0;
|
|
8801
|
+
const patterIndex = toolIndexByBlock.get(blockIdx);
|
|
8802
|
+
if (patterIndex !== void 0) {
|
|
8803
|
+
yield {
|
|
8804
|
+
type: "tool_call",
|
|
8805
|
+
index: patterIndex,
|
|
8806
|
+
id: toolIdByBlock.get(blockIdx),
|
|
8807
|
+
arguments: event.delta.partial_json
|
|
8808
|
+
};
|
|
8809
|
+
}
|
|
8810
|
+
}
|
|
8811
|
+
}
|
|
8812
|
+
}
|
|
8813
|
+
}
|
|
8814
|
+
yield { type: "done" };
|
|
8815
|
+
}
|
|
8816
|
+
};
|
|
8817
|
+
function toAnthropicTools(tools) {
|
|
8818
|
+
return tools.map((t) => {
|
|
8819
|
+
const fn = t.function ?? t;
|
|
8820
|
+
return {
|
|
8821
|
+
name: String(fn.name ?? ""),
|
|
8822
|
+
description: String(fn.description ?? ""),
|
|
8823
|
+
input_schema: fn.parameters ?? { type: "object", properties: {} }
|
|
8824
|
+
};
|
|
8825
|
+
});
|
|
8826
|
+
}
|
|
8827
|
+
function toAnthropicMessages(messages) {
|
|
8828
|
+
const systemParts = [];
|
|
8829
|
+
const out = [];
|
|
8830
|
+
for (const rawMsg of messages) {
|
|
8831
|
+
const role = rawMsg.role;
|
|
8832
|
+
if (role === "system") {
|
|
8833
|
+
if (typeof rawMsg.content === "string" && rawMsg.content) {
|
|
8834
|
+
systemParts.push(rawMsg.content);
|
|
8835
|
+
}
|
|
8836
|
+
continue;
|
|
8837
|
+
}
|
|
8838
|
+
if (role === "user") {
|
|
8839
|
+
if (typeof rawMsg.content === "string") {
|
|
8840
|
+
out.push({ role: "user", content: rawMsg.content });
|
|
8841
|
+
} else if (rawMsg.content) {
|
|
8842
|
+
out.push({ role: "user", content: rawMsg.content });
|
|
8843
|
+
}
|
|
8844
|
+
continue;
|
|
8845
|
+
}
|
|
8846
|
+
if (role === "assistant") {
|
|
8847
|
+
const blocks = [];
|
|
8848
|
+
if (typeof rawMsg.content === "string" && rawMsg.content) {
|
|
8849
|
+
blocks.push({ type: "text", text: rawMsg.content });
|
|
8850
|
+
}
|
|
8851
|
+
for (const tc of rawMsg.tool_calls ?? []) {
|
|
8852
|
+
let args = {};
|
|
8853
|
+
try {
|
|
8854
|
+
args = JSON.parse(tc.function?.arguments ?? "{}");
|
|
8855
|
+
} catch {
|
|
8856
|
+
args = {};
|
|
8857
|
+
}
|
|
8858
|
+
blocks.push({
|
|
8859
|
+
type: "tool_use",
|
|
8860
|
+
id: tc.id ?? "",
|
|
8861
|
+
name: tc.function?.name ?? "",
|
|
8862
|
+
input: args
|
|
8863
|
+
});
|
|
8864
|
+
}
|
|
8865
|
+
if (blocks.length > 0) {
|
|
8866
|
+
out.push({ role: "assistant", content: blocks });
|
|
8867
|
+
}
|
|
8868
|
+
continue;
|
|
8869
|
+
}
|
|
8870
|
+
if (role === "tool") {
|
|
8871
|
+
const contentStr = typeof rawMsg.content === "string" ? rawMsg.content : JSON.stringify(rawMsg.content);
|
|
8872
|
+
out.push({
|
|
8873
|
+
role: "user",
|
|
8874
|
+
content: [
|
|
8875
|
+
{
|
|
8876
|
+
type: "tool_result",
|
|
8877
|
+
tool_use_id: rawMsg.tool_call_id ?? "",
|
|
8878
|
+
content: contentStr
|
|
8879
|
+
}
|
|
8880
|
+
]
|
|
8881
|
+
});
|
|
8882
|
+
continue;
|
|
8883
|
+
}
|
|
8884
|
+
}
|
|
8885
|
+
return { system: systemParts.join("\n\n"), messages: out };
|
|
8886
|
+
}
|
|
8887
|
+
|
|
8888
|
+
// src/llm/anthropic.ts
|
|
8889
|
+
var LLM2 = class extends AnthropicLLMProvider {
|
|
8890
|
+
constructor(opts = {}) {
|
|
8891
|
+
const key = opts.apiKey ?? process.env.ANTHROPIC_API_KEY;
|
|
8892
|
+
if (!key) {
|
|
8893
|
+
throw new Error(
|
|
8894
|
+
"Anthropic LLM requires an apiKey. Pass { apiKey: 'sk-ant-...' } or set ANTHROPIC_API_KEY."
|
|
8895
|
+
);
|
|
8896
|
+
}
|
|
8897
|
+
super({
|
|
8898
|
+
apiKey: key,
|
|
8899
|
+
model: opts.model,
|
|
8900
|
+
maxTokens: opts.maxTokens,
|
|
8901
|
+
temperature: opts.temperature,
|
|
8902
|
+
baseUrl: opts.baseUrl,
|
|
8903
|
+
anthropicVersion: opts.anthropicVersion
|
|
8904
|
+
});
|
|
8905
|
+
}
|
|
8906
|
+
};
|
|
8907
|
+
|
|
8908
|
+
// src/providers/groq-llm.ts
|
|
8909
|
+
init_logger();
|
|
8910
|
+
var GROQ_BASE_URL = "https://api.groq.com/openai/v1";
|
|
8911
|
+
var DEFAULT_MODEL2 = "llama-3.3-70b-versatile";
|
|
8912
|
+
var GroqLLMProvider = class {
|
|
8913
|
+
apiKey;
|
|
8914
|
+
model;
|
|
8915
|
+
baseUrl;
|
|
8916
|
+
constructor(options) {
|
|
8917
|
+
if (!options.apiKey) {
|
|
8918
|
+
throw new Error(
|
|
8919
|
+
"Groq API key is required. Pass it via { apiKey } or read GROQ_API_KEY from the environment."
|
|
8920
|
+
);
|
|
8921
|
+
}
|
|
8922
|
+
this.apiKey = options.apiKey;
|
|
8923
|
+
this.model = options.model ?? DEFAULT_MODEL2;
|
|
8924
|
+
this.baseUrl = options.baseUrl ?? GROQ_BASE_URL;
|
|
8925
|
+
}
|
|
8926
|
+
async *stream(messages, tools) {
|
|
8927
|
+
const body = {
|
|
8928
|
+
model: this.model,
|
|
8929
|
+
messages,
|
|
8930
|
+
stream: true
|
|
8931
|
+
};
|
|
8932
|
+
if (tools) body.tools = tools;
|
|
8933
|
+
const response = await fetch(`${this.baseUrl}/chat/completions`, {
|
|
8934
|
+
method: "POST",
|
|
8935
|
+
headers: {
|
|
8936
|
+
"Content-Type": "application/json",
|
|
8937
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
8938
|
+
},
|
|
8939
|
+
body: JSON.stringify(body),
|
|
8940
|
+
signal: AbortSignal.timeout(3e4)
|
|
8941
|
+
});
|
|
8942
|
+
if (!response.ok) {
|
|
8943
|
+
const errText = await response.text();
|
|
8944
|
+
getLogger().error(`Groq API error: ${response.status} ${errText}`);
|
|
8945
|
+
return;
|
|
8946
|
+
}
|
|
8947
|
+
yield* parseOpenAISseStream(response);
|
|
8948
|
+
}
|
|
8949
|
+
};
|
|
8950
|
+
async function* parseOpenAISseStream(response) {
|
|
8951
|
+
const reader = response.body?.getReader();
|
|
8952
|
+
if (!reader) return;
|
|
8953
|
+
const decoder = new TextDecoder();
|
|
8954
|
+
let buffer = "";
|
|
8955
|
+
while (true) {
|
|
8956
|
+
const { done, value } = await reader.read();
|
|
8957
|
+
if (done) break;
|
|
8958
|
+
buffer += decoder.decode(value, { stream: true });
|
|
8959
|
+
const lines = buffer.split("\n");
|
|
8960
|
+
buffer = lines.pop() || "";
|
|
8961
|
+
for (const line of lines) {
|
|
8962
|
+
const trimmed = line.trim();
|
|
8963
|
+
if (!trimmed || !trimmed.startsWith("data: ")) continue;
|
|
8964
|
+
const data = trimmed.slice(6);
|
|
8965
|
+
if (data === "[DONE]") continue;
|
|
8966
|
+
let chunk;
|
|
8967
|
+
try {
|
|
8968
|
+
chunk = JSON.parse(data);
|
|
8969
|
+
} catch {
|
|
8970
|
+
continue;
|
|
8971
|
+
}
|
|
8972
|
+
const delta = chunk.choices?.[0]?.delta;
|
|
8973
|
+
if (!delta) continue;
|
|
8974
|
+
if (delta.content) {
|
|
8975
|
+
yield { type: "text", content: delta.content };
|
|
8976
|
+
}
|
|
8977
|
+
if (delta.tool_calls) {
|
|
8978
|
+
for (const tc of delta.tool_calls) {
|
|
8979
|
+
yield {
|
|
8980
|
+
type: "tool_call",
|
|
8981
|
+
index: tc.index,
|
|
8982
|
+
id: tc.id,
|
|
8983
|
+
name: tc.function?.name,
|
|
8984
|
+
arguments: tc.function?.arguments
|
|
8985
|
+
};
|
|
8986
|
+
}
|
|
8987
|
+
}
|
|
8988
|
+
}
|
|
8989
|
+
}
|
|
8990
|
+
}
|
|
8991
|
+
|
|
8992
|
+
// src/llm/groq.ts
|
|
8993
|
+
var LLM3 = class extends GroqLLMProvider {
|
|
8994
|
+
constructor(opts = {}) {
|
|
8995
|
+
const key = opts.apiKey ?? process.env.GROQ_API_KEY;
|
|
8996
|
+
if (!key) {
|
|
8997
|
+
throw new Error(
|
|
8998
|
+
"Groq LLM requires an apiKey. Pass { apiKey: 'gsk_...' } or set GROQ_API_KEY."
|
|
8999
|
+
);
|
|
9000
|
+
}
|
|
9001
|
+
super({
|
|
9002
|
+
apiKey: key,
|
|
9003
|
+
model: opts.model,
|
|
9004
|
+
baseUrl: opts.baseUrl
|
|
9005
|
+
});
|
|
9006
|
+
}
|
|
9007
|
+
};
|
|
9008
|
+
|
|
9009
|
+
// src/providers/cerebras-llm.ts
|
|
9010
|
+
init_logger();
|
|
9011
|
+
var CEREBRAS_BASE_URL = "https://api.cerebras.ai/v1";
|
|
9012
|
+
var DEFAULT_MODEL3 = "llama3.1-8b";
|
|
9013
|
+
var CerebrasLLMProvider = class {
|
|
9014
|
+
apiKey;
|
|
9015
|
+
model;
|
|
9016
|
+
baseUrl;
|
|
9017
|
+
gzipCompression;
|
|
9018
|
+
constructor(options) {
|
|
9019
|
+
if (!options.apiKey) {
|
|
9020
|
+
throw new Error(
|
|
9021
|
+
"Cerebras API key is required. Pass it via { apiKey } or read CEREBRAS_API_KEY from the environment."
|
|
9022
|
+
);
|
|
9023
|
+
}
|
|
9024
|
+
this.apiKey = options.apiKey;
|
|
9025
|
+
this.model = options.model ?? DEFAULT_MODEL3;
|
|
9026
|
+
this.baseUrl = options.baseUrl ?? CEREBRAS_BASE_URL;
|
|
9027
|
+
this.gzipCompression = options.gzipCompression ?? false;
|
|
9028
|
+
}
|
|
9029
|
+
async *stream(messages, tools) {
|
|
9030
|
+
const body = {
|
|
9031
|
+
model: this.model,
|
|
9032
|
+
messages,
|
|
9033
|
+
stream: true
|
|
9034
|
+
};
|
|
9035
|
+
if (tools) body.tools = tools;
|
|
9036
|
+
const headers = {
|
|
9037
|
+
"Content-Type": "application/json",
|
|
9038
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
9039
|
+
};
|
|
9040
|
+
let payload = JSON.stringify(body);
|
|
9041
|
+
if (this.gzipCompression) {
|
|
9042
|
+
const compressed = await gzipEncode(payload);
|
|
9043
|
+
if (compressed) {
|
|
9044
|
+
payload = compressed;
|
|
9045
|
+
headers["Content-Encoding"] = "gzip";
|
|
9046
|
+
}
|
|
9047
|
+
}
|
|
9048
|
+
const response = await fetch(`${this.baseUrl}/chat/completions`, {
|
|
9049
|
+
method: "POST",
|
|
9050
|
+
headers,
|
|
9051
|
+
body: payload,
|
|
9052
|
+
signal: AbortSignal.timeout(3e4)
|
|
9053
|
+
});
|
|
9054
|
+
if (!response.ok) {
|
|
9055
|
+
const errText = await response.text();
|
|
9056
|
+
getLogger().error(`Cerebras API error: ${response.status} ${errText}`);
|
|
9057
|
+
return;
|
|
9058
|
+
}
|
|
9059
|
+
yield* parseOpenAISseStream(response);
|
|
9060
|
+
}
|
|
9061
|
+
};
|
|
9062
|
+
async function gzipEncode(data) {
|
|
9063
|
+
const CompressionCtor = globalThis.CompressionStream;
|
|
9064
|
+
if (!CompressionCtor) return null;
|
|
9065
|
+
const stream = new CompressionCtor("gzip");
|
|
9066
|
+
const writer = stream.writable.getWriter();
|
|
9067
|
+
const encoder = new TextEncoder();
|
|
9068
|
+
await writer.write(encoder.encode(data));
|
|
9069
|
+
await writer.close();
|
|
9070
|
+
const chunks = [];
|
|
9071
|
+
const reader = stream.readable.getReader();
|
|
9072
|
+
while (true) {
|
|
9073
|
+
const { done, value } = await reader.read();
|
|
9074
|
+
if (done) break;
|
|
9075
|
+
if (value) chunks.push(value);
|
|
9076
|
+
}
|
|
9077
|
+
const total = chunks.reduce((n, c) => n + c.length, 0);
|
|
9078
|
+
const out = new Uint8Array(total);
|
|
9079
|
+
let offset = 0;
|
|
9080
|
+
for (const c of chunks) {
|
|
9081
|
+
out.set(c, offset);
|
|
9082
|
+
offset += c.length;
|
|
9083
|
+
}
|
|
9084
|
+
return out;
|
|
9085
|
+
}
|
|
9086
|
+
|
|
9087
|
+
// src/llm/cerebras.ts
|
|
9088
|
+
var LLM4 = class extends CerebrasLLMProvider {
|
|
9089
|
+
constructor(opts = {}) {
|
|
9090
|
+
const key = opts.apiKey ?? process.env.CEREBRAS_API_KEY;
|
|
9091
|
+
if (!key) {
|
|
9092
|
+
throw new Error(
|
|
9093
|
+
"Cerebras LLM requires an apiKey. Pass { apiKey: 'csk-...' } or set CEREBRAS_API_KEY."
|
|
9094
|
+
);
|
|
9095
|
+
}
|
|
9096
|
+
super({
|
|
9097
|
+
apiKey: key,
|
|
9098
|
+
model: opts.model,
|
|
9099
|
+
baseUrl: opts.baseUrl,
|
|
9100
|
+
gzipCompression: opts.gzipCompression
|
|
9101
|
+
});
|
|
9102
|
+
}
|
|
9103
|
+
};
|
|
9104
|
+
|
|
9105
|
+
// src/providers/google-llm.ts
|
|
9106
|
+
init_logger();
|
|
9107
|
+
var DEFAULT_MODEL4 = "gemini-2.5-flash";
|
|
9108
|
+
var DEFAULT_BASE_URL3 = "https://generativelanguage.googleapis.com/v1beta";
|
|
9109
|
+
var GoogleLLMProvider = class {
|
|
9110
|
+
apiKey;
|
|
9111
|
+
model;
|
|
9112
|
+
baseUrl;
|
|
9113
|
+
temperature;
|
|
9114
|
+
maxOutputTokens;
|
|
9115
|
+
constructor(options) {
|
|
9116
|
+
if (!options.apiKey) {
|
|
9117
|
+
throw new Error(
|
|
9118
|
+
"Google API key is required. Pass it via { apiKey } or read GOOGLE_API_KEY from the environment."
|
|
9119
|
+
);
|
|
9120
|
+
}
|
|
9121
|
+
this.apiKey = options.apiKey;
|
|
9122
|
+
this.model = options.model ?? DEFAULT_MODEL4;
|
|
9123
|
+
this.baseUrl = options.baseUrl ?? DEFAULT_BASE_URL3;
|
|
9124
|
+
this.temperature = options.temperature;
|
|
9125
|
+
this.maxOutputTokens = options.maxOutputTokens;
|
|
9126
|
+
}
|
|
9127
|
+
async *stream(messages, tools) {
|
|
9128
|
+
const { systemInstruction, contents } = toGeminiContents(messages);
|
|
9129
|
+
const geminiTools = tools ? toGeminiTools(tools) : null;
|
|
9130
|
+
const body = { contents };
|
|
9131
|
+
if (systemInstruction) {
|
|
9132
|
+
body.systemInstruction = { role: "system", parts: [{ text: systemInstruction }] };
|
|
9133
|
+
}
|
|
9134
|
+
if (geminiTools) body.tools = geminiTools;
|
|
9135
|
+
const generationConfig = {};
|
|
9136
|
+
if (this.temperature !== void 0) generationConfig.temperature = this.temperature;
|
|
9137
|
+
if (this.maxOutputTokens !== void 0)
|
|
9138
|
+
generationConfig.maxOutputTokens = this.maxOutputTokens;
|
|
9139
|
+
if (Object.keys(generationConfig).length > 0) body.generationConfig = generationConfig;
|
|
9140
|
+
const url = `${this.baseUrl}/models/${encodeURIComponent(this.model)}:streamGenerateContent?alt=sse&key=${encodeURIComponent(this.apiKey)}`;
|
|
9141
|
+
const response = await fetch(url, {
|
|
9142
|
+
method: "POST",
|
|
9143
|
+
headers: { "Content-Type": "application/json" },
|
|
9144
|
+
body: JSON.stringify(body),
|
|
9145
|
+
signal: AbortSignal.timeout(3e4)
|
|
9146
|
+
});
|
|
9147
|
+
if (!response.ok) {
|
|
9148
|
+
const errText = await response.text();
|
|
9149
|
+
getLogger().error(`Gemini API error: ${response.status} ${errText}`);
|
|
9150
|
+
return;
|
|
9151
|
+
}
|
|
9152
|
+
const reader = response.body?.getReader();
|
|
9153
|
+
if (!reader) return;
|
|
9154
|
+
const decoder = new TextDecoder();
|
|
9155
|
+
let buffer = "";
|
|
9156
|
+
let nextIndex = 0;
|
|
9157
|
+
while (true) {
|
|
9158
|
+
const { done, value } = await reader.read();
|
|
9159
|
+
if (done) break;
|
|
9160
|
+
buffer += decoder.decode(value, { stream: true });
|
|
9161
|
+
const lines = buffer.split("\n");
|
|
9162
|
+
buffer = lines.pop() || "";
|
|
9163
|
+
for (const line of lines) {
|
|
9164
|
+
const trimmed = line.trim();
|
|
9165
|
+
if (!trimmed.startsWith("data: ")) continue;
|
|
9166
|
+
const data = trimmed.slice(6);
|
|
9167
|
+
if (!data) continue;
|
|
9168
|
+
let payload;
|
|
9169
|
+
try {
|
|
9170
|
+
payload = JSON.parse(data);
|
|
9171
|
+
} catch {
|
|
9172
|
+
continue;
|
|
9173
|
+
}
|
|
9174
|
+
const candidate = payload.candidates?.[0];
|
|
9175
|
+
const parts = candidate?.content?.parts ?? [];
|
|
9176
|
+
for (const part of parts) {
|
|
9177
|
+
if (part.functionCall) {
|
|
9178
|
+
const args = part.functionCall.args ?? {};
|
|
9179
|
+
const callId = part.functionCall.id ?? `gemini_call_${nextIndex}`;
|
|
9180
|
+
yield {
|
|
9181
|
+
type: "tool_call",
|
|
9182
|
+
index: nextIndex,
|
|
9183
|
+
id: callId,
|
|
9184
|
+
name: part.functionCall.name ?? "",
|
|
9185
|
+
arguments: JSON.stringify(args)
|
|
9186
|
+
};
|
|
9187
|
+
nextIndex++;
|
|
9188
|
+
continue;
|
|
9189
|
+
}
|
|
9190
|
+
if (part.text) {
|
|
9191
|
+
yield { type: "text", content: part.text };
|
|
9192
|
+
}
|
|
9193
|
+
}
|
|
9194
|
+
}
|
|
9195
|
+
}
|
|
9196
|
+
yield { type: "done" };
|
|
9197
|
+
}
|
|
9198
|
+
};
|
|
9199
|
+
function toGeminiTools(tools) {
|
|
9200
|
+
const functionDeclarations = tools.map((t) => {
|
|
9201
|
+
const fn = t.function ?? t;
|
|
9202
|
+
return {
|
|
9203
|
+
name: String(fn.name ?? ""),
|
|
9204
|
+
description: String(fn.description ?? ""),
|
|
9205
|
+
parameters: fn.parameters ?? { type: "object", properties: {} }
|
|
9206
|
+
};
|
|
9207
|
+
});
|
|
9208
|
+
if (functionDeclarations.length === 0) return [];
|
|
9209
|
+
return [{ functionDeclarations }];
|
|
9210
|
+
}
|
|
9211
|
+
function toGeminiContents(messages) {
|
|
9212
|
+
const systemParts = [];
|
|
9213
|
+
const contents = [];
|
|
9214
|
+
for (const rawMsg of messages) {
|
|
9215
|
+
const role = rawMsg.role;
|
|
9216
|
+
if (role === "system") {
|
|
9217
|
+
if (typeof rawMsg.content === "string" && rawMsg.content) {
|
|
9218
|
+
systemParts.push(rawMsg.content);
|
|
9219
|
+
}
|
|
9220
|
+
continue;
|
|
9221
|
+
}
|
|
9222
|
+
if (role === "user") {
|
|
9223
|
+
if (typeof rawMsg.content === "string" && rawMsg.content) {
|
|
9224
|
+
contents.push({ role: "user", parts: [{ text: rawMsg.content }] });
|
|
9225
|
+
}
|
|
9226
|
+
continue;
|
|
9227
|
+
}
|
|
9228
|
+
if (role === "assistant") {
|
|
9229
|
+
const parts = [];
|
|
9230
|
+
if (typeof rawMsg.content === "string" && rawMsg.content) {
|
|
9231
|
+
parts.push({ text: rawMsg.content });
|
|
9232
|
+
}
|
|
9233
|
+
for (const tc of rawMsg.tool_calls ?? []) {
|
|
9234
|
+
let args = {};
|
|
9235
|
+
try {
|
|
9236
|
+
const parsed = JSON.parse(tc.function?.arguments ?? "{}");
|
|
9237
|
+
if (parsed && typeof parsed === "object") args = parsed;
|
|
9238
|
+
} catch {
|
|
9239
|
+
args = {};
|
|
9240
|
+
}
|
|
9241
|
+
parts.push({
|
|
9242
|
+
functionCall: {
|
|
9243
|
+
name: tc.function?.name ?? "",
|
|
9244
|
+
args,
|
|
9245
|
+
id: tc.id
|
|
9246
|
+
}
|
|
9247
|
+
});
|
|
9248
|
+
}
|
|
9249
|
+
if (parts.length > 0) contents.push({ role: "model", parts });
|
|
9250
|
+
continue;
|
|
9251
|
+
}
|
|
9252
|
+
if (role === "tool") {
|
|
9253
|
+
const raw = rawMsg.content;
|
|
9254
|
+
let response;
|
|
9255
|
+
if (typeof raw === "string") {
|
|
9256
|
+
try {
|
|
9257
|
+
const parsed = JSON.parse(raw);
|
|
9258
|
+
response = parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : { result: parsed };
|
|
9259
|
+
} catch {
|
|
9260
|
+
response = { result: raw };
|
|
9261
|
+
}
|
|
9262
|
+
} else {
|
|
9263
|
+
response = raw ?? {};
|
|
9264
|
+
}
|
|
9265
|
+
contents.push({
|
|
9266
|
+
role: "user",
|
|
9267
|
+
parts: [
|
|
9268
|
+
{
|
|
9269
|
+
functionResponse: {
|
|
9270
|
+
name: rawMsg.name ?? rawMsg.tool_call_id ?? "",
|
|
9271
|
+
response,
|
|
9272
|
+
id: rawMsg.tool_call_id
|
|
9273
|
+
}
|
|
9274
|
+
}
|
|
9275
|
+
]
|
|
9276
|
+
});
|
|
9277
|
+
continue;
|
|
9278
|
+
}
|
|
9279
|
+
}
|
|
9280
|
+
return { systemInstruction: systemParts.join("\n\n"), contents };
|
|
9281
|
+
}
|
|
9282
|
+
|
|
9283
|
+
// src/llm/google.ts
|
|
9284
|
+
var LLM5 = class extends GoogleLLMProvider {
|
|
9285
|
+
constructor(opts = {}) {
|
|
9286
|
+
const key = opts.apiKey ?? process.env.GEMINI_API_KEY ?? process.env.GOOGLE_API_KEY;
|
|
9287
|
+
if (!key) {
|
|
9288
|
+
throw new Error(
|
|
9289
|
+
"Google LLM requires an apiKey. Pass { apiKey: 'AIza...' } or set GEMINI_API_KEY (or GOOGLE_API_KEY)."
|
|
9290
|
+
);
|
|
9291
|
+
}
|
|
9292
|
+
super({
|
|
9293
|
+
apiKey: key,
|
|
9294
|
+
model: opts.model,
|
|
9295
|
+
baseUrl: opts.baseUrl,
|
|
9296
|
+
temperature: opts.temperature,
|
|
9297
|
+
maxOutputTokens: opts.maxOutputTokens
|
|
9298
|
+
});
|
|
9299
|
+
}
|
|
9300
|
+
};
|
|
9301
|
+
|
|
9467
9302
|
// src/carriers/twilio.ts
|
|
9468
9303
|
var Carrier = class {
|
|
9469
9304
|
kind = "twilio";
|
|
@@ -10178,6 +10013,7 @@ function isAudioConfig(value) {
|
|
|
10178
10013
|
// Annotate the CommonJS export names for ESM import in node:
|
|
10179
10014
|
0 && (module.exports = {
|
|
10180
10015
|
AllProvidersFailedError,
|
|
10016
|
+
AnthropicLLM,
|
|
10181
10017
|
AssemblyAISTT,
|
|
10182
10018
|
AuthenticationError,
|
|
10183
10019
|
BackgroundAudioPlayer,
|
|
@@ -10185,6 +10021,7 @@ function isAudioConfig(value) {
|
|
|
10185
10021
|
CallMetricsAccumulator,
|
|
10186
10022
|
CartesiaSTT,
|
|
10187
10023
|
CartesiaTTS,
|
|
10024
|
+
CerebrasLLM,
|
|
10188
10025
|
ChatContext,
|
|
10189
10026
|
CloudflareTunnel,
|
|
10190
10027
|
DEFAULT_MIN_SENTENCE_LEN,
|
|
@@ -10198,11 +10035,14 @@ function isAudioConfig(value) {
|
|
|
10198
10035
|
GEMINI_DEFAULT_INPUT_SR,
|
|
10199
10036
|
GEMINI_DEFAULT_OUTPUT_SR,
|
|
10200
10037
|
GeminiLiveAdapter,
|
|
10038
|
+
GoogleLLM,
|
|
10039
|
+
GroqLLM,
|
|
10201
10040
|
Guardrail,
|
|
10202
10041
|
IVRActivity,
|
|
10203
10042
|
LLMLoop,
|
|
10204
10043
|
LMNTTTS,
|
|
10205
10044
|
MetricsStore,
|
|
10045
|
+
OpenAILLM,
|
|
10206
10046
|
OpenAILLMProvider,
|
|
10207
10047
|
OpenAIRealtime,
|
|
10208
10048
|
OpenAIRealtimeAdapter,
|