signalwire-agents 0.1.6__py3-none-any.whl → 1.0.7__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.
Files changed (140) hide show
  1. signalwire_agents/__init__.py +130 -4
  2. signalwire_agents/agent_server.py +438 -32
  3. signalwire_agents/agents/bedrock.py +296 -0
  4. signalwire_agents/cli/__init__.py +18 -0
  5. signalwire_agents/cli/build_search.py +1367 -0
  6. signalwire_agents/cli/config.py +80 -0
  7. signalwire_agents/cli/core/__init__.py +10 -0
  8. signalwire_agents/cli/core/agent_loader.py +470 -0
  9. signalwire_agents/cli/core/argparse_helpers.py +179 -0
  10. signalwire_agents/cli/core/dynamic_config.py +71 -0
  11. signalwire_agents/cli/core/service_loader.py +303 -0
  12. signalwire_agents/cli/execution/__init__.py +10 -0
  13. signalwire_agents/cli/execution/datamap_exec.py +446 -0
  14. signalwire_agents/cli/execution/webhook_exec.py +134 -0
  15. signalwire_agents/cli/init_project.py +1225 -0
  16. signalwire_agents/cli/output/__init__.py +10 -0
  17. signalwire_agents/cli/output/output_formatter.py +255 -0
  18. signalwire_agents/cli/output/swml_dump.py +186 -0
  19. signalwire_agents/cli/simulation/__init__.py +10 -0
  20. signalwire_agents/cli/simulation/data_generation.py +374 -0
  21. signalwire_agents/cli/simulation/data_overrides.py +200 -0
  22. signalwire_agents/cli/simulation/mock_env.py +282 -0
  23. signalwire_agents/cli/swaig_test_wrapper.py +52 -0
  24. signalwire_agents/cli/test_swaig.py +809 -0
  25. signalwire_agents/cli/types.py +81 -0
  26. signalwire_agents/core/__init__.py +2 -2
  27. signalwire_agents/core/agent/__init__.py +12 -0
  28. signalwire_agents/core/agent/config/__init__.py +12 -0
  29. signalwire_agents/core/agent/deployment/__init__.py +9 -0
  30. signalwire_agents/core/agent/deployment/handlers/__init__.py +9 -0
  31. signalwire_agents/core/agent/prompt/__init__.py +14 -0
  32. signalwire_agents/core/agent/prompt/manager.py +306 -0
  33. signalwire_agents/core/agent/routing/__init__.py +9 -0
  34. signalwire_agents/core/agent/security/__init__.py +9 -0
  35. signalwire_agents/core/agent/swml/__init__.py +9 -0
  36. signalwire_agents/core/agent/tools/__init__.py +15 -0
  37. signalwire_agents/core/agent/tools/decorator.py +97 -0
  38. signalwire_agents/core/agent/tools/registry.py +210 -0
  39. signalwire_agents/core/agent_base.py +959 -2166
  40. signalwire_agents/core/auth_handler.py +233 -0
  41. signalwire_agents/core/config_loader.py +259 -0
  42. signalwire_agents/core/contexts.py +707 -0
  43. signalwire_agents/core/data_map.py +487 -0
  44. signalwire_agents/core/function_result.py +1150 -1
  45. signalwire_agents/core/logging_config.py +376 -0
  46. signalwire_agents/core/mixins/__init__.py +28 -0
  47. signalwire_agents/core/mixins/ai_config_mixin.py +442 -0
  48. signalwire_agents/core/mixins/auth_mixin.py +287 -0
  49. signalwire_agents/core/mixins/prompt_mixin.py +358 -0
  50. signalwire_agents/core/mixins/serverless_mixin.py +368 -0
  51. signalwire_agents/core/mixins/skill_mixin.py +55 -0
  52. signalwire_agents/core/mixins/state_mixin.py +153 -0
  53. signalwire_agents/core/mixins/tool_mixin.py +230 -0
  54. signalwire_agents/core/mixins/web_mixin.py +1134 -0
  55. signalwire_agents/core/security/session_manager.py +174 -86
  56. signalwire_agents/core/security_config.py +333 -0
  57. signalwire_agents/core/skill_base.py +200 -0
  58. signalwire_agents/core/skill_manager.py +244 -0
  59. signalwire_agents/core/swaig_function.py +33 -9
  60. signalwire_agents/core/swml_builder.py +212 -12
  61. signalwire_agents/core/swml_handler.py +43 -13
  62. signalwire_agents/core/swml_renderer.py +123 -297
  63. signalwire_agents/core/swml_service.py +277 -260
  64. signalwire_agents/prefabs/concierge.py +6 -2
  65. signalwire_agents/prefabs/info_gatherer.py +149 -33
  66. signalwire_agents/prefabs/receptionist.py +14 -22
  67. signalwire_agents/prefabs/survey.py +6 -2
  68. signalwire_agents/schema.json +9218 -5489
  69. signalwire_agents/search/__init__.py +137 -0
  70. signalwire_agents/search/document_processor.py +1223 -0
  71. signalwire_agents/search/index_builder.py +804 -0
  72. signalwire_agents/search/migration.py +418 -0
  73. signalwire_agents/search/models.py +30 -0
  74. signalwire_agents/search/pgvector_backend.py +752 -0
  75. signalwire_agents/search/query_processor.py +502 -0
  76. signalwire_agents/search/search_engine.py +1264 -0
  77. signalwire_agents/search/search_service.py +574 -0
  78. signalwire_agents/skills/README.md +452 -0
  79. signalwire_agents/skills/__init__.py +23 -0
  80. signalwire_agents/skills/api_ninjas_trivia/README.md +215 -0
  81. signalwire_agents/skills/api_ninjas_trivia/__init__.py +12 -0
  82. signalwire_agents/skills/api_ninjas_trivia/skill.py +237 -0
  83. signalwire_agents/skills/datasphere/README.md +210 -0
  84. signalwire_agents/skills/datasphere/__init__.py +12 -0
  85. signalwire_agents/skills/datasphere/skill.py +310 -0
  86. signalwire_agents/skills/datasphere_serverless/README.md +258 -0
  87. signalwire_agents/skills/datasphere_serverless/__init__.py +10 -0
  88. signalwire_agents/skills/datasphere_serverless/skill.py +237 -0
  89. signalwire_agents/skills/datetime/README.md +132 -0
  90. signalwire_agents/skills/datetime/__init__.py +10 -0
  91. signalwire_agents/skills/datetime/skill.py +126 -0
  92. signalwire_agents/skills/joke/README.md +149 -0
  93. signalwire_agents/skills/joke/__init__.py +10 -0
  94. signalwire_agents/skills/joke/skill.py +109 -0
  95. signalwire_agents/skills/math/README.md +161 -0
  96. signalwire_agents/skills/math/__init__.py +10 -0
  97. signalwire_agents/skills/math/skill.py +105 -0
  98. signalwire_agents/skills/mcp_gateway/README.md +230 -0
  99. signalwire_agents/skills/mcp_gateway/__init__.py +10 -0
  100. signalwire_agents/skills/mcp_gateway/skill.py +421 -0
  101. signalwire_agents/skills/native_vector_search/README.md +210 -0
  102. signalwire_agents/skills/native_vector_search/__init__.py +10 -0
  103. signalwire_agents/skills/native_vector_search/skill.py +820 -0
  104. signalwire_agents/skills/play_background_file/README.md +218 -0
  105. signalwire_agents/skills/play_background_file/__init__.py +12 -0
  106. signalwire_agents/skills/play_background_file/skill.py +242 -0
  107. signalwire_agents/skills/registry.py +459 -0
  108. signalwire_agents/skills/spider/README.md +236 -0
  109. signalwire_agents/skills/spider/__init__.py +13 -0
  110. signalwire_agents/skills/spider/skill.py +598 -0
  111. signalwire_agents/skills/swml_transfer/README.md +395 -0
  112. signalwire_agents/skills/swml_transfer/__init__.py +10 -0
  113. signalwire_agents/skills/swml_transfer/skill.py +359 -0
  114. signalwire_agents/skills/weather_api/README.md +178 -0
  115. signalwire_agents/skills/weather_api/__init__.py +12 -0
  116. signalwire_agents/skills/weather_api/skill.py +191 -0
  117. signalwire_agents/skills/web_search/README.md +163 -0
  118. signalwire_agents/skills/web_search/__init__.py +10 -0
  119. signalwire_agents/skills/web_search/skill.py +739 -0
  120. signalwire_agents/skills/wikipedia_search/README.md +228 -0
  121. signalwire_agents/{core/state → skills/wikipedia_search}/__init__.py +5 -4
  122. signalwire_agents/skills/wikipedia_search/skill.py +210 -0
  123. signalwire_agents/utils/__init__.py +14 -0
  124. signalwire_agents/utils/schema_utils.py +111 -44
  125. signalwire_agents/web/__init__.py +17 -0
  126. signalwire_agents/web/web_service.py +559 -0
  127. signalwire_agents-1.0.7.data/data/share/man/man1/sw-agent-init.1 +307 -0
  128. signalwire_agents-1.0.7.data/data/share/man/man1/sw-search.1 +483 -0
  129. signalwire_agents-1.0.7.data/data/share/man/man1/swaig-test.1 +308 -0
  130. signalwire_agents-1.0.7.dist-info/METADATA +992 -0
  131. signalwire_agents-1.0.7.dist-info/RECORD +142 -0
  132. {signalwire_agents-0.1.6.dist-info → signalwire_agents-1.0.7.dist-info}/WHEEL +1 -1
  133. signalwire_agents-1.0.7.dist-info/entry_points.txt +4 -0
  134. signalwire_agents/core/state/file_state_manager.py +0 -219
  135. signalwire_agents/core/state/state_manager.py +0 -101
  136. signalwire_agents-0.1.6.data/data/schema.json +0 -5611
  137. signalwire_agents-0.1.6.dist-info/METADATA +0 -199
  138. signalwire_agents-0.1.6.dist-info/RECORD +0 -34
  139. {signalwire_agents-0.1.6.dist-info → signalwire_agents-1.0.7.dist-info}/licenses/LICENSE +0 -0
  140. {signalwire_agents-0.1.6.dist-info → signalwire_agents-1.0.7.dist-info}/top_level.txt +0 -0
@@ -1,3 +1,4 @@
1
+ #!/usr/bin/env python3
1
2
  """
2
3
  Copyright (c) 2025 SignalWire
3
4
 
@@ -7,62 +8,129 @@ Licensed under the MIT License.
7
8
  See LICENSE file in the project root for full license information.
8
9
  """
9
10
 
11
+ # -*- coding: utf-8 -*-
10
12
  """
11
- Utilities for working with the SWML JSON schema.
12
-
13
- This module provides functions for loading, parsing, and validating SWML schemas.
14
- It also provides utilities for working with SWML documents based on the schema.
13
+ Schema utilities for SWML validation and verb extraction
15
14
  """
16
15
 
17
- import json
18
16
  import os
19
- import re
20
- from typing import Dict, List, Any, Optional, Set, Tuple, Callable
17
+ import json
18
+ import logging
19
+ from typing import Dict, Any, List, Optional, Tuple
21
20
 
21
+ try:
22
+ import structlog
23
+ # Ensure structlog is configured
24
+ if not structlog.is_configured():
25
+ structlog.configure(
26
+ processors=[
27
+ structlog.stdlib.filter_by_level,
28
+ structlog.stdlib.add_logger_name,
29
+ structlog.stdlib.add_log_level,
30
+ structlog.stdlib.PositionalArgumentsFormatter(),
31
+ structlog.processors.TimeStamper(fmt="%Y-%m-%d %H:%M:%S"),
32
+ structlog.processors.StackInfoRenderer(),
33
+ structlog.processors.format_exc_info,
34
+ structlog.processors.UnicodeDecoder(),
35
+ structlog.dev.ConsoleRenderer()
36
+ ],
37
+ context_class=dict,
38
+ logger_factory=structlog.stdlib.LoggerFactory(),
39
+ wrapper_class=structlog.stdlib.BoundLogger,
40
+ cache_logger_on_first_use=True,
41
+ )
42
+ except ImportError:
43
+ raise ImportError(
44
+ "structlog is required. Install it with: pip install structlog"
45
+ )
46
+
47
+ # Create a logger
48
+ logger = structlog.get_logger("schema_utils")
22
49
 
23
50
  class SchemaUtils:
24
51
  """
25
- Utilities for working with SWML JSON schema.
26
-
27
- This class provides methods for:
28
- - Loading and parsing schema files
29
- - Extracting verb definitions
30
- - Validating SWML objects against the schema
31
- - Generating helpers for schema operations
52
+ Utility class for loading and working with SWML schemas
32
53
  """
33
54
 
34
55
  def __init__(self, schema_path: Optional[str] = None):
35
56
  """
36
- Initialize the SchemaUtils with the provided schema
57
+ Initialize the schema utilities
37
58
 
38
59
  Args:
39
- schema_path: Path to the schema file (optional)
60
+ schema_path: Path to the schema file
40
61
  """
62
+ self.log = logger.bind(component="schema_utils")
63
+
41
64
  self.schema_path = schema_path
42
65
  if not self.schema_path:
43
66
  self.schema_path = self._get_default_schema_path()
44
- print(f"No schema_path provided, using default: {self.schema_path}")
67
+ self.log.debug("using_default_schema_path", path=self.schema_path)
45
68
 
46
69
  self.schema = self.load_schema()
47
70
  self.verbs = self._extract_verb_definitions()
48
- print(f"Extracted {len(self.verbs)} verbs from schema")
71
+ self.log.debug("schema_initialized", verb_count=len(self.verbs))
49
72
  if self.verbs:
50
- print(f"First few verbs: {list(self.verbs.keys())[:5]}")
73
+ self.log.debug("first_verbs_extracted", verbs=list(self.verbs.keys())[:5])
51
74
 
52
- def _get_default_schema_path(self) -> str:
75
+ def _get_default_schema_path(self) -> Optional[str]:
53
76
  """
54
- Get the default path to the schema file
77
+ Get the default path to the schema file using the same robust logic as SWMLService
55
78
 
56
79
  Returns:
57
- Path to the schema file
80
+ Path to the schema file or None if not found
58
81
  """
59
- # Default path is the schema.json in the root directory
60
- package_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
61
- default_path = os.path.join(package_dir, "schema.json")
62
- print(f"Default schema path: {default_path}")
63
- print(f"Path exists: {os.path.exists(default_path)}")
64
-
65
- return default_path
82
+ # Try package resources first (most reliable after pip install)
83
+ try:
84
+ import importlib.resources
85
+ try:
86
+ # Python 3.9+
87
+ try:
88
+ # Python 3.13+
89
+ path = importlib.resources.files("signalwire_agents").joinpath("schema.json")
90
+ return str(path)
91
+ except Exception:
92
+ # Python 3.9-3.12
93
+ with importlib.resources.files("signalwire_agents").joinpath("schema.json") as path:
94
+ return str(path)
95
+ except AttributeError:
96
+ # Python 3.7-3.8
97
+ with importlib.resources.path("signalwire_agents", "schema.json") as path:
98
+ return str(path)
99
+ except (ImportError, ModuleNotFoundError):
100
+ pass
101
+
102
+ # Fall back to pkg_resources for older Python or alternative lookup
103
+ try:
104
+ import pkg_resources
105
+ return pkg_resources.resource_filename("signalwire_agents", "schema.json")
106
+ except (ImportError, ModuleNotFoundError, pkg_resources.DistributionNotFound):
107
+ pass
108
+
109
+ # Fall back to manual search in various locations
110
+ import sys
111
+
112
+ # Get package directory relative to this file
113
+ package_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
114
+
115
+ # Potential locations for schema.json
116
+ potential_paths = [
117
+ os.path.join(os.getcwd(), "schema.json"), # Current working directory
118
+ os.path.join(package_dir, "schema.json"), # Package directory
119
+ os.path.join(os.path.dirname(package_dir), "schema.json"), # Parent of package directory
120
+ os.path.join(sys.prefix, "schema.json"), # Python installation directory
121
+ os.path.join(package_dir, "data", "schema.json"), # Data subdirectory
122
+ os.path.join(os.path.dirname(package_dir), "data", "schema.json"), # Parent's data subdirectory
123
+ ]
124
+
125
+ # Try to find the schema file
126
+ for path in potential_paths:
127
+ self.log.debug("checking_schema_path", path=path, exists=os.path.exists(path))
128
+ if os.path.exists(path):
129
+ self.log.debug("schema_found_at", path=path)
130
+ return path
131
+
132
+ self.log.warning("schema_not_found_in_any_location")
133
+ return None
66
134
 
67
135
  def load_schema(self) -> Dict[str, Any]:
68
136
  """
@@ -72,27 +140,26 @@ class SchemaUtils:
72
140
  The schema as a dictionary
73
141
  """
74
142
  if not self.schema_path:
75
- print(f"Warning: No schema path provided. Using empty schema.")
143
+ self.log.warning("no_schema_path_provided")
76
144
  return {}
77
145
 
78
146
  try:
79
- print(f"Attempting to load schema from: {self.schema_path}")
80
- print(f"File exists: {os.path.exists(self.schema_path)}")
147
+ self.log.debug("loading_schema", path=self.schema_path, exists=os.path.exists(self.schema_path))
81
148
 
82
149
  if os.path.exists(self.schema_path):
83
150
  with open(self.schema_path, "r") as f:
84
151
  schema = json.load(f)
85
- print(f"Successfully loaded schema from {self.schema_path}")
86
- print(f"Schema has {len(schema.keys()) if schema else 0} top-level keys")
152
+ self.log.debug("schema_loaded_successfully",
153
+ path=self.schema_path,
154
+ top_level_keys=len(schema.keys()) if schema else 0)
87
155
  if "$defs" in schema:
88
- print(f"Schema has {len(schema['$defs'])} definitions")
156
+ self.log.debug("schema_definitions_found", count=len(schema['$defs']))
89
157
  return schema
90
158
  else:
91
- print(f"Schema file not found at {self.schema_path}")
159
+ self.log.error("schema_file_not_found", path=self.schema_path)
92
160
  return {}
93
161
  except (FileNotFoundError, json.JSONDecodeError) as e:
94
- print(f"Error loading schema: {e}")
95
- print(f"Using empty schema as fallback")
162
+ self.log.error("schema_loading_error", error=str(e), path=self.schema_path)
96
163
  return {}
97
164
 
98
165
  def _extract_verb_definitions(self) -> Dict[str, Dict[str, Any]]:
@@ -107,17 +174,17 @@ class SchemaUtils:
107
174
  # Extract from SWMLMethod anyOf
108
175
  if "$defs" in self.schema and "SWMLMethod" in self.schema["$defs"]:
109
176
  swml_method = self.schema["$defs"]["SWMLMethod"]
110
- print(f"Found SWMLMethod in schema with keys: {swml_method.keys()}")
177
+ self.log.debug("swml_method_found", keys=list(swml_method.keys()))
111
178
 
112
179
  if "anyOf" in swml_method:
113
- print(f"Found anyOf in SWMLMethod with {len(swml_method['anyOf'])} items")
180
+ self.log.debug("anyof_found", count=len(swml_method['anyOf']))
114
181
 
115
182
  for ref in swml_method["anyOf"]:
116
183
  if "$ref" in ref:
117
184
  # Extract the verb name from the reference
118
185
  verb_ref = ref["$ref"]
119
186
  verb_name = verb_ref.split("/")[-1]
120
- print(f"Processing verb reference: {verb_ref} -> {verb_name}")
187
+ self.log.debug("processing_verb_reference", ref=verb_ref, name=verb_name)
121
188
 
122
189
  # Look up the verb definition
123
190
  if verb_name in self.schema["$defs"]:
@@ -133,11 +200,11 @@ class SchemaUtils:
133
200
  "schema_name": verb_name,
134
201
  "definition": verb_def
135
202
  }
136
- print(f"Added verb: {actual_verb}")
203
+ self.log.debug("verb_added", verb=actual_verb)
137
204
  else:
138
- print(f"Missing $defs or SWMLMethod in schema")
205
+ self.log.warning("missing_swml_method_or_defs")
139
206
  if "$defs" in self.schema:
140
- print(f"Available definitions: {list(self.schema['$defs'].keys())}")
207
+ self.log.debug("available_definitions", defs=list(self.schema['$defs'].keys()))
141
208
 
142
209
  return verbs
143
210
 
@@ -0,0 +1,17 @@
1
+ """
2
+ Copyright (c) 2025 SignalWire
3
+
4
+ This file is part of the SignalWire AI Agents SDK.
5
+
6
+ Licensed under the MIT License.
7
+ See LICENSE file in the project root for full license information.
8
+ """
9
+
10
+ """SignalWire Agents Web Service Module
11
+
12
+ This module provides static file serving capabilities for the SignalWire Agents SDK.
13
+ """
14
+
15
+ from .web_service import WebService
16
+
17
+ __all__ = ['WebService']