@tangle-network/agent-integrations 0.61.2 → 0.62.0
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 +1 -0
- package/data/bundled-adapter-manifests.json +1 -1
- package/dist/{adapters-Dp5h7mF-.js → adapters-DZb0dJHa.js} +779 -44
- package/dist/{adapters-Dp5h7mF-.js.map → adapters-DZb0dJHa.js.map} +1 -1
- package/dist/{bundled-manifest-data-D8W3xNyQ.js → bundled-manifest-data-D5zxeonm.js} +413 -28
- package/dist/{bundled-manifest-data-D8W3xNyQ.js.map → bundled-manifest-data-D5zxeonm.js.map} +1 -1
- package/dist/connectors/adapters/index.js +1 -1
- package/dist/connectors/index.js +2 -2
- package/dist/coverage-catalog.js +2 -2
- package/dist/coverage-catalog.js.map +1 -1
- package/dist/index-BXhHnxfA.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/internal/bundled-manifest-runtime.js +1 -1
- package/dist/mcp.js +1 -1
- package/dist/registry.js +1 -1
- package/dist/{specs-ElJzHwc7.js → specs-k7fs10sB.js} +2 -2
- package/dist/{specs-ElJzHwc7.js.map → specs-k7fs10sB.js.map} +1 -1
- package/dist/specs.js +1 -1
- package/dist/{src-91m6v5vV.js → src-CZtOkebG.js} +3 -3
- package/dist/{src-91m6v5vV.js.map → src-CZtOkebG.js.map} +1 -1
- package/docs/voice-tools.md +41 -0
- package/package.json +1 -1
|
@@ -89,6 +89,32 @@ var __exportAll = (all, no_symbols) => {
|
|
|
89
89
|
* Read. POST /v1/collections/:id/search. Hybrid vector+keyword search
|
|
90
90
|
* over a collection. Returns { results, queryTokens, graphContext? }.
|
|
91
91
|
*
|
|
92
|
+
* list_voices(provider?, query?, limit?, cursor?)
|
|
93
|
+
* Read. GET /v1/voices. Voices an agent can speak with: the account's
|
|
94
|
+
* clones plus provider voices, each naming `provider` and
|
|
95
|
+
* `providerVoiceId` (set those as an agent's ttsProvider and voiceId).
|
|
96
|
+
*
|
|
97
|
+
* list_phone_numbers()
|
|
98
|
+
* Read. GET /v1/phone-numbers. Caller ids that start_outbound_call accepts.
|
|
99
|
+
*
|
|
100
|
+
* synthesize_speech(text, voiceId?, provider?, format?, speed?)
|
|
101
|
+
* Mutation (billed). POST /v1/synthesize. A voice memo: ph0ny stores the
|
|
102
|
+
* audio and returns a download URL valid for about an hour; save it as a
|
|
103
|
+
* file rather than passing audio through the conversation.
|
|
104
|
+
*
|
|
105
|
+
* transcribe(audioUrl, language?, diarize?, …)
|
|
106
|
+
* Read (billed). POST /v1/transcribe. Speech-to-text of a public URL.
|
|
107
|
+
*
|
|
108
|
+
* clone_voice(name, sampleUrls, consent, …)
|
|
109
|
+
* Mutation, external effect. POST /v1/voices/clone. Instant clone of the
|
|
110
|
+
* requester's OWN voice only: consent.subject must be "self" and
|
|
111
|
+
* consent.statement must quote them consenting. ph0ny stores the consent
|
|
112
|
+
* with the voice. Use the returned voice.id as start_outbound_call's
|
|
113
|
+
* voiceCloneId.
|
|
114
|
+
*
|
|
115
|
+
* update_agent(agentId, …)
|
|
116
|
+
* Mutation. PUT /v1/agents/:id. Change an agent's voice, prompt or model.
|
|
117
|
+
*
|
|
92
118
|
* The agent test/eval routes (/v1/agents/:id/tests/*, benchmark, redteam) are
|
|
93
119
|
* deliberately NOT exposed here: they run platform-funded LLM/TTS inference with
|
|
94
120
|
* no usage metering, and are platform-admin tooling — not workspace-agent surface.
|
|
@@ -241,7 +267,22 @@ function createPhonyConnector(options = {}) {
|
|
|
241
267
|
},
|
|
242
268
|
voiceCloneId: {
|
|
243
269
|
type: "string",
|
|
244
|
-
description: "Optional
|
|
270
|
+
description: "Optional voice.id from clone_voice. The agent must use the same ttsProvider as the clone (cartesia)."
|
|
271
|
+
},
|
|
272
|
+
callback: {
|
|
273
|
+
type: "object",
|
|
274
|
+
description: "Optional. ph0ny POSTs the outcome (summary, extracted fields, transcript, recording URL) here once the call ends, signed X-Signature: hex(HMAC-SHA256(body, token)) and sent with Authorization: Bearer <token>.",
|
|
275
|
+
properties: {
|
|
276
|
+
url: {
|
|
277
|
+
type: "string",
|
|
278
|
+
description: "https URL that receives the outcome."
|
|
279
|
+
},
|
|
280
|
+
token: {
|
|
281
|
+
type: "string",
|
|
282
|
+
description: "Shared secret, 16-512 chars."
|
|
283
|
+
}
|
|
284
|
+
},
|
|
285
|
+
required: ["url", "token"]
|
|
245
286
|
},
|
|
246
287
|
userConsentRecorded: {
|
|
247
288
|
type: "boolean",
|
|
@@ -646,6 +687,223 @@ function createPhonyConnector(options = {}) {
|
|
|
646
687
|
},
|
|
647
688
|
required: ["collectionId", "query"]
|
|
648
689
|
}
|
|
690
|
+
},
|
|
691
|
+
{
|
|
692
|
+
name: "list_voices",
|
|
693
|
+
class: "read",
|
|
694
|
+
description: "List voices an agent can speak with: your cloned voices, ElevenLabs account voices and, with provider \"cartesia\", Cartesia stock voices. Each voice names provider and providerVoiceId; set them as an agent's ttsProvider and voiceId.",
|
|
695
|
+
parameters: {
|
|
696
|
+
type: "object",
|
|
697
|
+
properties: {
|
|
698
|
+
provider: {
|
|
699
|
+
type: "string",
|
|
700
|
+
enum: ["cartesia"],
|
|
701
|
+
description: "Also list this provider's stock voices."
|
|
702
|
+
},
|
|
703
|
+
query: {
|
|
704
|
+
type: "string",
|
|
705
|
+
description: "Filter provider voices by name (with provider)."
|
|
706
|
+
},
|
|
707
|
+
limit: {
|
|
708
|
+
type: "integer",
|
|
709
|
+
minimum: 1,
|
|
710
|
+
maximum: 200,
|
|
711
|
+
default: 50
|
|
712
|
+
},
|
|
713
|
+
cursor: {
|
|
714
|
+
type: "string",
|
|
715
|
+
description: "Pagination cursor from a prior response."
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
},
|
|
720
|
+
{
|
|
721
|
+
name: "list_phone_numbers",
|
|
722
|
+
class: "read",
|
|
723
|
+
description: "List the phone numbers on your ph0ny account; use one as start_outbound_call fromNumber.",
|
|
724
|
+
parameters: {
|
|
725
|
+
type: "object",
|
|
726
|
+
properties: {}
|
|
727
|
+
}
|
|
728
|
+
},
|
|
729
|
+
{
|
|
730
|
+
name: "transcribe",
|
|
731
|
+
class: "read",
|
|
732
|
+
consistencyModel: "authoritative",
|
|
733
|
+
description: "Transcribe speech from a public audio URL (billed per audio minute).",
|
|
734
|
+
parameters: {
|
|
735
|
+
type: "object",
|
|
736
|
+
properties: {
|
|
737
|
+
audioUrl: {
|
|
738
|
+
type: "string",
|
|
739
|
+
description: "Public https URL of the audio."
|
|
740
|
+
},
|
|
741
|
+
language: {
|
|
742
|
+
type: "string",
|
|
743
|
+
description: "BCP-47 language hint, e.g. \"en\"."
|
|
744
|
+
},
|
|
745
|
+
diarize: {
|
|
746
|
+
type: "boolean",
|
|
747
|
+
description: "Label speakers."
|
|
748
|
+
},
|
|
749
|
+
mode: {
|
|
750
|
+
type: "string",
|
|
751
|
+
enum: ["fast", "accurate"]
|
|
752
|
+
}
|
|
753
|
+
},
|
|
754
|
+
required: ["audioUrl"]
|
|
755
|
+
}
|
|
756
|
+
},
|
|
757
|
+
{
|
|
758
|
+
name: "synthesize_speech",
|
|
759
|
+
class: "mutation",
|
|
760
|
+
description: "Speak text in a voice and store it as an audio file (a voice memo). Returns audioUrl, a download link valid for about an hour: save the file to the workspace instead of pasting audio into the conversation.",
|
|
761
|
+
cas: "none",
|
|
762
|
+
externalEffect: false,
|
|
763
|
+
parameters: {
|
|
764
|
+
type: "object",
|
|
765
|
+
properties: {
|
|
766
|
+
text: {
|
|
767
|
+
type: "string",
|
|
768
|
+
description: "What to say (1-10000 chars)."
|
|
769
|
+
},
|
|
770
|
+
voiceId: {
|
|
771
|
+
type: "string",
|
|
772
|
+
description: "providerVoiceId from list_voices; omitted uses the default voice."
|
|
773
|
+
},
|
|
774
|
+
provider: {
|
|
775
|
+
type: "string",
|
|
776
|
+
description: "The voice's provider from list_voices, e.g. \"cartesia\" or \"elevenlabs\"."
|
|
777
|
+
},
|
|
778
|
+
format: {
|
|
779
|
+
type: "string",
|
|
780
|
+
enum: [
|
|
781
|
+
"mp3",
|
|
782
|
+
"wav",
|
|
783
|
+
"ogg"
|
|
784
|
+
],
|
|
785
|
+
default: "mp3"
|
|
786
|
+
},
|
|
787
|
+
speed: {
|
|
788
|
+
type: "number",
|
|
789
|
+
minimum: .5,
|
|
790
|
+
maximum: 2
|
|
791
|
+
}
|
|
792
|
+
},
|
|
793
|
+
required: ["text"]
|
|
794
|
+
}
|
|
795
|
+
},
|
|
796
|
+
{
|
|
797
|
+
name: "clone_voice",
|
|
798
|
+
class: "mutation",
|
|
799
|
+
description: "Clone the requester's OWN voice from their recording(s). Only self-clones are allowed: consent.subject must be \"self\" and consent.statement must quote the speaker consenting (for example \"I consent to Tangle cloning my voice\"). Never clone someone else's voice. Returns voice.id for start_outbound_call voiceCloneId.",
|
|
800
|
+
cas: "none",
|
|
801
|
+
externalEffect: true,
|
|
802
|
+
parameters: {
|
|
803
|
+
type: "object",
|
|
804
|
+
properties: {
|
|
805
|
+
name: {
|
|
806
|
+
type: "string",
|
|
807
|
+
description: "Voice name (1-100 chars)."
|
|
808
|
+
},
|
|
809
|
+
sampleUrls: {
|
|
810
|
+
type: "array",
|
|
811
|
+
minItems: 1,
|
|
812
|
+
maxItems: 10,
|
|
813
|
+
items: { type: "string" },
|
|
814
|
+
description: "Public https URLs of the speaker's recordings (any common audio format, including iMessage voice memos); 10 s to 3 min of clean speech works best."
|
|
815
|
+
},
|
|
816
|
+
language: {
|
|
817
|
+
type: "string",
|
|
818
|
+
description: "ISO 639-1 code; defaults to \"en\"."
|
|
819
|
+
},
|
|
820
|
+
description: {
|
|
821
|
+
type: "string",
|
|
822
|
+
description: "Optional description (<=500 chars)."
|
|
823
|
+
},
|
|
824
|
+
consent: {
|
|
825
|
+
type: "object",
|
|
826
|
+
properties: {
|
|
827
|
+
subject: {
|
|
828
|
+
type: "string",
|
|
829
|
+
enum: ["self"],
|
|
830
|
+
description: "Whose voice: only \"self\" is accepted."
|
|
831
|
+
},
|
|
832
|
+
statement: {
|
|
833
|
+
type: "string",
|
|
834
|
+
description: "The speaker's own words consenting to the clone, quoted from their request."
|
|
835
|
+
},
|
|
836
|
+
speakerName: {
|
|
837
|
+
type: "string",
|
|
838
|
+
description: "Who the speaker is."
|
|
839
|
+
},
|
|
840
|
+
sourceRef: {
|
|
841
|
+
type: "string",
|
|
842
|
+
description: "Where the consent was given, e.g. the message id."
|
|
843
|
+
}
|
|
844
|
+
},
|
|
845
|
+
required: ["subject", "statement"]
|
|
846
|
+
}
|
|
847
|
+
},
|
|
848
|
+
required: [
|
|
849
|
+
"name",
|
|
850
|
+
"sampleUrls",
|
|
851
|
+
"consent"
|
|
852
|
+
]
|
|
853
|
+
}
|
|
854
|
+
},
|
|
855
|
+
{
|
|
856
|
+
name: "update_agent",
|
|
857
|
+
class: "mutation",
|
|
858
|
+
description: "Update a voice agent: its voice (voiceId + ttsProvider from list_voices), prompt, greeting, kind or model.",
|
|
859
|
+
cas: "none",
|
|
860
|
+
externalEffect: true,
|
|
861
|
+
parameters: {
|
|
862
|
+
type: "object",
|
|
863
|
+
properties: {
|
|
864
|
+
agentId: {
|
|
865
|
+
type: "string",
|
|
866
|
+
description: "Agent to update."
|
|
867
|
+
},
|
|
868
|
+
name: { type: "string" },
|
|
869
|
+
agentKind: {
|
|
870
|
+
type: "string",
|
|
871
|
+
enum: [
|
|
872
|
+
"inbound",
|
|
873
|
+
"personal_assistant",
|
|
874
|
+
"outbound"
|
|
875
|
+
]
|
|
876
|
+
},
|
|
877
|
+
description: { type: "string" },
|
|
878
|
+
systemPrompt: { type: "string" },
|
|
879
|
+
firstMessage: { type: "string" },
|
|
880
|
+
voiceId: {
|
|
881
|
+
type: "string",
|
|
882
|
+
description: "providerVoiceId from list_voices."
|
|
883
|
+
},
|
|
884
|
+
ttsProvider: {
|
|
885
|
+
type: "string",
|
|
886
|
+
description: "provider from list_voices."
|
|
887
|
+
},
|
|
888
|
+
ttsModel: { type: "string" },
|
|
889
|
+
sttProvider: { type: "string" },
|
|
890
|
+
llmProvider: { type: "string" },
|
|
891
|
+
llmModel: { type: "string" },
|
|
892
|
+
language: { type: "string" },
|
|
893
|
+
temperature: {
|
|
894
|
+
type: "number",
|
|
895
|
+
minimum: 0,
|
|
896
|
+
maximum: 2
|
|
897
|
+
},
|
|
898
|
+
maxTokens: {
|
|
899
|
+
type: "integer",
|
|
900
|
+
minimum: 1,
|
|
901
|
+
maximum: 16384
|
|
902
|
+
},
|
|
903
|
+
metadata: { type: "object" }
|
|
904
|
+
},
|
|
905
|
+
required: ["agentId"]
|
|
906
|
+
}
|
|
649
907
|
}
|
|
650
908
|
]
|
|
651
909
|
},
|
|
@@ -716,6 +974,56 @@ function createPhonyConnector(options = {}) {
|
|
|
716
974
|
fetchedAt: Date.now()
|
|
717
975
|
};
|
|
718
976
|
}
|
|
977
|
+
if (inv.capabilityName === "list_voices") {
|
|
978
|
+
const { provider, query, limit, cursor } = inv.args;
|
|
979
|
+
const params = new URLSearchParams({
|
|
980
|
+
includeCustom: "true",
|
|
981
|
+
limit: String(Math.min(Math.max(1, limit ?? 50), 200))
|
|
982
|
+
});
|
|
983
|
+
if (provider === "cartesia") params.set("provider", "cartesia");
|
|
984
|
+
if (query) params.set("q", query);
|
|
985
|
+
if (cursor) params.set("cursor", cursor);
|
|
986
|
+
const json = await ph0ny(inv.source.id, token, {
|
|
987
|
+
method: "GET",
|
|
988
|
+
path: `/v1/voices?${params.toString()}`,
|
|
989
|
+
timeout: 15e3
|
|
990
|
+
}, "list_voices");
|
|
991
|
+
return {
|
|
992
|
+
data: {
|
|
993
|
+
voices: json.data ?? [],
|
|
994
|
+
nextCursor: json.nextCursor ?? null,
|
|
995
|
+
hasMore: json.hasMore ?? false
|
|
996
|
+
},
|
|
997
|
+
fetchedAt: Date.now()
|
|
998
|
+
};
|
|
999
|
+
}
|
|
1000
|
+
if (inv.capabilityName === "list_phone_numbers") return {
|
|
1001
|
+
data: { phoneNumbers: (await ph0ny(inv.source.id, token, {
|
|
1002
|
+
method: "GET",
|
|
1003
|
+
path: "/v1/phone-numbers",
|
|
1004
|
+
timeout: 1e4
|
|
1005
|
+
}, "list_phone_numbers")).data ?? [] },
|
|
1006
|
+
fetchedAt: Date.now()
|
|
1007
|
+
};
|
|
1008
|
+
if (inv.capabilityName === "transcribe") {
|
|
1009
|
+
const args = inv.args;
|
|
1010
|
+
assertHttpsUrl(args.audioUrl, "transcribe audioUrl");
|
|
1011
|
+
const payload = pick$2(args, [
|
|
1012
|
+
"audioUrl",
|
|
1013
|
+
"language",
|
|
1014
|
+
"diarize",
|
|
1015
|
+
"mode"
|
|
1016
|
+
]);
|
|
1017
|
+
return {
|
|
1018
|
+
data: await ph0ny(inv.source.id, token, {
|
|
1019
|
+
method: "POST",
|
|
1020
|
+
path: "/v1/transcribe",
|
|
1021
|
+
body: payload,
|
|
1022
|
+
timeout: 12e4
|
|
1023
|
+
}, "transcribe"),
|
|
1024
|
+
fetchedAt: Date.now()
|
|
1025
|
+
};
|
|
1026
|
+
}
|
|
719
1027
|
throw new Error(`phony: unknown read capability ${inv.capabilityName}`);
|
|
720
1028
|
},
|
|
721
1029
|
async executeMutation(inv) {
|
|
@@ -732,6 +1040,7 @@ function createPhonyConnector(options = {}) {
|
|
|
732
1040
|
if (args.missionId !== void 0) payload.missionId = args.missionId;
|
|
733
1041
|
if (args.callerProfile !== void 0) payload.callerProfile = args.callerProfile;
|
|
734
1042
|
if (args.voiceCloneId !== void 0) payload.voiceCloneId = args.voiceCloneId;
|
|
1043
|
+
if (args.callback !== void 0) payload.callback = args.callback;
|
|
735
1044
|
if (args.dryRun !== void 0) payload.dryRun = args.dryRun;
|
|
736
1045
|
const json = await ph0ny(inv.source.id, token, {
|
|
737
1046
|
method: "POST",
|
|
@@ -825,6 +1134,68 @@ function createPhonyConnector(options = {}) {
|
|
|
825
1134
|
idempotentReplay: false
|
|
826
1135
|
};
|
|
827
1136
|
}
|
|
1137
|
+
if (inv.capabilityName === "synthesize_speech") {
|
|
1138
|
+
const args = inv.args;
|
|
1139
|
+
if (typeof args.text !== "string" || args.text.trim().length === 0 || args.text.length > 1e4) throw new Error("phony synthesize_speech text must be 1-10000 chars");
|
|
1140
|
+
const payload = pick$2(args, [
|
|
1141
|
+
"text",
|
|
1142
|
+
"voiceId",
|
|
1143
|
+
"provider",
|
|
1144
|
+
"format",
|
|
1145
|
+
"speed"
|
|
1146
|
+
]);
|
|
1147
|
+
if (payload.format === void 0) payload.format = "mp3";
|
|
1148
|
+
const json = await ph0ny(inv.source.id, token, {
|
|
1149
|
+
method: "POST",
|
|
1150
|
+
path: "/v1/synthesize",
|
|
1151
|
+
body: payload,
|
|
1152
|
+
timeout: 6e4
|
|
1153
|
+
}, "synthesize_speech");
|
|
1154
|
+
if (!json.audioUrl) throw new Error("phony synthesize_speech: ph0ny returned no audioUrl (storage unavailable)");
|
|
1155
|
+
return {
|
|
1156
|
+
status: "committed",
|
|
1157
|
+
data: {
|
|
1158
|
+
audioUrl: json.audioUrl,
|
|
1159
|
+
format: payload.format,
|
|
1160
|
+
durationSeconds: json.duration ?? null,
|
|
1161
|
+
charactersUsed: json.charactersUsed ?? null,
|
|
1162
|
+
provider: json.provider ?? null
|
|
1163
|
+
},
|
|
1164
|
+
committedAt: Date.now(),
|
|
1165
|
+
idempotentReplay: false
|
|
1166
|
+
};
|
|
1167
|
+
}
|
|
1168
|
+
if (inv.capabilityName === "clone_voice") {
|
|
1169
|
+
const payload = validateCloneArgs(inv.args);
|
|
1170
|
+
return {
|
|
1171
|
+
status: "committed",
|
|
1172
|
+
data: { voice: (await ph0ny(inv.source.id, token, {
|
|
1173
|
+
method: "POST",
|
|
1174
|
+
path: "/v1/voices/clone",
|
|
1175
|
+
body: payload,
|
|
1176
|
+
timeout: 12e4
|
|
1177
|
+
}, "clone_voice")).voice ?? null },
|
|
1178
|
+
committedAt: Date.now(),
|
|
1179
|
+
idempotentReplay: false
|
|
1180
|
+
};
|
|
1181
|
+
}
|
|
1182
|
+
if (inv.capabilityName === "update_agent") {
|
|
1183
|
+
const { agentId, ...rest } = inv.args;
|
|
1184
|
+
if (typeof agentId !== "string" || agentId.length === 0 || agentId.length > 128) throw new Error("phony update_agent requires agentId");
|
|
1185
|
+
const payload = pick$2(rest, AGENT_FIELDS.filter((f) => f !== "id"));
|
|
1186
|
+
if (Object.keys(payload).length === 0) throw new Error("phony update_agent needs at least one field to change");
|
|
1187
|
+
return {
|
|
1188
|
+
status: "committed",
|
|
1189
|
+
data: { agent: await ph0ny(inv.source.id, token, {
|
|
1190
|
+
method: "PUT",
|
|
1191
|
+
path: `/v1/agents/${encodeURIComponent(agentId)}`,
|
|
1192
|
+
body: payload,
|
|
1193
|
+
timeout: 2e4
|
|
1194
|
+
}, "update_agent") },
|
|
1195
|
+
committedAt: Date.now(),
|
|
1196
|
+
idempotentReplay: false
|
|
1197
|
+
};
|
|
1198
|
+
}
|
|
828
1199
|
throw new Error(`phony: unknown mutation capability ${inv.capabilityName}`);
|
|
829
1200
|
},
|
|
830
1201
|
async test(source) {
|
|
@@ -877,6 +1248,11 @@ function validateOutboundStartArgs(args) {
|
|
|
877
1248
|
if (args.callerProfile.userName !== void 0) assertNonEmptyString(args.callerProfile.userName, "callerProfile.userName", 120);
|
|
878
1249
|
if (args.callerProfile.companyName !== void 0) assertNonEmptyString(args.callerProfile.companyName, "callerProfile.companyName", 120);
|
|
879
1250
|
}
|
|
1251
|
+
if (args.callback !== void 0) {
|
|
1252
|
+
if (!isRecord$3(args.callback)) throw new Error("phony start_outbound_call callback must be an object");
|
|
1253
|
+
assertHttpsUrl(args.callback.url, "start_outbound_call callback.url");
|
|
1254
|
+
if (typeof args.callback.token !== "string" || args.callback.token.length < 16 || args.callback.token.length > 512) throw new Error("phony start_outbound_call callback.token must be 16-512 chars");
|
|
1255
|
+
}
|
|
880
1256
|
if (args.dryRun !== void 0 && typeof args.dryRun !== "boolean") throw new Error("phony start_outbound_call dryRun must be boolean when supplied");
|
|
881
1257
|
return args;
|
|
882
1258
|
}
|
|
@@ -890,6 +1266,25 @@ function assertOptionalInteger(value, field, min, max) {
|
|
|
890
1266
|
if (value === void 0) return;
|
|
891
1267
|
if (typeof value !== "number" || !Number.isInteger(value) || value < min || value > max) throw new Error(`phony start_outbound_call ${field} must be an integer between ${min} and ${max}`);
|
|
892
1268
|
}
|
|
1269
|
+
function assertHttpsUrl(value, field) {
|
|
1270
|
+
if (typeof value !== "string" || value.length > 2048 || !URL.canParse(value) || new URL(value).protocol !== "https:") throw new Error(`phony ${field} must be an https URL`);
|
|
1271
|
+
}
|
|
1272
|
+
/** The self-clone rule, checked before ph0ny is contacted; ph0ny enforces it again. */
|
|
1273
|
+
function validateCloneArgs(args) {
|
|
1274
|
+
if (typeof args.name !== "string" || args.name.trim().length === 0 || args.name.length > 100) throw new Error("phony clone_voice name must be 1-100 chars");
|
|
1275
|
+
if (!Array.isArray(args.sampleUrls) || args.sampleUrls.length < 1 || args.sampleUrls.length > 10) throw new Error("phony clone_voice sampleUrls must hold 1-10 URLs");
|
|
1276
|
+
for (const url of args.sampleUrls) assertHttpsUrl(url, "clone_voice sampleUrls[]");
|
|
1277
|
+
const consent = args.consent;
|
|
1278
|
+
if (!isRecord$3(consent) || consent.subject !== "self") throw new Error("phony clone_voice only clones the requester's own voice: consent.subject must be \"self\"");
|
|
1279
|
+
if (typeof consent.statement !== "string" || consent.statement.trim().length < 10 || !/consent/i.test(consent.statement)) throw new Error("phony clone_voice consent.statement must quote the speaker consenting to the clone");
|
|
1280
|
+
return pick$2(args, [
|
|
1281
|
+
"name",
|
|
1282
|
+
"sampleUrls",
|
|
1283
|
+
"language",
|
|
1284
|
+
"description",
|
|
1285
|
+
"consent"
|
|
1286
|
+
]);
|
|
1287
|
+
}
|
|
893
1288
|
function isRecord$3(value) {
|
|
894
1289
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
895
1290
|
}
|
|
@@ -7363,7 +7758,7 @@ const message = {
|
|
|
7363
7758
|
minLength: 1,
|
|
7364
7759
|
maxLength: 18e3
|
|
7365
7760
|
};
|
|
7366
|
-
const base$
|
|
7761
|
+
const base$10 = declarativeRestConnector({
|
|
7367
7762
|
kind: "contiguity",
|
|
7368
7763
|
displayName: "Contiguity",
|
|
7369
7764
|
category: "crm",
|
|
@@ -7623,14 +8018,14 @@ const base$9 = declarativeRestConnector({
|
|
|
7623
8018
|
]
|
|
7624
8019
|
});
|
|
7625
8020
|
const contiguityConnector = {
|
|
7626
|
-
...base$
|
|
8021
|
+
...base$10,
|
|
7627
8022
|
async executeMutation(inv) {
|
|
7628
|
-
if (inv.capabilityName !== "email.send") return base$
|
|
8023
|
+
if (inv.capabilityName !== "email.send") return base$10.executeMutation(inv);
|
|
7629
8024
|
const { body, contentType, ...args } = inv.args;
|
|
7630
8025
|
if (typeof body !== "string" || !body.length || contentType !== void 0 && contentType !== "text/plain" && contentType !== "text/html") throw new Error("Contiguity email requires a body and supported contentType");
|
|
7631
8026
|
delete args.text;
|
|
7632
8027
|
delete args.html;
|
|
7633
|
-
return base$
|
|
8028
|
+
return base$10.executeMutation({
|
|
7634
8029
|
...inv,
|
|
7635
8030
|
args: {
|
|
7636
8031
|
...args,
|
|
@@ -8142,7 +8537,7 @@ function transcriptResponse(value) {
|
|
|
8142
8537
|
language: "multi"
|
|
8143
8538
|
};
|
|
8144
8539
|
}
|
|
8145
|
-
const base$
|
|
8540
|
+
const base$9 = declarativeRestConnector({
|
|
8146
8541
|
kind: "deepgram",
|
|
8147
8542
|
displayName: "Deepgram",
|
|
8148
8543
|
description: "Transcribe audio to text, synthesize text to speech, and analyze audio content with AI-powered speech recognition.",
|
|
@@ -8236,7 +8631,7 @@ const base$8 = declarativeRestConnector({
|
|
|
8236
8631
|
{
|
|
8237
8632
|
name: "speak.generate",
|
|
8238
8633
|
class: "mutation",
|
|
8239
|
-
description: "Convert text to speech with
|
|
8634
|
+
description: "Convert text to speech. Returns the audio as base64 with its content type.",
|
|
8240
8635
|
parameters: {
|
|
8241
8636
|
type: "object",
|
|
8242
8637
|
properties: {
|
|
@@ -8267,7 +8662,8 @@ const base$8 = declarativeRestConnector({
|
|
|
8267
8662
|
encoding: "{encoding}",
|
|
8268
8663
|
sample_rate: "{sample_rate}"
|
|
8269
8664
|
},
|
|
8270
|
-
body: { text: "{text}" }
|
|
8665
|
+
body: { text: "{text}" },
|
|
8666
|
+
responseBody: "base64"
|
|
8271
8667
|
},
|
|
8272
8668
|
cas: "native-idempotency"
|
|
8273
8669
|
},
|
|
@@ -8385,10 +8781,10 @@ const base$8 = declarativeRestConnector({
|
|
|
8385
8781
|
]
|
|
8386
8782
|
});
|
|
8387
8783
|
const deepgramConnector = {
|
|
8388
|
-
...base$
|
|
8784
|
+
...base$9,
|
|
8389
8785
|
manifest: {
|
|
8390
|
-
...base$
|
|
8391
|
-
capabilities: [...base$
|
|
8786
|
+
...base$9.manifest,
|
|
8787
|
+
capabilities: [...base$9.manifest.capabilities, {
|
|
8392
8788
|
name: "transcription.bytes",
|
|
8393
8789
|
class: "mutation",
|
|
8394
8790
|
cas: "none",
|
|
@@ -8415,7 +8811,7 @@ const deepgramConnector = {
|
|
|
8415
8811
|
}]
|
|
8416
8812
|
},
|
|
8417
8813
|
async executeMutation(inv) {
|
|
8418
|
-
if (inv.capabilityName !== "transcription.bytes") return base$
|
|
8814
|
+
if (inv.capabilityName !== "transcription.bytes") return base$9.executeMutation(inv);
|
|
8419
8815
|
const { bytes, contentType } = privateAudio(inv.args);
|
|
8420
8816
|
if (inv.source.credentials.kind !== "api-key" || !inv.source.credentials.apiKey || /[\u0000-\u0020\u007f]/.test(inv.source.credentials.apiKey)) throw new IntegrationRuntimeError({
|
|
8421
8817
|
code: "provider_auth_failed",
|
|
@@ -9500,54 +9896,393 @@ const echowinConnector = declarativeRestConnector({
|
|
|
9500
9896
|
});
|
|
9501
9897
|
//#endregion
|
|
9502
9898
|
//#region src/connectors/adapters/elevenlabs.ts
|
|
9503
|
-
|
|
9899
|
+
/**
|
|
9900
|
+
* ElevenLabs connector — a workspace's own ElevenLabs account (bring your
|
|
9901
|
+
* own key). Company-paid voice work goes through the ph0ny connector instead.
|
|
9902
|
+
*
|
|
9903
|
+
* ElevenLabs authenticates with an `xi-api-key` header, not Bearer.
|
|
9904
|
+
*
|
|
9905
|
+
* speech.synthesis POST /v1/text-to-speech/{voiceId}; audio as base64.
|
|
9906
|
+
* voices.list GET /v2/voices; the account's voices.
|
|
9907
|
+
* voices.clone_instant POST /v1/voices/add (multipart); the requester's
|
|
9908
|
+
* own voice only, from public sample URLs. Needs a
|
|
9909
|
+
* paid ElevenLabs plan.
|
|
9910
|
+
* speech_to_text POST /v1/speech-to-text with cloud_storage_url.
|
|
9911
|
+
* agents.list / agents.create
|
|
9912
|
+
* Conversational AI agents (/v1/convai/agents).
|
|
9913
|
+
*/
|
|
9914
|
+
const ELEVENLABS_BASE_URL = "https://api.elevenlabs.io";
|
|
9915
|
+
const MAX_SAMPLE_BYTES = 11e6;
|
|
9916
|
+
const base$8 = declarativeRestConnector({
|
|
9504
9917
|
kind: "elevenlabs",
|
|
9505
9918
|
displayName: "ElevenLabs",
|
|
9506
|
-
description: "
|
|
9919
|
+
description: "Your own ElevenLabs account: text to speech, voices, instant voice clones of your own voice, speech to text, and conversational voice agents.",
|
|
9507
9920
|
auth: {
|
|
9508
9921
|
kind: "api-key",
|
|
9509
|
-
hint: "ElevenLabs API key."
|
|
9922
|
+
hint: "ElevenLabs API key (Profile > API keys)."
|
|
9510
9923
|
},
|
|
9511
|
-
category: "
|
|
9924
|
+
category: "comms",
|
|
9512
9925
|
defaultConsistencyModel: "authoritative",
|
|
9513
|
-
baseUrl:
|
|
9926
|
+
baseUrl: ELEVENLABS_BASE_URL,
|
|
9927
|
+
credentialPlacement: {
|
|
9928
|
+
kind: "header",
|
|
9929
|
+
header: "xi-api-key"
|
|
9930
|
+
},
|
|
9514
9931
|
test: {
|
|
9515
9932
|
method: "GET",
|
|
9516
9933
|
path: "/v1/user"
|
|
9517
9934
|
},
|
|
9518
|
-
capabilities: [
|
|
9519
|
-
|
|
9520
|
-
|
|
9521
|
-
|
|
9522
|
-
|
|
9523
|
-
|
|
9524
|
-
|
|
9525
|
-
|
|
9526
|
-
|
|
9527
|
-
|
|
9935
|
+
capabilities: [
|
|
9936
|
+
{
|
|
9937
|
+
name: "speech.synthesis",
|
|
9938
|
+
class: "mutation",
|
|
9939
|
+
description: "Convert text to speech. Returns the MP3 audio as base64 with its content type.",
|
|
9940
|
+
parameters: {
|
|
9941
|
+
type: "object",
|
|
9942
|
+
properties: {
|
|
9943
|
+
voiceId: {
|
|
9944
|
+
type: "string",
|
|
9945
|
+
description: "voice_id from voices.list"
|
|
9946
|
+
},
|
|
9947
|
+
text: {
|
|
9948
|
+
type: "string",
|
|
9949
|
+
description: "The text to convert to speech"
|
|
9950
|
+
},
|
|
9951
|
+
modelId: {
|
|
9952
|
+
type: "string",
|
|
9953
|
+
description: "Optional model id, e.g. eleven_multilingual_v2"
|
|
9954
|
+
}
|
|
9528
9955
|
},
|
|
9529
|
-
|
|
9530
|
-
|
|
9531
|
-
|
|
9956
|
+
required: ["voiceId", "text"]
|
|
9957
|
+
},
|
|
9958
|
+
request: {
|
|
9959
|
+
method: "POST",
|
|
9960
|
+
path: "/v1/text-to-speech/{voiceId}",
|
|
9961
|
+
query: { output_format: "mp3_44100_128" },
|
|
9962
|
+
body: {
|
|
9963
|
+
text: "{text}",
|
|
9964
|
+
model_id: "{modelId}"
|
|
9532
9965
|
},
|
|
9533
|
-
|
|
9534
|
-
type: "string",
|
|
9535
|
-
description: "Optional model ID (defaults to eleven_monolingual_v1)"
|
|
9536
|
-
}
|
|
9966
|
+
responseBody: "base64"
|
|
9537
9967
|
},
|
|
9538
|
-
|
|
9968
|
+
cas: "native-idempotency"
|
|
9539
9969
|
},
|
|
9540
|
-
|
|
9541
|
-
|
|
9542
|
-
|
|
9543
|
-
|
|
9544
|
-
|
|
9545
|
-
|
|
9970
|
+
{
|
|
9971
|
+
name: "voices.list",
|
|
9972
|
+
class: "read",
|
|
9973
|
+
description: "List the voices on the ElevenLabs account, optionally filtered by name.",
|
|
9974
|
+
parameters: {
|
|
9975
|
+
type: "object",
|
|
9976
|
+
properties: {
|
|
9977
|
+
search: {
|
|
9978
|
+
type: "string",
|
|
9979
|
+
description: "Filter by name or description"
|
|
9980
|
+
},
|
|
9981
|
+
pageSize: {
|
|
9982
|
+
type: "integer",
|
|
9983
|
+
minimum: 1,
|
|
9984
|
+
maximum: 100,
|
|
9985
|
+
default: 30
|
|
9986
|
+
},
|
|
9987
|
+
nextPageToken: {
|
|
9988
|
+
type: "string",
|
|
9989
|
+
description: "Pagination token from a prior response"
|
|
9990
|
+
}
|
|
9991
|
+
}
|
|
9992
|
+
},
|
|
9993
|
+
request: {
|
|
9994
|
+
method: "GET",
|
|
9995
|
+
path: "/v2/voices",
|
|
9996
|
+
query: {
|
|
9997
|
+
search: "{search}",
|
|
9998
|
+
page_size: "{pageSize}",
|
|
9999
|
+
next_page_token: "{nextPageToken}"
|
|
10000
|
+
}
|
|
9546
10001
|
}
|
|
9547
10002
|
},
|
|
9548
|
-
|
|
9549
|
-
|
|
10003
|
+
{
|
|
10004
|
+
name: "agents.list",
|
|
10005
|
+
class: "read",
|
|
10006
|
+
description: "List the conversational voice agents on the ElevenLabs account.",
|
|
10007
|
+
parameters: {
|
|
10008
|
+
type: "object",
|
|
10009
|
+
properties: {
|
|
10010
|
+
search: { type: "string" },
|
|
10011
|
+
pageSize: {
|
|
10012
|
+
type: "integer",
|
|
10013
|
+
minimum: 1,
|
|
10014
|
+
maximum: 100,
|
|
10015
|
+
default: 30
|
|
10016
|
+
},
|
|
10017
|
+
cursor: { type: "string" }
|
|
10018
|
+
}
|
|
10019
|
+
},
|
|
10020
|
+
request: {
|
|
10021
|
+
method: "GET",
|
|
10022
|
+
path: "/v1/convai/agents",
|
|
10023
|
+
query: {
|
|
10024
|
+
search: "{search}",
|
|
10025
|
+
page_size: "{pageSize}",
|
|
10026
|
+
cursor: "{cursor}"
|
|
10027
|
+
}
|
|
10028
|
+
}
|
|
10029
|
+
}
|
|
10030
|
+
]
|
|
9550
10031
|
});
|
|
10032
|
+
const elevenlabsConnector = {
|
|
10033
|
+
...base$8,
|
|
10034
|
+
manifest: {
|
|
10035
|
+
...base$8.manifest,
|
|
10036
|
+
capabilities: [
|
|
10037
|
+
...base$8.manifest.capabilities,
|
|
10038
|
+
{
|
|
10039
|
+
name: "voices.clone_instant",
|
|
10040
|
+
class: "mutation",
|
|
10041
|
+
cas: "none",
|
|
10042
|
+
externalEffect: true,
|
|
10043
|
+
consistencyModel: "advisory",
|
|
10044
|
+
description: "Instant-clone the requester's OWN voice from 1-5 public recordings (needs a paid ElevenLabs plan). consent.subject must be \"self\" and consent.statement must quote the speaker consenting; never clone anyone else.",
|
|
10045
|
+
parameters: {
|
|
10046
|
+
type: "object",
|
|
10047
|
+
properties: {
|
|
10048
|
+
name: {
|
|
10049
|
+
type: "string",
|
|
10050
|
+
minLength: 1,
|
|
10051
|
+
maxLength: 100
|
|
10052
|
+
},
|
|
10053
|
+
sampleUrls: {
|
|
10054
|
+
type: "array",
|
|
10055
|
+
minItems: 1,
|
|
10056
|
+
maxItems: 5,
|
|
10057
|
+
items: { type: "string" }
|
|
10058
|
+
},
|
|
10059
|
+
description: {
|
|
10060
|
+
type: "string",
|
|
10061
|
+
maxLength: 500
|
|
10062
|
+
},
|
|
10063
|
+
removeBackgroundNoise: { type: "boolean" },
|
|
10064
|
+
consent: {
|
|
10065
|
+
type: "object",
|
|
10066
|
+
properties: {
|
|
10067
|
+
subject: {
|
|
10068
|
+
type: "string",
|
|
10069
|
+
enum: ["self"]
|
|
10070
|
+
},
|
|
10071
|
+
statement: { type: "string" }
|
|
10072
|
+
},
|
|
10073
|
+
required: ["subject", "statement"]
|
|
10074
|
+
}
|
|
10075
|
+
},
|
|
10076
|
+
required: [
|
|
10077
|
+
"name",
|
|
10078
|
+
"sampleUrls",
|
|
10079
|
+
"consent"
|
|
10080
|
+
],
|
|
10081
|
+
additionalProperties: false
|
|
10082
|
+
}
|
|
10083
|
+
},
|
|
10084
|
+
{
|
|
10085
|
+
name: "speech_to_text",
|
|
10086
|
+
class: "read",
|
|
10087
|
+
consistencyModel: "authoritative",
|
|
10088
|
+
description: "Transcribe a public audio or video URL with ElevenLabs Scribe (billed per audio minute).",
|
|
10089
|
+
parameters: {
|
|
10090
|
+
type: "object",
|
|
10091
|
+
properties: {
|
|
10092
|
+
audioUrl: {
|
|
10093
|
+
type: "string",
|
|
10094
|
+
description: "Public https URL of the recording"
|
|
10095
|
+
},
|
|
10096
|
+
languageCode: {
|
|
10097
|
+
type: "string",
|
|
10098
|
+
description: "ISO 639 code; omitted auto-detects"
|
|
10099
|
+
},
|
|
10100
|
+
diarize: { type: "boolean" }
|
|
10101
|
+
},
|
|
10102
|
+
required: ["audioUrl"],
|
|
10103
|
+
additionalProperties: false
|
|
10104
|
+
}
|
|
10105
|
+
},
|
|
10106
|
+
{
|
|
10107
|
+
name: "agents.create",
|
|
10108
|
+
class: "mutation",
|
|
10109
|
+
cas: "none",
|
|
10110
|
+
externalEffect: true,
|
|
10111
|
+
consistencyModel: "advisory",
|
|
10112
|
+
description: "Create an ElevenLabs conversational voice agent with a prompt, greeting and voice.",
|
|
10113
|
+
parameters: {
|
|
10114
|
+
type: "object",
|
|
10115
|
+
properties: {
|
|
10116
|
+
name: {
|
|
10117
|
+
type: "string",
|
|
10118
|
+
minLength: 1,
|
|
10119
|
+
maxLength: 100
|
|
10120
|
+
},
|
|
10121
|
+
prompt: {
|
|
10122
|
+
type: "string",
|
|
10123
|
+
minLength: 1,
|
|
10124
|
+
maxLength: 2e4,
|
|
10125
|
+
description: "System prompt"
|
|
10126
|
+
},
|
|
10127
|
+
firstMessage: {
|
|
10128
|
+
type: "string",
|
|
10129
|
+
maxLength: 1e3,
|
|
10130
|
+
description: "What the agent says first"
|
|
10131
|
+
},
|
|
10132
|
+
voiceId: {
|
|
10133
|
+
type: "string",
|
|
10134
|
+
description: "voice_id from voices.list"
|
|
10135
|
+
},
|
|
10136
|
+
language: {
|
|
10137
|
+
type: "string",
|
|
10138
|
+
description: "ISO 639-1 code; defaults to en"
|
|
10139
|
+
}
|
|
10140
|
+
},
|
|
10141
|
+
required: ["name", "prompt"],
|
|
10142
|
+
additionalProperties: false
|
|
10143
|
+
}
|
|
10144
|
+
}
|
|
10145
|
+
]
|
|
10146
|
+
},
|
|
10147
|
+
async executeRead(inv) {
|
|
10148
|
+
if (inv.capabilityName !== "speech_to_text") return base$8.executeRead(inv);
|
|
10149
|
+
const audioUrl = httpsUrl(inv.args.audioUrl, "audioUrl");
|
|
10150
|
+
const form = new FormData();
|
|
10151
|
+
form.append("model_id", "scribe_v1");
|
|
10152
|
+
form.append("cloud_storage_url", audioUrl);
|
|
10153
|
+
if (typeof inv.args.languageCode === "string" && /^[a-z]{2,3}$/.test(inv.args.languageCode)) form.append("language_code", inv.args.languageCode);
|
|
10154
|
+
if (inv.args.diarize === true) form.append("diarize", "true");
|
|
10155
|
+
const json = await elevenlabs(inv, "/v1/speech-to-text", form, 3e5);
|
|
10156
|
+
return {
|
|
10157
|
+
data: {
|
|
10158
|
+
text: typeof json.text === "string" ? json.text : "",
|
|
10159
|
+
languageCode: json.language_code ?? null,
|
|
10160
|
+
...Array.isArray(json.words) && inv.args.diarize === true ? { words: json.words } : {}
|
|
10161
|
+
},
|
|
10162
|
+
fetchedAt: Date.now()
|
|
10163
|
+
};
|
|
10164
|
+
},
|
|
10165
|
+
async executeMutation(inv) {
|
|
10166
|
+
if (inv.capabilityName === "voices.clone_instant") {
|
|
10167
|
+
const { name, sampleUrls, description, removeBackgroundNoise, consent } = inv.args;
|
|
10168
|
+
if (typeof name !== "string" || !name.trim() || name.length > 100) invalid("name must be 1-100 chars");
|
|
10169
|
+
if (!record$3(consent) || consent.subject !== "self" || typeof consent.statement !== "string" || consent.statement.trim().length < 10 || !/consent/i.test(consent.statement)) invalid("Only the requester's own voice can be cloned: consent.subject must be \"self\" and consent.statement must quote them consenting");
|
|
10170
|
+
if (!Array.isArray(sampleUrls) || sampleUrls.length < 1 || sampleUrls.length > 5) invalid("sampleUrls must hold 1-5 URLs");
|
|
10171
|
+
const form = new FormData();
|
|
10172
|
+
form.append("name", name);
|
|
10173
|
+
if (typeof description === "string" && description) form.append("description", description.slice(0, 500));
|
|
10174
|
+
if (removeBackgroundNoise === true) form.append("remove_background_noise", "true");
|
|
10175
|
+
form.append("labels", JSON.stringify({
|
|
10176
|
+
consent: "self",
|
|
10177
|
+
consent_statement: consent.statement.slice(0, 200)
|
|
10178
|
+
}));
|
|
10179
|
+
for (const [i, url] of sampleUrls.entries()) {
|
|
10180
|
+
const sample = await downloadSample(httpsUrl(url, "sampleUrls[]"));
|
|
10181
|
+
form.append("files", new Blob([Uint8Array.from(sample.bytes)], { type: sample.contentType }), `sample-${i}`);
|
|
10182
|
+
}
|
|
10183
|
+
const json = await elevenlabs(inv, "/v1/voices/add", form, 12e4);
|
|
10184
|
+
return {
|
|
10185
|
+
status: "committed",
|
|
10186
|
+
data: {
|
|
10187
|
+
voiceId: json.voice_id ?? null,
|
|
10188
|
+
requiresVerification: json.requires_verification ?? false
|
|
10189
|
+
},
|
|
10190
|
+
committedAt: Date.now(),
|
|
10191
|
+
idempotentReplay: false
|
|
10192
|
+
};
|
|
10193
|
+
}
|
|
10194
|
+
if (inv.capabilityName === "agents.create") {
|
|
10195
|
+
const { name, prompt, firstMessage, voiceId, language } = inv.args;
|
|
10196
|
+
if (typeof name !== "string" || !name.trim()) invalid("name is required");
|
|
10197
|
+
if (typeof prompt !== "string" || !prompt.trim()) invalid("prompt is required");
|
|
10198
|
+
const body = {
|
|
10199
|
+
name,
|
|
10200
|
+
conversation_config: {
|
|
10201
|
+
agent: {
|
|
10202
|
+
prompt: { prompt },
|
|
10203
|
+
...typeof firstMessage === "string" ? { first_message: firstMessage } : {},
|
|
10204
|
+
language: typeof language === "string" ? language : "en"
|
|
10205
|
+
},
|
|
10206
|
+
...typeof voiceId === "string" ? { tts: { voice_id: voiceId } } : {}
|
|
10207
|
+
}
|
|
10208
|
+
};
|
|
10209
|
+
return {
|
|
10210
|
+
status: "committed",
|
|
10211
|
+
data: { agentId: (await elevenlabs(inv, "/v1/convai/agents/create", JSON.stringify(body), 3e4)).agent_id ?? null },
|
|
10212
|
+
committedAt: Date.now(),
|
|
10213
|
+
idempotentReplay: false
|
|
10214
|
+
};
|
|
10215
|
+
}
|
|
10216
|
+
return base$8.executeMutation(inv);
|
|
10217
|
+
}
|
|
10218
|
+
};
|
|
10219
|
+
function invalid(message) {
|
|
10220
|
+
throw new IntegrationRuntimeError({
|
|
10221
|
+
code: "input_invalid",
|
|
10222
|
+
message: `ElevenLabs ${message}`
|
|
10223
|
+
});
|
|
10224
|
+
}
|
|
10225
|
+
function httpsUrl(value, field) {
|
|
10226
|
+
if (typeof value !== "string" || value.length > 2048 || !URL.canParse(value) || new URL(value).protocol !== "https:") invalid(`${field} must be an https URL`);
|
|
10227
|
+
return value;
|
|
10228
|
+
}
|
|
10229
|
+
async function downloadSample(url) {
|
|
10230
|
+
const res = await fetch(url, {
|
|
10231
|
+
redirect: "follow",
|
|
10232
|
+
signal: AbortSignal.timeout(2e4)
|
|
10233
|
+
});
|
|
10234
|
+
if (!res.ok) invalid(`could not download sample (${res.status})`);
|
|
10235
|
+
const bytes = Buffer.from(await res.arrayBuffer());
|
|
10236
|
+
if (bytes.length === 0 || bytes.length > MAX_SAMPLE_BYTES) invalid("each sample must be under 11 MB");
|
|
10237
|
+
return {
|
|
10238
|
+
bytes,
|
|
10239
|
+
contentType: res.headers.get("content-type")?.split(";", 1)[0] ?? "application/octet-stream"
|
|
10240
|
+
};
|
|
10241
|
+
}
|
|
10242
|
+
async function elevenlabs(inv, path, body, timeoutMs) {
|
|
10243
|
+
const creds = inv.source.credentials;
|
|
10244
|
+
if (creds.kind !== "api-key" || !creds.apiKey || /[\u0000- \u007f]/.test(creds.apiKey)) throw new IntegrationRuntimeError({
|
|
10245
|
+
code: "provider_auth_failed",
|
|
10246
|
+
message: "ElevenLabs requires the connected API key",
|
|
10247
|
+
userAction: {
|
|
10248
|
+
type: "reconnect",
|
|
10249
|
+
label: "Reconnect ElevenLabs"
|
|
10250
|
+
}
|
|
10251
|
+
});
|
|
10252
|
+
try {
|
|
10253
|
+
const json = await requestJson(`${ELEVENLABS_BASE_URL}${path}`, {
|
|
10254
|
+
method: "POST",
|
|
10255
|
+
headers: {
|
|
10256
|
+
"xi-api-key": creds.apiKey,
|
|
10257
|
+
...typeof body === "string" ? { "Content-Type": "application/json" } : {}
|
|
10258
|
+
},
|
|
10259
|
+
body
|
|
10260
|
+
}, {
|
|
10261
|
+
timeoutMs,
|
|
10262
|
+
maxResponseBytes: 8e6
|
|
10263
|
+
});
|
|
10264
|
+
if (!record$3(json)) throw new ProviderProtocolError("ElevenLabs returned a non-object response", "invalid_response");
|
|
10265
|
+
return json;
|
|
10266
|
+
} catch (error) {
|
|
10267
|
+
if (error instanceof ProviderProtocolError && error.status === 401) throw new CredentialsExpired("ElevenLabs rejected the connected API key", inv.source.id, { status: 401 });
|
|
10268
|
+
if (error instanceof ProviderProtocolError && error.status === 429) throw new ProviderRateLimited("ElevenLabs rate limit", inv.source.id, {
|
|
10269
|
+
status: 429,
|
|
10270
|
+
retryAfterMs: error.retryAfterMs ?? 6e4
|
|
10271
|
+
});
|
|
10272
|
+
if (error instanceof ProviderProtocolError && [
|
|
10273
|
+
400,
|
|
10274
|
+
402,
|
|
10275
|
+
403,
|
|
10276
|
+
413,
|
|
10277
|
+
415,
|
|
10278
|
+
422
|
|
10279
|
+
].includes(error.status)) throw new IntegrationRuntimeError({
|
|
10280
|
+
code: "input_invalid",
|
|
10281
|
+
message: `ElevenLabs refused the request (${error.status}${error.status === 402 || error.status === 403 ? ": this feature may need a paid plan" : ""})`
|
|
10282
|
+
});
|
|
10283
|
+
throw error;
|
|
10284
|
+
}
|
|
10285
|
+
}
|
|
9551
10286
|
//#endregion
|
|
9552
10287
|
//#region src/connectors/adapters/excel-files.ts
|
|
9553
10288
|
const MAX_COLUMNS$2 = 256;
|
|
@@ -193118,4 +193853,4 @@ var adapters_exports = /* @__PURE__ */ __exportAll({
|
|
|
193118
193853
|
//#endregion
|
|
193119
193854
|
export { uscreenConnector as $, openaiConnector as $a, harvestConnector as $c, clearoutphoneConnector as $d, campaignMonitorConnector as $i, checkoutConnector as $l, mailerooConnector as $n, zohoBooksConnector as $o, mailercheckConnector as $r, parquetFilesConnector as $s, postizConnector as $t, snowflakeConnector as $u, bettercontactConnector as A, altTextAiConnector as Aa, microsoftCalendar as Ac, giftbitConnector as Ad, copyAiConnector as Ai, classifyGoogleError as Al, instasentConnector as An, digitalOceanConnector as Ao, joggAiConnector as Ar, sageIntacctConnector as As, sendinblueConnector as At, avomaConnector as Au, woocommerceConnector as B, airOpsConnector as Ba, kafkaConnector as Bc, echowinConnector as Bd, clockifyConnector as Bi, filloutFormsConnector as Bl, gptzeroDetectAiConnector as Bn, smartleadConnector as Bo, hashiCorpVaultConnector as Br, rssConnector as Bs, retableConnector as Bt, amazonEventBridgeConnector as Bu, serperConnector as C, apitableConnector as Ca, microsoftPowerBiConnector as Cc, clicdataConnector as Cd, oktaConnector as Cf, descriptConnector as Ci, metaAdsConnector as Cl, nocodbConnector as Cn, createMySqlConnector as Co, koFiConnector as Cr, todoistConnector as Cs, simplybookmeConnector as Ct, backblazeConnector as Cu, snovIoConnector as D, amazonTextractConnector as Da, microsoftExcel365Connector as Dc, adpConnector as Dd, customgptConnector as Di, gorgiasConnector as Dl, loopsConnector as Dn, googleBigqueryConnector as Do, kimaiConnector as Dr, stripePackConnector as Ds, serviceNowConnector as Dt, azureBlobStorageConnector as Du, wizaConnector as E, apitemplateIoConnector as Ea, microsoftGraph as Ec, bexioConnector as Ed, phonyConnector as Ef, deepseekConnector as Ei, googleCalendar as El, mailchainConnector as En, hightouchConnector as Eo, kissflowConnector as Er, tallyConnector as Es, signrequestConnector as Et, azureEventGridConnector as Eu, zeplinConnector as F, aipriseConnector as Fa, linkedinConnector as Fc, fellowConnector as Fd, cometapiConnector as Fi, frontConnector as Fl, humeAiConnector as Fn, TELEGRAM_FILE_DOWNLOAD_ROOT as Fo, instantlyAiConnector as Fr, savvycalConnector as Fs, sardisConnector as Ft, amazonSqsConnector as Fu, webscrapingAiConnector as G, bamboohrConnector as Ga, ironcladConnector as Gc, detectingAiConnector as Gd, chatbaseConnector as Gi, fathomConnector as Gl, missiveConnector as Gn, lemlistConnector as Go, greenptConnector as Gr, postgresConnector as Gs, raiaAiConnector as Gt, zuoraConnector as Gu, wonderchatConnector as H, activecampaignConnector as Ha, justcallConnector as Hc, docsbotConnector as Hd, chatnodeConnector as Hi, figjamConnector as Hl, glideConnector as Hn, outreachConnector as Ho, hastewireConnector as Hr, rampConnector as Hs, reoonVerifierConnector as Ht, affinityConnector as Hu, youcanbookmeConnector as I, acumbamailConnector as Ia, linearConnector as Ic, featheryConnector as Id, cohereConnector as Ii, freshsalesConnector as Il, hedyConnector as In, telegramConnector as Io, huggingFaceConnector as Ir, saleorConnector as Is, saasticConnector as It, amazonSnsConnector as Iu, vtigerConnector as J, weaviateConnector as Ja, instagramBusinessConnector as Jc, couchbaseConnector as Jd, cannyConnector as Ji, dropboxConnector as Jl, mindeeConnector as Jn, brazeConnector as Jo, ghostcmsConnector as Jr, createRedisConnector as Js, pushoverConnector as Jt, wootricConnector as Ju, whatConvertsConnector as K, qdrantConnector as Ka, invoiceninjaConnector as Kc, deepgramConnector as Kd, chatlingConnector as Ki, etsyConnector as Kl, mixpanelConnector as Kn, klaviyoConnector as Ko, googleSearchConnector as Kr, createRedshiftConnector as Ks, quadernoConnector as Kt, zoominfoConnector as Ku, wufooConnector as L, aidbaseConnector as La, lemonSqueezyConnector as Lc, everhourConnector as Ld, cognitoFormsConnector as Li, freshdeskConnector as Ll, heartbeatConnector as Ln, mattermostConnector as Lo, influencersClubConnector as Lr, createSftpConnector as Ls, runwareConnector as Lt, amazonS3Connector as Lu, lagrowthmachineConnector as M, airtopConnector as Ma, microsoft365PeopleConnector as Mc, genderApiConnector as Md, convertkitConnector as Mi, googleApiError as Ml, imapConnector as Mn, datadogConnector as Mo, jiraDataCenterConnector as Mr, signNowConnector as Ms, seekTableConnector as Mt, auth0Connector as Mu, heyreachConnector as N, amazonSecretsManagerConnector as Na, makeConnector as Nc, gammaConnector as Nd, crispConnector as Ni, googleErrorReason as Nl, ibmCognoseConnector as Nn, baserowConnector as No, jinaAiConnector as Nr, shippoConnector as Ns, scrapelessConnector as Nt, attioConnector as Nu, findymailConnector as O, amazonSesConnector as Oa, microsoftDynamicsCrmConnector as Oc, adobeCreativeCloudConnector as Od, cryptolensConnector as Oi, gongConnector as Ol, knockConnector as On, firebaseConnector as Oo, kapsoConnector as Or, squareConnector as Os, serpstatConnector as Ot, azureAdConnector as Ou, amplemarketConnector as P, amazonBedrockConnector as Pa, createLinkedinConnector as Pc, flowParserConnector as Pd, comfyicuConnector as Pi, googleTestFailureReason as Pl, hystructConnector as Pn, airtableConnector as Po, imageRouterConnector as Pr, sharepoint as Ps, scrapegraphaiConnector as Pt, asanaConnector as Pu, vboutConnector as Q, anthropicConnector as Qa, helpscoutConnector as Qc, clickfunnelsConnector as Qd, braveSearchConnector as Qi, chessComConnector as Ql, messagebirdConnector as Qn, zohoCampaignsConnector as Qo, frameConnector as Qr, quickbooksConnector as Qs, posthogConnector as Qt, teableConnector as Qu, writesonicBulkConnector as R, afforaiConnector as Ra, leadConnectorConnector as Rc, excelFilesConnector as Rd, clearoutConnector as Ri, folkConnector as Rl, griptapeConnector as Rn, matrixConnector as Ro, housecallProConnector as Rr, sftpConnector as Rs, robollyConnector as Rt, amazonLambdaConnector as Ru, warmlyConnector as S, aminosConnector as Sa, microsoftTodoConnector as Sc, clioConnector as Sd, clientCredentialsRestConnector as Sf, datocmsConnector as Si, xAdsConnector as Sl, ntfyConnector as Sn, segmentConnector as So, kudosityConnector as Sr, trelloConnector as Ss, smartsheetConnector as St, biginByZohoConnector as Su, commonRoomConnector as T, ampecoConnector as Ta, microsoftTeams as Tc, bigcommerceConnector as Td, createPhonyConnector as Tf, denserAiConnector as Ti, googleAnalyticsConnector as Tl, medullarConnector as Tn, metabaseConnector as To, klentyConnector as Tr, ticktickConnector as Ts, shortIoConnector as Tt, azureServiceBusConnector as Tu, whatsscaleConnector as U, smooveConnector as Ua, jotformConnector as Uc, duckdbConnector as Ud, chatDataConnector as Ui, firefliesAiConnector as Ul, googleVertexaiConnector as Un, marketoConnector as Uo, guideliteConnector as Ur, recallAiConnector as Us, reachinboxConnector as Ut, aircallConnector as Uu, woodpeckerConnector as V, kustomerConnector as Va, publicKafkaSocketFactory as Vc, dripConnector as Vd, clockodoConnector as Vi, figmaConnector as Vl, gotifyConnector as Vn, salesloftConnector as Vo, heygenConnector as Vr, ringcentralConnector as Vs, replyIoConnector as Vt, amplitudeConnector as Vu, whatsappConnector as W, greenhouseConnector as Wa, jiraCloudConnector as Wc, digitalPilotConnector as Wd, chartlyConnector as Wi, fireberryConnector as Wl, exaConnector as Wn, mailchimpConnector as Wo, greipConnector as Wr, createPostgresConnector as Ws, rapidtextAiConnector as Wt, adobeSignConnector as Wu, vlmRunConnector as X, geminiConnector as Xa, httpConnector as Xc, contextualAiConnector as Xd, certopusConnector as Xi, docusignConnector as Xl, memConnector as Xn, zohoMailConnector as Xo, gameballConnector as Xr, createRabbitMqConnector as Xs, productboardConnector as Xt, vercelConnector as Xu, vtexConnector as Y, huggingfaceConnector as Ya, intercomConnector as Yc, contiguityConnector as Yd, chainalysisApiConnector as Yi, dialpadConnector as Yl, millionverifierConnector as Yn, apolloConnector as Yo, freshserviceConnector as Yr, redisConnector as Ys, proxycurlConnector as Yt, videoaskConnector as Yu, vidlab7Connector as Z, googleGeminiConnector as Za, hubspot as Zc, codyConnector as Zd, captainDataConnector as Zi, docuseal as Zl, mauticConnector as Zn, zohoInvoiceConnector as Zo, fragmentConnector as Zr, rabbitMqConnector as Zs, predictLeadsConnector as Zt, tenzoConnector as Zu, phantombusterConnector as _, ashbyConnector as _a, mondayConnector as _c, formstackConnector as _d, aianswerConnector as _f, dubConnector as _i, pinterestAdsConnector as _l, opportifyConnector as _n, neverbounceConnector as _o, linkupConnector as _r, tiktokConnector as _s, swarmnodeConnector as _t, billplzConnector as _u, linqConnector as a, bonjoroConnector as aa, outlookMail as ac, pushbulletConnector as ad, csvFilesConnector as af, facebookLeadsConnector as ai, googleSheets as al, perplexityAiConnector as an, quickzuConnector as ao, mailerLiteConnector as ar, zoomConnector as as, twinLabsConnector as at, copperConnector as au, crustdataConnector as b, semrushConnector as ba, meetgeekAiConnector as bc, constantContactConnector as bd, pingIdentityConnector as bf, documergeConnector as bi, linkedinAdsConnector as bl, omniCoConnector as bn, builtwithConnector as bo, kommoConnector as br, typeformConnector as bs, smsmodeConnector as bt, baremetricsConnector as bu, factorsAiConnector as c, bettermodeConnector as ca, openPhoneConnector as cc, opsgenieConnector as cd, buttondownConnector as cf, firecrawlConnector as ci, googleMeetConnector as cl, parseurConnector as cn, githubConnector as co, logsnagConnector as cr, youtubeDataConnector as cs, togglTrackConnector as ct, codaConnector as cu, signwellConnector as d, barcodeLookupConnector as da, n8nConnector as dc, lightfunnelsConnector as dd, base44Connector as df, emailoctopusConnector as di, googleDocs as dl, pastefyConnector as dn, gtmAgentConnector as do, magicalApiConnector as dr, webflowConnector as ds, textcortexAiConnector as dt, clickupConnector as du, brilliantDirectoriesConnector as ea, pipedriveConnector as ec, sendpulseConnector as ed, claudeConnector as ef, fountainConnector as ei, hellosign as el, pollybotAiConnector as en, sentryConnector as eo, mailgunConnector as er, zohoCrmConnector as es, umamiConnector as et, circleConnector as eu, polytomicConnector as f, autocallsConnector as fa, notion as fc, leverConnector as fd, bannerbearConnector as ff, dustConnector as fi, googleContactsConnector as fl, paperformConnector as fn, webhookConnector as fo, llmrailsConnector as fr, xeroConnector as fs, telnyxConnector as ft, closeConnector as fu, zenrowsConnector as g, assemblyaiConnector as ga, mongodbConnector as gc, freeAgentConnector as gd, airparserConnector as gf, documentproConnector as gi, createMicrosoftAdsConnector as gl, openmicAiConnector as gn, theirstackConnector as go, letsCalendarConnector as gr, tiktok as gs, stripeConnector as gt, calComConnector as gu, oceanIoConnector as h, avianConnector as ha, createMongoDbConnector as hc, giteaConnector as hd, anyhookWebsocketConnector as hf, elasticEmailConnector as hi, createAmazonAdsConnector as hl, opnformConnector as hn, zerobounceConnector as ho, linkaConnector as hr, twilioSmsConnector as hs, systemeIoConnector as ht, calCom as hu, linqWhatsappConnector as i, blueskyConnector as ia, pandadoc as ic, redditConnector as id, chainAwareConnector as if, flowiseConnector as ii, googleSlidesConnector as il, personalAiConnector as in, zagomailConnector as io, luxuryPresenceConnector as ir, zohoBookingsConnector as is, twilioConnector as it, chargebeeConnector as iu, saleshandyConnector as j, alaiConnector as ja, microsoft365PlannerConnector as jc, generatebannersConnector as jd, dashworksConnector as ji, classifyGoogleReason as jl, insightoAiConnector as jn, discourseConnector as jo, justInvoiceConnector as jr, slack as js, skyprepConnector as jt, acuitySchedulingConnector as ju, contactoutConnector as k, alttextifyConnector as ka, microsoftDynamics365BusinessCentralConnector as kc, modelslabConnector as kd, datafuelConnector as ki, gmail as kl, kallabotAiConnector as kn, clicksendConnector as ko, kizeoFormsConnector as kr, shopifyConnector as ks, senjaConnector as kt, avalaraConnector as ku, modjoConnector as l, beamerConnector as la, ninjapipeConnector as lc, niftyConnector as ld, bikaConnector as lf, esignaturesConnector as li, googleForms as ll, paywhirlConnector as ln, slackEventsConnector as lo, logrocketConnector as lr, wrikeConnector as ls, timelinesAiConnector as lt, cloudinaryConnector as lu, seamlessAiConnector as m, asknewsConnector as ma, mycaseConnector as mc, gustoConnector as md, apifyConnector as mf, edenAiConnector as mi, googleCloudStorageConnector as ml, orimonConnector as mn, resolveConnectorAdapterFactoryOptions as mo, localaiConnector as mr, voucheryIoConnector as ms, tableauConnector as mt, calendlyConnector as mu, sendblueConnector as n, bookedinConnector as na, plaidConnector as nc, ripplingConnector as nd, chatAidConnector as nf, formbricksConnector as ni, googlechatConnector as nl, plausibleConnector as nn, sendgridConnector as no, matomoConnector as nr, pricelabsConnector as ns, vapiConnector as nt, taxjarConnector as nu, inkboxConnector as o, bitlyConnector as oa, oneSpanSignConnector as oc, paychexConnector as od, cartloomConnector as of, enrichlayerConnector as oi, googleSearchConsoleConnector as ol, peekshotConnector as on, facebookPagesConnector as oo, lushaConnector as or, zendeskConnector as os, typefullyConnector as ot, contentfulConnector as ou, usergemsConnector as p, azureCommunicationServicesConnector as pa, notionConnector as pc, instaChartsConnector as pd, askHandleConnector as pf, easyPeasyAiConnector as pi, googlePubSubConnector as pl, oracleDatabaseConnector as pn, CONNECTOR_ADAPTER_FACTORIES as po, lobstermailConnector as pr, whatsappBusiness as ps, talkableConnector as pt, capsuleCrmConnector as pu, wafeqConnector as q, pineconeConnector as qa, insightlyConnector as qc, dappierConnector as qd, chargekeepConnector as qi, ebayConnector as ql, mixmaxConnector as qn, customerIoConnector as qo, gistlyConnector as qr, redshiftConnector as qs, qawafelConnector as qt, workdayConnector as qu, resendConnector as r, bolnaConnector as ra, paddleConnector as rc, reddit as rd, chaindeskConnector as rf, flipandoConnector as ri, googleTasksConnector as rl, placidConnector as rn, zendeskSellConnector as ro, lucidyaConnector as rr, cloudbedsConnector as rs, upgradechatConnector as rt, recurlyConnector as ru, getresponseConnector as s, blandAiConnector as sa, oneDrive as sc, pagerdutyConnector as sd, cambAiConnector as sf, fathomAnalyticsConnector as si, googleMyBusinessConnector as sl, pdfmonkeyConnector as sn, gitlabConnector as so, loftyConnector as sr, zapierConnector as ss, totalcmsConnector as st, confluenceConnector as su, adapters_exports as t, browseAiConnector as ta, pipedreamConnector as tc, sanityConnector as td, chatsistantConnector as tf, foreplayCoConnector as ti, granolaConnector as tl, pocketbaseConnector as tn, postmarkConnector as to, manychatConnector as tr, zohoDeskConnector as ts, validatedmailsConnector as tt, cashfreePaymentsConnector as tu, nooksConnector as u, azureOpenaiConnector as ua, netsuiteConnector as uc, netlifyConnector as ud, beehiivConnector as uf, emailitConnector as ui, googleDrive as ul, pinchPaymentsConnector as un, stripeWebhookReceiverConnector as uo, lokaliseConnector as ur, wordpressConnector as us, timeOpsConnector as ut, cloudflareConnector as uu, brightdataConnector as v, clayConnector as va, miroConnector as vc, discordConnector as vd, actualbudgetConnector as vf, dumplingAiConnector as vi, snapchatAdsConnector as vl, openRouterConnector as vn, hunterConnector as vo, lettaConnector as vr, twitter as vs, supadataConnector as vt, billComConnector as vu, leadfeederConnector as w, appfollowConnector as wa, microsoftOnenoteConnector as wc, canvaConnector as wd, declarativeRestConnector as wf, devinConnector as wi, googleAdsConnector as wl, mindStudioConnector as wn, mysqlConnector as wo, knackConnector as wr, tlDvConnector as ws, simplirouteConnector as wt, basecampConnector as wu, autoboundConnector as x, similarwebConnector as xa, mastodonConnector as xc, cloudconvertConnector as xd, oneloginConnector as xf, dittofeedConnector as xi, tiktokAdsConnector as xl, odooConnector as xn, supabaseConnector as xo, leapAiConnector as xr, twentyConnector as xs, smartsuiteConnector as xt, boxConnector as xu, leadmagicConnector as y, cognismConnector as ya, mollieConnector as yc, demandbaseConnector as yd, scimConnector as yf, doctlyConnector as yi, redditAdsConnector as yl, omnihrConnector as yn, fullenrichConnector as yo, leexiConnector as yr, twitterConnector as ys, socialkitConnector as yt, brexConnector as yu, workableConnector as z, agentxConnector as za, createKafkaConnector as zc, elevenlabsConnector as zd, cloutlyConnector as zi, flowluConnector as zl, gristConnector as zn, chatwootConnector as zo, heymarketSmsConnector as zr, salesforceConnector as zs, retellAiConnector as zt, amazonCloudWatchConnector as zu };
|
|
193120
193855
|
|
|
193121
|
-
//# sourceMappingURL=adapters-
|
|
193856
|
+
//# sourceMappingURL=adapters-DZb0dJHa.js.map
|