signalwire-agents 1.0.7__py3-none-any.whl → 1.0.17.dev4__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 (24) hide show
  1. signalwire_agents/__init__.py +1 -1
  2. signalwire_agents/agent_server.py +103 -68
  3. signalwire_agents/cli/dokku.py +2320 -0
  4. signalwire_agents/cli/init_project.py +1503 -92
  5. signalwire_agents/core/agent_base.py +25 -5
  6. signalwire_agents/core/mixins/auth_mixin.py +6 -13
  7. signalwire_agents/core/mixins/serverless_mixin.py +204 -112
  8. signalwire_agents/core/mixins/web_mixin.py +14 -6
  9. signalwire_agents/core/swml_service.py +4 -3
  10. signalwire_agents/mcp_gateway/__init__.py +29 -0
  11. signalwire_agents/mcp_gateway/gateway_service.py +564 -0
  12. signalwire_agents/mcp_gateway/mcp_manager.py +513 -0
  13. signalwire_agents/mcp_gateway/session_manager.py +218 -0
  14. signalwire_agents/search/pgvector_backend.py +10 -14
  15. signalwire_agents/skills/__init__.py +4 -1
  16. {signalwire_agents-1.0.7.data → signalwire_agents-1.0.17.dev4.data}/data/share/man/man1/sw-agent-init.1 +107 -14
  17. {signalwire_agents-1.0.7.dist-info → signalwire_agents-1.0.17.dev4.dist-info}/METADATA +4 -1
  18. {signalwire_agents-1.0.7.dist-info → signalwire_agents-1.0.17.dev4.dist-info}/RECORD +24 -19
  19. {signalwire_agents-1.0.7.dist-info → signalwire_agents-1.0.17.dev4.dist-info}/entry_points.txt +2 -0
  20. {signalwire_agents-1.0.7.data → signalwire_agents-1.0.17.dev4.data}/data/share/man/man1/sw-search.1 +0 -0
  21. {signalwire_agents-1.0.7.data → signalwire_agents-1.0.17.dev4.data}/data/share/man/man1/swaig-test.1 +0 -0
  22. {signalwire_agents-1.0.7.dist-info → signalwire_agents-1.0.17.dev4.dist-info}/WHEEL +0 -0
  23. {signalwire_agents-1.0.7.dist-info → signalwire_agents-1.0.17.dev4.dist-info}/licenses/LICENSE +0 -0
  24. {signalwire_agents-1.0.7.dist-info → signalwire_agents-1.0.17.dev4.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,218 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Copyright (c) 2025 SignalWire
4
+
5
+ This file is part of the SignalWire AI Agents SDK.
6
+
7
+ Licensed under the MIT License.
8
+ See LICENSE file in the project root for full license information.
9
+ """
10
+
11
+ """
12
+ Session Manager for MCP Gateway
13
+
14
+ Manages lifecycle of MCP server sessions tied to SignalWire call IDs.
15
+ Handles timeouts, cleanup, and resource limits.
16
+ """
17
+
18
+ import threading
19
+ import time
20
+ import logging
21
+ from typing import Dict, Optional, Any
22
+ from datetime import datetime, timedelta
23
+ from dataclasses import dataclass, field
24
+
25
+ logger = logging.getLogger(__name__)
26
+
27
+
28
+ @dataclass
29
+ class Session:
30
+ """Represents an active MCP session"""
31
+ session_id: str
32
+ service_name: str
33
+ process: Any # MCPClient instance
34
+ created_at: datetime = field(default_factory=datetime.now)
35
+ last_accessed: datetime = field(default_factory=datetime.now)
36
+ timeout: int = 300 # seconds
37
+ metadata: Dict[str, Any] = field(default_factory=dict)
38
+
39
+ @property
40
+ def is_expired(self) -> bool:
41
+ """Check if session has expired based on timeout"""
42
+ return datetime.now() > self.last_accessed + timedelta(seconds=self.timeout)
43
+
44
+ @property
45
+ def is_alive(self) -> bool:
46
+ """Check if the underlying MCP client is still running"""
47
+ return self.process and self.process.process and self.process.process.poll() is None
48
+
49
+ def touch(self):
50
+ """Update last accessed time"""
51
+ self.last_accessed = datetime.now()
52
+
53
+
54
+ class SessionManager:
55
+ """Manages MCP server sessions with automatic cleanup"""
56
+
57
+ def __init__(self, config: Dict[str, Any]):
58
+ self.config = config
59
+ self.sessions: Dict[str, Session] = {}
60
+ self.lock = threading.RLock()
61
+ self.cleanup_interval = config.get('session', {}).get('cleanup_interval', 60)
62
+ self.max_sessions_per_service = config.get('session', {}).get('max_sessions_per_service', 100)
63
+ self.default_timeout = config.get('session', {}).get('default_timeout', 300)
64
+ self._shutdown = threading.Event()
65
+
66
+ # Start cleanup thread
67
+ self.cleanup_thread = threading.Thread(target=self._cleanup_loop, daemon=True)
68
+ self.cleanup_thread.start()
69
+
70
+ logger.info(f"SessionManager initialized with cleanup_interval={self.cleanup_interval}s")
71
+
72
+ def create_session(self, session_id: str, service_name: str, process: Any,
73
+ timeout: Optional[int] = None, metadata: Optional[Dict[str, Any]] = None) -> Session:
74
+ """Create and register a new session"""
75
+ with self.lock:
76
+ # Check if session already exists
77
+ if session_id in self.sessions:
78
+ logger.warning(f"Session {session_id} already exists, closing old session")
79
+ self.close_session(session_id)
80
+
81
+ # Check service limits
82
+ service_count = sum(1 for s in self.sessions.values() if s.service_name == service_name)
83
+ if service_count >= self.max_sessions_per_service:
84
+ raise RuntimeError(f"Max sessions limit reached for service {service_name}")
85
+
86
+ # Create new session
87
+ session = Session(
88
+ session_id=session_id,
89
+ service_name=service_name,
90
+ process=process,
91
+ timeout=timeout or self.default_timeout,
92
+ metadata=metadata or {}
93
+ )
94
+
95
+ self.sessions[session_id] = session
96
+ logger.info(f"Created session {session_id} for service {service_name}")
97
+
98
+ return session
99
+
100
+ def get_session(self, session_id: str) -> Optional[Session]:
101
+ """Get an active session by ID"""
102
+ with self.lock:
103
+ session = self.sessions.get(session_id)
104
+
105
+ if session:
106
+ if not session.is_alive:
107
+ logger.warning(f"Session {session_id} process is dead, removing")
108
+ self.close_session(session_id)
109
+ return None
110
+
111
+ if session.is_expired:
112
+ logger.info(f"Session {session_id} has expired, removing")
113
+ self.close_session(session_id)
114
+ return None
115
+
116
+ # Update last accessed time
117
+ session.touch()
118
+
119
+ return session
120
+
121
+ def close_session(self, session_id: str) -> bool:
122
+ """Close and remove a session"""
123
+ with self.lock:
124
+ session = self.sessions.pop(session_id, None)
125
+
126
+ if not session:
127
+ logger.warning(f"Attempted to close non-existent session {session_id}")
128
+ return False
129
+
130
+ # Terminate the MCP client
131
+ if session.process:
132
+ try:
133
+ # Stop the MCP client
134
+ session.process.stop()
135
+ except Exception as e:
136
+ logger.error(f"Error stopping MCP client for session {session_id}: {e}")
137
+
138
+ logger.info(f"Closed session {session_id}")
139
+ return True
140
+
141
+ def list_sessions(self) -> Dict[str, Dict[str, Any]]:
142
+ """List all active sessions with their info"""
143
+ with self.lock:
144
+ result = {}
145
+
146
+ for session_id, session in list(self.sessions.items()):
147
+ # Check if still valid
148
+ if not session.is_alive or session.is_expired:
149
+ self.close_session(session_id)
150
+ continue
151
+
152
+ result[session_id] = {
153
+ 'service_name': session.service_name,
154
+ 'created_at': session.created_at.isoformat(),
155
+ 'last_accessed': session.last_accessed.isoformat(),
156
+ 'timeout': session.timeout,
157
+ 'metadata': session.metadata,
158
+ 'time_remaining': max(0, (session.last_accessed + timedelta(seconds=session.timeout) - datetime.now()).total_seconds())
159
+ }
160
+
161
+ return result
162
+
163
+ def get_service_session_count(self, service_name: str) -> int:
164
+ """Get number of active sessions for a service"""
165
+ with self.lock:
166
+ return sum(1 for s in self.sessions.values()
167
+ if s.service_name == service_name and s.is_alive and not s.is_expired)
168
+
169
+ def _cleanup_loop(self):
170
+ """Background thread that cleans up expired sessions"""
171
+ logger.info("Session cleanup thread started")
172
+
173
+ while not self._shutdown.is_set():
174
+ try:
175
+ # Wait with timeout so we can check shutdown flag
176
+ if self._shutdown.wait(timeout=self.cleanup_interval):
177
+ break
178
+
179
+ with self.lock:
180
+ expired_sessions = []
181
+
182
+ for session_id, session in self.sessions.items():
183
+ if session.is_expired or not session.is_alive:
184
+ expired_sessions.append(session_id)
185
+
186
+ for session_id in expired_sessions:
187
+ logger.info(f"Cleaning up expired session {session_id}")
188
+ self.close_session(session_id)
189
+
190
+ if expired_sessions:
191
+ logger.info(f"Cleaned up {len(expired_sessions)} expired sessions")
192
+
193
+ except Exception as e:
194
+ logger.error(f"Error in cleanup thread: {e}")
195
+
196
+ logger.info("Session cleanup thread stopped")
197
+
198
+ def shutdown(self):
199
+ """Shutdown all sessions and cleanup"""
200
+ logger.info("Shutting down SessionManager")
201
+
202
+ # Signal cleanup thread to stop
203
+ self._shutdown.set()
204
+
205
+ with self.lock:
206
+ # Close all sessions
207
+ session_ids = list(self.sessions.keys())
208
+ logger.info(f"Closing {len(session_ids)} active sessions")
209
+ for session_id in session_ids:
210
+ self.close_session(session_id)
211
+
212
+ # Wait for cleanup thread to finish (with timeout)
213
+ if self.cleanup_thread.is_alive():
214
+ self.cleanup_thread.join(timeout=2.0)
215
+ if self.cleanup_thread.is_alive():
216
+ logger.warning("Cleanup thread did not stop gracefully")
217
+
218
+ logger.info("SessionManager shutdown complete")
@@ -441,37 +441,33 @@ class PgVectorSearchBackend:
441
441
  List of search results with scores and metadata
442
442
  """
443
443
  self._ensure_connection()
444
-
444
+
445
445
  # Extract query terms for metadata search
446
446
  query_terms = enhanced_text.lower().split()
447
-
447
+
448
448
  # Vector search
449
449
  vector_results = self._vector_search(query_vector, count * 2, tags)
450
450
 
451
+ # Apply similarity threshold to raw vector scores BEFORE weighting
452
+ # This ensures threshold behaves intuitively (filters on actual similarity, not weighted score)
453
+ if similarity_threshold > 0:
454
+ vector_results = [r for r in vector_results if r['score'] >= similarity_threshold]
455
+
451
456
  # Keyword search
452
457
  keyword_results = self._keyword_search(enhanced_text, count * 2, tags)
453
458
 
454
459
  # Metadata search
455
460
  metadata_results = self._metadata_search(query_terms, count * 2, tags)
456
461
 
457
-
458
- # Merge all results
462
+ # Merge all results (threshold already applied to vector results)
459
463
  merged_results = self._merge_all_results(vector_results, keyword_results, metadata_results, keyword_weight)
460
464
 
461
-
462
- # Filter by distance threshold
463
- filtered_results = [
464
- r for r in merged_results
465
- if r['score'] >= similarity_threshold
466
- ]
467
-
468
-
469
465
  # Ensure 'score' field exists for CLI compatibility
470
- for r in filtered_results:
466
+ for r in merged_results:
471
467
  if 'score' not in r:
472
468
  r['score'] = r.get('final_score', 0.0)
473
469
 
474
- return filtered_results[:count]
470
+ return merged_results[:count]
475
471
 
476
472
  def _vector_search(self, query_vector: List[float], count: int,
477
473
  tags: Optional[List[str]] = None) -> List[Dict[str, Any]]:
@@ -17,7 +17,10 @@ Skills are automatically discovered from subdirectories.
17
17
  # Import the registry to make it available
18
18
  from .registry import skill_registry
19
19
 
20
+ # Import SkillBase for convenience
21
+ from signalwire_agents.core.skill_base import SkillBase
22
+
20
23
  # Trigger skill discovery on import
21
24
  # skill_registry.discover_skills()
22
25
 
23
- __all__ = ["skill_registry"]
26
+ __all__ = ["skill_registry", "SkillBase"]
@@ -1,7 +1,7 @@
1
1
  .\" Man page for sw-agent-init
2
2
  .\" Copyright (c) 2025 SignalWire
3
3
  .\" Licensed under the MIT License
4
- .TH SW-AGENT-INIT 1 "November 2025" "SignalWire Agents SDK 1.0.6" "SignalWire Commands"
4
+ .TH SW-AGENT-INIT 1 "November 2025" "SignalWire Agents SDK 1.0.8" "SignalWire Commands"
5
5
  .SH NAME
6
6
  sw-agent-init \- create a new SignalWire AI agent project
7
7
  .SH SYNOPSIS
@@ -14,14 +14,14 @@ sw-agent-init \- create a new SignalWire AI agent project
14
14
  .SH DESCRIPTION
15
15
  .B sw-agent-init
16
16
  is an interactive command-line tool for creating new SignalWire AI agent
17
- projects. It generates a complete project structure with all the necessary
18
- files to get started building voice AI agents.
17
+ projects. It supports both local agent projects (FastAPI/uvicorn) and
18
+ cloud function deployments (AWS Lambda, Google Cloud Functions, Azure Functions).
19
19
  .PP
20
20
  When run without arguments, the tool enters interactive mode and prompts
21
- for project configuration. When given a project name, it runs in quick
22
- mode with sensible defaults.
21
+ for project configuration including platform selection. When given a project
22
+ name, it runs in quick mode with sensible defaults (local platform by default).
23
23
  .PP
24
- The generated project includes:
24
+ For local projects, the generated project includes:
25
25
  .IP \(bu 2
26
26
  Agent module with sample SWAIG function
27
27
  .IP \(bu 2
@@ -46,8 +46,36 @@ interactive mode and prompts for a name.
46
46
  .BR \-h ", " \-\-help
47
47
  Display help message and exit.
48
48
  .TP
49
+ .BI \-p ", " \-\-platform " PLATFORM"
50
+ Target deployment platform. Valid values:
51
+ .RS
52
+ .IP \(bu 2
53
+ .B local
54
+ \- Local agent with FastAPI/uvicorn server (default)
55
+ .IP \(bu 2
56
+ .B aws
57
+ \- AWS Lambda function with API Gateway
58
+ .IP \(bu 2
59
+ .B gcp
60
+ \- Google Cloud Function (Gen 2)
61
+ .IP \(bu 2
62
+ .B azure
63
+ \- Azure Function
64
+ .RE
65
+ .TP
66
+ .BI \-r ", " \-\-region " REGION"
67
+ Cloud region for deployment (only for cloud platforms). Default regions:
68
+ .RS
69
+ .IP \(bu 2
70
+ AWS: us-east-1
71
+ .IP \(bu 2
72
+ GCP: us-central1
73
+ .IP \(bu 2
74
+ Azure: eastus
75
+ .RE
76
+ .TP
49
77
  .BI \-\-type " TYPE"
50
- Agent type to create. Valid values:
78
+ Agent type to create (only for local platform). Valid values:
51
79
  .RS
52
80
  .IP \(bu 2
53
81
  .B basic
@@ -58,8 +86,8 @@ Agent type to create. Valid values:
58
86
  .RE
59
87
  .TP
60
88
  .B \-\-no\-venv
61
- Skip virtual environment creation. By default, a Python virtual
62
- environment is created in the project directory.
89
+ Skip virtual environment creation (only for local platform). By default,
90
+ a Python virtual environment is created in the project directory.
63
91
  .TP
64
92
  .BI \-\-dir " DIRECTORY"
65
93
  Parent directory for the project. The project will be created as
@@ -68,14 +96,20 @@ a subdirectory. Default is the current directory.
68
96
  When run without a project name, the tool prompts for:
69
97
  .SS Project Configuration
70
98
  .IP \(bu 2
99
+ .B Target platform
100
+ \- Local, AWS Lambda, GCP, or Azure
101
+ .IP \(bu 2
71
102
  .B Project name
72
103
  \- Name of the project directory
73
104
  .IP \(bu 2
74
105
  .B Project directory
75
106
  \- Where to create the project
76
107
  .IP \(bu 2
108
+ .B Region
109
+ \- Cloud region (for cloud platforms only)
110
+ .IP \(bu 2
77
111
  .B Agent type
78
- \- Basic or full setup
112
+ \- Basic or full setup (for local platform only)
79
113
  .SS Feature Selection
80
114
  The following features can be enabled or disabled:
81
115
  .IP \(bu 2
@@ -189,8 +223,8 @@ Run without arguments for guided setup:
189
223
  sw-agent-init
190
224
  .fi
191
225
  .RE
192
- .SS Quick Mode
193
- Create a basic agent project:
226
+ .SS Quick Mode - Local
227
+ Create a basic local agent project:
194
228
  .PP
195
229
  .RS
196
230
  .nf
@@ -198,7 +232,7 @@ sw-agent-init myagent
198
232
  .fi
199
233
  .RE
200
234
  .PP
201
- Create a full-featured project:
235
+ Create a full-featured local project:
202
236
  .PP
203
237
  .RS
204
238
  .nf
@@ -221,7 +255,39 @@ Create in a specific directory:
221
255
  sw-agent-init myagent --dir /opt/projects
222
256
  .fi
223
257
  .RE
224
- .SS After Creation
258
+ .SS Quick Mode - Cloud Functions
259
+ Create an AWS Lambda project:
260
+ .PP
261
+ .RS
262
+ .nf
263
+ sw-agent-init myagent -p aws
264
+ .fi
265
+ .RE
266
+ .PP
267
+ Create an AWS Lambda project in a specific region:
268
+ .PP
269
+ .RS
270
+ .nf
271
+ sw-agent-init myagent -p aws -r us-west-2
272
+ .fi
273
+ .RE
274
+ .PP
275
+ Create a Google Cloud Function project:
276
+ .PP
277
+ .RS
278
+ .nf
279
+ sw-agent-init myagent -p gcp
280
+ .fi
281
+ .RE
282
+ .PP
283
+ Create an Azure Function project:
284
+ .PP
285
+ .RS
286
+ .nf
287
+ sw-agent-init myagent -p azure
288
+ .fi
289
+ .RE
290
+ .SS After Creation - Local
225
291
  Start the agent:
226
292
  .PP
227
293
  .RS
@@ -251,6 +317,33 @@ swaig-test agents/main_agent.py --exec get_info --topic "test"
251
317
  swaig-test agents/main_agent.py --dump-swml
252
318
  .fi
253
319
  .RE
320
+ .SS After Creation - Cloud Functions
321
+ Deploy to AWS Lambda:
322
+ .PP
323
+ .RS
324
+ .nf
325
+ cd myagent
326
+ ./deploy.sh
327
+ .fi
328
+ .RE
329
+ .PP
330
+ Deploy to Google Cloud:
331
+ .PP
332
+ .RS
333
+ .nf
334
+ cd myagent
335
+ ./deploy.sh
336
+ .fi
337
+ .RE
338
+ .PP
339
+ Deploy to Azure:
340
+ .PP
341
+ .RS
342
+ .nf
343
+ cd myagent
344
+ ./deploy.sh
345
+ .fi
346
+ .RE
254
347
  .SH AGENT TYPES
255
348
  .SS Basic Agent
256
349
  The basic agent type includes:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: signalwire_agents
3
- Version: 1.0.7
3
+ Version: 1.0.17.dev4
4
4
  Summary: SignalWire AI Agents SDK
5
5
  Author-email: SignalWire Team <info@signalwire.com>
6
6
  License: MIT
@@ -75,6 +75,9 @@ Requires-Dist: pgvector>=0.2.0; extra == "search-all"
75
75
  Provides-Extra: pgvector
76
76
  Requires-Dist: psycopg2-binary>=2.9.0; extra == "pgvector"
77
77
  Requires-Dist: pgvector>=0.2.0; extra == "pgvector"
78
+ Provides-Extra: mcp-gateway
79
+ Requires-Dist: flask>=2.0.0; extra == "mcp-gateway"
80
+ Requires-Dist: flask-limiter>=3.5.0; extra == "mcp-gateway"
78
81
  Provides-Extra: all
79
82
  Requires-Dist: sentence-transformers>=2.2.0; extra == "all"
80
83
  Requires-Dist: scikit-learn>=1.3.0; extra == "all"
@@ -1,11 +1,12 @@
1
- signalwire_agents/__init__.py,sha256=sN_xHIXM-HsCXjYqOjjhGJE0gRq52fXESYWP9mY38lA,5030
2
- signalwire_agents/agent_server.py,sha256=5GPt6XekVxep9esZY9s4MG6sOR-VF_m53U25r3WoML4,30964
1
+ signalwire_agents/__init__.py,sha256=DYvpwmWb5SgEYdvPhRykJUF0J_AJQUOS7ExFWD0nfrg,5036
2
+ signalwire_agents/agent_server.py,sha256=2zJFNOOEpEOXn5J5Diz1NpL1JFEUA2_6qbV0PPK_Vhc,32352
3
3
  signalwire_agents/schema.json,sha256=YQv4-KiegE00XvxoLMKAml6aCGitnt3kBq31ECxTHK8,385886
4
4
  signalwire_agents/agents/bedrock.py,sha256=J582gooNtxtep4xdVOfyDzRtHp_XrurPMS93xf2Xod0,10836
5
5
  signalwire_agents/cli/__init__.py,sha256=XbxAQFaCIdGXIXJiriVBWoFPOJsC401u21588nO4TG8,388
6
6
  signalwire_agents/cli/build_search.py,sha256=wDuonVY9fcqspThRHmbArTuZLKsiStu-ozVExtqawA8,54937
7
7
  signalwire_agents/cli/config.py,sha256=2i4e0BArdKsaXxjeueYYRNke7GWicHPYC2wuitVrP7A,2541
8
- signalwire_agents/cli/init_project.py,sha256=A7Qx7UoMOG1fdWWyn4ceH6oc5BV6jVAxudPrtOVBBjM,36396
8
+ signalwire_agents/cli/dokku.py,sha256=WuyqErWPZ-Wyqfxlzb3DyPhkyrSropUYzHtTuqzjGiM,80255
9
+ signalwire_agents/cli/init_project.py,sha256=nNBPni3x1xzdJ5pAZsQRUYK1t1e64NzwUUkq-Uc3mzo,78835
9
10
  signalwire_agents/cli/swaig_test_wrapper.py,sha256=t63HQpEc1Up5AcysEHP1OsEQcgSMKH-9H1L2IhFso18,1533
10
11
  signalwire_agents/cli/test_swaig.py,sha256=-v-XjTUWZNxmMJuOF5_cB1Jz8x8emJoqgqS_8jLeT4Y,31487
11
12
  signalwire_agents/cli/types.py,sha256=U8Abc4Atb5-wMbhM3MjcuIXsbONLOu1ucePWOCgqdco,1810
@@ -25,7 +26,7 @@ signalwire_agents/cli/simulation/data_generation.py,sha256=pxa9aJ6XkI0O8yAIGvBTU
25
26
  signalwire_agents/cli/simulation/data_overrides.py,sha256=3_3pT6j-q2gRufPX2bZ1BrmY7u1IdloLooKAJil33vI,6319
26
27
  signalwire_agents/cli/simulation/mock_env.py,sha256=fvaR_xdLMm8AbpNUbTJOFG9THcti3Zds-0QNDbKMaYk,10249
27
28
  signalwire_agents/core/__init__.py,sha256=xjPq8DmUnWYUG28sd17n430VWPmMH9oZ9W14gYwG96g,806
28
- signalwire_agents/core/agent_base.py,sha256=wQIE3q2PGg4xGZQfOch3wfjwA0Niv4_iHUmYv5QkAbc,57897
29
+ signalwire_agents/core/agent_base.py,sha256=zZRykB8VD277_5_NZbYP7ZcpeqTdQ4yWlpNnLXOljEY,58883
29
30
  signalwire_agents/core/auth_handler.py,sha256=jXrof9WZ1W9qqlQT9WElcmSRafL2kG7207x5SqWN9MU,8481
30
31
  signalwire_agents/core/config_loader.py,sha256=rStVRRUaeMGrMc44ocr0diMQQARZhbKqwMqQ6kqUNos,8722
31
32
  signalwire_agents/core/contexts.py,sha256=g9FgOGMfGCUWlm57YZcv7CvOf-Ub9FdKZIOMu14ADfE,24428
@@ -40,7 +41,7 @@ signalwire_agents/core/swaig_function.py,sha256=KnUQ2g99kDSzOzD1PJ0Iqs8DeeZ6jDII
40
41
  signalwire_agents/core/swml_builder.py,sha256=tJBFDAVTENEfjGLp2h9_AKOYt5O9FrSYLI-nZZVwM1E,15604
41
42
  signalwire_agents/core/swml_handler.py,sha256=hFDq41dQWL3EdFbq6h0hizE1dIqdVeiTeCrujbZsPzo,8397
42
43
  signalwire_agents/core/swml_renderer.py,sha256=-WAB_5ss836a8nBo5zlb6SaQKFNF4XIo1odWIXM4eE8,6860
43
- signalwire_agents/core/swml_service.py,sha256=vgK_OScBlXdsr3dMe7pLUnm_cQVWtmNl_lu5guAKDlg,49851
44
+ signalwire_agents/core/swml_service.py,sha256=TCsn3g_kAxz1DfSiPygpBv6KTd6EEDaWplFVqZZnZw8,49995
44
45
  signalwire_agents/core/agent/__init__.py,sha256=qccTmLD9b24tZDAoIPEY6vJ2p1R_ArZ_ZCKbBlKvPQ8,239
45
46
  signalwire_agents/core/agent/config/__init__.py,sha256=5XvTfnYeeGdoLr4tJjbe1OhF26nOcR5VTDIhtMGCu3I,244
46
47
  signalwire_agents/core/agent/deployment/__init__.py,sha256=4Mr7baQ_xR_hfJ72YxQRAT_GFa663YjFX_PumJ35Xds,191
@@ -55,15 +56,19 @@ signalwire_agents/core/agent/tools/decorator.py,sha256=pC6j1114GwVBd2U3h23I9gKLt
55
56
  signalwire_agents/core/agent/tools/registry.py,sha256=HScbKKwpJqFZ_odmeFklSQ0p0EMasEyKSxNwX568OPo,8054
56
57
  signalwire_agents/core/mixins/__init__.py,sha256=NsFpfF7TDP_lNR0Riw4Nbvt4fDbv_A3OoVbBqRrtXQM,652
57
58
  signalwire_agents/core/mixins/ai_config_mixin.py,sha256=In7SrVlKoRaGsDIXEDNGsrEqCjotmcQr_XA563VWABQ,16265
58
- signalwire_agents/core/mixins/auth_mixin.py,sha256=Y9kR423-76U_pKL7KXzseeXX2a-4WxNWyo3odS7TDQM,9879
59
+ signalwire_agents/core/mixins/auth_mixin.py,sha256=FIzQjLOkEgQhy6uIKjnevsM3ubdMnY5gDDksslEUtF8,9729
59
60
  signalwire_agents/core/mixins/prompt_mixin.py,sha256=bEsuw9J2F_upFYI02KyC7o2eGZjwOKQ352rmJBZirAM,13729
60
- signalwire_agents/core/mixins/serverless_mixin.py,sha256=QIIbl_-16XFJi5aqrWpNzORbyCJQmhaplWXnW6U9i68,16137
61
+ signalwire_agents/core/mixins/serverless_mixin.py,sha256=XP_dFGO1aa4_Ouq9YLRhQ_MmjNTv-qsAXKHyf90ETMQ,20599
61
62
  signalwire_agents/core/mixins/skill_mixin.py,sha256=Qz3RKPmq_iMY4NecyxOHk3dW3W-O4iEm2ahhMjAcqRs,1861
62
63
  signalwire_agents/core/mixins/state_mixin.py,sha256=q3achpyUYZKuJaqKf12O22FXpSsNNsMEonSvlpSHCkA,6594
63
64
  signalwire_agents/core/mixins/tool_mixin.py,sha256=6CaNdaspHcfte0qSB_bSN8PTsqxRZzL_AXYk8QoWyXE,8660
64
- signalwire_agents/core/mixins/web_mixin.py,sha256=2Tj0mulcjiUBuqHnJ76UHc5C2L5xV91HKyxfG3lNj4k,50612
65
+ signalwire_agents/core/mixins/web_mixin.py,sha256=Yknov_Rd2k7R0DO9JRsrbsv5l_ztkAjBy5MBPMjmNYU,51057
65
66
  signalwire_agents/core/security/__init__.py,sha256=4Mr7baQ_xR_hfJ72YxQRAT_GFa663YjFX_PumJ35Xds,191
66
67
  signalwire_agents/core/security/session_manager.py,sha256=s5hXYcFnrsYFoyo-zcN7EJy-wInZQI_cWTBHX9MxHR4,9164
68
+ signalwire_agents/mcp_gateway/__init__.py,sha256=uZhyt0cBa9Wk_OPr_Ewphh6apsaf_5O9G48NVkm_00I,619
69
+ signalwire_agents/mcp_gateway/gateway_service.py,sha256=hytoEhiXSyZxk_LxV-zo0mfCCAJf-y2Gs5gJ__iIRB0,23081
70
+ signalwire_agents/mcp_gateway/mcp_manager.py,sha256=DaR49BX5b6hn2mXJygS3idNEr3IDImWGNdsrQSYxiEE,19669
71
+ signalwire_agents/mcp_gateway/session_manager.py,sha256=sGMPT8aSzS2RRR_ewkd0nxwYI-LK5CaWrendGhXAW9c,8505
67
72
  signalwire_agents/prefabs/__init__.py,sha256=MW11J63XH7KxF2MWguRsMFM9iqMWexaEO9ynDPL_PDM,715
68
73
  signalwire_agents/prefabs/concierge.py,sha256=XB-Ziy0tteYI5NHu7Sinx-N960nzkhq2m4v8Ei8UHas,9921
69
74
  signalwire_agents/prefabs/faq_bot.py,sha256=cUuHhnDB8S4aVg-DiQe4jBmCAPrYQrND_Mff9iaeEa0,10572
@@ -75,12 +80,12 @@ signalwire_agents/search/document_processor.py,sha256=emlmYAgr34Qyhfqm4VppqTCpm1
75
80
  signalwire_agents/search/index_builder.py,sha256=v1LGhbzzKlCilO4g6nqQJVYEAWvInP2j5B1QrAEj4V8,33772
76
81
  signalwire_agents/search/migration.py,sha256=UZPrpUOMZeLVNO1cEDp3tnZYG6ys8-VCFlZXmzig_E0,16582
77
82
  signalwire_agents/search/models.py,sha256=isYOYwQT0eWCVdcYSSd8w6z2gFYUobtC8BAUhV7FUVI,840
78
- signalwire_agents/search/pgvector_backend.py,sha256=pYAFB0_KX0LM1AeAYC_yQ44HMrBJJAxXZQn0OWtNQI4,28557
83
+ signalwire_agents/search/pgvector_backend.py,sha256=bFxdAtBWEBPLlbQYrcSvyUqcyJn8Y_22GJNknkGTGP0,28717
79
84
  signalwire_agents/search/query_processor.py,sha256=34MXOWyEKKMgSCNNM5X2SRyWwF8CPJeorgNjFn661zs,19587
80
85
  signalwire_agents/search/search_engine.py,sha256=kDIIBuxSMAoedMS0mnxvPCZOx59fx4mJwxhVRpB6BNU,57461
81
86
  signalwire_agents/search/search_service.py,sha256=FYjX95TD0Cr6jakYU4A1GIdBkj72euq2fM3zaBe2b9U,22379
82
87
  signalwire_agents/skills/README.md,sha256=sM1_08IsKdRDCzYHPLzppJbaK5MvRelsVL6Kd9A9Ubo,12193
83
- signalwire_agents/skills/__init__.py,sha256=9AMEcyk2tDaGiUjwVIson_tVWxV4oU_2NnGGNTbHuyQ,533
88
+ signalwire_agents/skills/__init__.py,sha256=JrFQR7IaLtT3BXFURP_a1ZySPhv7FfPWM60xpLMnLqc,638
84
89
  signalwire_agents/skills/registry.py,sha256=zURdeAaccZyUSwLRl8K4ILXICMV3ouYQIA4rUBq6b5E,20792
85
90
  signalwire_agents/skills/api_ninjas_trivia/README.md,sha256=SoyS7VFh3eVIiVnQ5gfTfs0a_gAlLwnmT2W2FrbNU0A,6762
86
91
  signalwire_agents/skills/api_ninjas_trivia/__init__.py,sha256=zN305bBQkzlJyUNsPUMPt3gDJbvc-Iigkdh0rBou_RE,267
@@ -131,12 +136,12 @@ signalwire_agents/utils/token_generators.py,sha256=4Mr7baQ_xR_hfJ72YxQRAT_GFa663
131
136
  signalwire_agents/utils/validators.py,sha256=4Mr7baQ_xR_hfJ72YxQRAT_GFa663YjFX_PumJ35Xds,191
132
137
  signalwire_agents/web/__init__.py,sha256=XE_pSTY9Aalzr7J7wqFth1Zr3cccQHPPcF5HWNrOpz8,383
133
138
  signalwire_agents/web/web_service.py,sha256=a2PSHJgX1tlZr0Iz1A1UouZjXEePJAZL632evvLVM38,21071
134
- signalwire_agents-1.0.7.data/data/share/man/man1/sw-agent-init.1,sha256=EFE8iOj2aGrZRwSXRoZdrZTZXOROuQmuIrZuzp9yI2s,6880
135
- signalwire_agents-1.0.7.data/data/share/man/man1/sw-search.1,sha256=9jJ6V6t6DgmXByz8Lw9exjf683Cw3sJGro8-eB0M9EY,10413
136
- signalwire_agents-1.0.7.data/data/share/man/man1/swaig-test.1,sha256=Ri0EITo8YMFowkcYltwPSwU4VJdRzo7XTWloi5WddCg,7815
137
- signalwire_agents-1.0.7.dist-info/licenses/LICENSE,sha256=NYvAsB-rTcSvG9cqHt9EUHAWLiA9YzM4Qfz-mPdvDR0,1067
138
- signalwire_agents-1.0.7.dist-info/METADATA,sha256=F5nXnOYnUtPMN_GUga44bks-UZUyRIk4Tn3YsZ2Z96s,41599
139
- signalwire_agents-1.0.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
140
- signalwire_agents-1.0.7.dist-info/entry_points.txt,sha256=GDaOxm8I9Bf3Sd2jDSGRXDG2ezDMgmX6ockjpDfK_IY,200
141
- signalwire_agents-1.0.7.dist-info/top_level.txt,sha256=kDGS6ZYv84K9P5Kyg9_S8P_pbUXoHkso0On_DB5bbWc,18
142
- signalwire_agents-1.0.7.dist-info/RECORD,,
139
+ signalwire_agents-1.0.17.dev4.data/data/share/man/man1/sw-agent-init.1,sha256=J4k5Oi74BnWCPCvsaw00vuyyqDPuIECjJIPu5OynvJc,8381
140
+ signalwire_agents-1.0.17.dev4.data/data/share/man/man1/sw-search.1,sha256=9jJ6V6t6DgmXByz8Lw9exjf683Cw3sJGro8-eB0M9EY,10413
141
+ signalwire_agents-1.0.17.dev4.data/data/share/man/man1/swaig-test.1,sha256=Ri0EITo8YMFowkcYltwPSwU4VJdRzo7XTWloi5WddCg,7815
142
+ signalwire_agents-1.0.17.dev4.dist-info/licenses/LICENSE,sha256=NYvAsB-rTcSvG9cqHt9EUHAWLiA9YzM4Qfz-mPdvDR0,1067
143
+ signalwire_agents-1.0.17.dev4.dist-info/METADATA,sha256=cUBLrL5nVgu8q1agp7cMq4bOuRIcfPjZaWoIMETqFF8,41745
144
+ signalwire_agents-1.0.17.dev4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
145
+ signalwire_agents-1.0.17.dev4.dist-info/entry_points.txt,sha256=fMiBH-GLeXGaWWn58Mcj7KM_m3SdomQMUQu-1LTqscw,315
146
+ signalwire_agents-1.0.17.dev4.dist-info/top_level.txt,sha256=kDGS6ZYv84K9P5Kyg9_S8P_pbUXoHkso0On_DB5bbWc,18
147
+ signalwire_agents-1.0.17.dev4.dist-info/RECORD,,
@@ -1,4 +1,6 @@
1
1
  [console_scripts]
2
+ mcp-gateway = signalwire_agents.mcp_gateway.gateway_service:main
3
+ sw-agent-dokku = signalwire_agents.cli.dokku:main
2
4
  sw-agent-init = signalwire_agents.cli.init_project:main
3
5
  sw-search = signalwire_agents.cli.build_search:console_entry_point
4
6
  swaig-test = signalwire_agents.cli.swaig_test_wrapper:main