elevenlabs-cli 0.1.8

Unofficial CLI for ElevenLabs text-to-speech API
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
//! Tool definitions for MCP server.
//!
//! This module provides tool schemas and handlers for all ElevenLabs API operations.

use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

fn default_tts_model() -> String {
    "eleven_multilingual_v2".to_string()
}

fn default_output_format() -> String {
    "mp3_44100_128".to_string()
}

// ============================================================================
// TTS Tools
// ============================================================================

/// Convert text to speech
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct TextToSpeechInput {
    /// The text to convert to speech
    pub text: String,
    /// Voice ID or name to use (e.g., "Brian", "Rachel", or a voice ID)
    pub voice: String,
    /// Model to use: eleven_multilingual_v2, eleven_flash_v2_5, eleven_turbo_v2, eleven_v3
    #[serde(default = "default_tts_model")]
    pub model: String,
    /// Output format: mp3_44100_128, mp3_44100_192, pcm_16000, etc.
    #[serde(default = "default_output_format")]
    pub output_format: String,
    /// Voice stability (0.0-1.0, higher = more stable)
    #[serde(default)]
    pub stability: Option<f32>,
    /// Voice similarity boost (0.0-1.0)
    #[serde(default)]
    pub similarity_boost: Option<f32>,
    /// Voice style (0.0-1.0)
    #[serde(default)]
    pub style: Option<f32>,
    /// Enable speaker boost
    #[serde(default)]
    pub speaker_boost: bool,
    /// Output file path (if not specified, returns base64 audio)
    #[serde(default)]
    pub output_file: Option<String>,
}

/// Result of text-to-speech conversion
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct TextToSpeechOutput {
    /// Whether the operation was successful
    pub success: bool,
    /// Output file path (if saved to disk)
    pub output_file: Option<String>,
    /// Base64-encoded audio data (if not saved to disk)
    pub audio_base64: Option<String>,
    /// Audio duration in seconds
    pub duration_seconds: Option<f64>,
    /// Error message if unsuccessful
    pub error: Option<String>,
}

// ============================================================================
// Speech-to-Text Tools
// ============================================================================

/// Transcribe audio to text
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct SpeechToTextInput {
    /// Path to the audio file to transcribe
    pub file: String,
    /// Model: scribe_v1, scribe_v1_base, scribe_v2
    #[serde(default = "default_stt_model")]
    pub model: String,
    /// Language code (auto-detected if not specified)
    #[serde(default)]
    pub language: Option<String>,
    /// Enable speaker diarization
    #[serde(default)]
    pub diarize: bool,
    /// Number of speakers (for diarization)
    #[serde(default)]
    pub num_speakers: Option<u32>,
    /// Timestamps granularity: none, word, character
    #[serde(default = "default_timestamps")]
    pub timestamps: String,
}

fn default_stt_model() -> String {
    "scribe_v1".to_string()
}

fn default_timestamps() -> String {
    "word".to_string()
}

/// Result of speech-to-text transcription
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct SpeechToTextOutput {
    /// Whether the operation was successful
    pub success: bool,
    /// Transcribed text
    pub text: Option<String>,
    /// Detected language code
    pub language_code: Option<String>,
    /// Language detection confidence
    pub language_probability: Option<f64>,
    /// Word-level timestamps
    pub words: Option<Vec<WordTimestamp>>,
    /// Error message if unsuccessful
    pub error: Option<String>,
}

/// Word with timing information
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct WordTimestamp {
    pub text: String,
    pub start: Option<f64>,
    pub end: Option<f64>,
    pub speaker_id: Option<String>,
}

// ============================================================================
// Voice Management Tools
// ============================================================================

/// List available voices
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct ListVoicesInput {
    /// Include detailed information
    #[serde(default)]
    pub detailed: bool,
}

/// Voice information
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct VoiceInfo {
    pub voice_id: String,
    pub name: String,
    pub category: Option<String>,
    pub description: Option<String>,
    pub labels: Option<std::collections::HashMap<String, String>>,
}

/// Result of listing voices
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct ListVoicesOutput {
    pub success: bool,
    pub voices: Vec<VoiceInfo>,
    pub total_count: usize,
    pub error: Option<String>,
}

/// Clone a voice from audio samples
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct CloneVoiceInput {
    /// Name for the cloned voice
    pub name: String,
    /// Description of the voice
    #[serde(default)]
    pub description: Option<String>,
    /// Paths to audio sample files
    pub samples: Vec<String>,
    /// Labels as key=value pairs
    #[serde(default)]
    pub labels: Option<std::collections::HashMap<String, String>>,
}

/// Result of voice cloning
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct CloneVoiceOutput {
    pub success: bool,
    pub voice_id: Option<String>,
    pub requires_verification: Option<bool>,
    pub error: Option<String>,
}

// ============================================================================
// Sound Effects Tools
// ============================================================================

/// Generate sound effects from text
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct GenerateSfxInput {
    /// Text description of the sound effect
    pub text: String,
    /// Duration in seconds (0.5-22, auto if not specified)
    #[serde(default)]
    pub duration: Option<f32>,
    /// Prompt influence (0-1)
    #[serde(default)]
    pub influence: Option<f32>,
    /// Output file path
    #[serde(default)]
    pub output_file: Option<String>,
}

/// Result of sound effect generation
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct GenerateSfxOutput {
    pub success: bool,
    pub output_file: Option<String>,
    pub audio_base64: Option<String>,
    pub duration_seconds: Option<f64>,
    pub error: Option<String>,
}

// ============================================================================
// Audio Isolation Tools
// ============================================================================

/// Isolate vocals/speech from audio
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct AudioIsolationInput {
    /// Path to the input audio file
    pub file: String,
    /// Output file path
    #[serde(default)]
    pub output_file: Option<String>,
}

/// Result of audio isolation
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct AudioIsolationOutput {
    pub success: bool,
    pub output_file: Option<String>,
    pub audio_base64: Option<String>,
    pub error: Option<String>,
}

// ============================================================================
// Voice Changer Tools
// ============================================================================

/// Transform voice in audio file
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct VoiceChangerInput {
    /// Path to the input audio file
    pub file: String,
    /// Target voice ID or name
    pub voice: String,
    /// Model to use
    #[serde(default = "default_vc_model")]
    pub model: String,
    /// Output file path
    #[serde(default)]
    pub output_file: Option<String>,
}

fn default_vc_model() -> String {
    "eleven_multilingual_sts_v2".to_string()
}

/// Result of voice changing
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct VoiceChangerOutput {
    pub success: bool,
    pub output_file: Option<String>,
    pub audio_base64: Option<String>,
    pub error: Option<String>,
}

// ============================================================================
// Dubbing Tools
// ============================================================================

/// Create a dubbing project
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct CreateDubbingInput {
    /// Path to the video/audio file
    pub file: String,
    /// Source language code
    pub source_lang: String,
    /// Target language code
    pub target_lang: String,
    /// Number of speakers
    #[serde(default)]
    pub num_speakers: Option<u32>,
}

/// Result of creating dubbing project
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct CreateDubbingOutput {
    pub success: bool,
    pub dubbing_id: Option<String>,
    pub expected_duration_sec: Option<f64>,
    pub error: Option<String>,
}

/// Check dubbing status
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct GetDubbingStatusInput {
    pub dubbing_id: String,
}

/// Dubbing status result
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct GetDubbingStatusOutput {
    pub success: bool,
    pub status: Option<String>,
    pub name: Option<String>,
    pub target_languages: Option<Vec<String>>,
    pub error: Option<String>,
}

// ============================================================================
// Agent Tools
// ============================================================================

/// List agents
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct ListAgentsInput {
    /// Maximum number of agents to return
    #[serde(default)]
    pub limit: Option<u32>,
}

/// Agent information
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct AgentInfo {
    pub agent_id: String,
    pub name: String,
    pub description: Option<String>,
    pub created_at: Option<String>,
}

/// Result of listing agents
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct ListAgentsOutput {
    pub success: bool,
    pub agents: Vec<AgentInfo>,
    pub total_count: usize,
    pub error: Option<String>,
}

/// Create an agent
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct CreateAgentInput {
    /// Agent name
    pub name: String,
    /// Agent description
    #[serde(default)]
    pub description: Option<String>,
    /// Voice ID for the agent
    #[serde(default)]
    pub voice_id: Option<String>,
    /// First message template
    #[serde(default)]
    pub first_message: Option<String>,
    /// System prompt
    #[serde(default)]
    pub system_prompt: Option<String>,
}

/// Result of creating agent
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct CreateAgentOutput {
    pub success: bool,
    pub agent_id: Option<String>,
    pub error: Option<String>,
}

// ============================================================================
// History Tools
// ============================================================================

/// List generation history
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct ListHistoryInput {
    /// Maximum number of items to return
    #[serde(default = "default_history_limit")]
    pub limit: u32,
}

fn default_history_limit() -> u32 {
    10
}

/// History item information
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct HistoryItemInfo {
    pub history_item_id: String,
    pub voice_name: String,
    pub voice_id: String,
    pub model_id: Option<String>,
    pub text: String,
    pub date_unix: i64,
    pub character_count: i32,
}

/// Result of listing history
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct ListHistoryOutput {
    pub success: bool,
    pub items: Vec<HistoryItemInfo>,
    pub total_count: usize,
    pub error: Option<String>,
}

// ============================================================================
// Usage Tools
// ============================================================================

/// Get usage statistics
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct GetUsageInput {
    /// Start time (Unix timestamp, defaults to 30 days ago)
    #[serde(default)]
    pub start: Option<u64>,
    /// End time (Unix timestamp, defaults to now)
    #[serde(default)]
    pub end: Option<u64>,
}

/// Usage statistics result
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct GetUsageOutput {
    pub success: bool,
    pub total_characters: u64,
    pub usage_by_type: Option<std::collections::HashMap<String, u64>>,
    pub error: Option<String>,
}

// ============================================================================
// User Tools
// ============================================================================

/// Get user information
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct GetUserInfoInput;

/// User information result
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct GetUserInfoOutput {
    pub success: bool,
    pub user_id: Option<String>,
    pub subscription_tier: Option<String>,
    pub character_count: Option<i32>,
    pub character_limit: Option<i32>,
    pub usage_percentage: Option<f64>,
    pub error: Option<String>,
}

// ============================================================================
// Model Tools
// ============================================================================

/// List available models
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct ListModelsInput;

/// Model information
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct ModelInfo {
    pub model_id: String,
    pub name: String,
    pub description: Option<String>,
    pub languages: Vec<String>,
}

/// Result of listing models
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct ListModelsOutput {
    pub success: bool,
    pub models: Vec<ModelInfo>,
    pub total_count: usize,
    pub error: Option<String>,
}

// ============================================================================
// Dialogue Tools
// ============================================================================

/// Create multi-voice dialogue
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct CreateDialogueInput {
    /// Dialogue inputs as array of {text, voice_id} objects
    pub inputs: Vec<DialogueInputItem>,
    /// Model to use
    #[serde(default = "default_dialogue_model")]
    pub model: String,
    /// Output file path
    #[serde(default)]
    pub output_file: Option<String>,
}

/// Single dialogue input
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct DialogueInputItem {
    pub text: String,
    pub voice_id: String,
}

fn default_dialogue_model() -> String {
    "eleven_v3".to_string()
}

/// Result of dialogue creation
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct CreateDialogueOutput {
    pub success: bool,
    pub output_file: Option<String>,
    pub audio_base64: Option<String>,
    pub voice_segments: Option<Vec<VoiceSegmentInfo>>,
    pub error: Option<String>,
}

/// Voice segment information
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct VoiceSegmentInfo {
    pub voice_id: String,
    pub start_time_seconds: f64,
    pub end_time_seconds: f64,
}

// ============================================================================
// Knowledge Base Tools
// ============================================================================

/// Add document to knowledge base
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct AddKnowledgeInput {
    /// Source type: url, text, or file
    pub source_type: String,
    /// Content (URL, text, or file path)
    pub content: String,
    /// Document name
    pub name: String,
    /// Document description
    #[serde(default)]
    pub description: Option<String>,
}

/// Result of adding knowledge
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct AddKnowledgeOutput {
    pub success: bool,
    pub document_id: Option<String>,
    pub error: Option<String>,
}

/// List knowledge base documents
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct ListKnowledgeInput {
    #[serde(default)]
    pub limit: Option<u32>,
}

/// Knowledge document info
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct KnowledgeDocumentInfo {
    pub id: String,
    pub name: String,
    pub document_type: Option<String>,
    pub created_at: String,
}

/// Result of listing knowledge
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct ListKnowledgeOutput {
    pub success: bool,
    pub documents: Vec<KnowledgeDocumentInfo>,
    pub total_count: usize,
    pub error: Option<String>,
}

// ============================================================================
// Webhook Tools
// ============================================================================

/// Create a webhook
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct CreateWebhookInput {
    pub name: String,
    pub url: String,
    pub events: Vec<String>,
}

/// Result of creating webhook
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct CreateWebhookOutput {
    pub success: bool,
    pub webhook_id: Option<String>,
    pub error: Option<String>,
}

/// List webhooks
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct ListWebhooksInput;

/// Webhook info
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct WebhookInfo {
    pub id: String,
    pub name: String,
    pub url: String,
    pub events: Vec<String>,
}

/// Result of listing webhooks
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct ListWebhooksOutput {
    pub success: bool,
    pub webhooks: Vec<WebhookInfo>,
    pub error: Option<String>,
}

// ============================================================================
// Voice Library Tools
// ============================================================================

/// List voices from the shared voice library
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct ListVoicesFromLibraryInput {
    /// Maximum number of voices to return
    #[serde(default)]
    pub limit: Option<u32>,
    /// Voice category filter (professional, high_quality, generated, famous)
    #[serde(default)]
    pub category: Option<String>,
    /// Gender filter (male, female)
    #[serde(default)]
    pub gender: Option<String>,
    /// Age filter (young, middle_aged, old)
    #[serde(default)]
    pub age: Option<String>,
    /// Search query
    #[serde(default)]
    pub search: Option<String>,
}

/// Result of listing voices from library
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct ListVoicesFromLibraryOutput {
    pub success: bool,
    pub voices: Vec<VoiceInfo>,
    pub total_count: usize,
    pub error: Option<String>,
}

/// Add a voice from the shared library to user's saved voices
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct AddVoiceToLibraryInput {
    /// Public user ID of the voice owner
    pub public_user_id: String,
    /// Voice ID to add
    pub voice_id: String,
    /// Name for the saved voice
    pub name: String,
}

/// Result of adding voice to library
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct AddVoiceToLibraryOutput {
    pub success: bool,
    pub voice_id: Option<String>,
    pub error: Option<String>,
}

/// List voice collections
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct ListCollectionsInput {
    /// Maximum number of collections to return
    #[serde(default)]
    pub page_size: Option<u32>,
}

/// Collection info
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct CollectionInfo {
    pub collection_id: String,
    pub name: String,
    pub voice_count: Option<u32>,
    pub created_at: Option<String>,
}

/// Result of listing collections
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct ListCollectionsOutput {
    pub success: bool,
    pub collections: Vec<CollectionInfo>,
    pub total_count: usize,
    pub error: Option<String>,
}

/// List voices in a collection
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct CollectionVoicesInput {
    /// Collection ID
    pub collection_id: String,
}

/// Collection voice info
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct CollectionVoiceInfo {
    pub voice_id: String,
    pub name: String,
    pub category: Option<String>,
}

/// Result of listing collection voices
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct CollectionVoicesOutput {
    pub success: bool,
    pub voices: Vec<CollectionVoiceInfo>,
    pub total_count: usize,
    pub error: Option<String>,
}

// ============================================================================
// Samples Tools
// ============================================================================

/// Get sample audio for a voice
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct GetSampleAudioInput {
    /// Voice ID
    pub voice_id: String,
    /// Sample ID
    pub sample_id: String,
}

/// Result of getting sample audio
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct GetSampleAudioOutput {
    pub success: bool,
    pub audio_base64: Option<String>,
    pub error: Option<String>,
}

// ============================================================================
// Pronunciation Tools
// ============================================================================

/// List pronunciation dictionaries
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct ListDictionariesInput;

/// Pronunciation dictionary info
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct DictionaryInfo {
    pub id: String,
    pub name: String,
    pub latest_version_id: String,
    pub creation_time_unix: i64,
}

/// Result of listing dictionaries
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct ListDictionariesOutput {
    pub success: bool,
    pub dictionaries: Vec<DictionaryInfo>,
    pub total_count: usize,
    pub error: Option<String>,
}

/// Add a pronunciation dictionary
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct AddDictionaryInput {
    /// Path to the PLS file
    pub file: String,
    /// Dictionary name
    pub name: String,
    /// Dictionary description
    #[serde(default)]
    pub description: Option<String>,
}

/// Result of adding dictionary
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct AddDictionaryOutput {
    pub success: bool,
    pub dictionary_id: Option<String>,
    pub version_id: Option<String>,
    pub error: Option<String>,
}

/// Get a pronunciation dictionary
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct GetDictionaryInput {
    /// Dictionary ID
    pub dictionary_id: String,
}

/// Dictionary detail info
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct DictionaryDetailInfo {
    pub id: String,
    pub name: String,
    pub description: Option<String>,
    pub latest_version_id: String,
    pub creation_time_unix: i64,
}

/// Result of getting dictionary
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct GetDictionaryOutput {
    pub success: bool,
    pub dictionary: Option<DictionaryDetailInfo>,
    pub error: Option<String>,
}

/// Delete a pronunciation dictionary
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct DeleteDictionaryInput {
    /// Dictionary ID
    pub dictionary_id: String,
}

/// Result of deleting dictionary
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct DeleteDictionaryOutput {
    pub success: bool,
    pub error: Option<String>,
}

/// List rules in a pronunciation dictionary
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct ListRulesInput {
    /// Dictionary ID
    pub dictionary_id: String,
}

/// Pronunciation rule
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct PronunciationRule {
    pub word: String,
    pub phoneme: Option<String>,
    pub aliases: Option<Vec<String>>,
}

/// Result of listing rules
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct ListRulesOutput {
    pub success: bool,
    pub rules: Vec<PronunciationRule>,
    pub total_count: usize,
    pub error: Option<String>,
}

/// Add rules to a pronunciation dictionary
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct AddRulesInput {
    /// Dictionary ID
    pub dictionary_id: String,
    /// Rules file path (JSON format)
    pub rules_file: String,
}

/// Result of adding rules
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct AddRulesOutput {
    pub success: bool,
    pub error: Option<String>,
}

/// Remove rules from a pronunciation dictionary
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct RemoveRulesInput {
    /// Dictionary ID
    pub dictionary_id: String,
    /// Rules file path (JSON format)
    pub rules_file: String,
}

/// Result of removing rules
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct RemoveRulesOutput {
    pub success: bool,
    pub error: Option<String>,
}

// ============================================================================
// History Tools (Additional)
// ============================================================================

/// Get a specific history item
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct GetHistoryItemInput {
    /// History item ID
    pub history_item_id: String,
}

/// Result of getting history item
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct GetHistoryItemOutput {
    pub success: bool,
    pub history_item: Option<HistoryItemInfo>,
    pub error: Option<String>,
}

/// Delete a history item
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct DeleteHistoryItemInput {
    /// History item ID
    pub history_item_id: String,
}

/// Result of deleting history item
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct DeleteHistoryItemOutput {
    pub success: bool,
    pub error: Option<String>,
}

/// Submit feedback for a history item
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct SubmitFeedbackInput {
    /// History item ID
    pub history_item_id: String,
    /// Thumbs up or down
    pub thumbs_up: bool,
    /// Optional feedback text
    #[serde(default)]
    pub feedback: Option<String>,
}

/// Result of submitting feedback
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct SubmitFeedbackOutput {
    pub success: bool,
    pub error: Option<String>,
}

// ============================================================================
// RAG Tools
// ============================================================================

/// Rebuild RAG index for a document
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct RebuildIndexInput {
    /// Document ID
    pub document_id: String,
}

/// Result of rebuilding index
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct RebuildIndexOutput {
    pub success: bool,
    pub index_id: Option<String>,
    pub status: Option<String>,
    pub error: Option<String>,
}

/// Get RAG index status for a document
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct GetIndexStatusInput {
    /// Document ID
    pub document_id: String,
}

/// Index status info
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct IndexStatusInfo {
    pub id: Option<String>,
    pub status: Option<String>,
    pub active: Option<bool>,
    pub document_id: Option<String>,
    pub error: Option<String>,
}

/// Result of getting index status
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct GetIndexStatusOutput {
    pub success: bool,
    pub status: Option<IndexStatusInfo>,
    pub error: Option<String>,
}

// ============================================================================
// Audio Native Tools
// ============================================================================

/// List Audio Native projects
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct ListAudioNativeInput {
    /// Maximum number of projects to return
    #[serde(default = "default_limit_10")]
    pub limit: u32,
    /// Page number
    #[serde(default = "default_page_1")]
    pub page: u32,
}

fn default_limit_10() -> u32 {
    10
}

fn default_page_1() -> u32 {
    1
}

/// Audio Native project info
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct AudioNativeProjectInfo {
    pub project_id: String,
    pub name: String,
    pub author: Option<String>,
    pub title: Option<String>,
    pub voice_id: Option<String>,
    pub model_id: Option<String>,
    pub created_at: String,
}

/// Result of listing Audio Native projects
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct ListAudioNativeOutput {
    pub success: bool,
    pub projects: Vec<AudioNativeProjectInfo>,
    pub total_count: usize,
    pub error: Option<String>,
}

/// Get an Audio Native project
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct GetAudioNativeInput {
    /// Project ID
    pub project_id: String,
}

/// Result of getting Audio Native project
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct GetAudioNativeOutput {
    pub success: bool,
    pub project: Option<AudioNativeProjectInfo>,
    pub error: Option<String>,
}

// ============================================================================
// Conversation Tools
// ============================================================================

/// Get a conversation
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct GetConversationInput {
    /// Conversation ID
    pub conversation_id: String,
}

/// Transcript message
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct TranscriptMessage {
    pub role: String,
    pub content: String,
    pub timestamp: Option<String>,
}

/// Conversation detail
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct ConversationDetailInfo {
    pub conversation_id: String,
    pub agent_id: Option<String>,
    pub version_id: Option<String>,
    pub status: Option<String>,
    pub created_at: Option<String>,
    pub transcript: Option<Vec<TranscriptMessage>>,
}

/// Result of getting conversation
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct GetConversationOutput {
    pub success: bool,
    pub conversation: Option<ConversationDetailInfo>,
    pub error: Option<String>,
}

/// Delete a conversation
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct DeleteConversationInput {
    /// Conversation ID
    pub conversation_id: String,
}

/// Result of deleting conversation
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct DeleteConversationOutput {
    pub success: bool,
    pub error: Option<String>,
}

/// Get conversation audio
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct GetConversationAudioInput {
    /// Conversation ID
    pub conversation_id: String,
    /// Output file path
    #[serde(default)]
    pub output: Option<String>,
}

/// Result of getting conversation audio
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct GetConversationAudioOutput {
    pub success: bool,
    pub output_file: Option<String>,
    pub audio_base64: Option<String>,
    pub error: Option<String>,
}

// ============================================================================
// Workspace Tools
// ============================================================================

/// List workspace members
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct ListMembersInput;

/// Workspace member info
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct MemberInfo {
    pub user_id: String,
    pub email: String,
    pub role: String,
    pub joined_at: Option<String>,
}

/// Result of listing members
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct ListMembersOutput {
    pub success: bool,
    pub members: Vec<MemberInfo>,
    pub total_count: usize,
    pub error: Option<String>,
}

/// Invite a member to the workspace
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct InviteMemberInput {
    /// Email address
    pub email: String,
    /// Role (admin, editor, viewer, contributor)
    pub role: String,
}

/// Result of inviting member
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct InviteMemberOutput {
    pub success: bool,
    pub error: Option<String>,
}

/// Revoke an invitation
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct RevokeInviteInput {
    /// Email address
    pub email: String,
}

/// Result of revoking invite
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct RevokeInviteOutput {
    pub success: bool,
    pub error: Option<String>,
}

/// List workspace secrets
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct ListSecretsInput;

/// Secret info
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct SecretInfo {
    pub name: String,
    pub secret_type: String,
    pub created_at: Option<String>,
}

/// Result of listing secrets
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct ListSecretsOutput {
    pub success: bool,
    pub secrets: Vec<SecretInfo>,
    pub total_count: usize,
    pub error: Option<String>,
}

/// Add a workspace secret
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct AddSecretInput {
    /// Secret name
    pub name: String,
    /// Secret value
    pub value: String,
    /// Secret type (api_key, env_variable, secret)
    pub secret_type: String,
}

/// Result of adding secret
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct AddSecretOutput {
    pub success: bool,
    pub error: Option<String>,
}

/// Delete a workspace secret
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct DeleteSecretInput {
    /// Secret name
    pub name: String,
}

/// Result of deleting secret
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct DeleteSecretOutput {
    pub success: bool,
    pub error: Option<String>,
}

// ============================================================================
// Phone Tools
// ============================================================================

/// Get a phone number
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct GetPhoneNumberInput {
    /// Phone number ID
    pub phone_id: String,
}

/// Phone number info
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct PhoneNumberInfo {
    pub phone_number_id: String,
    pub phone_number: String,
    pub label: Option<String>,
    pub provider: Option<String>,
    pub agent_id: Option<String>,
    pub status: Option<String>,
    pub created_at: Option<String>,
}

/// Result of getting phone number
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct GetPhoneNumberOutput {
    pub success: bool,
    pub phone_number: Option<PhoneNumberInfo>,
    pub error: Option<String>,
}

/// Delete a phone number
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct DeletePhoneNumberInput {
    /// Phone number ID
    pub phone_id: String,
}

/// Result of deleting phone number
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct DeletePhoneNumberOutput {
    pub success: bool,
    pub error: Option<String>,
}