signalwire-agents 0.1.17__py3-none-any.whl → 0.1.19__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.
@@ -18,7 +18,7 @@ A package for building AI agents using SignalWire's AI and SWML capabilities.
18
18
  from .core.logging_config import configure_logging
19
19
  configure_logging()
20
20
 
21
- __version__ = "0.1.17"
21
+ __version__ = "0.1.19"
22
22
 
23
23
  # Import core classes for easier access
24
24
  from .core.agent_base import AgentBase
@@ -85,6 +85,10 @@ Examples:
85
85
  sw-search search ./docs.swsearch "how to create an agent"
86
86
  sw-search search ./docs.swsearch "API reference" --count 3 --verbose
87
87
  sw-search search ./docs.swsearch "configuration" --tags documentation --json
88
+
89
+ # Search via remote API
90
+ sw-search remote http://localhost:8001 "how to create an agent" --index-name docs
91
+ sw-search remote localhost:8001 "API reference" --index-name docs --count 3 --verbose
88
92
  """
89
93
  )
90
94
 
@@ -263,7 +267,7 @@ Examples:
263
267
 
264
268
  try:
265
269
  # Create index builder - import only when actually needed
266
- from ..search.index_builder import IndexBuilder
270
+ from signalwire_agents.search.index_builder import IndexBuilder
267
271
  builder = IndexBuilder(
268
272
  model_name=args.model,
269
273
  chunking_strategy=args.chunking_strategy,
@@ -328,7 +332,7 @@ def validate_command():
328
332
  sys.exit(1)
329
333
 
330
334
  try:
331
- from ..search.index_builder import IndexBuilder
335
+ from signalwire_agents.search.index_builder import IndexBuilder
332
336
  builder = IndexBuilder()
333
337
 
334
338
  validation = builder.validate_index(args.index_file)
@@ -376,8 +380,8 @@ def search_command():
376
380
  try:
377
381
  # Import search dependencies
378
382
  try:
379
- from ..search.search_engine import SearchEngine
380
- from ..search.query_processor import preprocess_query
383
+ from signalwire_agents.search.search_engine import SearchEngine
384
+ from signalwire_agents.search.query_processor import preprocess_query
381
385
  except ImportError as e:
382
386
  print(f"Error: Search functionality not available. Install with: pip install signalwire-agents[search]")
383
387
  print(f"Details: {e}")
@@ -478,6 +482,141 @@ def search_command():
478
482
  traceback.print_exc()
479
483
  sys.exit(1)
480
484
 
485
+ def remote_command():
486
+ """Search via remote API endpoint"""
487
+ parser = argparse.ArgumentParser(description='Search via remote API endpoint')
488
+ parser.add_argument('endpoint', help='Remote API endpoint URL (e.g., http://localhost:8001)')
489
+ parser.add_argument('query', help='Search query')
490
+ parser.add_argument('--index-name', required=True, help='Name of the index to search')
491
+ parser.add_argument('--count', type=int, default=5, help='Number of results to return (default: 5)')
492
+ parser.add_argument('--distance-threshold', type=float, default=0.0, help='Minimum similarity score (default: 0.0)')
493
+ parser.add_argument('--tags', help='Comma-separated tags to filter by')
494
+ parser.add_argument('--verbose', action='store_true', help='Show detailed information')
495
+ parser.add_argument('--json', action='store_true', help='Output results as JSON')
496
+ parser.add_argument('--no-content', action='store_true', help='Hide content in results (show only metadata)')
497
+ parser.add_argument('--timeout', type=int, default=30, help='Request timeout in seconds (default: 30)')
498
+
499
+ args = parser.parse_args()
500
+
501
+ # Ensure endpoint starts with http:// or https://
502
+ endpoint = args.endpoint
503
+ if not endpoint.startswith(('http://', 'https://')):
504
+ endpoint = f"http://{endpoint}"
505
+
506
+ # Ensure endpoint ends with /search
507
+ if not endpoint.endswith('/search'):
508
+ if endpoint.endswith('/'):
509
+ endpoint += 'search'
510
+ else:
511
+ endpoint += '/search'
512
+
513
+ try:
514
+ import requests
515
+ except ImportError:
516
+ print("Error: requests library not available. Install with: pip install requests")
517
+ sys.exit(1)
518
+
519
+ # Prepare request payload
520
+ payload = {
521
+ 'query': args.query,
522
+ 'index_name': args.index_name,
523
+ 'count': args.count,
524
+ 'distance_threshold': args.distance_threshold
525
+ }
526
+
527
+ if args.tags:
528
+ payload['tags'] = [tag.strip() for tag in args.tags.split(',')]
529
+
530
+ if args.verbose:
531
+ print(f"Searching remote endpoint: {endpoint}")
532
+ print(f"Payload: {payload}")
533
+ print()
534
+
535
+ try:
536
+ # Make the API request
537
+ response = requests.post(
538
+ endpoint,
539
+ json=payload,
540
+ headers={'Content-Type': 'application/json'},
541
+ timeout=args.timeout
542
+ )
543
+
544
+ if response.status_code == 200:
545
+ result = response.json()
546
+
547
+ if args.json:
548
+ # Output raw JSON response
549
+ import json
550
+ print(json.dumps(result, indent=2))
551
+ else:
552
+ # Human-readable output
553
+ results = result.get('results', [])
554
+ if not results:
555
+ print(f"No results found for '{args.query}' in index '{args.index_name}'")
556
+ sys.exit(0)
557
+
558
+ print(f"Found {len(results)} result(s) for '{args.query}' in index '{args.index_name}':")
559
+ if result.get('enhanced_query') and result.get('enhanced_query') != args.query:
560
+ print(f"Enhanced query: '{result.get('enhanced_query')}'")
561
+ print("=" * 80)
562
+
563
+ for i, search_result in enumerate(results):
564
+ print(f"\n[{i+1}] Score: {search_result.get('score', 0):.4f}")
565
+
566
+ # Show metadata
567
+ metadata = search_result.get('metadata', {})
568
+ print(f"File: {metadata.get('filename', 'Unknown')}")
569
+ if metadata.get('section'):
570
+ print(f"Section: {metadata['section']}")
571
+ if metadata.get('line_start'):
572
+ print(f"Lines: {metadata['line_start']}-{metadata.get('line_end', metadata['line_start'])}")
573
+ if metadata.get('tags'):
574
+ print(f"Tags: {', '.join(metadata['tags'])}")
575
+
576
+ # Show content unless suppressed
577
+ if not args.no_content and 'content' in search_result:
578
+ content = search_result['content']
579
+ if len(content) > 500 and not args.verbose:
580
+ content = content[:500] + "..."
581
+ print(f"\nContent:\n{content}")
582
+
583
+ if i < len(results) - 1:
584
+ print("-" * 80)
585
+
586
+ elif response.status_code == 404:
587
+ try:
588
+ error_detail = response.json()
589
+ error_msg = error_detail.get('detail', 'Index not found')
590
+ except:
591
+ error_msg = 'Index not found'
592
+ print(f"Error: {error_msg}")
593
+ sys.exit(1)
594
+ else:
595
+ try:
596
+ error_detail = response.json()
597
+ error_msg = error_detail.get('detail', f'HTTP {response.status_code}')
598
+ except:
599
+ error_msg = f'HTTP {response.status_code}: {response.text}'
600
+ print(f"Error: {error_msg}")
601
+ sys.exit(1)
602
+
603
+ except requests.ConnectionError:
604
+ print(f"Error: Could not connect to {endpoint}")
605
+ print("Make sure the search server is running")
606
+ sys.exit(1)
607
+ except requests.Timeout:
608
+ print(f"Error: Request timed out after {args.timeout} seconds")
609
+ sys.exit(1)
610
+ except requests.RequestException as e:
611
+ print(f"Error making request: {e}")
612
+ sys.exit(1)
613
+ except Exception as e:
614
+ print(f"Error: {e}")
615
+ if args.verbose:
616
+ import traceback
617
+ traceback.print_exc()
618
+ sys.exit(1)
619
+
481
620
  def console_entry_point():
482
621
  """Console script entry point for pip installation"""
483
622
  import sys
@@ -594,6 +733,10 @@ Examples:
594
733
  sw-search search ./docs.swsearch "how to create an agent"
595
734
  sw-search search ./docs.swsearch "API reference" --count 3 --verbose
596
735
  sw-search search ./docs.swsearch "configuration" --tags documentation --json
736
+
737
+ # Search via remote API
738
+ sw-search remote http://localhost:8001 "how to create an agent" --index-name docs
739
+ sw-search remote localhost:8001 "API reference" --index-name docs --count 3 --verbose
597
740
  """)
598
741
  return
599
742
 
@@ -609,6 +752,11 @@ Examples:
609
752
  sys.argv.pop(1)
610
753
  search_command()
611
754
  return
755
+ elif sys.argv[1] == 'remote':
756
+ # Remove 'remote' from argv and call remote_command
757
+ sys.argv.pop(1)
758
+ remote_command()
759
+ return
612
760
 
613
761
  # Regular build command
614
762
  main()