tiphys.bootstrap
Application bootstrap and context factory.
This module is the Composition Root - the single place where the entire application object graph is assembled.
1""" 2Application bootstrap and context factory. 3 4This module is the Composition Root - the single place where 5the entire application object graph is assembled. 6""" 7 8from __future__ import annotations 9 10from pathlib import Path 11from typing import TYPE_CHECKING, Any 12 13from tiphys.config import TiphysConfig, load_config 14from tiphys.context import AppContext, set_context 15 16if TYPE_CHECKING: 17 from tiphys.hooks.manager import HookManager 18 from tiphys.plugins.registry import PluginRegistry 19 from tiphys.routing.registry import AgentRegistry 20 from tiphys.routing.resolver import RouteResolver 21 from tiphys.security.policy import PolicyEngine 22 from tiphys.server.bus import EventBus 23 from tiphys.tools.base import ToolRegistry 24 25 26async def create_app_context( 27 config: TiphysConfig | None = None, 28 config_path: Path | None = None, 29 *, 30 # Optional overrides for testing 31 event_bus: EventBus | None = None, 32 hook_manager: HookManager | None = None, 33 tool_registry: ToolRegistry | None = None, 34 agent_registry: AgentRegistry | None = None, 35 plugin_registry: PluginRegistry | None = None, 36 route_resolver: RouteResolver | None = None, 37 policy_engine: PolicyEngine | None = None, 38 register_tools: bool = True, 39 run_startup: bool = True, 40 set_as_current: bool = True, 41) -> AppContext: 42 """ 43 Create and initialize the application context. 44 45 This is the main factory function for bootstrapping the application. 46 It creates all services, wires dependencies, and runs initialization. 47 48 Args: 49 config: Optional pre-loaded config. Loaded from environment if not provided. 50 config_path: Optional path to config file. 51 event_bus: Optional EventBus instance (for testing). 52 hook_manager: Optional HookManager instance (for testing). 53 tool_registry: Optional ToolRegistry instance (for testing). 54 agent_registry: Optional AgentRegistry instance (for testing). 55 plugin_registry: Optional PluginRegistry instance (for testing). 56 route_resolver: Optional RouteResolver instance (for testing). 57 policy_engine: Optional PolicyEngine instance (for testing). 58 register_tools: Whether to register built-in tools. Defaults to True. 59 run_startup: Whether to run startup hooks. Defaults to True. 60 set_as_current: Whether to set as current context. Defaults to True. 61 62 Returns: 63 Fully initialized AppContext. 64 65 Example: 66 # Standard usage 67 ctx = await create_app_context() 68 69 # With custom config 70 ctx = await create_app_context(config=my_config) 71 72 # For testing with mocks 73 ctx = await create_app_context( 74 config=test_config, 75 event_bus=mock_bus, 76 run_startup=False, 77 set_as_current=False, 78 ) 79 """ 80 # Load config if not provided 81 if config is None: 82 config = load_config() 83 84 # Create the context with all provided overrides 85 ctx = AppContext( 86 config=config, 87 event_bus=event_bus, # type: ignore[arg-type] 88 hook_manager=hook_manager, # type: ignore[arg-type] 89 tool_registry=tool_registry, # type: ignore[arg-type] 90 agent_registry=agent_registry, # type: ignore[arg-type] 91 plugin_registry=plugin_registry, 92 route_resolver=route_resolver, 93 policy_engine=policy_engine, 94 ) 95 96 # Register built-in tools 97 if register_tools: 98 from tiphys.tools import register_builtin_tools 99 100 register_builtin_tools(ctx.tool_registry) 101 102 # Wire Castor kernel services (L1 Guard + L2 Deep Guard) 103 if config.budget.enabled: 104 _wire_castor_guard(ctx) 105 _wire_castor_kernel(ctx) 106 107 # Set as current context 108 if set_as_current: 109 set_context(ctx) 110 111 # Run startup hooks 112 if run_startup: 113 await ctx.startup() 114 115 return ctx 116 117 118def create_app_context_sync( 119 config: TiphysConfig | None = None, 120 **kwargs: Any, 121) -> AppContext: 122 """ 123 Create application context synchronously (without running async startup). 124 125 Useful for testing or when you need to create context outside async context. 126 127 Args: 128 config: Optional pre-loaded config. 129 **kwargs: Additional arguments passed to AppContext. 130 131 Returns: 132 AppContext (startup hooks not run). 133 """ 134 if config is None: 135 config = load_config() 136 137 ctx = AppContext(config=config, **kwargs) 138 139 from tiphys.tools import register_builtin_tools 140 141 register_builtin_tools(ctx.tool_registry) 142 143 # Wire Castor kernel services (L1 Guard + L2 Deep Guard) 144 if config.budget.enabled: 145 _wire_castor_guard(ctx) 146 _wire_castor_kernel(ctx) 147 148 set_context(ctx) 149 150 return ctx 151 152 153def _wire_castor_guard(ctx: AppContext) -> None: 154 """Create and attach Castor L1 Guard services to the AppContext.""" 155 from castor import CapabilityManager, SyscallGate 156 from castor.gate.registry import ToolRegistry as CastorToolRegistry 157 158 from tiphys.kernel.bridge import HITLBridge 159 from tiphys.kernel.budget import SessionBudgetManager 160 from tiphys.kernel.guard import TiphysGuard 161 from tiphys.kernel.tools import register_chela_tools 162 163 # Build Castor tool registry from Tiphys's registered tools 164 castor_tool_registry = CastorToolRegistry() 165 register_chela_tools(ctx.tool_registry, castor_tool_registry) 166 167 # Create Castor subsystems 168 gate = SyscallGate(castor_tool_registry) 169 cap_mgr = CapabilityManager() 170 171 # Assemble guard and budget manager 172 ctx.castor_guard = TiphysGuard(gate, cap_mgr) 173 ctx.session_budget_mgr = SessionBudgetManager(ctx.config.budget, cap_mgr) 174 ctx.hitl_bridge = HITLBridge(ctx.event_bus) 175 176 177def _wire_castor_kernel(ctx: AppContext) -> None: 178 """Create and attach Castor L2 Deep Guard services to the AppContext.""" 179 from castor import Castor 180 181 from tiphys.kernel.bridge import CheckpointHITLBridge 182 from tiphys.kernel.runner import CastorAgentRunner 183 184 # Build the Castor kernel facade (reuses L1 guard's Gate if available) 185 gate = ctx.castor_guard.gate if ctx.castor_guard else None 186 cap_mgr = ctx.castor_guard.capability_manager if ctx.castor_guard else None 187 kernel = Castor( 188 gate=gate, 189 capability_manager=cap_mgr, 190 store=ctx.checkpoint_store, 191 default_budgets=ctx.config.budget.default_budgets, 192 ) 193 ctx.castor_kernel = kernel 194 195 # Create CastorAgentRunner 196 ctx.castor_agent_runner = CastorAgentRunner(context=ctx) 197 198 # Create L2 checkpoint HITL bridge 199 ctx.checkpoint_hitl_bridge = CheckpointHITLBridge( 200 event_bus=ctx.event_bus, 201 kernel=kernel, 202 )
27async def create_app_context( 28 config: TiphysConfig | None = None, 29 config_path: Path | None = None, 30 *, 31 # Optional overrides for testing 32 event_bus: EventBus | None = None, 33 hook_manager: HookManager | None = None, 34 tool_registry: ToolRegistry | None = None, 35 agent_registry: AgentRegistry | None = None, 36 plugin_registry: PluginRegistry | None = None, 37 route_resolver: RouteResolver | None = None, 38 policy_engine: PolicyEngine | None = None, 39 register_tools: bool = True, 40 run_startup: bool = True, 41 set_as_current: bool = True, 42) -> AppContext: 43 """ 44 Create and initialize the application context. 45 46 This is the main factory function for bootstrapping the application. 47 It creates all services, wires dependencies, and runs initialization. 48 49 Args: 50 config: Optional pre-loaded config. Loaded from environment if not provided. 51 config_path: Optional path to config file. 52 event_bus: Optional EventBus instance (for testing). 53 hook_manager: Optional HookManager instance (for testing). 54 tool_registry: Optional ToolRegistry instance (for testing). 55 agent_registry: Optional AgentRegistry instance (for testing). 56 plugin_registry: Optional PluginRegistry instance (for testing). 57 route_resolver: Optional RouteResolver instance (for testing). 58 policy_engine: Optional PolicyEngine instance (for testing). 59 register_tools: Whether to register built-in tools. Defaults to True. 60 run_startup: Whether to run startup hooks. Defaults to True. 61 set_as_current: Whether to set as current context. Defaults to True. 62 63 Returns: 64 Fully initialized AppContext. 65 66 Example: 67 # Standard usage 68 ctx = await create_app_context() 69 70 # With custom config 71 ctx = await create_app_context(config=my_config) 72 73 # For testing with mocks 74 ctx = await create_app_context( 75 config=test_config, 76 event_bus=mock_bus, 77 run_startup=False, 78 set_as_current=False, 79 ) 80 """ 81 # Load config if not provided 82 if config is None: 83 config = load_config() 84 85 # Create the context with all provided overrides 86 ctx = AppContext( 87 config=config, 88 event_bus=event_bus, # type: ignore[arg-type] 89 hook_manager=hook_manager, # type: ignore[arg-type] 90 tool_registry=tool_registry, # type: ignore[arg-type] 91 agent_registry=agent_registry, # type: ignore[arg-type] 92 plugin_registry=plugin_registry, 93 route_resolver=route_resolver, 94 policy_engine=policy_engine, 95 ) 96 97 # Register built-in tools 98 if register_tools: 99 from tiphys.tools import register_builtin_tools 100 101 register_builtin_tools(ctx.tool_registry) 102 103 # Wire Castor kernel services (L1 Guard + L2 Deep Guard) 104 if config.budget.enabled: 105 _wire_castor_guard(ctx) 106 _wire_castor_kernel(ctx) 107 108 # Set as current context 109 if set_as_current: 110 set_context(ctx) 111 112 # Run startup hooks 113 if run_startup: 114 await ctx.startup() 115 116 return ctx
Create and initialize the application context.
This is the main factory function for bootstrapping the application. It creates all services, wires dependencies, and runs initialization.
Args: config: Optional pre-loaded config. Loaded from environment if not provided. config_path: Optional path to config file. event_bus: Optional EventBus instance (for testing). hook_manager: Optional HookManager instance (for testing). tool_registry: Optional ToolRegistry instance (for testing). agent_registry: Optional AgentRegistry instance (for testing). plugin_registry: Optional PluginRegistry instance (for testing). route_resolver: Optional RouteResolver instance (for testing). policy_engine: Optional PolicyEngine instance (for testing). register_tools: Whether to register built-in tools. Defaults to True. run_startup: Whether to run startup hooks. Defaults to True. set_as_current: Whether to set as current context. Defaults to True.
Returns: Fully initialized AppContext.
Example: # Standard usage ctx = await create_app_context()
# With custom config
ctx = await create_app_context(config=my_config)
# For testing with mocks
ctx = await create_app_context(
config=test_config,
event_bus=mock_bus,
run_startup=False,
set_as_current=False,
)
119def create_app_context_sync( 120 config: TiphysConfig | None = None, 121 **kwargs: Any, 122) -> AppContext: 123 """ 124 Create application context synchronously (without running async startup). 125 126 Useful for testing or when you need to create context outside async context. 127 128 Args: 129 config: Optional pre-loaded config. 130 **kwargs: Additional arguments passed to AppContext. 131 132 Returns: 133 AppContext (startup hooks not run). 134 """ 135 if config is None: 136 config = load_config() 137 138 ctx = AppContext(config=config, **kwargs) 139 140 from tiphys.tools import register_builtin_tools 141 142 register_builtin_tools(ctx.tool_registry) 143 144 # Wire Castor kernel services (L1 Guard + L2 Deep Guard) 145 if config.budget.enabled: 146 _wire_castor_guard(ctx) 147 _wire_castor_kernel(ctx) 148 149 set_context(ctx) 150 151 return ctx
Create application context synchronously (without running async startup).
Useful for testing or when you need to create context outside async context.
Args: config: Optional pre-loaded config. **kwargs: Additional arguments passed to AppContext.
Returns: AppContext (startup hooks not run).