signalwire-agents 0.1.43__tar.gz → 0.1.44__tar.gz
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.
- {signalwire_agents-0.1.43/signalwire_agents.egg-info → signalwire_agents-0.1.44}/PKG-INFO +1 -1
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/pyproject.toml +1 -1
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/__init__.py +5 -1
- signalwire_agents-0.1.44/signalwire_agents/web/__init__.py +17 -0
- signalwire_agents-0.1.44/signalwire_agents/web/web_service.py +559 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44/signalwire_agents.egg-info}/PKG-INFO +1 -1
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents.egg-info/SOURCES.txt +3 -1
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/LICENSE +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/README.md +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/setup.cfg +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/setup.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/agent_server.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/agents/bedrock.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/cli/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/cli/build_search.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/cli/config.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/cli/core/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/cli/core/agent_loader.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/cli/core/argparse_helpers.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/cli/core/dynamic_config.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/cli/core/service_loader.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/cli/execution/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/cli/execution/datamap_exec.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/cli/execution/webhook_exec.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/cli/output/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/cli/output/output_formatter.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/cli/output/swml_dump.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/cli/simulation/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/cli/simulation/data_generation.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/cli/simulation/data_overrides.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/cli/simulation/mock_env.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/cli/swaig_test_wrapper.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/cli/test_swaig.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/cli/types.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/agent/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/agent/config/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/agent/deployment/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/agent/deployment/handlers/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/agent/prompt/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/agent/prompt/manager.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/agent/routing/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/agent/security/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/agent/swml/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/agent/tools/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/agent/tools/decorator.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/agent/tools/registry.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/agent_base.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/auth_handler.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/config_loader.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/contexts.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/data_map.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/function_result.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/logging_config.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/mixins/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/mixins/ai_config_mixin.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/mixins/auth_mixin.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/mixins/prompt_mixin.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/mixins/serverless_mixin.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/mixins/skill_mixin.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/mixins/state_mixin.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/mixins/tool_mixin.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/mixins/web_mixin.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/pom_builder.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/security/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/security/session_manager.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/security_config.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/skill_base.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/skill_manager.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/swaig_function.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/swml_builder.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/swml_handler.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/swml_renderer.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/swml_service.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/prefabs/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/prefabs/concierge.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/prefabs/faq_bot.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/prefabs/info_gatherer.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/prefabs/receptionist.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/prefabs/survey.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/schema.json +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/search/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/search/document_processor.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/search/index_builder.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/search/pgvector_backend.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/search/query_processor.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/search/search_engine.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/search/search_service.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/README.md +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/api_ninjas_trivia/README.md +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/api_ninjas_trivia/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/api_ninjas_trivia/skill.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/datasphere/README.md +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/datasphere/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/datasphere/skill.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/datasphere_serverless/README.md +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/datasphere_serverless/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/datasphere_serverless/skill.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/datetime/README.md +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/datetime/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/datetime/skill.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/joke/README.md +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/joke/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/joke/skill.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/math/README.md +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/math/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/math/skill.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/mcp_gateway/README.md +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/mcp_gateway/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/mcp_gateway/skill.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/native_vector_search/README.md +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/native_vector_search/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/native_vector_search/skill.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/play_background_file/README.md +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/play_background_file/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/play_background_file/skill.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/registry.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/spider/README.md +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/spider/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/spider/skill.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/swml_transfer/README.md +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/swml_transfer/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/swml_transfer/skill.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/weather_api/README.md +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/weather_api/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/weather_api/skill.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/web_search/README.md +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/web_search/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/web_search/skill.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/wikipedia_search/README.md +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/wikipedia_search/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/wikipedia_search/skill.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/utils/__init__.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/utils/pom_utils.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/utils/schema_utils.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/utils/token_generators.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/utils/validators.py +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents.egg-info/dependency_links.txt +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents.egg-info/entry_points.txt +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents.egg-info/requires.txt +0 -0
- {signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents.egg-info/top_level.txt +0 -0
@@ -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.
|
21
|
+
__version__ = "0.1.44"
|
22
22
|
|
23
23
|
# Import core classes for easier access
|
24
24
|
from .core.agent_base import AgentBase
|
@@ -31,6 +31,9 @@ from signalwire_agents.core.function_result import SwaigFunctionResult
|
|
31
31
|
from signalwire_agents.core.swaig_function import SWAIGFunction
|
32
32
|
from signalwire_agents.agents.bedrock import BedrockAgent
|
33
33
|
|
34
|
+
# Import WebService for static file serving
|
35
|
+
from signalwire_agents.web import WebService
|
36
|
+
|
34
37
|
# Lazy import skills to avoid slow startup for CLI tools
|
35
38
|
# Skills are now loaded on-demand when requested
|
36
39
|
def _get_skill_registry():
|
@@ -138,6 +141,7 @@ __all__ = [
|
|
138
141
|
"Context",
|
139
142
|
"Step",
|
140
143
|
"create_simple_context",
|
144
|
+
"WebService",
|
141
145
|
"start_agent",
|
142
146
|
"run_agent",
|
143
147
|
"list_skills",
|
@@ -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']
|
@@ -0,0 +1,559 @@
|
|
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
|
+
import os
|
11
|
+
import mimetypes
|
12
|
+
from pathlib import Path
|
13
|
+
from typing import Dict, Optional, Tuple, Any
|
14
|
+
import logging
|
15
|
+
|
16
|
+
try:
|
17
|
+
from fastapi import FastAPI, HTTPException, Request, Response, Depends
|
18
|
+
from fastapi.middleware.cors import CORSMiddleware
|
19
|
+
from fastapi.security import HTTPBasic, HTTPBasicCredentials
|
20
|
+
from fastapi.staticfiles import StaticFiles
|
21
|
+
from fastapi.responses import FileResponse, HTMLResponse
|
22
|
+
except ImportError:
|
23
|
+
FastAPI = None
|
24
|
+
HTTPException = None
|
25
|
+
Request = None
|
26
|
+
Response = None
|
27
|
+
Depends = None
|
28
|
+
CORSMiddleware = None
|
29
|
+
HTTPBasic = None
|
30
|
+
HTTPBasicCredentials = None
|
31
|
+
StaticFiles = None
|
32
|
+
FileResponse = None
|
33
|
+
HTMLResponse = None
|
34
|
+
|
35
|
+
from signalwire_agents.core.security_config import SecurityConfig
|
36
|
+
from signalwire_agents.core.config_loader import ConfigLoader
|
37
|
+
from signalwire_agents.core.logging_config import get_logger
|
38
|
+
|
39
|
+
logger = get_logger("web_service")
|
40
|
+
|
41
|
+
class WebService:
|
42
|
+
"""Static file serving service with HTTP API"""
|
43
|
+
|
44
|
+
def __init__(self,
|
45
|
+
port: int = 8002,
|
46
|
+
directories: Dict[str, str] = None,
|
47
|
+
basic_auth: Optional[Tuple[str, str]] = None,
|
48
|
+
config_file: Optional[str] = None,
|
49
|
+
enable_directory_browsing: bool = False,
|
50
|
+
allowed_extensions: Optional[list] = None,
|
51
|
+
blocked_extensions: Optional[list] = None,
|
52
|
+
max_file_size: int = 100 * 1024 * 1024, # 100MB default
|
53
|
+
enable_cors: bool = True):
|
54
|
+
"""
|
55
|
+
Initialize WebService
|
56
|
+
|
57
|
+
Args:
|
58
|
+
port: Port to bind to (default: 8002)
|
59
|
+
directories: Dict mapping URL paths to local directories
|
60
|
+
basic_auth: Optional tuple of (username, password)
|
61
|
+
config_file: Optional configuration file path
|
62
|
+
enable_directory_browsing: Allow directory listing
|
63
|
+
allowed_extensions: List of allowed file extensions (e.g., ['.html', '.css'])
|
64
|
+
blocked_extensions: List of blocked extensions (e.g., ['.env', '.git'])
|
65
|
+
max_file_size: Maximum file size in bytes to serve
|
66
|
+
enable_cors: Enable CORS support
|
67
|
+
"""
|
68
|
+
# Load configuration first
|
69
|
+
self._load_config(config_file)
|
70
|
+
|
71
|
+
# Override with constructor params if provided
|
72
|
+
self.port = port
|
73
|
+
self.enable_directory_browsing = enable_directory_browsing
|
74
|
+
self.max_file_size = max_file_size
|
75
|
+
self.enable_cors = enable_cors
|
76
|
+
|
77
|
+
if directories is not None:
|
78
|
+
self.directories = directories
|
79
|
+
|
80
|
+
# Set up file extension filters
|
81
|
+
self.allowed_extensions = allowed_extensions
|
82
|
+
self.blocked_extensions = blocked_extensions or [
|
83
|
+
'.env', '.git', '.gitignore', '.key', '.pem', '.crt',
|
84
|
+
'.pyc', '__pycache__', '.DS_Store', '.swp'
|
85
|
+
]
|
86
|
+
|
87
|
+
# Initialize mimetypes
|
88
|
+
mimetypes.init()
|
89
|
+
# Add custom MIME types if needed
|
90
|
+
mimetypes.add_type('application/javascript', '.js')
|
91
|
+
mimetypes.add_type('text/css', '.css')
|
92
|
+
mimetypes.add_type('application/json', '.json')
|
93
|
+
|
94
|
+
# Load security configuration
|
95
|
+
self.security = SecurityConfig(config_file=config_file, service_name="web")
|
96
|
+
self.security.log_config("WebService")
|
97
|
+
|
98
|
+
# Set up authentication
|
99
|
+
self._basic_auth = basic_auth or self.security.get_basic_auth()
|
100
|
+
|
101
|
+
if FastAPI:
|
102
|
+
self.app = FastAPI(
|
103
|
+
title="SignalWire Web Service",
|
104
|
+
description="Static file serving for SignalWire Agents"
|
105
|
+
)
|
106
|
+
self._setup_security()
|
107
|
+
self._setup_routes()
|
108
|
+
self._mount_directories()
|
109
|
+
else:
|
110
|
+
self.app = None
|
111
|
+
logger.warning("FastAPI not available. HTTP service will not be available.")
|
112
|
+
|
113
|
+
def _load_config(self, config_file: Optional[str]):
|
114
|
+
"""Load configuration from file if available"""
|
115
|
+
# Initialize defaults
|
116
|
+
self.directories = {}
|
117
|
+
self.port = 8002
|
118
|
+
|
119
|
+
# Find config file
|
120
|
+
if not config_file:
|
121
|
+
config_file = ConfigLoader.find_config_file("web")
|
122
|
+
|
123
|
+
if not config_file:
|
124
|
+
return
|
125
|
+
|
126
|
+
# Load config
|
127
|
+
config_loader = ConfigLoader([config_file])
|
128
|
+
if not config_loader.has_config():
|
129
|
+
return
|
130
|
+
|
131
|
+
logger.info("loading_config_from_file", file=config_file)
|
132
|
+
|
133
|
+
# Get service section
|
134
|
+
service_config = config_loader.get_section('service')
|
135
|
+
if service_config:
|
136
|
+
if 'port' in service_config:
|
137
|
+
self.port = int(service_config['port'])
|
138
|
+
|
139
|
+
if 'directories' in service_config and isinstance(service_config['directories'], dict):
|
140
|
+
self.directories = service_config['directories']
|
141
|
+
|
142
|
+
if 'enable_directory_browsing' in service_config:
|
143
|
+
self.enable_directory_browsing = bool(service_config['enable_directory_browsing'])
|
144
|
+
|
145
|
+
if 'max_file_size' in service_config:
|
146
|
+
self.max_file_size = int(service_config['max_file_size'])
|
147
|
+
|
148
|
+
if 'allowed_extensions' in service_config:
|
149
|
+
self.allowed_extensions = service_config['allowed_extensions']
|
150
|
+
|
151
|
+
if 'blocked_extensions' in service_config:
|
152
|
+
self.blocked_extensions = service_config['blocked_extensions']
|
153
|
+
|
154
|
+
def _setup_security(self):
|
155
|
+
"""Setup security middleware and authentication"""
|
156
|
+
if not self.app:
|
157
|
+
return
|
158
|
+
|
159
|
+
# Add CORS middleware if enabled
|
160
|
+
if self.enable_cors and CORSMiddleware:
|
161
|
+
self.app.add_middleware(
|
162
|
+
CORSMiddleware,
|
163
|
+
**self.security.get_cors_config()
|
164
|
+
)
|
165
|
+
|
166
|
+
# Add security headers middleware
|
167
|
+
@self.app.middleware("http")
|
168
|
+
async def add_security_headers(request: Request, call_next):
|
169
|
+
response = await call_next(request)
|
170
|
+
|
171
|
+
# Add security headers
|
172
|
+
is_https = request.url.scheme == "https"
|
173
|
+
headers = self.security.get_security_headers(is_https)
|
174
|
+
for header, value in headers.items():
|
175
|
+
response.headers[header] = value
|
176
|
+
|
177
|
+
# Add cache headers for static files
|
178
|
+
if request.url.path.startswith(tuple(self.directories.keys())):
|
179
|
+
# Cache static files for 1 hour
|
180
|
+
response.headers["Cache-Control"] = "public, max-age=3600"
|
181
|
+
|
182
|
+
return response
|
183
|
+
|
184
|
+
# Add host validation middleware
|
185
|
+
@self.app.middleware("http")
|
186
|
+
async def validate_host(request: Request, call_next):
|
187
|
+
host = request.headers.get("host", "").split(":")[0]
|
188
|
+
if host and not self.security.should_allow_host(host):
|
189
|
+
return Response(content="Invalid host", status_code=400)
|
190
|
+
|
191
|
+
return await call_next(request)
|
192
|
+
|
193
|
+
def _get_current_username(self, credentials: HTTPBasicCredentials = None) -> str:
|
194
|
+
"""Validate basic auth credentials"""
|
195
|
+
if not credentials:
|
196
|
+
return None
|
197
|
+
|
198
|
+
correct_username, correct_password = self._basic_auth
|
199
|
+
|
200
|
+
# Compare credentials
|
201
|
+
import secrets
|
202
|
+
username_correct = secrets.compare_digest(credentials.username, correct_username)
|
203
|
+
password_correct = secrets.compare_digest(credentials.password, correct_password)
|
204
|
+
|
205
|
+
if not (username_correct and password_correct):
|
206
|
+
raise HTTPException(
|
207
|
+
status_code=401,
|
208
|
+
detail="Invalid authentication credentials",
|
209
|
+
headers={"WWW-Authenticate": "Basic"},
|
210
|
+
)
|
211
|
+
|
212
|
+
return credentials.username
|
213
|
+
|
214
|
+
def _is_file_allowed(self, file_path: Path) -> bool:
|
215
|
+
"""Check if file is allowed to be served"""
|
216
|
+
# Check file size
|
217
|
+
if file_path.stat().st_size > self.max_file_size:
|
218
|
+
return False
|
219
|
+
|
220
|
+
# Check extension and name
|
221
|
+
ext = file_path.suffix.lower()
|
222
|
+
name = file_path.name
|
223
|
+
|
224
|
+
# Check blocked extensions and names
|
225
|
+
for blocked in self.blocked_extensions:
|
226
|
+
if blocked.startswith('.'):
|
227
|
+
# Check both as extension and as full name (for files like .env, .gitignore)
|
228
|
+
if ext == blocked or name == blocked:
|
229
|
+
return False
|
230
|
+
else:
|
231
|
+
if name == blocked or blocked in str(file_path):
|
232
|
+
return False
|
233
|
+
|
234
|
+
# If allowed_extensions is set, only allow those
|
235
|
+
if self.allowed_extensions:
|
236
|
+
return ext in self.allowed_extensions
|
237
|
+
|
238
|
+
return True
|
239
|
+
|
240
|
+
def _generate_directory_listing(self, directory: Path, url_path: str) -> str:
|
241
|
+
"""Generate HTML directory listing"""
|
242
|
+
items = []
|
243
|
+
|
244
|
+
# Add parent directory link if not at root
|
245
|
+
if url_path != '/':
|
246
|
+
items.append('<li><a href="../">../</a></li>')
|
247
|
+
|
248
|
+
# List directories first
|
249
|
+
for item in sorted(directory.iterdir()):
|
250
|
+
if item.name.startswith('.'):
|
251
|
+
continue # Skip hidden files
|
252
|
+
|
253
|
+
if item.is_dir():
|
254
|
+
items.append(f'<li>📁 <a href="{item.name}/">{item.name}/</a></li>')
|
255
|
+
|
256
|
+
# Then list files
|
257
|
+
for item in sorted(directory.iterdir()):
|
258
|
+
if item.name.startswith('.'):
|
259
|
+
continue
|
260
|
+
|
261
|
+
if item.is_file() and self._is_file_allowed(item):
|
262
|
+
size = item.stat().st_size
|
263
|
+
if size < 1024:
|
264
|
+
size_str = f"{size} B"
|
265
|
+
elif size < 1024 * 1024:
|
266
|
+
size_str = f"{size / 1024:.1f} KB"
|
267
|
+
else:
|
268
|
+
size_str = f"{size / (1024 * 1024):.1f} MB"
|
269
|
+
|
270
|
+
items.append(f'<li>📄 <a href="{item.name}">{item.name}</a> ({size_str})</li>')
|
271
|
+
|
272
|
+
html = f"""
|
273
|
+
<!DOCTYPE html>
|
274
|
+
<html>
|
275
|
+
<head>
|
276
|
+
<title>Directory listing for {url_path}</title>
|
277
|
+
<style>
|
278
|
+
body {{ font-family: sans-serif; margin: 40px; }}
|
279
|
+
h1 {{ color: #333; }}
|
280
|
+
ul {{ list-style: none; padding: 0; }}
|
281
|
+
li {{ padding: 5px 0; }}
|
282
|
+
a {{ text-decoration: none; color: #0066cc; }}
|
283
|
+
a:hover {{ text-decoration: underline; }}
|
284
|
+
</style>
|
285
|
+
</head>
|
286
|
+
<body>
|
287
|
+
<h1>Directory listing for {url_path}</h1>
|
288
|
+
<ul>
|
289
|
+
{''.join(items)}
|
290
|
+
</ul>
|
291
|
+
</body>
|
292
|
+
</html>
|
293
|
+
"""
|
294
|
+
return html
|
295
|
+
|
296
|
+
def _setup_routes(self):
|
297
|
+
"""Setup FastAPI routes"""
|
298
|
+
if not self.app:
|
299
|
+
return
|
300
|
+
|
301
|
+
# Create security dependency if HTTPBasic is available
|
302
|
+
security = HTTPBasic() if HTTPBasic else None
|
303
|
+
|
304
|
+
@self.app.get("/health")
|
305
|
+
async def health():
|
306
|
+
return {
|
307
|
+
"status": "healthy",
|
308
|
+
"directories": list(self.directories.keys()),
|
309
|
+
"ssl_enabled": self.security.ssl_enabled,
|
310
|
+
"auth_required": bool(security),
|
311
|
+
"directory_browsing": self.enable_directory_browsing
|
312
|
+
}
|
313
|
+
|
314
|
+
@self.app.get("/")
|
315
|
+
async def root():
|
316
|
+
"""Root endpoint showing available directories"""
|
317
|
+
html = """
|
318
|
+
<!DOCTYPE html>
|
319
|
+
<html>
|
320
|
+
<head>
|
321
|
+
<title>SignalWire Web Service</title>
|
322
|
+
<style>
|
323
|
+
body { font-family: sans-serif; margin: 40px; }
|
324
|
+
h1 { color: #333; }
|
325
|
+
ul { list-style: none; padding: 0; }
|
326
|
+
li { padding: 10px 0; }
|
327
|
+
a { text-decoration: none; color: #0066cc; font-size: 18px; }
|
328
|
+
a:hover { text-decoration: underline; }
|
329
|
+
.path { color: #666; font-size: 14px; }
|
330
|
+
</style>
|
331
|
+
</head>
|
332
|
+
<body>
|
333
|
+
<h1>SignalWire Web Service</h1>
|
334
|
+
<h2>Available Directories:</h2>
|
335
|
+
<ul>
|
336
|
+
"""
|
337
|
+
|
338
|
+
for route, local_path in self.directories.items():
|
339
|
+
html += f'<li>📁 <a href="{route}">{route}</a> <span class="path">→ {local_path}</span></li>'
|
340
|
+
|
341
|
+
html += """
|
342
|
+
</ul>
|
343
|
+
</body>
|
344
|
+
</html>
|
345
|
+
"""
|
346
|
+
|
347
|
+
if HTMLResponse:
|
348
|
+
return HTMLResponse(content=html)
|
349
|
+
else:
|
350
|
+
return {"directories": list(self.directories.keys())}
|
351
|
+
|
352
|
+
def _mount_directories(self):
|
353
|
+
"""Mount static file directories"""
|
354
|
+
if not self.app or not StaticFiles:
|
355
|
+
return
|
356
|
+
|
357
|
+
# Create security dependency if HTTPBasic is available
|
358
|
+
security = HTTPBasic() if HTTPBasic else None
|
359
|
+
|
360
|
+
for route, directory in self.directories.items():
|
361
|
+
# Ensure directory exists
|
362
|
+
dir_path = Path(directory)
|
363
|
+
if not dir_path.exists():
|
364
|
+
logger.warning(f"Directory does not exist: {directory}")
|
365
|
+
continue
|
366
|
+
|
367
|
+
if not dir_path.is_dir():
|
368
|
+
logger.warning(f"Path is not a directory: {directory}")
|
369
|
+
continue
|
370
|
+
|
371
|
+
# Normalize route
|
372
|
+
if not route.startswith('/'):
|
373
|
+
route = '/' + route
|
374
|
+
|
375
|
+
logger.info(f"Mounting directory {directory} at route {route}")
|
376
|
+
|
377
|
+
# Create custom static file handler with our security checks
|
378
|
+
@self.app.get(f"{route}/{{file_path:path}}")
|
379
|
+
async def serve_file(
|
380
|
+
file_path: str,
|
381
|
+
request: Request,
|
382
|
+
credentials: HTTPBasicCredentials = None if not security else Depends(security),
|
383
|
+
route=route,
|
384
|
+
directory=directory
|
385
|
+
):
|
386
|
+
"""Serve files with security checks"""
|
387
|
+
if security:
|
388
|
+
self._get_current_username(credentials)
|
389
|
+
|
390
|
+
# Build full file path
|
391
|
+
full_path = Path(directory) / file_path
|
392
|
+
|
393
|
+
# Security: Prevent path traversal
|
394
|
+
try:
|
395
|
+
full_path = full_path.resolve()
|
396
|
+
dir_path = Path(directory).resolve()
|
397
|
+
if not str(full_path).startswith(str(dir_path)):
|
398
|
+
raise HTTPException(status_code=403, detail="Access denied")
|
399
|
+
except Exception:
|
400
|
+
raise HTTPException(status_code=403, detail="Invalid path")
|
401
|
+
|
402
|
+
# Check if path exists
|
403
|
+
if not full_path.exists():
|
404
|
+
raise HTTPException(status_code=404, detail="File not found")
|
405
|
+
|
406
|
+
# Handle directory requests
|
407
|
+
if full_path.is_dir():
|
408
|
+
if not self.enable_directory_browsing:
|
409
|
+
# Try to serve index.html if it exists
|
410
|
+
index_path = full_path / "index.html"
|
411
|
+
if index_path.exists() and self._is_file_allowed(index_path):
|
412
|
+
return FileResponse(index_path)
|
413
|
+
else:
|
414
|
+
raise HTTPException(status_code=403, detail="Directory browsing disabled")
|
415
|
+
else:
|
416
|
+
# Generate directory listing
|
417
|
+
html = self._generate_directory_listing(full_path, request.url.path)
|
418
|
+
if HTMLResponse:
|
419
|
+
return HTMLResponse(content=html)
|
420
|
+
else:
|
421
|
+
raise HTTPException(status_code=403, detail="Directory browsing not available")
|
422
|
+
|
423
|
+
# Check if file is allowed
|
424
|
+
if not self._is_file_allowed(full_path):
|
425
|
+
raise HTTPException(status_code=403, detail="File type not allowed")
|
426
|
+
|
427
|
+
# Serve the file
|
428
|
+
mime_type = mimetypes.guess_type(str(full_path))[0] or 'application/octet-stream'
|
429
|
+
|
430
|
+
if FileResponse:
|
431
|
+
return FileResponse(
|
432
|
+
full_path,
|
433
|
+
media_type=mime_type,
|
434
|
+
headers={
|
435
|
+
"Cache-Control": "public, max-age=3600",
|
436
|
+
"X-Content-Type-Options": "nosniff"
|
437
|
+
}
|
438
|
+
)
|
439
|
+
else:
|
440
|
+
# Fallback if FileResponse not available
|
441
|
+
with open(full_path, 'rb') as f:
|
442
|
+
content = f.read()
|
443
|
+
return Response(
|
444
|
+
content=content,
|
445
|
+
media_type=mime_type,
|
446
|
+
headers={
|
447
|
+
"Cache-Control": "public, max-age=3600",
|
448
|
+
"X-Content-Type-Options": "nosniff"
|
449
|
+
}
|
450
|
+
)
|
451
|
+
|
452
|
+
def add_directory(self, route: str, directory: str) -> None:
|
453
|
+
"""
|
454
|
+
Add a new directory to serve
|
455
|
+
|
456
|
+
Args:
|
457
|
+
route: URL path to mount at (e.g., "/docs")
|
458
|
+
directory: Local directory path to serve
|
459
|
+
"""
|
460
|
+
# Normalize route
|
461
|
+
if not route.startswith('/'):
|
462
|
+
route = '/' + route
|
463
|
+
|
464
|
+
# Verify directory exists
|
465
|
+
dir_path = Path(directory)
|
466
|
+
if not dir_path.exists():
|
467
|
+
raise ValueError(f"Directory does not exist: {directory}")
|
468
|
+
|
469
|
+
if not dir_path.is_dir():
|
470
|
+
raise ValueError(f"Path is not a directory: {directory}")
|
471
|
+
|
472
|
+
self.directories[route] = directory
|
473
|
+
|
474
|
+
# If app is already running, mount the new directory
|
475
|
+
if self.app:
|
476
|
+
self._mount_directories()
|
477
|
+
|
478
|
+
def remove_directory(self, route: str) -> None:
|
479
|
+
"""
|
480
|
+
Remove a directory from being served
|
481
|
+
|
482
|
+
Args:
|
483
|
+
route: URL path to remove
|
484
|
+
"""
|
485
|
+
# Normalize route
|
486
|
+
if not route.startswith('/'):
|
487
|
+
route = '/' + route
|
488
|
+
|
489
|
+
if route in self.directories:
|
490
|
+
del self.directories[route]
|
491
|
+
|
492
|
+
def start(self, host: str = "0.0.0.0", port: Optional[int] = None,
|
493
|
+
ssl_cert: Optional[str] = None, ssl_key: Optional[str] = None):
|
494
|
+
"""
|
495
|
+
Start the service with optional HTTPS support
|
496
|
+
|
497
|
+
Args:
|
498
|
+
host: Host to bind to (default: "0.0.0.0")
|
499
|
+
port: Port to bind to (default: self.port)
|
500
|
+
ssl_cert: Path to SSL certificate file (overrides environment)
|
501
|
+
ssl_key: Path to SSL key file (overrides environment)
|
502
|
+
"""
|
503
|
+
if not self.app:
|
504
|
+
raise RuntimeError("FastAPI not available. Cannot start HTTP service.")
|
505
|
+
|
506
|
+
port = port or self.port
|
507
|
+
|
508
|
+
# Get SSL configuration
|
509
|
+
ssl_kwargs = {}
|
510
|
+
if ssl_cert and ssl_key:
|
511
|
+
# Use provided SSL files
|
512
|
+
ssl_kwargs = {
|
513
|
+
'ssl_certfile': ssl_cert,
|
514
|
+
'ssl_keyfile': ssl_key
|
515
|
+
}
|
516
|
+
else:
|
517
|
+
# Use security config SSL settings
|
518
|
+
ssl_kwargs = self.security.get_ssl_context_kwargs()
|
519
|
+
|
520
|
+
# Build startup URL
|
521
|
+
scheme = "https" if ssl_kwargs else "http"
|
522
|
+
startup_url = f"{scheme}://{host}:{port}"
|
523
|
+
|
524
|
+
# Get auth credentials
|
525
|
+
username, password = self._basic_auth
|
526
|
+
|
527
|
+
# Log startup information
|
528
|
+
logger.info(
|
529
|
+
"starting_web_service",
|
530
|
+
url=startup_url,
|
531
|
+
ssl_enabled=bool(ssl_kwargs),
|
532
|
+
directories=list(self.directories.keys()),
|
533
|
+
username=username
|
534
|
+
)
|
535
|
+
|
536
|
+
# Print user-friendly startup message
|
537
|
+
print(f"\nSignalWire Web Service starting...")
|
538
|
+
print(f"URL: {startup_url}")
|
539
|
+
print(f"Directories: {', '.join(self.directories.keys()) if self.directories else 'None'}")
|
540
|
+
print(f"Basic Auth: {username}:{password}")
|
541
|
+
print(f"Directory Browsing: {'Enabled' if self.enable_directory_browsing else 'Disabled'}")
|
542
|
+
if ssl_kwargs:
|
543
|
+
print(f"SSL: Enabled")
|
544
|
+
print("")
|
545
|
+
|
546
|
+
try:
|
547
|
+
import uvicorn
|
548
|
+
uvicorn.run(
|
549
|
+
self.app,
|
550
|
+
host=host,
|
551
|
+
port=port,
|
552
|
+
**ssl_kwargs
|
553
|
+
)
|
554
|
+
except ImportError:
|
555
|
+
raise RuntimeError("uvicorn not available. Cannot start HTTP service.")
|
556
|
+
|
557
|
+
def stop(self):
|
558
|
+
"""Stop the service (placeholder for cleanup)"""
|
559
|
+
pass
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents.egg-info/SOURCES.txt
RENAMED
@@ -135,4 +135,6 @@ signalwire_agents/utils/__init__.py
|
|
135
135
|
signalwire_agents/utils/pom_utils.py
|
136
136
|
signalwire_agents/utils/schema_utils.py
|
137
137
|
signalwire_agents/utils/token_generators.py
|
138
|
-
signalwire_agents/utils/validators.py
|
138
|
+
signalwire_agents/utils/validators.py
|
139
|
+
signalwire_agents/web/__init__.py
|
140
|
+
signalwire_agents/web/web_service.py
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/cli/core/__init__.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/cli/core/agent_loader.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/cli/core/argparse_helpers.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/cli/core/dynamic_config.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/cli/core/service_loader.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/cli/execution/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/cli/output/__init__.py
RENAMED
File without changes
|
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/cli/output/swml_dump.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/cli/simulation/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/cli/simulation/mock_env.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/cli/swaig_test_wrapper.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/agent/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/agent/prompt/manager.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/agent/swml/__init__.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/agent/tools/__init__.py
RENAMED
File without changes
|
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/agent/tools/registry.py
RENAMED
File without changes
|
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/auth_handler.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/config_loader.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/function_result.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/logging_config.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/mixins/__init__.py
RENAMED
File without changes
|
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/mixins/auth_mixin.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/mixins/prompt_mixin.py
RENAMED
File without changes
|
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/mixins/skill_mixin.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/mixins/state_mixin.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/mixins/tool_mixin.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/mixins/web_mixin.py
RENAMED
File without changes
|
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/security/__init__.py
RENAMED
File without changes
|
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/security_config.py
RENAMED
File without changes
|
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/skill_manager.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/swaig_function.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/swml_builder.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/swml_handler.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/swml_renderer.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/core/swml_service.py
RENAMED
File without changes
|
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/prefabs/concierge.py
RENAMED
File without changes
|
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/prefabs/info_gatherer.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/prefabs/receptionist.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/search/document_processor.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/search/index_builder.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/search/pgvector_backend.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/search/query_processor.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/search/search_engine.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/search/search_service.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/datasphere/README.md
RENAMED
File without changes
|
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/datasphere/skill.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/datetime/README.md
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/datetime/__init__.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/datetime/skill.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/joke/README.md
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/joke/__init__.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/joke/skill.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/math/README.md
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/math/__init__.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/math/skill.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/mcp_gateway/README.md
RENAMED
File without changes
|
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/mcp_gateway/skill.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/spider/README.md
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/spider/__init__.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/spider/skill.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/weather_api/README.md
RENAMED
File without changes
|
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/weather_api/skill.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/web_search/README.md
RENAMED
File without changes
|
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/skills/web_search/skill.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/utils/schema_utils.py
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents/utils/token_generators.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents.egg-info/entry_points.txt
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents.egg-info/requires.txt
RENAMED
File without changes
|
{signalwire_agents-0.1.43 → signalwire_agents-0.1.44}/signalwire_agents.egg-info/top_level.txt
RENAMED
File without changes
|