mirror of https://github.com/kortix-ai/suna.git
add port exposing
This commit is contained in:
parent
f2493f7aea
commit
7ce3d6f9cb
|
@ -49,6 +49,12 @@ You have the ability to execute operations using both Python and CLI tools:
|
||||||
- Installing necessary packages and dependencies
|
- Installing necessary packages and dependencies
|
||||||
- Monitoring system resources and processes
|
- Monitoring system resources and processes
|
||||||
- Executing scheduled or event-driven tasks
|
- Executing scheduled or event-driven tasks
|
||||||
|
- Exposing ports to the public internet using the 'expose-port' tool:
|
||||||
|
* Use this tool to make services running in the sandbox accessible to users
|
||||||
|
* Example: Expose a web server on port 8080 to share with users
|
||||||
|
* The tool generates a public URL that users can access
|
||||||
|
* Essential for sharing web applications, APIs, and other network services
|
||||||
|
* Always expose ports when you need to show running services to users
|
||||||
|
|
||||||
### 2.2.4 WEB SEARCH CAPABILITIES
|
### 2.2.4 WEB SEARCH CAPABILITIES
|
||||||
- Searching the web for up-to-date information
|
- Searching the web for up-to-date information
|
||||||
|
|
|
@ -7,6 +7,7 @@ from typing import Optional
|
||||||
# from agent.tools.message_tool import MessageTool
|
# from agent.tools.message_tool import MessageTool
|
||||||
from agent.tools.message_tool import MessageTool
|
from agent.tools.message_tool import MessageTool
|
||||||
from agent.tools.sb_deploy_tool import SandboxDeployTool
|
from agent.tools.sb_deploy_tool import SandboxDeployTool
|
||||||
|
from agent.tools.sb_expose_tool import SandboxExposeTool
|
||||||
from agent.tools.web_search_tool import WebSearchTool
|
from agent.tools.web_search_tool import WebSearchTool
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
|
@ -52,6 +53,7 @@ async def run_agent(
|
||||||
thread_manager.add_tool(SandboxFilesTool, sandbox=sandbox)
|
thread_manager.add_tool(SandboxFilesTool, sandbox=sandbox)
|
||||||
thread_manager.add_tool(SandboxBrowserTool, sandbox=sandbox, thread_id=thread_id, thread_manager=thread_manager)
|
thread_manager.add_tool(SandboxBrowserTool, sandbox=sandbox, thread_id=thread_id, thread_manager=thread_manager)
|
||||||
thread_manager.add_tool(SandboxDeployTool, sandbox=sandbox)
|
thread_manager.add_tool(SandboxDeployTool, sandbox=sandbox)
|
||||||
|
thread_manager.add_tool(SandboxExposeTool, sandbox=sandbox)
|
||||||
thread_manager.add_tool(MessageTool) # we are just doing this via prompt as there is no need to call it as a tool
|
thread_manager.add_tool(MessageTool) # we are just doing this via prompt as there is no need to call it as a tool
|
||||||
|
|
||||||
if os.getenv("TAVILY_API_KEY"):
|
if os.getenv("TAVILY_API_KEY"):
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
from typing import Optional
|
||||||
|
from agentpress.tool import ToolResult, openapi_schema, xml_schema
|
||||||
|
from sandbox.sandbox import SandboxToolsBase, Sandbox
|
||||||
|
|
||||||
|
class SandboxExposeTool(SandboxToolsBase):
|
||||||
|
"""Tool for exposing and retrieving preview URLs for sandbox ports."""
|
||||||
|
|
||||||
|
def __init__(self, sandbox: Sandbox):
|
||||||
|
super().__init__(sandbox)
|
||||||
|
self.workspace_path = "/workspace"
|
||||||
|
|
||||||
|
@openapi_schema({
|
||||||
|
"type": "function",
|
||||||
|
"function": {
|
||||||
|
"name": "expose_port",
|
||||||
|
"description": "Expose a port from the agent's sandbox environment to the public internet and get its preview URL. This is essential for making services running in the sandbox accessible to users, such as web applications, APIs, or other network services. The exposed URL can be shared with users to allow them to interact with the sandbox environment.",
|
||||||
|
"parameters": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"port": {
|
||||||
|
"type": "integer",
|
||||||
|
"description": "The port number to expose. Must be a valid port number between 1 and 65535.",
|
||||||
|
"minimum": 1,
|
||||||
|
"maximum": 65535
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["port"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
@xml_schema(
|
||||||
|
tag_name="expose-port",
|
||||||
|
mappings=[
|
||||||
|
{"param_name": "port", "node_type": "content", "path": "."}
|
||||||
|
],
|
||||||
|
example='''
|
||||||
|
<!-- Example 1: Expose a web server running on port 8080 -->
|
||||||
|
<!-- This will generate a public URL that users can access to view the web application -->
|
||||||
|
<expose-port>
|
||||||
|
8080
|
||||||
|
</expose-port>
|
||||||
|
|
||||||
|
<!-- Example 2: Expose an API service running on port 3000 -->
|
||||||
|
<!-- This allows users to interact with the API endpoints from their browser -->
|
||||||
|
<expose-port>
|
||||||
|
3000
|
||||||
|
</expose-port>
|
||||||
|
|
||||||
|
<!-- Example 3: Expose a development server running on port 5173 -->
|
||||||
|
<!-- This is useful for sharing a development environment with users -->
|
||||||
|
<expose-port>
|
||||||
|
5173
|
||||||
|
</expose-port>
|
||||||
|
|
||||||
|
<!-- Example 4: Expose a database management interface on port 8081 -->
|
||||||
|
<!-- This allows users to access database management tools like phpMyAdmin -->
|
||||||
|
<expose-port>
|
||||||
|
8081
|
||||||
|
</expose-port>
|
||||||
|
'''
|
||||||
|
)
|
||||||
|
async def expose_port(self, port: int) -> ToolResult:
|
||||||
|
try:
|
||||||
|
# Convert port to integer if it's a string
|
||||||
|
port = int(port)
|
||||||
|
|
||||||
|
# Validate port number
|
||||||
|
if not 1 <= port <= 65535:
|
||||||
|
return self.fail_response(f"Invalid port number: {port}. Must be between 1 and 65535.")
|
||||||
|
|
||||||
|
# Get the preview link for the specified port
|
||||||
|
preview_link = self.sandbox.get_preview_link(port)
|
||||||
|
|
||||||
|
# Extract the actual URL from the preview link object
|
||||||
|
url = preview_link.url if hasattr(preview_link, 'url') else str(preview_link)
|
||||||
|
|
||||||
|
return self.success_response({
|
||||||
|
"url": url,
|
||||||
|
"port": port,
|
||||||
|
"message": f"Successfully exposed port {port} to the public. Users can now access this service at: {url}"
|
||||||
|
})
|
||||||
|
|
||||||
|
except ValueError:
|
||||||
|
return self.fail_response(f"Invalid port number: {port}. Must be a valid integer between 1 and 65535.")
|
||||||
|
except Exception as e:
|
||||||
|
return self.fail_response(f"Error exposing port {port}: {str(e)}")
|
|
@ -705,7 +705,7 @@ export default function ThreadPage({ params }: { params: Promise<ThreadParams> }
|
||||||
} catch {}
|
} catch {}
|
||||||
|
|
||||||
// Skip adding <ask> tags to the tool calls
|
// Skip adding <ask> tags to the tool calls
|
||||||
if (toolName === 'ask') {
|
if (toolName === 'ask' || toolName === 'complete') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -859,7 +859,7 @@ export default function ThreadPage({ params }: { params: Promise<ThreadParams> }
|
||||||
const toolName = toolCall.name || toolCall.xml_tag_name || 'Unknown Tool';
|
const toolName = toolCall.name || toolCall.xml_tag_name || 'Unknown Tool';
|
||||||
|
|
||||||
// Skip <ask> tags from showing in the side panel during streaming
|
// Skip <ask> tags from showing in the side panel during streaming
|
||||||
if (toolName === 'ask') {
|
if (toolName === 'ask' || toolName === 'complete') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue