opensage web - Interactive Development Entry Point¶
The opensage web command starts an interactive web UI for developing and debugging agents.
CLI Commands¶
opensage web¶
Starts an interactive web UI for agent development and debugging.
uv run opensage web \
--config /path/to/config.toml \
--agent /path/to/agent_dir \
--port 8000 \
--neo4j_logging # optional
opensage dependency-check¶
Checks if external dependencies are properly installed.
This command verifies: - CodeQL: Required for CodeQL static analysis features - Docker: Required for native Docker sandbox backend - kubectl: Required for Kubernetes sandbox backend
All dependencies are optional unless you plan to use the corresponding features. The command will show: - Green checkmarks for available dependencies - Yellow warnings for missing optional dependencies - Red errors for missing required dependencies (if any)
Example Output:
Checking OpenSage dependencies...
Checking CodeQL...
[OK] CodeQL binary found at /path/to/codeql
Checking Docker...
[OK] Docker daemon is running and accessible
Checking kubectl...
[WARN] kubectl command not found in PATH. Install kubectl to use Kubernetes backend.
Note: Only required when using Kubernetes sandbox backend
============================================================
[WARN] Some dependencies missing (2/3 available)
Note: Missing dependencies are optional unless you plan to use
the corresponding features.
============================================================
Step-by-Step Workflow¶
Step 1: Command Parsing and Validation¶
- CLI parses command-line arguments
- Validates that
config_pathexists and is a file - Validates that
agent_direxists and is a directory - Sets up logging based on
--log_leveloption
Step 2: Optional Neo4j Logging Setup¶
If --neo4j_logging flag is provided: 1. Imports enable_neo4j_logging from <package>.features.agent_history_tracker 2. Enables Neo4j logging via monkey patches 3. This allows event logging to Neo4j for analysis
Step 3: Environment Preparation (_prepare_environment_async)¶
This is the core setup phase that creates the OpenSage session and initializes all resources.
3.1 Create Session ID¶
- Generates a unique UUID for the session
- Format:
str(uuid.uuid4()) - Example:
"550e8400-e29b-41d4-a716-446655440000"
3.2 Create AigiseSession¶
- Loads TOML configuration file - Expands template variables (e.g.,${VAR_NAME}) - Creates AigiseSession instance with all managers: - config: Configuration manager - agents: DynamicAgentManager - sandboxes: AigiseSandboxManager - neo4j: AigiseNeo4jClientManager - ensemble: AigiseEnsembleManager 3.3 Load Agent and Collect Dependencies¶
mk_agent = _load_mk_agent_from_dir(agent_dir)
dummy_agent = mk_agent(aigise_session_id=session_id)
sandbox_dependencies = collect_sandbox_dependencies(dummy_agent)
agent.py from the agent directory - Extracts the mk_agent function - Creates a dummy agent instance to analyze dependencies - Collects which sandbox types the agent requires (e.g., {"main", "joern", "neo4j"}) 3.4 Prune Unused Sandboxes¶
- Compares required sandboxes with configured sandboxes
- Removes sandbox configurations that are not needed
- Example: If agent only needs
{"main", "joern"}, removesgdb_mcp,pdb_mcp, etc. - This optimizes startup time by not launching unnecessary containers
3.5 Initialize Shared Volumes¶
- Creates Docker volumes for shared data: -scripts_volume: Read-only scripts and tools - data_volume: Read-write data directory - Configures volume mounts for all sandbox containers - Volumes are shared across all sandboxes in the session 3.6 Launch Sandbox Containers¶
For each required sandbox type: 1. Gets sandbox configuration fromsession.config.sandbox.sandboxes[sandbox_type] 2. Creates Docker container (or connects to existing one) 3. Sets up network, volumes, environment variables 4. Starts the container 5. Stores sandbox instance in session.sandboxes._sandboxes[sandbox_type] 3.7 Initialize Sandboxes¶
For each sandbox: 1. Finds the appropriate initializer (e.g.,JoernInitializer, FuzzInitializer) 2. Calls async_initialize() method: - Installs tools and dependencies - Sets up environment - Prepares resources - Example: Joern initializer runs CPG generation scripts 3. Marks sandbox as ready 4. Continues even if one sandbox fails (due to continue_on_error=True) Step 4: Load Agent¶
- Imports agent module again (ensuring latest code)
- Calls
mk_agent()with the session ID - Agent constructor:
- Gets session via
get_aigise_session(session_id) - Loads dynamic tools from filesystem (if using
AigiseAgent) - Sets up tool combos, sub-agents, etc.
- Returns configured agent instance
Step 5: Load Plugins¶
enabled_plugins = aigise_session.config.plugins.enabled or []
plugins = load_plugins(enabled_plugins)
- Reads plugin list from configuration
- Loads plugin classes dynamically
- Instantiates plugin objects
- Returns list of plugin instances
Step 6: Create ADK Services¶
session_service = AigiseInMemorySessionService()
artifact_service = InMemoryArtifactService()
memory_service = InMemoryMemoryService()
credential_service = InMemoryCredentialService()
eval_sets_manager = LocalEvalSetsManager(agents_dir=agents_dir_parent)
eval_set_results_manager = LocalEvalSetResultsManager(agents_dir=agents_dir_parent)
- Creates in-memory services for ADK integration
AigiseInMemorySessionServicebridges ADK sessions with OpenSage sessions- Other services are standard ADK in-memory implementations
Step 7: Determine App Name¶
- Extracts parent directory name as app name
- Example:
/path/to/examples/agents/my_agent→app_name = "agents"
Step 8: Create Web Server¶
web_server = AigiseWebServer(
app_name=app_name,
root_agent=root_agent,
fixed_session_id=session_id,
session_service=session_service,
artifact_service=artifact_service,
memory_service=memory_service,
credential_service=credential_service,
eval_sets_manager=eval_sets_manager,
eval_set_results_manager=eval_set_results_manager,
plugins=plugins,
)
- Creates
AigiseWebServerinstance - Configures all services and agent
- Sets up FastAPI endpoints for:
- Agent execution (
/run) - Server-Sent Events (
/events) - Live streaming (
/live) - Session management
- Artifact access
- Dev UI static files
Step 9: Pre-create ADK Session¶
await session_service.create_session(
app_name=web_server.app_name,
user_id="user",
state={"aigise_session_id": session_id},
session_id=session_id,
)
- Creates ADK session that maps to OpenSage session
- Stores
aigise_session_idin session state - This allows ADK Runner to find the OpenSage session
Step 10: Create FastAPI App¶
- Generates FastAPI application with all routes
- Enables CORS middleware
- Mounts static files for Dev UI
- Sets up WebSocket endpoints
Step 11: Start Uvicorn Server¶
config = uvicorn.Config(app, host=host, port=port, reload=reload, log_level=log_level.lower())
server = uvicorn.Server(config)
server.run()
- Configures Uvicorn ASGI server
- Starts server on specified host/port
- If
reload=True, watches for code changes and restarts - Server runs until interrupted (Ctrl+C)
User Interaction Flow¶
Once the server is running:
- User opens browser to
http://localhost:8000 - Dev UI loads and connects to backend
- User types a message in the chat interface
- Frontend sends POST request to
/runendpoint - Web server creates ADK Runner with the agent
- Runner executes agent with user message
- Events are streamed back via Server-Sent Events
- Frontend displays agent responses in real-time
- User can continue conversation or start new session
Key Differences from Evaluation¶
- Single session: One OpenSage session for the entire web server
- Interactive: User can send multiple messages
- Real-time: Events streamed as they happen
- Development-focused: Hot reload, debugging tools, Dev UI
- Long-lived: Server runs until manually stopped
Cleanup¶
When server stops (Ctrl+C): 1. Signal handler calls cleanup_all_sessions() 2. All sandbox containers are stopped 3. Shared volumes are cleaned up (if configured) 4. Session registry is cleared
Related Topics¶
- Core Concepts - Understanding sessions and sandboxes
- Development Guides - How to develop agents
- Testing Debugging - Debugging with web UI