signalwire-agents 0.1.14__py3-none-any.whl → 0.1.15__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.14"
21
+ __version__ = "0.1.15"
22
22
 
23
23
  # Import core classes for easier access
24
24
  from .core.agent_base import AgentBase
@@ -25,7 +25,7 @@ import re
25
25
  import signal
26
26
  import sys
27
27
  from typing import Optional, Union, List, Dict, Any, Tuple, Callable, Type
28
- from urllib.parse import urlparse, urlencode
28
+ from urllib.parse import urlparse, urlencode, urlunparse
29
29
 
30
30
  try:
31
31
  import fastapi
@@ -1299,51 +1299,61 @@ class AgentBase(SWMLService):
1299
1299
  script_name = os.getenv('SCRIPT_NAME', '')
1300
1300
  base_url = f"{protocol}://{host}{script_name}"
1301
1301
  elif mode == 'lambda':
1302
- function_url = os.getenv('AWS_LAMBDA_FUNCTION_URL')
1303
- if function_url and ('amazonaws.com' in function_url or 'on.aws' in function_url):
1304
- base_url = function_url.rstrip('/')
1302
+ # AWS Lambda Function URL format
1303
+ lambda_url = os.getenv('AWS_LAMBDA_FUNCTION_URL')
1304
+ if lambda_url:
1305
+ base_url = lambda_url.rstrip('/')
1305
1306
  else:
1306
- api_id = os.getenv('AWS_API_GATEWAY_ID')
1307
- if api_id:
1308
- region = os.getenv('AWS_REGION', 'us-east-1')
1309
- stage = os.getenv('AWS_API_GATEWAY_STAGE', 'prod')
1310
- base_url = f"https://{api_id}.execute-api.{region}.amazonaws.com/{stage}"
1311
- else:
1312
- import logging
1313
- logging.warning("Lambda mode detected but no URL configuration found")
1314
- base_url = "https://lambda-url-not-configured"
1315
- elif mode == 'cloud_function':
1316
- function_url = os.getenv('FUNCTION_URL')
1317
- if function_url:
1318
- base_url = function_url
1307
+ # Fallback construction for Lambda
1308
+ region = os.getenv('AWS_REGION', 'us-east-1')
1309
+ function_name = os.getenv('AWS_LAMBDA_FUNCTION_NAME', 'unknown')
1310
+ base_url = f"https://{function_name}.lambda-url.{region}.on.aws"
1311
+ elif mode == 'google_cloud_function':
1312
+ # Google Cloud Functions URL format
1313
+ project_id = os.getenv('GOOGLE_CLOUD_PROJECT') or os.getenv('GCP_PROJECT')
1314
+ region = os.getenv('FUNCTION_REGION') or os.getenv('GOOGLE_CLOUD_REGION', 'us-central1')
1315
+ service_name = os.getenv('K_SERVICE') or os.getenv('FUNCTION_TARGET', 'unknown')
1316
+
1317
+ if project_id:
1318
+ base_url = f"https://{region}-{project_id}.cloudfunctions.net/{service_name}"
1319
1319
  else:
1320
- project = os.getenv('GOOGLE_CLOUD_PROJECT')
1321
- if project:
1322
- region = os.getenv('GOOGLE_CLOUD_REGION', 'us-central1')
1323
- service = os.getenv('K_SERVICE', 'function')
1324
- base_url = f"https://{region}-{project}.cloudfunctions.net/{service}"
1325
- else:
1326
- import logging
1327
- logging.warning("Cloud Function mode detected but no URL configuration found")
1328
- base_url = "https://cloud-function-url-not-configured"
1329
- else:
1330
- # Server mode - preserve existing logic
1331
- if self._proxy_url_base:
1332
- proxy_base = self._proxy_url_base.rstrip('/')
1333
- route = self.route if self.route.startswith('/') else f"/{self.route}"
1334
- base_url = f"{proxy_base}{route}"
1320
+ # Fallback for local testing or incomplete environment
1321
+ base_url = f"https://localhost:8080"
1322
+ elif mode == 'azure_function':
1323
+ # Azure Functions URL format
1324
+ function_app_name = os.getenv('WEBSITE_SITE_NAME') or os.getenv('AZURE_FUNCTIONS_APP_NAME')
1325
+ function_name = os.getenv('AZURE_FUNCTION_NAME', 'unknown')
1326
+
1327
+ if function_app_name:
1328
+ base_url = f"https://{function_app_name}.azurewebsites.net/api/{function_name}"
1335
1329
  else:
1336
- if self.host in ("0.0.0.0", "127.0.0.1", "localhost"):
1337
- host = "localhost"
1338
- else:
1339
- host = self.host
1340
- base_url = f"http://{host}:{self.port}{self.route}"
1341
-
1342
- # Add auth if requested (applies to all modes now)
1330
+ # Fallback for local testing
1331
+ base_url = f"https://localhost:7071/api/{function_name}"
1332
+ else:
1333
+ # Server mode
1334
+ protocol = 'https' if self.ssl_cert and self.ssl_key else 'http'
1335
+ base_url = f"{protocol}://{self.host}:{self.port}"
1336
+
1337
+ # Add route if not already included (for server mode)
1338
+ if mode == 'server' and self.route and not base_url.endswith(self.route):
1339
+ base_url = f"{base_url}/{self.route.lstrip('/')}"
1340
+
1341
+ # Add authentication if requested
1343
1342
  if include_auth:
1344
- username, password = self._basic_auth
1345
- url = urlparse(base_url)
1346
- return url._replace(netloc=f"{username}:{password}@{url.netloc}").geturl()
1343
+ username, password = self.get_basic_auth_credentials()
1344
+ if username and password:
1345
+ # Parse URL to insert auth
1346
+ from urllib.parse import urlparse, urlunparse
1347
+ parsed = urlparse(base_url)
1348
+ # Reconstruct with auth
1349
+ base_url = urlunparse((
1350
+ parsed.scheme,
1351
+ f"{username}:{password}@{parsed.netloc}",
1352
+ parsed.path,
1353
+ parsed.params,
1354
+ parsed.query,
1355
+ parsed.fragment
1356
+ ))
1347
1357
 
1348
1358
  return base_url
1349
1359
 
@@ -1878,6 +1888,124 @@ class AgentBase(SWMLService):
1878
1888
  else:
1879
1889
  raise
1880
1890
 
1891
+ def _check_cgi_auth(self) -> bool:
1892
+ """
1893
+ Check basic auth in CGI mode using environment variables
1894
+
1895
+ Returns:
1896
+ True if auth is valid, False otherwise
1897
+ """
1898
+ # Check for HTTP_AUTHORIZATION environment variable
1899
+ auth_header = os.getenv('HTTP_AUTHORIZATION')
1900
+ if not auth_header:
1901
+ # Also check for REMOTE_USER (if web server handled auth)
1902
+ remote_user = os.getenv('REMOTE_USER')
1903
+ if remote_user:
1904
+ # If web server handled auth, trust it
1905
+ return True
1906
+ return False
1907
+
1908
+ if not auth_header.startswith('Basic '):
1909
+ return False
1910
+
1911
+ try:
1912
+ # Decode the base64 credentials
1913
+ credentials = base64.b64decode(auth_header[6:]).decode("utf-8")
1914
+ username, password = credentials.split(":", 1)
1915
+ return self.validate_basic_auth(username, password)
1916
+ except Exception:
1917
+ return False
1918
+
1919
+ def _send_cgi_auth_challenge(self) -> str:
1920
+ """
1921
+ Send authentication challenge in CGI mode
1922
+
1923
+ Returns:
1924
+ HTTP response with 401 status and WWW-Authenticate header
1925
+ """
1926
+ # In CGI, we need to output the complete HTTP response
1927
+ response = "Status: 401 Unauthorized\r\n"
1928
+ response += "WWW-Authenticate: Basic realm=\"SignalWire Agent\"\r\n"
1929
+ response += "Content-Type: application/json\r\n"
1930
+ response += "\r\n"
1931
+ response += json.dumps({"error": "Unauthorized"})
1932
+ return response
1933
+
1934
+ def _check_lambda_auth(self, event) -> bool:
1935
+ """
1936
+ Check basic auth in Lambda mode using event headers
1937
+
1938
+ Args:
1939
+ event: Lambda event object containing headers
1940
+
1941
+ Returns:
1942
+ True if auth is valid, False otherwise
1943
+ """
1944
+ if not event or 'headers' not in event:
1945
+ return False
1946
+
1947
+ headers = event['headers']
1948
+
1949
+ # Check for authorization header (case-insensitive)
1950
+ auth_header = None
1951
+ for key, value in headers.items():
1952
+ if key.lower() == 'authorization':
1953
+ auth_header = value
1954
+ break
1955
+
1956
+ if not auth_header or not auth_header.startswith('Basic '):
1957
+ return False
1958
+
1959
+ try:
1960
+ # Decode the base64 credentials
1961
+ credentials = base64.b64decode(auth_header[6:]).decode("utf-8")
1962
+ username, password = credentials.split(":", 1)
1963
+ return self.validate_basic_auth(username, password)
1964
+ except Exception:
1965
+ return False
1966
+
1967
+ def _send_lambda_auth_challenge(self) -> dict:
1968
+ """
1969
+ Send authentication challenge in Lambda mode
1970
+
1971
+ Returns:
1972
+ Lambda response with 401 status and WWW-Authenticate header
1973
+ """
1974
+ return {
1975
+ "statusCode": 401,
1976
+ "headers": {
1977
+ "WWW-Authenticate": "Basic realm=\"SignalWire Agent\"",
1978
+ "Content-Type": "application/json"
1979
+ },
1980
+ "body": json.dumps({"error": "Unauthorized"})
1981
+ }
1982
+
1983
+ def _check_cloud_function_auth(self, request) -> bool:
1984
+ """
1985
+ Check basic auth in Cloud Function mode
1986
+
1987
+ Args:
1988
+ request: Cloud Function request object
1989
+
1990
+ Returns:
1991
+ True if auth is valid, False otherwise
1992
+ """
1993
+ # This would need to be implemented based on the specific
1994
+ # cloud function framework being used (Flask, etc.)
1995
+ # For now, return True to maintain existing behavior
1996
+ return True
1997
+
1998
+ def _send_cloud_function_auth_challenge(self):
1999
+ """
2000
+ Send authentication challenge in Cloud Function mode
2001
+
2002
+ Returns:
2003
+ Cloud Function response with 401 status
2004
+ """
2005
+ # This would need to be implemented based on the specific
2006
+ # cloud function framework being used
2007
+ return {"error": "Unauthorized", "status": 401}
2008
+
1881
2009
  def handle_serverless_request(self, event=None, context=None, mode=None):
1882
2010
  """
1883
2011
  Handle serverless environment requests (CGI, Lambda, Cloud Functions)
@@ -1895,6 +2023,10 @@ class AgentBase(SWMLService):
1895
2023
 
1896
2024
  try:
1897
2025
  if mode == 'cgi':
2026
+ # Check authentication in CGI mode
2027
+ if not self._check_cgi_auth():
2028
+ return self._send_cgi_auth_challenge()
2029
+
1898
2030
  path_info = os.getenv('PATH_INFO', '').strip('/')
1899
2031
  if not path_info:
1900
2032
  return self._render_swml()
@@ -1930,6 +2062,10 @@ class AgentBase(SWMLService):
1930
2062
  return self._execute_swaig_function(path_info, args, call_id, raw_data)
1931
2063
 
1932
2064
  elif mode == 'lambda':
2065
+ # Check authentication in Lambda mode
2066
+ if not self._check_lambda_auth(event):
2067
+ return self._send_lambda_auth_challenge()
2068
+
1933
2069
  if event:
1934
2070
  path = event.get('pathParameters', {}).get('proxy', '') if event.get('pathParameters') else ''
1935
2071
  if not path:
@@ -1984,7 +2120,26 @@ class AgentBase(SWMLService):
1984
2120
  "body": swml_response
1985
2121
  }
1986
2122
 
1987
- elif mode in ['cloud_function', 'azure_function']:
2123
+ elif mode == 'google_cloud_function':
2124
+ # Check authentication in Google Cloud Functions mode
2125
+ if not self._check_google_cloud_function_auth(event):
2126
+ return self._send_google_cloud_function_auth_challenge()
2127
+
2128
+ return self._handle_google_cloud_function_request(event)
2129
+
2130
+ elif mode == 'azure_function':
2131
+ # Check authentication in Azure Functions mode
2132
+ if not self._check_azure_function_auth(event):
2133
+ return self._send_azure_function_auth_challenge()
2134
+
2135
+ return self._handle_azure_function_request(event)
2136
+
2137
+ elif mode in ['cloud_function']:
2138
+ # Legacy cloud function mode - deprecated
2139
+ # Check authentication in Cloud Function mode
2140
+ if not self._check_cloud_function_auth(event):
2141
+ return self._send_cloud_function_auth_challenge()
2142
+
1988
2143
  return self._handle_cloud_function_request(event)
1989
2144
 
1990
2145
  except Exception as e:
@@ -3410,3 +3565,245 @@ class AgentBase(SWMLService):
3410
3565
  def has_skill(self, skill_name: str) -> bool:
3411
3566
  """Check if skill is loaded"""
3412
3567
  return self.skill_manager.has_skill(skill_name)
3568
+
3569
+ def _check_google_cloud_function_auth(self, request) -> bool:
3570
+ """
3571
+ Check basic auth in Google Cloud Functions mode using request headers
3572
+
3573
+ Args:
3574
+ request: Flask request object or similar containing headers
3575
+
3576
+ Returns:
3577
+ True if auth is valid, False otherwise
3578
+ """
3579
+ if not hasattr(request, 'headers'):
3580
+ return False
3581
+
3582
+ # Check for authorization header (case-insensitive)
3583
+ auth_header = None
3584
+ for key in request.headers:
3585
+ if key.lower() == 'authorization':
3586
+ auth_header = request.headers[key]
3587
+ break
3588
+
3589
+ if not auth_header or not auth_header.startswith('Basic '):
3590
+ return False
3591
+
3592
+ try:
3593
+ import base64
3594
+ encoded_credentials = auth_header[6:] # Remove 'Basic '
3595
+ decoded_credentials = base64.b64decode(encoded_credentials).decode('utf-8')
3596
+ provided_username, provided_password = decoded_credentials.split(':', 1)
3597
+
3598
+ expected_username, expected_password = self.get_basic_auth_credentials()
3599
+ return (provided_username == expected_username and
3600
+ provided_password == expected_password)
3601
+ except Exception:
3602
+ return False
3603
+
3604
+ def _check_azure_function_auth(self, req) -> bool:
3605
+ """
3606
+ Check basic auth in Azure Functions mode using request object
3607
+
3608
+ Args:
3609
+ req: Azure Functions request object containing headers
3610
+
3611
+ Returns:
3612
+ True if auth is valid, False otherwise
3613
+ """
3614
+ if not hasattr(req, 'headers'):
3615
+ return False
3616
+
3617
+ # Check for authorization header (case-insensitive)
3618
+ auth_header = None
3619
+ for key, value in req.headers.items():
3620
+ if key.lower() == 'authorization':
3621
+ auth_header = value
3622
+ break
3623
+
3624
+ if not auth_header or not auth_header.startswith('Basic '):
3625
+ return False
3626
+
3627
+ try:
3628
+ import base64
3629
+ encoded_credentials = auth_header[6:] # Remove 'Basic '
3630
+ decoded_credentials = base64.b64decode(encoded_credentials).decode('utf-8')
3631
+ provided_username, provided_password = decoded_credentials.split(':', 1)
3632
+
3633
+ expected_username, expected_password = self.get_basic_auth_credentials()
3634
+ return (provided_username == expected_username and
3635
+ provided_password == expected_password)
3636
+ except Exception:
3637
+ return False
3638
+
3639
+ def _send_google_cloud_function_auth_challenge(self):
3640
+ """
3641
+ Send authentication challenge in Google Cloud Functions mode
3642
+
3643
+ Returns:
3644
+ Flask-compatible response with 401 status and WWW-Authenticate header
3645
+ """
3646
+ from flask import Response
3647
+ return Response(
3648
+ response=json.dumps({"error": "Unauthorized"}),
3649
+ status=401,
3650
+ headers={
3651
+ "WWW-Authenticate": "Basic realm=\"SignalWire Agent\"",
3652
+ "Content-Type": "application/json"
3653
+ }
3654
+ )
3655
+
3656
+ def _send_azure_function_auth_challenge(self):
3657
+ """
3658
+ Send authentication challenge in Azure Functions mode
3659
+
3660
+ Returns:
3661
+ Azure Functions response with 401 status and WWW-Authenticate header
3662
+ """
3663
+ import azure.functions as func
3664
+ return func.HttpResponse(
3665
+ body=json.dumps({"error": "Unauthorized"}),
3666
+ status_code=401,
3667
+ headers={
3668
+ "WWW-Authenticate": "Basic realm=\"SignalWire Agent\"",
3669
+ "Content-Type": "application/json"
3670
+ }
3671
+ )
3672
+
3673
+ def _handle_google_cloud_function_request(self, request):
3674
+ """
3675
+ Handle Google Cloud Functions specific requests
3676
+
3677
+ Args:
3678
+ request: Flask request object from Google Cloud Functions
3679
+
3680
+ Returns:
3681
+ Flask response object
3682
+ """
3683
+ try:
3684
+ # Get the path from the request
3685
+ path = request.path.strip('/')
3686
+
3687
+ if not path:
3688
+ # Root request - return SWML
3689
+ swml_response = self._render_swml()
3690
+ from flask import Response
3691
+ return Response(
3692
+ response=swml_response,
3693
+ status=200,
3694
+ headers={"Content-Type": "application/json"}
3695
+ )
3696
+ else:
3697
+ # SWAIG function call
3698
+ args = {}
3699
+ call_id = None
3700
+ raw_data = None
3701
+
3702
+ # Parse request data
3703
+ if request.method == 'POST':
3704
+ try:
3705
+ if request.is_json:
3706
+ raw_data = request.get_json()
3707
+ else:
3708
+ raw_data = json.loads(request.get_data(as_text=True))
3709
+
3710
+ call_id = raw_data.get("call_id")
3711
+
3712
+ # Extract arguments like the FastAPI handler does
3713
+ if "argument" in raw_data and isinstance(raw_data["argument"], dict):
3714
+ if "parsed" in raw_data["argument"] and isinstance(raw_data["argument"]["parsed"], list) and raw_data["argument"]["parsed"]:
3715
+ args = raw_data["argument"]["parsed"][0]
3716
+ elif "raw" in raw_data["argument"]:
3717
+ try:
3718
+ args = json.loads(raw_data["argument"]["raw"])
3719
+ except Exception:
3720
+ pass
3721
+ except Exception:
3722
+ # If parsing fails, continue with empty args
3723
+ pass
3724
+
3725
+ result = self._execute_swaig_function(path, args, call_id, raw_data)
3726
+ from flask import Response
3727
+ return Response(
3728
+ response=json.dumps(result) if isinstance(result, dict) else str(result),
3729
+ status=200,
3730
+ headers={"Content-Type": "application/json"}
3731
+ )
3732
+
3733
+ except Exception as e:
3734
+ import logging
3735
+ logging.error(f"Error in Google Cloud Function request handler: {e}")
3736
+ from flask import Response
3737
+ return Response(
3738
+ response=json.dumps({"error": str(e)}),
3739
+ status=500,
3740
+ headers={"Content-Type": "application/json"}
3741
+ )
3742
+
3743
+ def _handle_azure_function_request(self, req):
3744
+ """
3745
+ Handle Azure Functions specific requests
3746
+
3747
+ Args:
3748
+ req: Azure Functions HttpRequest object
3749
+
3750
+ Returns:
3751
+ Azure Functions HttpResponse object
3752
+ """
3753
+ try:
3754
+ import azure.functions as func
3755
+
3756
+ # Get the path from the request
3757
+ path = req.url.split('/')[-1] if req.url else ''
3758
+
3759
+ if not path or path == 'api':
3760
+ # Root request - return SWML
3761
+ swml_response = self._render_swml()
3762
+ return func.HttpResponse(
3763
+ body=swml_response,
3764
+ status_code=200,
3765
+ headers={"Content-Type": "application/json"}
3766
+ )
3767
+ else:
3768
+ # SWAIG function call
3769
+ args = {}
3770
+ call_id = None
3771
+ raw_data = None
3772
+
3773
+ # Parse request data
3774
+ if req.method == 'POST':
3775
+ try:
3776
+ body = req.get_body()
3777
+ if body:
3778
+ raw_data = json.loads(body.decode('utf-8'))
3779
+ call_id = raw_data.get("call_id")
3780
+
3781
+ # Extract arguments like the FastAPI handler does
3782
+ if "argument" in raw_data and isinstance(raw_data["argument"], dict):
3783
+ if "parsed" in raw_data["argument"] and isinstance(raw_data["argument"]["parsed"], list) and raw_data["argument"]["parsed"]:
3784
+ args = raw_data["argument"]["parsed"][0]
3785
+ elif "raw" in raw_data["argument"]:
3786
+ try:
3787
+ args = json.loads(raw_data["argument"]["raw"])
3788
+ except Exception:
3789
+ pass
3790
+ except Exception:
3791
+ # If parsing fails, continue with empty args
3792
+ pass
3793
+
3794
+ result = self._execute_swaig_function(path, args, call_id, raw_data)
3795
+ return func.HttpResponse(
3796
+ body=json.dumps(result) if isinstance(result, dict) else str(result),
3797
+ status_code=200,
3798
+ headers={"Content-Type": "application/json"}
3799
+ )
3800
+
3801
+ except Exception as e:
3802
+ import logging
3803
+ logging.error(f"Error in Azure Function request handler: {e}")
3804
+ import azure.functions as func
3805
+ return func.HttpResponse(
3806
+ body=json.dumps({"error": str(e)}),
3807
+ status_code=500,
3808
+ headers={"Content-Type": "application/json"}
3809
+ )
@@ -127,19 +127,34 @@ class BoundStructuredLoggerWrapper(StructuredLoggerWrapper):
127
127
  return BoundStructuredLoggerWrapper(self._logger, new_bound_data)
128
128
 
129
129
 
130
- def get_execution_mode() -> str:
130
+ def get_execution_mode():
131
131
  """
132
132
  Determine the execution mode based on environment variables
133
133
 
134
134
  Returns:
135
- 'cgi' if running in CGI mode
136
- 'lambda' if running in AWS Lambda
137
- 'server' for normal server mode
135
+ str: 'server', 'cgi', 'lambda', 'google_cloud_function', 'azure_function', or 'unknown'
138
136
  """
137
+ # Check for CGI environment
139
138
  if os.getenv('GATEWAY_INTERFACE'):
140
139
  return 'cgi'
140
+
141
+ # Check for AWS Lambda environment
141
142
  if os.getenv('AWS_LAMBDA_FUNCTION_NAME') or os.getenv('LAMBDA_TASK_ROOT'):
142
143
  return 'lambda'
144
+
145
+ # Check for Google Cloud Functions environment
146
+ if (os.getenv('FUNCTION_TARGET') or
147
+ os.getenv('K_SERVICE') or
148
+ os.getenv('GOOGLE_CLOUD_PROJECT')):
149
+ return 'google_cloud_function'
150
+
151
+ # Check for Azure Functions environment
152
+ if (os.getenv('AZURE_FUNCTIONS_ENVIRONMENT') or
153
+ os.getenv('FUNCTIONS_WORKER_RUNTIME') or
154
+ os.getenv('AzureWebJobsStorage')):
155
+ return 'azure_function'
156
+
157
+ # Default to server mode
143
158
  return 'server'
144
159
 
145
160
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: signalwire_agents
3
- Version: 0.1.14
3
+ Version: 0.1.15
4
4
  Summary: SignalWire AI Agents SDK
5
5
  Author-email: SignalWire Team <info@signalwire.com>
6
6
  Project-URL: Homepage, https://github.com/signalwire/signalwire-ai-agents
@@ -1,15 +1,15 @@
1
- signalwire_agents/__init__.py,sha256=VdzDfggQq5yncBmgKKO7HsQH2nolhgdHMlLChwu5kyg,2707
1
+ signalwire_agents/__init__.py,sha256=6_WbU3T1cal1qceEcsgxzMtn_HhA98F2g1bl1waW0Uc,2707
2
2
  signalwire_agents/agent_server.py,sha256=3Or8rIMAqW750V-XitBUMgOpW9BAIXmKXoGq7LkejAA,24988
3
3
  signalwire_agents/schema.json,sha256=M8Mn6pQda2P9jhbmkALrLr1wt-fRuhYRqdmEi9Rbhqk,178075
4
4
  signalwire_agents/cli/__init__.py,sha256=Iy2BfWDWBEZoA1cyHTDsooBSVMx4vH5Ddhr3sEuFe8c,197
5
5
  signalwire_agents/cli/build_search.py,sha256=PnGoIZVfIbSF21rb0m0_ceIL-8lJx59_qXrrl8l2yBE,22340
6
6
  signalwire_agents/cli/test_swaig.py,sha256=CqfdBWE8_fiFnFWHbv9ouU1eUA_rGUUHwyOf_iUaZFU,101851
7
7
  signalwire_agents/core/__init__.py,sha256=mVDLbpq1pg_WwiqsQR28NNZwJ6-VUXFIfg-vN7pk0ew,806
8
- signalwire_agents/core/agent_base.py,sha256=F4ZxvFHK6FDs-jIaYSqua8QWvnoKA9wOeuomxnJO20g,140489
8
+ signalwire_agents/core/agent_base.py,sha256=0MA1i6honMKfyEIyCrVgS7WAR-iL3v3n8u0ZI8B-hHA,155944
9
9
  signalwire_agents/core/contexts.py,sha256=h7hra4xoiKAUdVyJhcKggl8X9EoqwTVWBmNMp-sEsuc,9598
10
10
  signalwire_agents/core/data_map.py,sha256=U-HLEZQomWf-UI0-nLAE8g1oyRdE5bU_WxQpboI2YI4,17695
11
11
  signalwire_agents/core/function_result.py,sha256=SP46vPAliEzwh3JeeSxmLD_f7_ixRxMBtpSl3t7jieU,45370
12
- signalwire_agents/core/logging_config.py,sha256=A4huPkWicnpd7g7M4XYYKMALQqLSrhtIu21811nLV5c,12622
12
+ signalwire_agents/core/logging_config.py,sha256=x4d_RAjBjVpJOFA2vXnPP2dNr13BZHz091J5rGpC77Y,13142
13
13
  signalwire_agents/core/pom_builder.py,sha256=ywuiIfP8BeLBPo_G4X1teZlG6zTCMkW71CZnmyoDTAQ,6636
14
14
  signalwire_agents/core/skill_base.py,sha256=lOpVTLhD9NjStF7Lxh6bAQUGa3DpNYV4agXJRakRuX0,4258
15
15
  signalwire_agents/core/skill_manager.py,sha256=XWq4MeDQ3kmM4Th8qI-Gx5klokDHNZ-K9cChJPW-zmQ,8113
@@ -58,10 +58,10 @@ signalwire_agents/utils/pom_utils.py,sha256=4Mr7baQ_xR_hfJ72YxQRAT_GFa663YjFX_Pu
58
58
  signalwire_agents/utils/schema_utils.py,sha256=i4okv_O9bUApwT_jJf4Yoij3bLCrGrW3DC-vzSy2RuY,16392
59
59
  signalwire_agents/utils/token_generators.py,sha256=4Mr7baQ_xR_hfJ72YxQRAT_GFa663YjFX_PumJ35Xds,191
60
60
  signalwire_agents/utils/validators.py,sha256=4Mr7baQ_xR_hfJ72YxQRAT_GFa663YjFX_PumJ35Xds,191
61
- signalwire_agents-0.1.14.data/data/schema.json,sha256=M8Mn6pQda2P9jhbmkALrLr1wt-fRuhYRqdmEi9Rbhqk,178075
62
- signalwire_agents-0.1.14.dist-info/licenses/LICENSE,sha256=NYvAsB-rTcSvG9cqHt9EUHAWLiA9YzM4Qfz-mPdvDR0,1067
63
- signalwire_agents-0.1.14.dist-info/METADATA,sha256=_VCXeDp5iMOLmkdHJlognjxF5rLQV_rzp8mhiJpbADM,34572
64
- signalwire_agents-0.1.14.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
65
- signalwire_agents-0.1.14.dist-info/entry_points.txt,sha256=LRwltbVfaKUFMYmQoMxJGTT_-iQm0ftzXK0xPfD64Is,138
66
- signalwire_agents-0.1.14.dist-info/top_level.txt,sha256=kDGS6ZYv84K9P5Kyg9_S8P_pbUXoHkso0On_DB5bbWc,18
67
- signalwire_agents-0.1.14.dist-info/RECORD,,
61
+ signalwire_agents-0.1.15.data/data/schema.json,sha256=M8Mn6pQda2P9jhbmkALrLr1wt-fRuhYRqdmEi9Rbhqk,178075
62
+ signalwire_agents-0.1.15.dist-info/licenses/LICENSE,sha256=NYvAsB-rTcSvG9cqHt9EUHAWLiA9YzM4Qfz-mPdvDR0,1067
63
+ signalwire_agents-0.1.15.dist-info/METADATA,sha256=-23e4f5amRjNXWeTVDrlXbGStr7kOhxuQjRsjL2wrF4,34572
64
+ signalwire_agents-0.1.15.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
65
+ signalwire_agents-0.1.15.dist-info/entry_points.txt,sha256=LRwltbVfaKUFMYmQoMxJGTT_-iQm0ftzXK0xPfD64Is,138
66
+ signalwire_agents-0.1.15.dist-info/top_level.txt,sha256=kDGS6ZYv84K9P5Kyg9_S8P_pbUXoHkso0On_DB5bbWc,18
67
+ signalwire_agents-0.1.15.dist-info/RECORD,,