monkeyplug-enhanced 2.3.1__tar.gz → 2.3.2__tar.gz
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.
- {monkeyplug_enhanced-2.3.1 → monkeyplug_enhanced-2.3.2}/PKG-INFO +2 -2
- {monkeyplug_enhanced-2.3.1 → monkeyplug_enhanced-2.3.2}/pyproject.toml +2 -2
- {monkeyplug_enhanced-2.3.1 → monkeyplug_enhanced-2.3.2}/src/monkeyplug/monkeyplug.py +200 -16
- {monkeyplug_enhanced-2.3.1 → monkeyplug_enhanced-2.3.2}/.gitignore +0 -0
- {monkeyplug_enhanced-2.3.1 → monkeyplug_enhanced-2.3.2}/LICENSE +0 -0
- {monkeyplug_enhanced-2.3.1 → monkeyplug_enhanced-2.3.2}/README.md +0 -0
- {monkeyplug_enhanced-2.3.1 → monkeyplug_enhanced-2.3.2}/src/monkeyplug/__init__.py +0 -0
- {monkeyplug_enhanced-2.3.1 → monkeyplug_enhanced-2.3.2}/src/monkeyplug/data/profanity_list.json +0 -0
- {monkeyplug_enhanced-2.3.1 → monkeyplug_enhanced-2.3.2}/src/monkeyplug/groq_config.py +0 -0
- {monkeyplug_enhanced-2.3.1 → monkeyplug_enhanced-2.3.2}/src/monkeyplug/separation.py +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: monkeyplug-enhanced
|
|
3
|
-
Version: 2.3.
|
|
3
|
+
Version: 2.3.2
|
|
4
4
|
Summary: Enhanced fork of monkeyplug — censors profanity in audio files using speech recognition with Groq API, AI instrumental generation, and batch processing.
|
|
5
5
|
Project-URL: Homepage, https://github.com/ljbred08/monkeyplug
|
|
6
6
|
Project-URL: Issues, https://github.com/ljbred08/monkeyplug/issues
|
|
7
7
|
Project-URL: Repository, https://github.com/ljbred08/monkeyplug.git
|
|
8
|
-
Author-email: Seth Grover <mero.mero.guero@gmail.com
|
|
8
|
+
Author-email: Lincoln Brown <link@brown.fm>, Seth Grover <mero.mero.guero@gmail.com>
|
|
9
9
|
License-File: LICENSE
|
|
10
10
|
Classifier: License :: OSI Approved :: BSD License
|
|
11
11
|
Classifier: Operating System :: OS Independent
|
|
@@ -4,10 +4,10 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "monkeyplug-enhanced"
|
|
7
|
-
version = "2.3.
|
|
7
|
+
version = "2.3.2"
|
|
8
8
|
authors = [
|
|
9
|
-
{ name="Seth Grover", email="mero.mero.guero@gmail.com" },
|
|
10
9
|
{ name="Lincoln Brown", email="link@brown.fm" },
|
|
10
|
+
{ name="Seth Grover", email="mero.mero.guero@gmail.com" },
|
|
11
11
|
]
|
|
12
12
|
description = "Enhanced fork of monkeyplug — censors profanity in audio files using speech recognition with Groq API, AI instrumental generation, and batch processing."
|
|
13
13
|
readme = "README.md"
|
|
@@ -458,7 +458,7 @@ def _unify_album_metadata(file_paths, groq_api_key, model, prompt, rename_prompt
|
|
|
458
458
|
raise Exception("Album unification failed after maximum retries")
|
|
459
459
|
|
|
460
460
|
|
|
461
|
-
def _call_groq_api_single_batch(metadata_list, system_prompt, groq_api_key, model, batch_num=1, total_batches=1, debug=False):
|
|
461
|
+
def _call_groq_api_single_batch(metadata_list, system_prompt, groq_api_key, model, batch_num=1, total_batches=1, debug=False, progress_bar=None, batch_start_position=0.0, batch_slice_size=1.0, timing_log=None, operation_name='unify_batch_groq'):
|
|
462
462
|
"""Make a single API call to Groq for album unification.
|
|
463
463
|
|
|
464
464
|
Args:
|
|
@@ -469,6 +469,11 @@ def _call_groq_api_single_batch(metadata_list, system_prompt, groq_api_key, mode
|
|
|
469
469
|
batch_num: Current batch number (for debug output)
|
|
470
470
|
total_batches: Total expected batches (for debug output)
|
|
471
471
|
debug: Enable debug output
|
|
472
|
+
progress_bar: Optional tqdm progress bar for progress tracking
|
|
473
|
+
batch_start_position: Starting position (0.0 to 1.0) for this batch in overall progress
|
|
474
|
+
batch_slice_size: Size of this batch's slice (0.0 to 1.0) of overall progress
|
|
475
|
+
timing_log: Timing log dict for estimation
|
|
476
|
+
operation_name: Name of operation for timing tracking ('unify_batch_groq' or 'unify_batch_spotify')
|
|
472
477
|
|
|
473
478
|
Returns:
|
|
474
479
|
dict: Parsed JSON response with 'unified_album' and 'tracks'
|
|
@@ -482,9 +487,16 @@ def _call_groq_api_single_batch(metadata_list, system_prompt, groq_api_key, mode
|
|
|
482
487
|
# Build input for AI
|
|
483
488
|
input_text = json.dumps(metadata_list, indent=2, ensure_ascii=False)
|
|
484
489
|
|
|
490
|
+
# Estimate tokens for this batch
|
|
491
|
+
batch_tokens = _estimate_batch_tokens(metadata_list, system_prompt)
|
|
492
|
+
|
|
493
|
+
# Estimate duration based on historical data
|
|
494
|
+
batch_estimated = estimate_step_duration_tokens(timing_log, operation_name, batch_tokens) or batch_tokens * 0.1
|
|
495
|
+
|
|
485
496
|
# API call with retry logic (more retries for transient 400 JSON validation errors)
|
|
486
497
|
max_retries = 5
|
|
487
498
|
retry_delay = 1
|
|
499
|
+
smooth_ticker = None
|
|
488
500
|
|
|
489
501
|
for attempt in range(max_retries):
|
|
490
502
|
try:
|
|
@@ -493,6 +505,22 @@ def _call_groq_api_single_batch(metadata_list, system_prompt, groq_api_key, mode
|
|
|
493
505
|
mmguero.eprint(f"Calling Groq API{batch_info} (attempt {attempt + 1}/{max_retries})...")
|
|
494
506
|
mmguero.eprint(f"Sending {len(metadata_list)} files to AI for unification")
|
|
495
507
|
|
|
508
|
+
# Start smooth progress ticker for this batch
|
|
509
|
+
if progress_bar:
|
|
510
|
+
# Reset to batch start position on retry
|
|
511
|
+
if attempt > 0:
|
|
512
|
+
progress_bar.n = batch_start_position * progress_bar.total
|
|
513
|
+
progress_bar.refresh()
|
|
514
|
+
|
|
515
|
+
if smooth_ticker is None:
|
|
516
|
+
smooth_ticker = _SmoothProgressTicker(progress_bar)
|
|
517
|
+
|
|
518
|
+
smooth_ticker.start(
|
|
519
|
+
cumulative=batch_start_position * progress_bar.total,
|
|
520
|
+
step_estimated_seconds=batch_estimated
|
|
521
|
+
)
|
|
522
|
+
|
|
523
|
+
api_start = time.time()
|
|
496
524
|
response = requests.post(
|
|
497
525
|
"https://api.groq.com/openai/v1/chat/completions",
|
|
498
526
|
headers={
|
|
@@ -516,6 +544,19 @@ def _call_groq_api_single_batch(metadata_list, system_prompt, groq_api_key, mode
|
|
|
516
544
|
},
|
|
517
545
|
timeout=120,
|
|
518
546
|
)
|
|
547
|
+
api_elapsed = time.time() - api_start
|
|
548
|
+
|
|
549
|
+
# Stop ticker and get actual time
|
|
550
|
+
if smooth_ticker:
|
|
551
|
+
actual_time = smooth_ticker.stop()
|
|
552
|
+
# Snap to actual batch end position
|
|
553
|
+
progress_bar.n = (batch_start_position + batch_slice_size) * progress_bar.total
|
|
554
|
+
progress_bar.refresh()
|
|
555
|
+
|
|
556
|
+
# Record timing
|
|
557
|
+
if timing_log is not None:
|
|
558
|
+
update_timing_measurement_tokens(timing_log, operation_name, actual_time, batch_tokens)
|
|
559
|
+
save_timing_log(timing_log)
|
|
519
560
|
|
|
520
561
|
# Handle rate limiting
|
|
521
562
|
if response.status_code == 429:
|
|
@@ -552,6 +593,8 @@ def _call_groq_api_single_batch(metadata_list, system_prompt, groq_api_key, mode
|
|
|
552
593
|
return parsed
|
|
553
594
|
|
|
554
595
|
except requests.exceptions.Timeout:
|
|
596
|
+
if smooth_ticker:
|
|
597
|
+
smooth_ticker.stop()
|
|
555
598
|
if attempt < max_retries - 1:
|
|
556
599
|
if debug:
|
|
557
600
|
mmguero.eprint(f"Request timed out, retrying in {retry_delay}s...")
|
|
@@ -561,6 +604,8 @@ def _call_groq_api_single_batch(metadata_list, system_prompt, groq_api_key, mode
|
|
|
561
604
|
raise Exception("Album unification request timed out")
|
|
562
605
|
|
|
563
606
|
except requests.exceptions.RequestException as e:
|
|
607
|
+
if smooth_ticker:
|
|
608
|
+
smooth_ticker.stop()
|
|
564
609
|
if attempt < max_retries - 1:
|
|
565
610
|
if debug:
|
|
566
611
|
mmguero.eprint(f"Request failed: {e}, retrying in {retry_delay}s...")
|
|
@@ -572,7 +617,7 @@ def _call_groq_api_single_batch(metadata_list, system_prompt, groq_api_key, mode
|
|
|
572
617
|
raise Exception("Album unification failed after maximum retries")
|
|
573
618
|
|
|
574
619
|
|
|
575
|
-
def _unify_album_metadata_with_batching(file_paths, groq_api_key, model, prompt, rename_prompt=None, spotify_tracks=None, batch_size=10, batch_size_spotify=5, debug=False):
|
|
620
|
+
def _unify_album_metadata_with_batching(file_paths, groq_api_key, model, prompt, rename_prompt=None, spotify_tracks=None, batch_size=10, batch_size_spotify=5, debug=False, verbose=False):
|
|
576
621
|
"""Use Groq AI to unify album metadata with automatic batching for large file lists.
|
|
577
622
|
|
|
578
623
|
Implements automatic batching to handle Groq's output token limits.
|
|
@@ -585,7 +630,10 @@ def _unify_album_metadata_with_batching(file_paths, groq_api_key, model, prompt,
|
|
|
585
630
|
prompt: System prompt for the AI
|
|
586
631
|
rename_prompt: Optional prompt for renaming (if provided, adds suggested_name to response)
|
|
587
632
|
spotify_tracks: Optional list of track names from Spotify for accurate ordering
|
|
633
|
+
batch_size: Default batch size (without Spotify)
|
|
634
|
+
batch_size_spotify: Batch size when using Spotify (smaller due to larger prompts)
|
|
588
635
|
debug: Enable debug output
|
|
636
|
+
verbose: Disable progress bar if True
|
|
589
637
|
|
|
590
638
|
Returns:
|
|
591
639
|
Dict with 'unified_album' (str) and 'tracks' (list of dicts with
|
|
@@ -608,21 +656,58 @@ def _unify_album_metadata_with_batching(file_paths, groq_api_key, model, prompt,
|
|
|
608
656
|
if rename_prompt:
|
|
609
657
|
system_prompt = f"{prompt}\n\n{rename_prompt}"
|
|
610
658
|
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
processed_files = set() # Tracks which files we've gotten results for
|
|
659
|
+
# Determine operation name for timing
|
|
660
|
+
operation_name = 'unify_batch_spotify' if spotify_tracks else 'unify_batch_groq'
|
|
614
661
|
|
|
615
662
|
# Proactive batching: limit batch size to avoid overwhelming Groq
|
|
616
663
|
# With Spotify tracks, use smaller batches since the prompt is larger
|
|
617
664
|
max_batch_size = batch_size_spotify if spotify_tracks else batch_size
|
|
618
665
|
|
|
666
|
+
# Calculate expected batch count
|
|
667
|
+
expected_batches = (len(metadata_list) + max_batch_size - 1) // max_batch_size
|
|
668
|
+
|
|
669
|
+
# Guard against empty metadata list
|
|
670
|
+
if expected_batches == 0:
|
|
671
|
+
return {'unified_album': '', 'tracks': []}
|
|
672
|
+
|
|
673
|
+
# Estimate total tokens for all batches
|
|
674
|
+
total_tokens = 0
|
|
675
|
+
for i in range(expected_batches):
|
|
676
|
+
batch_metadata = metadata_list[i * max_batch_size : (i + 1) * max_batch_size]
|
|
677
|
+
batch_system_prompt = system_prompt
|
|
678
|
+
if spotify_tracks:
|
|
679
|
+
tracks_json = json.dumps(spotify_tracks, ensure_ascii=False)
|
|
680
|
+
batch_system_prompt = f"{system_prompt}\n\nOfficial track listing from Spotify: {tracks_json}"
|
|
681
|
+
total_tokens += _estimate_batch_tokens(batch_metadata, batch_system_prompt)
|
|
682
|
+
|
|
683
|
+
# Load timing log and estimate total duration
|
|
684
|
+
timing_log = load_timing_log()
|
|
685
|
+
total_estimated = estimate_step_duration_tokens(timing_log, operation_name, total_tokens) or total_tokens * 0.1
|
|
686
|
+
|
|
687
|
+
# Create progress bar
|
|
688
|
+
progress = None
|
|
689
|
+
if not verbose:
|
|
690
|
+
progress = tqdm(
|
|
691
|
+
total=total_estimated,
|
|
692
|
+
desc=f"Unifying Album ({expected_batches} batches)",
|
|
693
|
+
unit="s",
|
|
694
|
+
disable=False,
|
|
695
|
+
bar_format='{l_bar}{bar}| {n:.0f}/{total:.0f}s [{elapsed}<{remaining}]',
|
|
696
|
+
)
|
|
697
|
+
|
|
698
|
+
unified_album = None # Will be set from first batch and reused
|
|
699
|
+
all_tracks = [] # Accumulates results across batches
|
|
700
|
+
processed_files = set() # Tracks which files we've gotten results for
|
|
701
|
+
|
|
619
702
|
# Start with first batch
|
|
620
703
|
batch_metadata = metadata_list[:max_batch_size]
|
|
621
704
|
remaining_metadata = metadata_list[max_batch_size:]
|
|
622
705
|
batch_num = 0
|
|
706
|
+
actual_batch_num = 0 # Track actual batch attempts (including retries)
|
|
623
707
|
|
|
624
708
|
while batch_metadata:
|
|
625
709
|
batch_num += 1
|
|
710
|
+
actual_batch_num += 1
|
|
626
711
|
|
|
627
712
|
# Build system prompt for this batch
|
|
628
713
|
# ALWAYS pass full Spotify list - don't slice it!
|
|
@@ -634,18 +719,35 @@ def _unify_album_metadata_with_batching(file_paths, groq_api_key, model, prompt,
|
|
|
634
719
|
if debug and batch_num == 1:
|
|
635
720
|
mmguero.eprint(f"Providing full Spotify track list ({len(spotify_tracks)} tracks) - AI will match by name")
|
|
636
721
|
|
|
722
|
+
# Calculate batch slice size and start position
|
|
723
|
+
batch_slice_size = 1.0 / expected_batches
|
|
724
|
+
# Clamp batch number for progress calculation to handle retries
|
|
725
|
+
progress_batch_num = min(actual_batch_num - 1, expected_batches - 1)
|
|
726
|
+
batch_start_position = progress_batch_num * batch_slice_size
|
|
727
|
+
|
|
728
|
+
# Update progress bar description
|
|
729
|
+
if progress:
|
|
730
|
+
display_batch_num = min(actual_batch_num, expected_batches)
|
|
731
|
+
progress.set_description(f"Processing Batch {display_batch_num}/{expected_batches}")
|
|
732
|
+
|
|
637
733
|
# Call API with current batch
|
|
638
734
|
try:
|
|
639
735
|
parsed = _call_groq_api_single_batch(
|
|
640
736
|
batch_metadata, batch_system_prompt, groq_api_key, model,
|
|
641
|
-
|
|
737
|
+
actual_batch_num, expected_batches, debug=debug,
|
|
738
|
+
progress_bar=progress, batch_start_position=batch_start_position,
|
|
739
|
+
batch_slice_size=batch_slice_size, timing_log=timing_log,
|
|
740
|
+
operation_name=operation_name
|
|
642
741
|
)
|
|
643
742
|
except Exception as e:
|
|
644
743
|
# If this isn't the first batch, we have partial results - fail gracefully
|
|
645
744
|
if all_tracks:
|
|
646
|
-
mmguero.eprint(f"Batch {
|
|
745
|
+
mmguero.eprint(f"Batch {actual_batch_num} failed after {len(all_tracks)} tracks were processed: {e}")
|
|
647
746
|
mmguero.eprint("Proceeding with partial results...")
|
|
648
747
|
break
|
|
748
|
+
# Close progress bar before raising
|
|
749
|
+
if progress:
|
|
750
|
+
progress.close()
|
|
649
751
|
raise
|
|
650
752
|
|
|
651
753
|
# On first successful call, capture unified_album name
|
|
@@ -661,7 +763,7 @@ def _unify_album_metadata_with_batching(file_paths, groq_api_key, model, prompt,
|
|
|
661
763
|
|
|
662
764
|
# Guard against empty response to avoid infinite loop
|
|
663
765
|
if not returned_tracks:
|
|
664
|
-
mmguero.eprint(f"WARNING: Batch {
|
|
766
|
+
mmguero.eprint(f"WARNING: Batch {actual_batch_num} returned no tracks. Stopping to avoid infinite loop.")
|
|
665
767
|
break
|
|
666
768
|
|
|
667
769
|
for track in returned_tracks:
|
|
@@ -671,7 +773,7 @@ def _unify_album_metadata_with_batching(file_paths, groq_api_key, model, prompt,
|
|
|
671
773
|
processed_files.add(filename)
|
|
672
774
|
|
|
673
775
|
if debug:
|
|
674
|
-
mmguero.eprint(f"Batch {
|
|
776
|
+
mmguero.eprint(f"Batch {actual_batch_num} complete: {len(returned_tracks)} tracks returned, {len(all_tracks)} total processed")
|
|
675
777
|
|
|
676
778
|
# Determine what's missing from this batch
|
|
677
779
|
returned_filenames = {t['filename'] for t in returned_tracks}
|
|
@@ -701,10 +803,14 @@ def _unify_album_metadata_with_batching(file_paths, groq_api_key, model, prompt,
|
|
|
701
803
|
new_files = len(next_batch) - len(missing_metadata)
|
|
702
804
|
mmguero.eprint(f"Partial response: {len(missing_metadata)} files from this batch need retry. Next batch: {len(missing_metadata)} retries + {new_files} new files = {len(next_batch)} total")
|
|
703
805
|
else:
|
|
704
|
-
mmguero.eprint(f"Starting batch {
|
|
806
|
+
mmguero.eprint(f"Starting batch {actual_batch_num + 1} with {len(next_batch)} files...")
|
|
705
807
|
|
|
706
808
|
batch_metadata = next_batch
|
|
707
809
|
|
|
810
|
+
# Close progress bar
|
|
811
|
+
if progress:
|
|
812
|
+
progress.close()
|
|
813
|
+
|
|
708
814
|
return {
|
|
709
815
|
'unified_album': unified_album or '',
|
|
710
816
|
'tracks': all_tracks
|
|
@@ -1061,7 +1167,7 @@ def _apply_cover_art_to_files(file_paths, image_data, debug=False):
|
|
|
1061
1167
|
|
|
1062
1168
|
###################################################################################################
|
|
1063
1169
|
# Run album unification process
|
|
1064
|
-
def _run_album_unification(input_path, output_path, config, rename_prompt=None, use_spotify=None, debug=False):
|
|
1170
|
+
def _run_album_unification(input_path, output_path, config, rename_prompt=None, use_spotify=None, debug=False, verbose=False):
|
|
1065
1171
|
"""Run the album unification process on a folder of files.
|
|
1066
1172
|
|
|
1067
1173
|
Args:
|
|
@@ -1071,6 +1177,7 @@ def _run_album_unification(input_path, output_path, config, rename_prompt=None,
|
|
|
1071
1177
|
rename_prompt: Optional prompt for smart renaming (None = no renaming)
|
|
1072
1178
|
use_spotify: Spotify URL if provided, True to search for album, None/False to disable
|
|
1073
1179
|
debug: Enable debug output
|
|
1180
|
+
verbose: Disable progress bar if True
|
|
1074
1181
|
|
|
1075
1182
|
Returns:
|
|
1076
1183
|
str: Status message
|
|
@@ -1137,7 +1244,7 @@ def _run_album_unification(input_path, output_path, config, rename_prompt=None,
|
|
|
1137
1244
|
# Call AI to unify album metadata (first pass - gets unified album name)
|
|
1138
1245
|
unified_result = _unify_album_metadata_with_batching(
|
|
1139
1246
|
file_paths, groq_api_key, model, prompt, rename_prompt=rename_prompt,
|
|
1140
|
-
batch_size=batch_size, batch_size_spotify=batch_size_spotify, debug=debug
|
|
1247
|
+
batch_size=batch_size, batch_size_spotify=batch_size_spotify, debug=debug, verbose=verbose
|
|
1141
1248
|
)
|
|
1142
1249
|
|
|
1143
1250
|
unified_album = unified_result.get('unified_album', '')
|
|
@@ -1171,7 +1278,7 @@ def _run_album_unification(input_path, output_path, config, rename_prompt=None,
|
|
|
1171
1278
|
rename_prompt=rename_prompt,
|
|
1172
1279
|
spotify_tracks=spotify_info.get('tracks', []),
|
|
1173
1280
|
batch_size=batch_size, batch_size_spotify=batch_size_spotify,
|
|
1174
|
-
debug=debug
|
|
1281
|
+
debug=debug, verbose=verbose
|
|
1175
1282
|
)
|
|
1176
1283
|
else:
|
|
1177
1284
|
mmguero.eprint("Could not fetch Spotify info, using AI results only")
|
|
@@ -3837,6 +3944,80 @@ def update_timing_measurement(timing_log, operation, wall_seconds, audio_seconds
|
|
|
3837
3944
|
entry['run_count'] += 1
|
|
3838
3945
|
|
|
3839
3946
|
|
|
3947
|
+
def estimate_step_duration_tokens(timing_log, operation, input_tokens):
|
|
3948
|
+
"""Estimate wall-clock seconds for an operation based on token-based historical data.
|
|
3949
|
+
|
|
3950
|
+
Args:
|
|
3951
|
+
timing_log: Timing log dict
|
|
3952
|
+
operation: Operation name (e.g., 'unify_batch_groq')
|
|
3953
|
+
input_tokens: Estimated input tokens
|
|
3954
|
+
|
|
3955
|
+
Returns:
|
|
3956
|
+
float or None: Estimated seconds, or None if no data available.
|
|
3957
|
+
"""
|
|
3958
|
+
entry = timing_log.get(operation)
|
|
3959
|
+
if not entry or entry.get('run_count', 0) == 0:
|
|
3960
|
+
return None
|
|
3961
|
+
total_tokens = entry.get('total_input_tokens', 0)
|
|
3962
|
+
if total_tokens <= 0:
|
|
3963
|
+
return None
|
|
3964
|
+
rate = entry['total_wall_seconds'] / total_tokens
|
|
3965
|
+
return rate * input_tokens
|
|
3966
|
+
|
|
3967
|
+
|
|
3968
|
+
def update_timing_measurement_tokens(timing_log, operation, wall_seconds, input_tokens):
|
|
3969
|
+
"""Add a new token-based timing measurement to the running averages.
|
|
3970
|
+
|
|
3971
|
+
Args:
|
|
3972
|
+
timing_log: Timing log dict
|
|
3973
|
+
operation: Operation name
|
|
3974
|
+
wall_seconds: Actual wall-clock seconds elapsed
|
|
3975
|
+
input_tokens: Actual input tokens processed
|
|
3976
|
+
"""
|
|
3977
|
+
if operation not in timing_log:
|
|
3978
|
+
timing_log[operation] = {
|
|
3979
|
+
'total_input_tokens': 0,
|
|
3980
|
+
'total_wall_seconds': 0.0,
|
|
3981
|
+
'run_count': 0,
|
|
3982
|
+
}
|
|
3983
|
+
entry = timing_log[operation]
|
|
3984
|
+
entry['total_input_tokens'] += input_tokens
|
|
3985
|
+
entry['total_wall_seconds'] += wall_seconds
|
|
3986
|
+
entry['run_count'] += 1
|
|
3987
|
+
|
|
3988
|
+
|
|
3989
|
+
def _estimate_input_tokens(text):
|
|
3990
|
+
"""Estimate input token count using character approximation.
|
|
3991
|
+
|
|
3992
|
+
Args:
|
|
3993
|
+
text: String to estimate tokens for
|
|
3994
|
+
|
|
3995
|
+
Returns:
|
|
3996
|
+
int: Estimated token count (approximately characters / 4)
|
|
3997
|
+
"""
|
|
3998
|
+
return len(text) // 4
|
|
3999
|
+
|
|
4000
|
+
|
|
4001
|
+
def _estimate_batch_tokens(metadata_list, system_prompt):
|
|
4002
|
+
"""Estimate total input tokens for a batch request.
|
|
4003
|
+
|
|
4004
|
+
Args:
|
|
4005
|
+
metadata_list: List of metadata dicts
|
|
4006
|
+
system_prompt: System prompt string
|
|
4007
|
+
|
|
4008
|
+
Returns:
|
|
4009
|
+
int: Estimated input tokens
|
|
4010
|
+
"""
|
|
4011
|
+
# Count tokens in metadata
|
|
4012
|
+
metadata_json = json.dumps(metadata_list, indent=2, ensure_ascii=False)
|
|
4013
|
+
metadata_tokens = _estimate_input_tokens(metadata_json)
|
|
4014
|
+
|
|
4015
|
+
# Count tokens in system prompt
|
|
4016
|
+
prompt_tokens = _estimate_input_tokens(system_prompt)
|
|
4017
|
+
|
|
4018
|
+
return metadata_tokens + prompt_tokens
|
|
4019
|
+
|
|
4020
|
+
|
|
3840
4021
|
###################################################################################################
|
|
3841
4022
|
# RunMonkeyPlug
|
|
3842
4023
|
def RunMonkeyPlug():
|
|
@@ -4384,7 +4565,8 @@ def RunMonkeyPlug():
|
|
|
4384
4565
|
config,
|
|
4385
4566
|
rename_prompt=args.autoRename,
|
|
4386
4567
|
use_spotify=args.useSpotify,
|
|
4387
|
-
debug=args.debug
|
|
4568
|
+
debug=args.debug,
|
|
4569
|
+
verbose=args.debug
|
|
4388
4570
|
)
|
|
4389
4571
|
print(result)
|
|
4390
4572
|
except Exception as e:
|
|
@@ -4681,7 +4863,8 @@ def RunMonkeyPlug():
|
|
|
4681
4863
|
config,
|
|
4682
4864
|
rename_prompt=args.autoRename,
|
|
4683
4865
|
use_spotify=args.useSpotify,
|
|
4684
|
-
debug=args.debug
|
|
4866
|
+
debug=args.debug,
|
|
4867
|
+
verbose=args.debug
|
|
4685
4868
|
)
|
|
4686
4869
|
mmguero.eprint(result)
|
|
4687
4870
|
except Exception as e:
|
|
@@ -4991,7 +5174,8 @@ def RunMonkeyPlug():
|
|
|
4991
5174
|
config,
|
|
4992
5175
|
rename_prompt=args.autoRename,
|
|
4993
5176
|
use_spotify=args.useSpotify,
|
|
4994
|
-
debug=args.debug
|
|
5177
|
+
debug=args.debug,
|
|
5178
|
+
verbose=args.debug
|
|
4995
5179
|
)
|
|
4996
5180
|
mmguero.eprint(result)
|
|
4997
5181
|
except Exception as e:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{monkeyplug_enhanced-2.3.1 → monkeyplug_enhanced-2.3.2}/src/monkeyplug/data/profanity_list.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|