AbstractIntegratedModule 0.8.0__tar.gz → 0.8.1__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.
Files changed (23) hide show
  1. {abstractintegratedmodule-0.8.0 → abstractintegratedmodule-0.8.1}/AbstractIntegratedModule.egg-info/PKG-INFO +6 -7
  2. {abstractintegratedmodule-0.8.0 → abstractintegratedmodule-0.8.1}/AbstractIntegratedModule.py +341 -38
  3. {abstractintegratedmodule-0.8.0 → abstractintegratedmodule-0.8.1}/AbstractOptimizedModules.c +200 -200
  4. {abstractintegratedmodule-0.8.0 → abstractintegratedmodule-0.8.1}/PKG-INFO +6 -7
  5. {abstractintegratedmodule-0.8.0 → abstractintegratedmodule-0.8.1}/README.md +5 -6
  6. {abstractintegratedmodule-0.8.0 → abstractintegratedmodule-0.8.1}/setup.py +1 -1
  7. {abstractintegratedmodule-0.8.0 → abstractintegratedmodule-0.8.1}/AbstractIntegratedModule.egg-info/SOURCES.txt +0 -0
  8. {abstractintegratedmodule-0.8.0 → abstractintegratedmodule-0.8.1}/AbstractIntegratedModule.egg-info/dependency_links.txt +0 -0
  9. {abstractintegratedmodule-0.8.0 → abstractintegratedmodule-0.8.1}/AbstractIntegratedModule.egg-info/requires.txt +0 -0
  10. {abstractintegratedmodule-0.8.0 → abstractintegratedmodule-0.8.1}/AbstractIntegratedModule.egg-info/top_level.txt +0 -0
  11. {abstractintegratedmodule-0.8.0 → abstractintegratedmodule-0.8.1}/AbstractOptimizedModules.pyx +0 -0
  12. {abstractintegratedmodule-0.8.0 → abstractintegratedmodule-0.8.1}/MANIFEST.in +0 -0
  13. {abstractintegratedmodule-0.8.0 → abstractintegratedmodule-0.8.1}/abstract_model_storage/Cargo.toml +0 -0
  14. {abstractintegratedmodule-0.8.0 → abstractintegratedmodule-0.8.1}/abstract_model_storage/pyproject.toml +0 -0
  15. {abstractintegratedmodule-0.8.0 → abstractintegratedmodule-0.8.1}/abstract_model_storage/src/lib.rs +0 -0
  16. {abstractintegratedmodule-0.8.0 → abstractintegratedmodule-0.8.1}/abstract_model_storage/target/debug/build/libsqlite3-sys-ed07b882cd2aa5e2/out/bindgen.rs +0 -0
  17. {abstractintegratedmodule-0.8.0 → abstractintegratedmodule-0.8.1}/abstract_model_storage/target/debug/build/serde_core-ebc15f2e9cad7f5f/out/private.rs +0 -0
  18. {abstractintegratedmodule-0.8.0 → abstractintegratedmodule-0.8.1}/abstract_model_storage/target/debug/build/target-lexicon-08527f45de28143d/out/host.rs +0 -0
  19. {abstractintegratedmodule-0.8.0 → abstractintegratedmodule-0.8.1}/abstract_model_storage/target/release/build/libsqlite3-sys-bf0400df4523274c/out/bindgen.rs +0 -0
  20. {abstractintegratedmodule-0.8.0 → abstractintegratedmodule-0.8.1}/abstract_model_storage/target/release/build/serde_core-5cdb76131825e4af/out/private.rs +0 -0
  21. {abstractintegratedmodule-0.8.0 → abstractintegratedmodule-0.8.1}/abstract_model_storage/target/release/build/target-lexicon-43eb95a0588bf457/out/host.rs +0 -0
  22. {abstractintegratedmodule-0.8.0 → abstractintegratedmodule-0.8.1}/pyproject.toml +0 -0
  23. {abstractintegratedmodule-0.8.0 → abstractintegratedmodule-0.8.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: AbstractIntegratedModule
3
- Version: 0.8.0
3
+ Version: 0.8.1
4
4
  Summary: Library for Advanced Integrated Non-LLM AI Models - Optimized Backend Framework For Non-LLM AI Agent
5
5
  Author: Micro-Novelty
6
6
  Author-email: hernikpuspita5@gmail.com
@@ -42,7 +42,7 @@ https://github.com/Micro-Novelty/IntegratedPipeline-Specialized-Non-LLM-AI-Agent
42
42
  #### Note: The README here you are reading is a direct copy from my README Repository, to download the necessary files, you can visit my Repository with the provided link above.
43
43
 
44
44
  ### Library Short Description:
45
- - Development Stage: 0.8.0 Official Release.
45
+ - Development Stage: 0.8.1 Official Release.
46
46
  - Maintainer: Micro-Novelty.
47
47
  - library Source-Code is Open-sourced on github.
48
48
  - Purpose: Specifically Designed for providing Non-LLM AI Agent Framework for edge Devices, Optimized for ARM64 architecture.
@@ -80,12 +80,11 @@ https://github.com/Micro-Novelty/IntegratedPipeline-Specialized-Non-LLM-AI-Agent
80
80
  - Transformer Optimized using Cython, to reduce Memory overhead and Reduce CPU Usage, With Reduced Training Time.
81
81
  ______________
82
82
  - Changelog:
83
- - v0.8.0:
83
+ - v0.8.1:
84
84
  - [=] New features:
85
- - Fixed possible errors from inhomogenous shape during tokenizing arrays into a hash ID.
86
- - fixed fragility where number of classes is not distributed well to sequence encoding function causing the model to use wrong number of classes.
87
- - Added robustness for handling complex samples during prediction batching.
88
- - fixed missing label map initialization in sequence encoding inside advanced prediction method.
85
+ - Added robust conversion function to handles ragged list-to-list samples.
86
+ - added 2D array conversion function to handles inhomogenous shape during anisotropy measurement.
87
+ - fixed Fragile inhomogenous shape handling in AME Encoder function.
89
88
 
90
89
  ____________
91
90
  <img width="1280" height="600" alt="WhatsApp Image 2026-05-27 at 07 16 32" src="https://github.com/user-attachments/assets/4b58a556-45a3-419b-96fd-9c1b76cac574" />
@@ -8905,15 +8905,10 @@ class IntegratedPipeline:
8905
8905
  def anisotropy_measurement(self, x):
8906
8906
  eps = 1e-5
8907
8907
 
8908
- if isinstance(x, (str, np.str_)):
8909
- clean_str = str(x).replace('[', '').replace(']', '')
8910
- x = np.fromstring(clean_str, sep=' ')
8911
- if isinstance(x, np.ndarray) and np.issubdtype(x.dtype, np.character):
8912
- # catches arrays filled with string text
8913
- clean_str = ' '.join(x.astype(str).flatten()).replace('[', '').replace(']', '')
8914
- x = np.fromiter(
8915
- (v for v in clean_str.split() if x != "..."), dtype=float
8916
- )
8908
+ try:
8909
+ x = self._safe_convert(x)
8910
+ except:
8911
+ x = self._safe_to_2d_float(x)
8917
8912
 
8918
8913
  if _OPT_AVAILABLE:
8919
8914
  x = np.asarray(x)
@@ -10259,7 +10254,11 @@ class IntegratedPipeline:
10259
10254
  calibrated[i, mlp_target_int] * (1.5 * (1.0 - abstract_score)), 0.95
10260
10255
  )
10261
10256
 
10262
- row_sum = calibrated[i].sum()
10257
+ if i <= len(calibrated):
10258
+ row_sum = calibrated[i].sum()
10259
+ else:
10260
+ row_sum = calibrated[0].sum()
10261
+
10263
10262
  if row_sum > eps:
10264
10263
  calibrated[i] /= row_sum
10265
10264
  else:
@@ -10510,13 +10509,295 @@ class IntegratedPipeline:
10510
10509
 
10511
10510
  return X_adapted
10512
10511
 
10513
- def AME_Encoder(self, x):
10512
+
10513
+
10514
+ def _safe_to_2d(self, x) -> np.ndarray:
10515
+ """
10516
+ Convert ANY input shape to a well-formed 2D float64 array.
10517
+ Handles: ragged lists, 1D arrays, 4D attention tensors,
10518
+ string arrays, scalar inputs, None.
10519
+
10520
+ Strategy: PAD to max length.
10521
+ """
10522
+ if x is None:
10523
+ return None
10524
+
10525
+ # string input — parse to numeric first
10526
+ if isinstance(x, (str, np.str_)):
10527
+ clean = x.replace('[', '').replace(']', '').strip()
10528
+ try:
10529
+ X = np.fromstring(clean, sep=' ', dtype=np.float64)
10530
+ return X.reshape(1, -1) if X.size > 0 else None
10531
+ except ValueError:
10532
+ return None
10533
+
10534
+ # try direct conversion first — works for homogeneous inputs
10514
10535
  try:
10515
- X = np.asarray(x)
10516
- except:
10517
- raise Warning('[!] X samples has inhomogenous shape, normalizing to prevent corruption.')
10518
- flat_data = [item for sublist in x for item in sublist]
10519
- X = np.asarray(flat_data, dtype=np.int32)
10536
+ X = np.asarray(x, dtype=np.float64)
10537
+ except ValueError:
10538
+ # inhomogeneous shape pad to max length
10539
+ X = self._pad_ragged_to_array(x)
10540
+ if X is None:
10541
+ return None
10542
+
10543
+ # handle string dtype arrays
10544
+ if np.issubdtype(X.dtype, np.character):
10545
+ clean = ' '.join(X.astype(str).flatten()).replace('[', '').replace(']', '')
10546
+ try:
10547
+ vals = [float(v) for v in clean.split() if v != '...']
10548
+ X = np.array(vals, dtype=np.float64)
10549
+ except ValueError:
10550
+ return np.asarray(x, dtype=object)
10551
+
10552
+ # normalize to exactly 2D
10553
+ X = np.squeeze(X)
10554
+
10555
+ if X.ndim == 0:
10556
+ return np.array([[float(X)]])
10557
+
10558
+ if X.ndim == 1:
10559
+ return X.reshape(1, -1)
10560
+
10561
+ if X.ndim == 2:
10562
+ # even-dimension crop (your existing logic, preserved)
10563
+ rows, cols = X.shape
10564
+ new_rows = rows - 1 if (rows % 2 != 0 and rows > 1) else rows
10565
+ new_cols = cols - 1 if (cols % 2 != 0 and cols > 1) else cols
10566
+ return X[:new_rows, :new_cols].astype(np.float64)
10567
+
10568
+ if X.ndim > 2:
10569
+ # attention weights (B,H,T,T) or similar — flatten to (B, H*T*T)
10570
+ # preserves batch structure while giving AME a sensible 2D view
10571
+ return X.reshape(X.shape[0], -1).astype(np.float64)
10572
+
10573
+ return np.asarray(x, dtype=object)
10574
+
10575
+
10576
+ def _pad_ragged_to_array(self, x) -> np.ndarray:
10577
+ """
10578
+ Convert a ragged list-of-lists to a 2D array by padding shorter
10579
+ rows with zeros to match the longest row.
10580
+ Preserves per-row geometric structure for gradient computation.
10581
+ """
10582
+ try:
10583
+ rows = [np.asarray(item, dtype=np.float64).ravel()
10584
+ for item in x]
10585
+ except (TypeError, ValueError):
10586
+ return np.asarray(x, dtype=object)
10587
+
10588
+ if not rows:
10589
+ return None
10590
+
10591
+ max_len = max(len(r) for r in rows)
10592
+ if max_len == 0:
10593
+ return None
10594
+
10595
+ padded = np.zeros((len(rows), max_len), dtype=np.float64)
10596
+ for i, row in enumerate(rows):
10597
+ padded[i, :len(row)] = row
10598
+
10599
+ return padded
10600
+
10601
+
10602
+
10603
+
10604
+ def _coerce_to_2d_float(self, x) -> np.ndarray:
10605
+ """
10606
+ NumPy 1.24+ raises ValueError on ragged asarray() without dtype=object.
10607
+ This method handles that cross-platform consistently.
10608
+ """
10609
+ if x is None:
10610
+ return None
10611
+
10612
+ if isinstance(x, np.ndarray):
10613
+ return self._normalize_to_2d(x.astype(np.float64, copy=False))
10614
+
10615
+ # list/tuple — check for raggedness
10616
+ if isinstance(x, (list, tuple)) and len(x) > 0:
10617
+ first = x[0]
10618
+
10619
+ # check if items are sequences of potentially different lengths here
10620
+ if isinstance(first, (list, tuple, np.ndarray)):
10621
+ lengths = set()
10622
+ for item in x:
10623
+ if isinstance(item, np.ndarray):
10624
+ lengths.add(item.size)
10625
+ elif isinstance(item, (list, tuple)):
10626
+ lengths.add(len(item))
10627
+ else:
10628
+ lengths.add(1)
10629
+
10630
+ if len(lengths) > 1:
10631
+ # RAGGED — pad to uniform length
10632
+ max_len = max(lengths)
10633
+ print(f'[=] AME_Encoder: ragged input detected '
10634
+ f'(lengths: {lengths}) — padding to {max_len}')
10635
+ padded = np.zeros((len(x), max_len), dtype=np.float64)
10636
+ for i, item in enumerate(x):
10637
+ arr = np.asarray(item, dtype=np.float64).ravel()
10638
+ padded[i, :len(arr)] = arr
10639
+ return padded
10640
+
10641
+ # homogeneous — safe to call asarray directly
10642
+ try:
10643
+ X = np.asarray(x, dtype=np.float64)
10644
+ return self._normalize_to_2d(X)
10645
+ except ValueError:
10646
+ # last resort — try with dtype=object then convert
10647
+ try:
10648
+ X = np.asarray(x, dtype=object)
10649
+ flat = np.array([
10650
+ float(v) for v in X.ravel()
10651
+ if v is not None
10652
+ ], dtype=np.float64)
10653
+ return flat.reshape(1, -1)
10654
+ except Exception:
10655
+ print('[!] Cant Process and Convert X samples!')
10656
+ return np.asarray(x, dtype=object)
10657
+
10658
+ def _safe_to_2d_float(self, x) -> np.ndarray:
10659
+ """
10660
+ Attempt direct numpy conversion first (fast path for normal inputs).
10661
+ Only activates ragged/string handling when direct conversion fails.
10662
+ This avoids over-inspection that returns None for valid inputs.
10663
+ """
10664
+ try:
10665
+ if x is None:
10666
+ raise Warning('[!] X samples is None!')
10667
+ return np.asarray(x, dtype=object)
10668
+
10669
+ # FAST PATH — already a numeric numpy array, most common case
10670
+ if isinstance(x, np.ndarray):
10671
+ if np.issubdtype(x.dtype, np.floating) or \
10672
+ np.issubdtype(x.dtype, np.integer):
10673
+ return self._normalize_to_2d(x.astype(np.float64, copy=False))
10674
+ # non-numeric numpy array — string/object dtype
10675
+ return self._safe_to_2d(x)
10676
+
10677
+ # ATTEMPT direct conversion — works for all homogeneous inputs
10678
+ # including: flat lists, lists of same-length arrays, 2D lists, etc.
10679
+ try:
10680
+ X = np.asarray(x, dtype=np.float64)
10681
+ return self._normalize_to_2d(X)
10682
+
10683
+ except ValueError:
10684
+ # NumPy 1.24+ ragged array — activate padding path
10685
+ print(f'[=] _to_2d_float: ragged input detected — padding to uniform shape')
10686
+ return self._coerce_to_2d_float(x)
10687
+
10688
+ except TypeError:
10689
+ # string content or incompatible types — activate safe path
10690
+ print(f'[=] _to_2d_float: type conversion failed — trying safe path')
10691
+ return self._safe_to_2d(x)
10692
+
10693
+ except Exception as e:
10694
+ print(f'[!] _to_2d_float: unexpected error: {e} — using Robust method')
10695
+ try:
10696
+ result = self._convert_to_2d_float(x)
10697
+ except Exception as e:
10698
+ print('[!] cant Convert and calculate samples! - Using dtype object to compensate for the failure')
10699
+ return np.asarray(x, dtype=object)
10700
+
10701
+
10702
+ def _normalize_to_2d(self, X: np.ndarray) -> np.ndarray:
10703
+ """Squeeze and reshape any array to exactly 2D."""
10704
+ X = np.squeeze(X)
10705
+ if X.ndim == 0:
10706
+ return np.array([[float(X)]])
10707
+ if X.ndim == 1:
10708
+ return X.reshape(1, -1)
10709
+ if X.ndim == 2:
10710
+ rows, cols = X.shape
10711
+ new_rows = rows - 1 if (rows % 2 != 0 and rows > 1) else rows
10712
+ new_cols = cols - 1 if (cols % 2 != 0 and cols > 1) else cols
10713
+ return X[:new_rows, :new_cols]
10714
+ if X.ndim > 2:
10715
+ return X.reshape(X.shape[0], -1)
10716
+ return X
10717
+
10718
+ def _convert_to_2d_float(self, x) -> np.ndarray:
10719
+ """
10720
+ Adaptive gate — detects input characteristics and routes to
10721
+ the appropriate normalization path:
10722
+
10723
+ _coerce_to_2d_float → when input is ragged (variable-length sequences)
10724
+ or when NumPy 1.24+ would raise ValueError
10725
+ _safe_to_2d → when input has string/object dtype, nested
10726
+ structures, or needs deep type conversion
10727
+ direct numpy → when input is already a clean numeric array
10728
+ """
10729
+ if x is None:
10730
+ raise Warning('[!] X samples is None!')
10731
+ return None
10732
+
10733
+ # FAST PATH — already a clean numpy float array, skip both functions
10734
+ if isinstance(x, np.ndarray):
10735
+ if np.issubdtype(x.dtype, np.floating) or np.issubdtype(x.dtype, np.integer):
10736
+ return self._normalize_to_2d(x.astype(np.float64, copy=False))
10737
+ # non-numeric numpy array → needs _safe_to_2d for string/object handling
10738
+ return self._safe_to_2d(x)
10739
+
10740
+ # string input - always _safe_to_2d (handles parsing logic)
10741
+ if isinstance(x, (str, np.str_)):
10742
+ return self._safe_to_2d(x)
10743
+
10744
+ # list/tuple — detect ragged vs homogeneous vs string content
10745
+ if isinstance(x, (list, tuple)) and len(x) > 0:
10746
+ first = x[0]
10747
+
10748
+ # strings inside list → _safe_to_2d
10749
+ if isinstance(first, (str, np.str_)):
10750
+ return self._safe_to_2d(x)
10751
+
10752
+ # nested sequences — check for raggedness
10753
+ if isinstance(first, (list, tuple, np.ndarray)):
10754
+ lengths = set()
10755
+ has_strings = False
10756
+
10757
+ for item in x:
10758
+ if isinstance(item, (str, np.str_)):
10759
+ has_strings = True
10760
+ break
10761
+ elif isinstance(item, np.ndarray):
10762
+ lengths.add(item.size)
10763
+ if np.issubdtype(item.dtype, np.character):
10764
+ has_strings = True
10765
+ break
10766
+ elif isinstance(item, (list, tuple)):
10767
+ lengths.add(len(item))
10768
+
10769
+ # string content anywhere → _safe_to_2d
10770
+ if has_strings:
10771
+ return self._safe_to_2d(x)
10772
+
10773
+ # ragged numeric - _coerce_to_2d_float (pads to uniform length)
10774
+ if len(lengths) > 1:
10775
+ return self._coerce_to_2d_float(x)
10776
+
10777
+ # homogeneous numeric - direct numpy, fastest path
10778
+ try:
10779
+ X = np.asarray(x, dtype=np.float64)
10780
+ return self._normalize_to_2d(X)
10781
+ except ValueError:
10782
+ # for edge case — fall back to coerce
10783
+ return self._coerce_to_2d_float(x)
10784
+
10785
+ # flat list of scalars
10786
+ try:
10787
+ X = np.asarray(x, dtype=np.float64)
10788
+ return self._normalize_to_2d(X)
10789
+ except (ValueError, TypeError):
10790
+ return self._safe_to_2d(x)
10791
+
10792
+ # scalar input
10793
+ try:
10794
+ return np.array([[float(x)]])
10795
+ except (TypeError, ValueError):
10796
+ print('[!] Cant normalize and Convert X Samples! - Using dtype object to compensate failure!')
10797
+ return np.asarray(x, dtype=object)
10798
+
10799
+ def _safe_convert(self, x):
10800
+ X = np.asarray(x)
10520
10801
 
10521
10802
  if isinstance(X, (str, np.str_)):
10522
10803
  clean_str = str(X).replace('[', '').replace(']', '')
@@ -10527,8 +10808,6 @@ class IntegratedPipeline:
10527
10808
  X = np.fromiter(
10528
10809
  (x for x in clean_str.split() if x != "..."), dtype=float
10529
10810
  )
10530
- if _OPT_AVAILABLE and np.asarray(X).ndim == 2:
10531
- return optimized_ame_encoder(np.asarray(X, dtype=np.float64))
10532
10811
 
10533
10812
  X = np.squeeze(X)
10534
10813
  if X.ndim == 1:
@@ -10542,18 +10821,39 @@ class IntegratedPipeline:
10542
10821
 
10543
10822
  X = X[:new_rows, :new_cols]
10544
10823
 
10545
- if X.shape[1] == 1:
10546
- gradient = np.gradient(X, axis=0) # Calculate vertically instead of horizontally
10547
- else:
10548
- gradient = np.gradient(X, axis=-1) # Calculate horizontally
10549
- grad_energy = np.mean(np.linalg.norm(gradient, axis=-1))
10550
- X_mag = np.mean(np.linalg.norm(X, axis=-1))
10824
+ return X
10551
10825
 
10552
- AME = np.log1p(X_mag) * np.log1p(grad_energy)
10826
+ def AME_Encoder(self, x):
10827
+ eps = 1e-5
10828
+ try:
10829
+ try:
10830
+ X = self._safe_convert(x)
10831
+ except:
10832
+ X = self._safe_to_2d_float(x)
10833
+
10834
+ if _OPT_AVAILABLE and np.asarray(X).ndim == 2:
10835
+ AME = optimized_ame_encoder(np.asarray(X, dtype=np.float64))
10836
+ if isinstance(AME, (list, np.ndarray, tuple)):
10837
+ AME = np.mean(AME)
10838
+
10839
+ return AME
10553
10840
 
10554
- if AME == 0.0:
10555
- eps = 1e-5
10556
- AME = AME + eps
10841
+ if X.shape[1] == 1:
10842
+ gradient = np.gradient(X, axis=0) # Calculate vertically instead of horizontally
10843
+ else:
10844
+ gradient = np.gradient(X, axis=-1) # Calculate horizontally
10845
+
10846
+ grad_energy = np.mean(np.linalg.norm(gradient, axis=-1))
10847
+ X_mag = np.mean(np.linalg.norm(X, axis=-1))
10848
+
10849
+ AME = np.log1p(X_mag) * np.log1p(grad_energy)
10850
+
10851
+ if AME <= eps:
10852
+ AME = (1.0 - self.confidence_threshold) + eps
10853
+
10854
+ except Exception as e:
10855
+ print(f'[!] Cant calculate AME from samples due to: {e}, using normalized value...')
10856
+ AME = (1.0 - self.confidence_threshold) + eps
10557
10857
 
10558
10858
  return AME
10559
10859
 
@@ -13420,18 +13720,21 @@ class PipelinePredictionManager:
13420
13720
  except Exception as e:
13421
13721
  print(f'|| Failed to joblib dump file! : {e}, User Manual filepath suggestion needed...')
13422
13722
 
13423
- permission = input('|| Insert Filepath? [Y/N]: ')
13424
- if permission == 'Y':
13425
- suggested_path = input('|| Filepath suggestion: ')
13426
- if suggested_path:
13427
- self.pipeline.safe_pickle_save_with_feedback(self.pipeline, suggested_path)
13428
- print('💾 Model saved!')
13723
+ try:
13724
+ permission = input('|| Insert Filepath? [Y/N]: ')
13725
+ if permission == 'Y':
13726
+ suggested_path = input('|| Filepath suggestion: ')
13727
+ if suggested_path:
13728
+ self.pipeline.safe_pickle_save_with_feedback(self.pipeline, suggested_path)
13729
+ print('💾 Model saved!')
13730
+ else:
13731
+ print('|| Failed to dump Your model! ')
13732
+ pass
13429
13733
  else:
13430
13734
  print('|| Failed to dump Your model! ')
13431
- pass
13432
- else:
13433
- print('|| Failed to dump Your model! ')
13434
- pass
13735
+ pass
13736
+ except EOFError as e:
13737
+ print('[!] EOF Error from reading a line!')
13435
13738
 
13436
13739
  verbose = False
13437
13740
  if float(results[0]['confidence']) < self.pipeline.confidence_threshold: