abstractcore 2.5.0__py3-none-any.whl → 2.5.2__py3-none-any.whl

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.
@@ -1277,17 +1277,23 @@ def _parse_content_by_type(content_bytes: bytes, content_type: str, url: str, ex
1277
1277
  # Final fallback with error replacement
1278
1278
  text_content = content_bytes.decode('utf-8', errors='replace')
1279
1279
 
1280
- # Parse based on content type
1280
+ # Parse based on content type with fallback content detection
1281
1281
  if main_type.startswith('text/html') or main_type.startswith('application/xhtml'):
1282
1282
  return _parse_html_content(text_content, url, extract_links)
1283
1283
 
1284
1284
  elif main_type == 'application/json':
1285
1285
  return _parse_json_content(text_content)
1286
1286
 
1287
- elif main_type in ['application/xml', 'text/xml', 'application/rss+xml', 'application/atom+xml']:
1287
+ elif main_type in ['application/xml', 'text/xml', 'application/rss+xml', 'application/atom+xml', 'application/soap+xml']:
1288
1288
  return _parse_xml_content(text_content)
1289
1289
 
1290
1290
  elif main_type.startswith('text/'):
1291
+ # For generic text types, check if it's actually XML or JSON
1292
+ if text_content and text_content.strip():
1293
+ if _is_xml_content(text_content):
1294
+ return _parse_xml_content(text_content)
1295
+ elif _is_json_content(text_content):
1296
+ return _parse_json_content(text_content)
1291
1297
  return _parse_text_content(text_content, main_type)
1292
1298
 
1293
1299
  elif main_type.startswith('image/'):
@@ -1305,18 +1311,107 @@ def _parse_content_by_type(content_bytes: bytes, content_type: str, url: str, ex
1305
1311
  f"Content size: {len(content_bytes):,} bytes"
1306
1312
 
1307
1313
 
1314
+ def _is_xml_content(content: str) -> bool:
1315
+ """Detect if content is XML rather than HTML."""
1316
+ if not content:
1317
+ return False
1318
+
1319
+ content_lower = content.lower().strip()
1320
+
1321
+ # Check for XML declaration
1322
+ if content_lower.startswith('<?xml'):
1323
+ return True
1324
+
1325
+ # Check for common XML root elements without HTML indicators
1326
+ xml_indicators = ['<rss', '<feed', '<urlset', '<sitemap', '<soap:', '<xml']
1327
+ html_indicators = ['<!doctype html', '<html', '<head>', '<body>', '<div', '<span', '<p>', '<a ']
1328
+
1329
+ # Look at the first 1000 characters for indicators
1330
+ sample = content_lower[:1000]
1331
+
1332
+ # If we find HTML indicators, it's likely HTML
1333
+ if any(indicator in sample for indicator in html_indicators):
1334
+ return False
1335
+
1336
+ # If we find XML indicators without HTML indicators, it's likely XML
1337
+ if any(indicator in sample for indicator in xml_indicators):
1338
+ return True
1339
+
1340
+ # Check if it starts with a root element that looks like XML
1341
+ import re
1342
+ root_match = re.search(r'<([^?\s/>]+)', content)
1343
+ if root_match:
1344
+ root_element = root_match.group(1).lower()
1345
+ # Common XML root elements that are not HTML
1346
+ xml_roots = ['rss', 'feed', 'urlset', 'sitemap', 'configuration', 'data', 'response']
1347
+ if root_element in xml_roots:
1348
+ return True
1349
+
1350
+ return False
1351
+
1352
+
1353
+ def _is_json_content(content: str) -> bool:
1354
+ """Detect if content is JSON."""
1355
+ if not content:
1356
+ return False
1357
+
1358
+ content_stripped = content.strip()
1359
+
1360
+ # Quick check for JSON structure
1361
+ if (content_stripped.startswith('{') and content_stripped.endswith('}')) or \
1362
+ (content_stripped.startswith('[') and content_stripped.endswith(']')):
1363
+ try:
1364
+ import json
1365
+ json.loads(content_stripped)
1366
+ return True
1367
+ except (json.JSONDecodeError, ValueError):
1368
+ pass
1369
+
1370
+ return False
1371
+
1372
+
1373
+ def _get_appropriate_parser(content: str) -> str:
1374
+ """Get the appropriate BeautifulSoup parser for the content."""
1375
+ if not BS4_AVAILABLE:
1376
+ return None
1377
+
1378
+ # If lxml is available and content looks like XML, use xml parser
1379
+ if 'lxml' in BS4_PARSER and _is_xml_content(content):
1380
+ try:
1381
+ import lxml
1382
+ return 'xml'
1383
+ except ImportError:
1384
+ pass
1385
+
1386
+ # Default to the configured parser (lxml or html.parser)
1387
+ return BS4_PARSER
1388
+
1389
+
1308
1390
  def _parse_html_content(html_content: str, url: str, extract_links: bool = True) -> str:
1309
1391
  """Parse HTML content and extract meaningful information."""
1310
1392
  if not html_content:
1311
1393
  return "❌ No HTML content to parse"
1312
1394
 
1395
+ # Detect if content is actually XML (fallback detection)
1396
+ if _is_xml_content(html_content):
1397
+ return _parse_xml_content(html_content)
1398
+
1313
1399
  result_parts = []
1314
1400
  result_parts.append("🌐 HTML Document Analysis")
1315
1401
 
1316
1402
  # Use BeautifulSoup if available for better parsing
1317
1403
  if BS4_AVAILABLE:
1318
1404
  try:
1319
- soup = BeautifulSoup(html_content, BS4_PARSER)
1405
+ # Choose appropriate parser based on content analysis
1406
+ parser = _get_appropriate_parser(html_content)
1407
+
1408
+ # Suppress XML parsing warnings when using HTML parser on XML content
1409
+ import warnings
1410
+ from bs4 import XMLParsedAsHTMLWarning
1411
+
1412
+ with warnings.catch_warnings():
1413
+ warnings.filterwarnings("ignore", category=XMLParsedAsHTMLWarning)
1414
+ soup = BeautifulSoup(html_content, parser)
1320
1415
 
1321
1416
  # Extract title
1322
1417
  title = soup.find('title')
abstractcore/utils/cli.py CHANGED
@@ -39,7 +39,7 @@ except ImportError:
39
39
 
40
40
  from .. import create_llm, BasicSession
41
41
  from ..tools.common_tools import list_files, read_file, write_file, execute_command, search_files
42
- from ..processing import BasicExtractor, BasicJudge
42
+ from ..processing import BasicExtractor, BasicJudge, BasicIntentAnalyzer
43
43
 
44
44
 
45
45
  class SimpleCLI:
@@ -193,6 +193,10 @@ class SimpleCLI:
193
193
  print(" • /facts - Display in chat")
194
194
  print(" • /facts data - Save as data.jsonld")
195
195
  print(" /judge Evaluate conversation quality")
196
+ print(" /intent [participant] Analyze intents behind conversation")
197
+ print(" • /intent - Analyze all participants")
198
+ print(" • /intent user - Focus on user intents")
199
+ print(" • /intent assistant - Focus on assistant intents")
196
200
 
197
201
  print("\n⚙️ CONFIGURATION")
198
202
  print("─" * 50)
@@ -317,6 +321,17 @@ class SimpleCLI:
317
321
  elif cmd == 'judge':
318
322
  self.handle_judge()
319
323
 
324
+ elif cmd.startswith('intent'):
325
+ # Parse /intent [participant] command
326
+ parts = cmd.split()
327
+ if len(parts) == 1:
328
+ # No participant specified - analyze all
329
+ self.handle_intent(None)
330
+ else:
331
+ # Participant specified
332
+ participant = parts[1]
333
+ self.handle_intent(participant)
334
+
320
335
  elif cmd.startswith('system'):
321
336
  # Parse /system [prompt] command
322
337
  if cmd == 'system':
@@ -623,6 +638,103 @@ class SimpleCLI:
623
638
  import traceback
624
639
  traceback.print_exc()
625
640
 
641
+ def handle_intent(self, focus_participant: str = None):
642
+ """Handle /intent [participant] command - analyze intents behind conversation"""
643
+ messages = self.session.get_messages()
644
+
645
+ if len(messages) <= 1: # Only system message
646
+ print("📝 No conversation history to analyze intents from")
647
+ return
648
+
649
+ try:
650
+ if focus_participant:
651
+ print(f"🎯 Analyzing {focus_participant} intents in conversation...")
652
+ else:
653
+ print("🎯 Analyzing conversation intents for all participants...")
654
+
655
+ # Create intent analyzer using current provider for consistency
656
+ analyzer = BasicIntentAnalyzer(self.provider)
657
+
658
+ # Convert session messages to the format expected by intent analyzer
659
+ conversation_messages = [msg for msg in messages if msg.role != 'system']
660
+ message_dicts = [{"role": msg.role, "content": msg.content} for msg in conversation_messages]
661
+
662
+ if not message_dicts:
663
+ print("📝 No substantive conversation content found")
664
+ return
665
+
666
+ print(f" Processing {len(message_dicts)} messages...")
667
+
668
+ start_time = time.time()
669
+
670
+ # Analyze conversation intents
671
+ from ..processing.basic_intent import IntentDepth
672
+ results = analyzer.analyze_conversation_intents(
673
+ messages=message_dicts,
674
+ focus_participant=focus_participant,
675
+ depth=IntentDepth.UNDERLYING
676
+ )
677
+
678
+ duration = time.time() - start_time
679
+ print(f"✅ Intent analysis completed in {duration:.1f}s")
680
+
681
+ if not results:
682
+ print("❌ No intents could be analyzed from the conversation")
683
+ return
684
+
685
+ # Display results in a conversational format
686
+ print("\n🎯 CONVERSATION INTENT ANALYSIS")
687
+ print("=" * 60)
688
+
689
+ for participant, analysis in results.items():
690
+ print(f"\n👤 {participant.upper()} INTENTS:")
691
+ print("─" * 40)
692
+
693
+ # Primary Intent
694
+ primary = analysis.primary_intent
695
+ print(f"🎯 Primary Intent: {primary.intent_type.value.replace('_', ' ').title()}")
696
+ print(f" Description: {primary.description}")
697
+ print(f" Underlying Goal: {primary.underlying_goal}")
698
+ print(f" Emotional Undertone: {primary.emotional_undertone}")
699
+ print(f" Confidence: {primary.confidence:.2f} | Urgency: {primary.urgency_level:.2f}")
700
+
701
+ # Secondary Intents (show top 2 for brevity)
702
+ if analysis.secondary_intents:
703
+ print(f"\n🔄 Secondary Intents:")
704
+ for i, intent in enumerate(analysis.secondary_intents[:2], 1):
705
+ print(f" {i}. {intent.intent_type.value.replace('_', ' ').title()}")
706
+ print(f" Goal: {intent.underlying_goal}")
707
+ print(f" Confidence: {intent.confidence:.2f}")
708
+
709
+ # Key contextual factors (show top 3)
710
+ if analysis.contextual_factors:
711
+ print(f"\n🌍 Key Context Factors:")
712
+ for factor in analysis.contextual_factors[:3]:
713
+ print(f" • {factor}")
714
+
715
+ # Response approach
716
+ print(f"\n💡 Suggested Response Approach:")
717
+ # Truncate long response approaches for readability
718
+ response_approach = analysis.suggested_response_approach
719
+ if len(response_approach) > 200:
720
+ response_approach = response_approach[:197] + "..."
721
+ print(f" {response_approach}")
722
+
723
+ # Analysis metadata
724
+ print(f"\n📊 Analysis: {analysis.word_count_analyzed} words | "
725
+ f"Complexity: {analysis.intent_complexity:.2f} | "
726
+ f"Confidence: {analysis.overall_confidence:.2f} | "
727
+ f"Time: {duration:.1f}s")
728
+
729
+ print("\n" + "=" * 60)
730
+ print("💡 Note: This analysis identifies underlying motivations and goals behind communication")
731
+
732
+ except Exception as e:
733
+ print(f"❌ Intent analysis failed: {e}")
734
+ if self.debug_mode:
735
+ import traceback
736
+ traceback.print_exc()
737
+
626
738
  def _format_conversation_for_extraction(self, messages):
627
739
  """Format conversation messages for fact extraction"""
628
740
  formatted_lines = []
@@ -1337,6 +1449,7 @@ Key Commands:
1337
1449
  /compact [focus] Compress chat history with optional focus
1338
1450
  /facts [file] Extract knowledge facts
1339
1451
  /judge Evaluate conversation quality
1452
+ /intent [participant] Analyze conversation intents and motivations
1340
1453
  /system [prompt] View/change system prompt
1341
1454
 
1342
1455
  Tools: list_files, search_files, read_file, write_file, execute_command
@@ -11,4 +11,4 @@ including when the package is installed from PyPI where pyproject.toml is not av
11
11
 
12
12
  # Package version - update this when releasing new versions
13
13
  # This must be manually synchronized with the version in pyproject.toml
14
- __version__ = "2.5.0"
14
+ __version__ = "2.5.2"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: abstractcore
3
- Version: 2.5.0
3
+ Version: 2.5.2
4
4
  Summary: Unified interface to all LLM providers with essential infrastructure for tool calling, streaming, and model management
5
5
  Author-email: Laurent-Philippe Albou <contact@abstractcore.ai>
6
6
  Maintainer-email: Laurent-Philippe Albou <contact@abstractcore.ai>
@@ -40,9 +40,11 @@ Provides-Extra: huggingface
40
40
  Requires-Dist: transformers<5.0.0,>=4.30.0; extra == "huggingface"
41
41
  Requires-Dist: torch<3.0.0,>=1.12.0; extra == "huggingface"
42
42
  Requires-Dist: llama-cpp-python<1.0.0,>=0.2.0; extra == "huggingface"
43
+ Requires-Dist: outlines>=0.1.0; extra == "huggingface"
43
44
  Provides-Extra: mlx
44
45
  Requires-Dist: mlx<1.0.0,>=0.15.0; extra == "mlx"
45
46
  Requires-Dist: mlx-lm<1.0.0,>=0.15.0; extra == "mlx"
47
+ Requires-Dist: outlines>=0.1.0; extra == "mlx"
46
48
  Provides-Extra: embeddings
47
49
  Requires-Dist: sentence-transformers<4.0.0,>=2.7.0; extra == "embeddings"
48
50
  Requires-Dist: numpy<2.0.0,>=1.20.0; extra == "embeddings"
@@ -258,7 +260,7 @@ loaded_session = BasicSession.load('conversation.json', provider=llm)
258
260
 
259
261
  ### Media Handling
260
262
 
261
- AbstractCore provides **unified media handling** across all providers with **automatic maximum resolution optimization** for best results. Upload images, PDFs, and documents using the same simple API regardless of your provider.
263
+ AbstractCore provides unified media handling across all providers with automatic resolution optimization. Upload images, PDFs, and documents using the same simple API regardless of your provider.
262
264
 
263
265
  ```python
264
266
  from abstractcore import create_llm
@@ -296,7 +298,7 @@ response = llm.generate(
296
298
  - **Smart Resolution**: Automatically uses maximum resolution supported by each model
297
299
  - **Format Support**: PNG, JPEG, GIF, WEBP, BMP, TIFF images; PDF, TXT, MD, CSV, TSV, JSON documents
298
300
  - **Office Documents**: DOCX, XLSX, PPT (with `pip install abstractcore[all]`)
299
- - **Vision Optimization**: Model-specific image processing for best vision results
301
+ - **Vision Optimization**: Model-specific image processing for vision results
300
302
 
301
303
  **Provider compatibility:**
302
304
  - **High-resolution vision**: GPT-4o (up to 4096x4096), Claude 3.5 Sonnet (up to 1568x1568)
@@ -310,11 +312,11 @@ response = llm.generate(
310
312
  - **Provider Agnostic**: Seamlessly switch between OpenAI, Anthropic, Ollama, LMStudio, MLX, HuggingFace
311
313
  - **Centralized Configuration**: Global defaults and app-specific preferences at `~/.abstractcore/config/abstractcore.json`
312
314
  - **Intelligent Media Handling**: Upload images, PDFs, and documents with automatic maximum resolution optimization
313
- - **Vision Model Support**: Smart image processing at each model's maximum capability for best results
314
- - **Document Processing**: Advanced PDF extraction (PyMuPDF4LLM), Office documents (DOCX/XLSX/PPT), CSV/TSV analysis
315
+ - **Vision Model Support**: Smart image processing at each model's maximum capability
316
+ - **Document Processing**: PDF extraction (PyMuPDF4LLM), Office documents (DOCX/XLSX/PPT), CSV/TSV analysis
315
317
  - **Unified Tools**: Consistent tool calling across all providers
316
318
  - **Session Management**: Persistent conversations with metadata, analytics, and complete serialization
317
- - **Structured Responses**: Clean, predictable output formats with Pydantic
319
+ - **Native Structured Output**: Server-side schema enforcement for Ollama and LMStudio (OpenAI and Anthropic also supported)
318
320
  - **Streaming Support**: Real-time token generation for interactive experiences
319
321
  - **Consistent Token Terminology**: Unified `input_tokens`, `output_tokens`, `total_tokens` across all providers
320
322
  - **Embeddings**: Built-in support for semantic search and RAG applications
@@ -324,12 +326,12 @@ response = llm.generate(
324
326
 
325
327
  | Provider | Status | SEED Support | Setup |
326
328
  |----------|--------|-------------|-------|
327
- | **OpenAI** | Full | Native | [Get API key](docs/prerequisites.md#openai-setup) |
328
- | **Anthropic** | Full | ⚠️ Warning* | [Get API key](docs/prerequisites.md#anthropic-setup) |
329
- | **Ollama** | Full | Native | [Install guide](docs/prerequisites.md#ollama-setup) |
330
- | **LMStudio** | Full | Native | [Install guide](docs/prerequisites.md#lmstudio-setup) |
331
- | **MLX** | Full | Native | [Setup guide](docs/prerequisites.md#mlx-setup) |
332
- | **HuggingFace** | Full | Native | [Setup guide](docs/prerequisites.md#huggingface-setup) |
329
+ | **OpenAI** | Full | Native | [Get API key](docs/prerequisites.md#openai-setup) |
330
+ | **Anthropic** | Full | Warning* | [Get API key](docs/prerequisites.md#anthropic-setup) |
331
+ | **Ollama** | Full | Native | [Install guide](docs/prerequisites.md#ollama-setup) |
332
+ | **LMStudio** | Full | Native | [Install guide](docs/prerequisites.md#lmstudio-setup) |
333
+ | **MLX** | Full | Native | [Setup guide](docs/prerequisites.md#mlx-setup) |
334
+ | **HuggingFace** | Full | Native | [Setup guide](docs/prerequisites.md#huggingface-setup) |
333
335
 
334
336
  *Anthropic doesn't support seed parameters but issues a warning when provided. Use `temperature=0.0` for more consistent outputs.
335
337
 
@@ -374,7 +376,7 @@ response = client.chat.completions.create(
374
376
  - Building web applications that need HTTP API
375
377
  - Multi-language access (not just Python)
376
378
 
377
- ## Internal CLI (Optional Interactive Testing Tool)
379
+ ## AbstractCore CLI (Optional Interactive Testing Tool)
378
380
 
379
381
  AbstractCore includes a **built-in CLI** for interactive testing, development, and conversation management. This is an internal testing tool, distinct from external agentic CLIs.
380
382
 
@@ -394,6 +396,7 @@ python -m abstractcore.utils.cli --provider anthropic --model claude-3-5-haiku-l
394
396
  - Chat history compaction and management
395
397
  - Fact extraction from conversations
396
398
  - Conversation quality evaluation (LLM-as-a-judge)
399
+ - Intent analysis and deception detection
397
400
  - Tool call testing and debugging
398
401
  - System prompt management
399
402
  - Multiple provider support
@@ -402,12 +405,13 @@ python -m abstractcore.utils.cli --provider anthropic --model claude-3-5-haiku-l
402
405
  - `/compact` - Compress chat history while preserving context
403
406
  - `/facts [file]` - Extract structured facts from conversation
404
407
  - `/judge` - Evaluate conversation quality with feedback
408
+ - `/intent [participant]` - Analyze psychological intents and detect deception
405
409
  - `/history [n]` - View conversation history
406
410
  - `/stream` - Toggle real-time streaming
407
411
  - `/system [prompt]` - Show or change system prompt
408
412
  - `/status` - Show current provider, model, and capabilities
409
413
 
410
- **Full Documentation:** [Internal CLI Guide](docs/internal-cli.md)
414
+ **Full Documentation:** [AbstractCore CLI Guide](docs/acore-cli.md)
411
415
 
412
416
  **When to use the CLI:**
413
417
  - Interactive development and testing
@@ -418,7 +422,7 @@ python -m abstractcore.utils.cli --provider anthropic --model claude-3-5-haiku-l
418
422
 
419
423
  ## Built-in Applications (Ready-to-Use CLI Tools)
420
424
 
421
- AbstractCore includes **three specialized command-line applications** for common LLM tasks. These are production-ready tools that can be used directly from the terminal without any Python programming.
425
+ AbstractCore includes **four specialized command-line applications** for common LLM tasks. These are production-ready tools that can be used directly from the terminal without any Python programming.
422
426
 
423
427
  ### Available Applications
424
428
 
@@ -427,6 +431,7 @@ AbstractCore includes **three specialized command-line applications** for common
427
431
  | **Summarizer** | Document summarization | `summarizer` |
428
432
  | **Extractor** | Entity and relationship extraction | `extractor` |
429
433
  | **Judge** | Text evaluation and scoring | `judge` |
434
+ | **Intent Analyzer** | Psychological intent analysis & deception detection | `intent` |
430
435
 
431
436
  ### Quick Usage Examples
432
437
 
@@ -445,6 +450,11 @@ extractor doc.txt --iterate 3 --mode thorough --verbose
445
450
  judge essay.txt --criteria clarity,accuracy,coherence --context "academic writing"
446
451
  judge code.py --context "code review" --format plain --verbose
447
452
  judge proposal.md --custom-criteria has_examples,covers_risks --output assessment.json
453
+
454
+ # Intent analysis with psychological insights and deception detection
455
+ intent conversation.txt --focus-participant user --depth comprehensive
456
+ intent email.txt --format plain --context document --verbose
457
+ intent chat_log.json --conversation-mode --provider lmstudio --model qwen/qwen3-30b-a3b-2507
448
458
  ```
449
459
 
450
460
  ### Installation & Setup
@@ -459,6 +469,7 @@ pip install abstractcore[all]
459
469
  summarizer --help
460
470
  extractor --help
461
471
  judge --help
472
+ intent --help
462
473
  ```
463
474
 
464
475
  ### Alternative Usage Methods
@@ -468,11 +479,13 @@ judge --help
468
479
  summarizer document.txt
469
480
  extractor report.pdf
470
481
  judge essay.md
482
+ intent conversation.txt
471
483
 
472
484
  # Method 2: Via Python module
473
485
  python -m abstractcore.apps summarizer document.txt
474
486
  python -m abstractcore.apps extractor report.pdf
475
487
  python -m abstractcore.apps judge essay.md
488
+ python -m abstractcore.apps intent conversation.txt
476
489
  ```
477
490
 
478
491
  ### Key Parameters
@@ -514,10 +527,11 @@ python -m abstractcore.apps judge essay.md
514
527
 
515
528
  ### Full Documentation
516
529
 
517
- Each application has comprehensive documentation with examples and advanced usage:
530
+ Each application has documentation with examples and usage information:
518
531
 
519
532
  - **[Summarizer Guide](docs/apps/basic-summarizer.md)** - Document summarization with multiple strategies
520
533
  - **[Extractor Guide](docs/apps/basic-extractor.md)** - Entity and relationship extraction
534
+ - **[Intent Analyzer Guide](docs/apps/basic-intent.md)** - Psychological intent analysis and deception detection
521
535
  - **[Judge Guide](docs/apps/basic-judge.md)** - Text evaluation and scoring systems
522
536
 
523
537
  **When to use the apps:**
@@ -666,7 +680,7 @@ llm = create_llm("anthropic", model="claude-3.5-sonnet")
666
680
  response = llm.generate(analysis_prompt, media=documents)
667
681
 
668
682
  # Automatic format handling:
669
- # - PDF: Advanced text extraction with PyMuPDF4LLM
683
+ # - PDF: Text extraction with PyMuPDF4LLM
670
684
  # - Excel: Table parsing with pandas
671
685
  # - PowerPoint: Slide content extraction with unstructured
672
686
  ```
@@ -719,6 +733,8 @@ review = llm.generate(
719
733
  print(f"{review.title}: {review.rating}/5")
720
734
  ```
721
735
 
736
+ [Learn more about Structured Output](docs/structured-output.md)
737
+
722
738
  ### 7. Universal API Server
723
739
 
724
740
  ```bash
@@ -774,7 +790,7 @@ pip install abstractcore[all]
774
790
 
775
791
  **Media processing extras:**
776
792
  ```bash
777
- # For advanced PDF processing
793
+ # For PDF processing
778
794
  pip install pymupdf4llm
779
795
 
780
796
  # For Office documents (DOCX, XLSX, PPT)
@@ -1,26 +1,28 @@
1
1
  abstractcore/__init__.py,sha256=A7Gbn_C-robdWLLQXjtTyWsoaXDGIblSFmLRV_ni6O8,1934
2
2
  abstractcore/apps/__init__.py,sha256=sgNOv3lYyOWNBC-w6GnRN6aILGCbdkQtNcuQdJz5ghE,31
3
- abstractcore/apps/__main__.py,sha256=041daYkoIE1VLEO19IZC5nNIDOQZWNgpB7ogJ3SOlsE,1585
3
+ abstractcore/apps/__main__.py,sha256=fV9cGU99K4lGRsPNOLkh8qrDjH3JtMEWNlBiZrvI5Kk,1974
4
4
  abstractcore/apps/app_config_utils.py,sha256=5GIvXnD996LFIV3-BpfkqII6UqYlStm7ZCgmqDEN8dc,890
5
+ abstractcore/apps/deepsearch.py,sha256=UlmuBS9T4yNsz0V_iY08GNNDTstsI5OJNNV6c8CU6AE,23191
5
6
  abstractcore/apps/extractor.py,sha256=OfiqB9l_alH9xCGb6zOD__QJkDjdKOlLZngriVgmn7c,23749
7
+ abstractcore/apps/intent.py,sha256=5ie_H9_K_ZxlA0oCu7ROUrsgwfzDNFgVUyBNec6YVRE,22813
6
8
  abstractcore/apps/judge.py,sha256=nOgxvn-BbhNY6xU9AlTeD1yidTh73AiVlSN7hQCVE2M,23169
7
9
  abstractcore/apps/summarizer.py,sha256=9aD6KH21w-tv_wGp9MaO2uyJuaU71OemW7KpqrG5t6w,14669
8
10
  abstractcore/architectures/__init__.py,sha256=-4JucAM7JkMWShWKkePoclxrUHRKgaG36UTguJihE0U,1046
9
11
  abstractcore/architectures/detection.py,sha256=Cxap1pL6qOJjyY22Vc4hzbLALTuuBisPT5UaMotousk,10025
10
12
  abstractcore/architectures/enums.py,sha256=9vIv2vDBEKhxwzwH9iaSAyf-iVj3p8y9loMeN_mYTJ8,3821
11
13
  abstractcore/assets/architecture_formats.json,sha256=CIf6SaR_IJs1D7Uvd1K3zWngIXJ_yq3DM_IE3wnpCHY,16076
12
- abstractcore/assets/model_capabilities.json,sha256=iUkDiljyZUZzPlpYCOFgStXyc6e7dvOfReYQ0HFrX9Q,49703
14
+ abstractcore/assets/model_capabilities.json,sha256=AJwF1tmaGGl4P-UTbKX6awsgw7W543UN2TuqhC3y_Ss,50236
13
15
  abstractcore/assets/session_schema.json,sha256=hMCVrq3KSyVExrMGzuykf7bU-z6WyIVuEGU8du9_zUY,10570
14
16
  abstractcore/config/__init__.py,sha256=4mHX5z5Sq8R8xh78tb9jjZLaz_oBNW1eh914OsdDTxs,318
15
- abstractcore/config/main.py,sha256=PaFzy0Z03mhu293_ato_8qjZJunz1AcXVYny56ct7Zw,32602
16
- abstractcore/config/manager.py,sha256=6dYtVlwrXxcasDfz98CyocZ1nH9RPiD-yDKtsD3L7Ic,12508
17
+ abstractcore/config/main.py,sha256=U9zz-h9OvadqW9pBRRf999gVZKtBWsk27oPJtiJa8Qk,32646
18
+ abstractcore/config/manager.py,sha256=mo-cpT-jNfQmfTSe9LcalwE1WqjCyvNQexPIqNMS6sc,13098
17
19
  abstractcore/config/vision_config.py,sha256=jJzO4zBexh8SqSKp6YKOXdMDSv4AL4Ztl5Xi-5c4KyY,17869
18
20
  abstractcore/core/__init__.py,sha256=2h-86U4QkCQ4gzZ4iRusSTMlkODiUS6tKjZHiEXz6rM,684
19
21
  abstractcore/core/enums.py,sha256=BhkVnHC-X1_377JDmqd-2mnem9GdBLqixWlYzlP_FJU,695
20
22
  abstractcore/core/factory.py,sha256=ec7WGW2JKK-dhDplziTAeRkebEUFymtEEZ_bS5qkpqY,2798
21
23
  abstractcore/core/interface.py,sha256=-VAY0nlsTnWN_WghiuMC7iE7xUdZfYOg6KlgrAPi14Y,14086
22
24
  abstractcore/core/retry.py,sha256=wNlUAxfmvdO_uVWb4iqkhTqd7O1oRwXxqvVQaLXQOw0,14538
23
- abstractcore/core/session.py,sha256=fdqhnufCWrV022RjQ-Xfb1KFv_s9-GzetSSR-QuXv-Q,36452
25
+ abstractcore/core/session.py,sha256=thqG8zWICKpPeCJi5IoKbMhBDOH4RJlTfUjymP14TFY,38249
24
26
  abstractcore/core/types.py,sha256=jj44i07kMjdg9FQ3mA_fK6r_M0Lcgt1RQpy1Ra5w-eI,4578
25
27
  abstractcore/embeddings/__init__.py,sha256=hR3xZyqcRm4c2pq1dIa5lxj_-Bk70Zad802JQN4joWo,637
26
28
  abstractcore/embeddings/manager.py,sha256=uFVbRPHx_R-kVMVA7N7_7EzeUmCJCeN9Dv0EV8Jko24,52245
@@ -44,27 +46,29 @@ abstractcore/media/processors/pdf_processor.py,sha256=qniYt7cTYYPVRi_cS1IsXztOld
44
46
  abstractcore/media/processors/text_processor.py,sha256=E28FtT2_jzsvMIDwZi6aVWuu_pSyAPSBa96fe4YYcU8,21092
45
47
  abstractcore/media/utils/__init__.py,sha256=30-CTif91iRKOXJ4njGiduWAt-xp31U7NafMBNvgdO0,460
46
48
  abstractcore/media/utils/image_scaler.py,sha256=QrYqoNQc8tzGu7I9Sf_E-Iv7ei2oLh714AGiX3yACNM,11338
47
- abstractcore/processing/__init__.py,sha256=t6hiakQjcZROT4pw9ZFt2q6fF3vf5VpdMKG2EWlsFd8,540
49
+ abstractcore/processing/__init__.py,sha256=QcACEnhnHKYCkFL1LNOW_uqBrwkTAmz5A61N4K2dyu0,988
50
+ abstractcore/processing/basic_deepsearch.py,sha256=dzJQtH4k44XY9tvG0Z4JIlYt_s7HpbLdSPScha-t7vk,101036
48
51
  abstractcore/processing/basic_extractor.py,sha256=3x-3BdIHgLvqLnLF6K1-P4qVaLIpAnNIIutaJi7lDQM,49832
52
+ abstractcore/processing/basic_intent.py,sha256=wD99Z7fE2RiYk6oyTZXojUbv-bz8HhKFIuIHYLLTw54,32455
49
53
  abstractcore/processing/basic_judge.py,sha256=tKWJrg_tY4vCHzWgXxz0ZjgLXBYYfpMcpG7vl03hJcM,32218
50
54
  abstractcore/processing/basic_summarizer.py,sha256=XHNxMQ_8aLStTeUo6_2JaThlct12Htpz7ORmm0iuJsg,25495
51
55
  abstractcore/providers/__init__.py,sha256=n-2RMNm3QpKxHw9EOjv8icRMRnfJp5Xg0uSVzHCW3BI,1222
52
- abstractcore/providers/anthropic_provider.py,sha256=R87Z_DNNdeA4LMSxx84pqo8saKFz38dHCJMBpc-rL70,21552
53
- abstractcore/providers/base.py,sha256=YfrqM3c7wLT19vspL7goUO6Bv-z1691ZkCM2wxvQX4s,51501
54
- abstractcore/providers/huggingface_provider.py,sha256=pgpeSwpwyNB_5GDyLEz2OSTu9me-GAJzQ116dGtpCvQ,49012
55
- abstractcore/providers/lmstudio_provider.py,sha256=odT6luVR3POVcq2ZqkINLyLoCAu_YGpLLj3fEddNliU,21021
56
- abstractcore/providers/mlx_provider.py,sha256=sDgxf_kVJJwxprQWVef9w2CLOu2dLES8D0Vf5tY6PzE,18463
57
- abstractcore/providers/ollama_provider.py,sha256=1bE80NCj_TQADxRCiu9luyLuI_gZe2EO5pCKoC4VhQM,21740
58
- abstractcore/providers/openai_provider.py,sha256=1s7JJalyIBOvLB7UAUwXbTc2aYrYSWg7hJjKGnCX1qU,23313
59
- abstractcore/providers/registry.py,sha256=fKFrN6Z3o5Gi0dfwvXDPtrrJXDjx9oPSfjWjZf-NJBc,15883
56
+ abstractcore/providers/anthropic_provider.py,sha256=wXzRgW1AJCRX5dovXHVRTNxL96vycr7Ug9omKnLjPzo,21588
57
+ abstractcore/providers/base.py,sha256=gWlkchUZBXgcJAKNV8U1hROUGGw8MdDIuLHQM2LRx8Y,51530
58
+ abstractcore/providers/huggingface_provider.py,sha256=mTjpdZlC49QCMqsDHEabTnQbX21z7MNV77Dv9hs_RiM,53696
59
+ abstractcore/providers/lmstudio_provider.py,sha256=jzNMngjRtpw4lgdF66i5h22QIPWXvritezcJndetu7A,21632
60
+ abstractcore/providers/mlx_provider.py,sha256=1gI1KXJdKcgjiaivk7LpuBScpYgsVJ9YEikm-gCChoo,22156
61
+ abstractcore/providers/ollama_provider.py,sha256=VfPn6y87Jjih1MhFsHhijtv1AhbefhwSh4_Z2eAKc4o,21975
62
+ abstractcore/providers/openai_provider.py,sha256=kV1YXjzKyqJMQhmn9kG7AwQ-ssu8PipFwXdmmuosR98,23346
63
+ abstractcore/providers/registry.py,sha256=oqEaKjF2nuPiw9W0u6DM7TJgm4P2i94aKZRb8Ma6PqM,16002
60
64
  abstractcore/providers/streaming.py,sha256=VnffBV_CU9SAKzghL154OoFyEdDsiLwUNXPahyU41Bw,31342
61
65
  abstractcore/server/__init__.py,sha256=1DSAz_YhQtnKv7sNi5TMQV8GFujctDOabgvAdilQE0o,249
62
66
  abstractcore/server/app.py,sha256=7pG5ZkZqYNnyby4jyvp3_NKl5nNDmZpOhv_-F8Jruy4,96580
63
67
  abstractcore/structured/__init__.py,sha256=VXRQHGcm-iaYnLOBPin2kyhvhhQA0kaGt_pcNDGsE_8,339
64
- abstractcore/structured/handler.py,sha256=Vb15smiR81JGDXX2RLkY2Exuj67J7a6C-xwVrZoXp0I,17134
68
+ abstractcore/structured/handler.py,sha256=hcUe_fZcwx0O3msLqFiOsj6-jbq3S-ZQa9c1nRIZvuo,24622
65
69
  abstractcore/structured/retry.py,sha256=BN_PvrWybyU1clMy2cult1-TVxFSMaVqiCPmmXvA5aI,3805
66
70
  abstractcore/tools/__init__.py,sha256=oh6vG0RdM1lqUtOp95mLrTsWLh9VmhJf5_FVjGIP5_M,2259
67
- abstractcore/tools/common_tools.py,sha256=GkUSnBum3zMm9M-Zd9LlJQmlDp1XDssC7z8ItUcbloc,91692
71
+ abstractcore/tools/common_tools.py,sha256=sfCuwZX3mG229yZRAgaLlDrVpGCVfdH_Uq5tZUVw6n8,95122
68
72
  abstractcore/tools/core.py,sha256=lUUGihyceiRYlKUFvEMig9jWFF563d574mSDbYYD3fM,4777
69
73
  abstractcore/tools/handler.py,sha256=GmDenXAJkhceWSGlhvuF90aMb2301tRTh6WxGwBQifc,12022
70
74
  abstractcore/tools/parser.py,sha256=1r5nmEEp1Rid3JU6ct-s3lP-eCln67fvXG5HCjqiRew,27740
@@ -72,15 +76,15 @@ abstractcore/tools/registry.py,sha256=cN3nbPEK6L2vAd9740MIFf2fitW_4WHpQfK4KvQjnT
72
76
  abstractcore/tools/syntax_rewriter.py,sha256=c3NSTvUF3S3ho5Cwjp7GJJdibeYAI6k3iaBwhKcpTfo,17318
73
77
  abstractcore/tools/tag_rewriter.py,sha256=UGFMBj2QKwm12j8JQ6oc2C_N3ZeNqz9Enz4VkEIrS0c,20338
74
78
  abstractcore/utils/__init__.py,sha256=29mMc3jV_suEPBn7W8Yw_wqcdvFP-083ws5AUFJVM28,676
75
- abstractcore/utils/cli.py,sha256=btuTIECrBPV4cdoWoE-N1rkzcrq--dhwKbtZTQhvwok,65175
79
+ abstractcore/utils/cli.py,sha256=tO7S-iVSZavxJaX7OTruNAmF3lJz9eCDORK8Dm7FdgA,70558
76
80
  abstractcore/utils/message_preprocessor.py,sha256=GdHkm6tmrgjm3PwHRSCjIsq1XLkbhy_vDEKEUE7OiKY,6028
77
81
  abstractcore/utils/self_fixes.py,sha256=QEDwNTW80iQM4ftfEY3Ghz69F018oKwLM9yeRCYZOvw,5886
78
82
  abstractcore/utils/structured_logging.py,sha256=Vm-HviSa42G9DJCWmaEv4a0QG3NMsADD3ictLOs4En0,19952
79
83
  abstractcore/utils/token_utils.py,sha256=eLwFmJ68p9WMFD_MHLMmeJRW6Oqx_4hKELB8FNQ2Mnk,21097
80
- abstractcore/utils/version.py,sha256=vI5E04BYQ3mKTIy4xhwGPse-tZLrIK0hLgJzTYZKJMQ,605
81
- abstractcore-2.5.0.dist-info/licenses/LICENSE,sha256=PI2v_4HMvd6050uDD_4AY_8PzBnu2asa3RKbdDjowTA,1078
82
- abstractcore-2.5.0.dist-info/METADATA,sha256=VVP8VO51qhQD_zfPbq25CQ3rbeeMD-UYyeloPU_lFbw,32084
83
- abstractcore-2.5.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
84
- abstractcore-2.5.0.dist-info/entry_points.txt,sha256=eUQvRc0sGl4pK3r2zhlGZro7Fk_wl4szw1hDE8SnlDI,460
85
- abstractcore-2.5.0.dist-info/top_level.txt,sha256=DiNHBI35SIawW3N9Z-z0y6cQYNbXd32pvBkW0RLfScs,13
86
- abstractcore-2.5.0.dist-info/RECORD,,
84
+ abstractcore/utils/version.py,sha256=GC9cH32Kxl_Gm71B9JyHaV8605RVj_YHzLdOS6AjFM0,605
85
+ abstractcore-2.5.2.dist-info/licenses/LICENSE,sha256=PI2v_4HMvd6050uDD_4AY_8PzBnu2asa3RKbdDjowTA,1078
86
+ abstractcore-2.5.2.dist-info/METADATA,sha256=VeTcJ285fQCo75pDmpjGmnllxlWHH6JvyfSYeN_o8Y4,32893
87
+ abstractcore-2.5.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
88
+ abstractcore-2.5.2.dist-info/entry_points.txt,sha256=jXNdzeltVs23A2JM2e2HOiAHldHrsnud3EvPI5VffOs,658
89
+ abstractcore-2.5.2.dist-info/top_level.txt,sha256=DiNHBI35SIawW3N9Z-z0y6cQYNbXd32pvBkW0RLfScs,13
90
+ abstractcore-2.5.2.dist-info/RECORD,,
@@ -2,9 +2,13 @@
2
2
  abstractcore = abstractcore.config.main:main
3
3
  abstractcore-chat = abstractcore.utils.cli:main
4
4
  abstractcore-config = abstractcore.config.main:main
5
+ abstractcore-deepsearch = abstractcore.apps.deepsearch:main
5
6
  abstractcore-extractor = abstractcore.apps.extractor:main
7
+ abstractcore-intent = abstractcore.apps.intent:main
6
8
  abstractcore-judge = abstractcore.apps.judge:main
7
9
  abstractcore-summarizer = abstractcore.apps.summarizer:main
10
+ deepsearch = abstractcore.apps.deepsearch:main
8
11
  extractor = abstractcore.apps.extractor:main
12
+ intent = abstractcore.apps.intent:main
9
13
  judge = abstractcore.apps.judge:main
10
14
  summarizer = abstractcore.apps.summarizer:main