config.mojo (14799B)
1 from std.os.path import exists 2 from std.pathlib import Path 3 4 from morph.toml import from_toml 5 6 # ADR-0010 D21 fixes the request-budget derivation, not this value: the absolute 7 # budget is min(positive request deadline, the configured provider 8 # request_timeout_ms). This named constant preserves the pre-existing 15000 ms 9 # default for H092's derivation; it is not a D21-selected bound, and it is not 10 # enlarged or weakened here. 11 comptime DEFAULT_PROVIDER_REQUEST_TIMEOUT_MS: Int = 15000 12 13 14 @fieldwise_init 15 struct HyfServiceRuntimeConfig(Copyable, Defaultable, Movable): 16 var transport: String 17 18 def __init__(out self): 19 self.transport = "stdio" 20 21 22 @fieldwise_init 23 struct HyfExecutionRuntimeConfig(Copyable, Defaultable, Movable): 24 var default_execution_mode: String 25 var allow_assisted: Bool 26 var enable_farm_update_interpret: Bool 27 var enable_buyer_request_interpret: Bool 28 var enable_buyer_request_match: Bool 29 var disable_provider: Bool 30 31 def __init__(out self): 32 self.default_execution_mode = "deterministic" 33 self.allow_assisted = False 34 self.enable_farm_update_interpret = False 35 self.enable_buyer_request_interpret = False 36 self.enable_buyer_request_match = False 37 self.disable_provider = False 38 39 40 @fieldwise_init 41 struct HyfMaxLocalProviderRuntimeConfig(Copyable, Defaultable, Movable): 42 var enabled: Bool 43 var base_url: String 44 var health_url: String 45 var model: String 46 var request_timeout_ms: Int 47 48 def __init__(out self): 49 self.enabled = False 50 self.base_url = "" 51 self.health_url = "" 52 self.model = "" 53 self.request_timeout_ms = 0 54 55 56 @fieldwise_init 57 struct HyfTypesafeProviderRuntimeConfig(Copyable, Defaultable, Movable): 58 var enabled: Bool 59 var base_url: String 60 var model: String 61 var request_timeout_ms: Int 62 63 def __init__(out self): 64 self.enabled = False 65 self.base_url = "https://api.typesafe.ai" 66 self.model = "jev-1.13.0" 67 self.request_timeout_ms = DEFAULT_PROVIDER_REQUEST_TIMEOUT_MS 68 69 70 @fieldwise_init 71 struct HyfAssistedRuntimeConfig(Copyable, Defaultable, Movable): 72 var provider: String 73 var max_local: HyfMaxLocalProviderRuntimeConfig 74 var typesafe: HyfTypesafeProviderRuntimeConfig 75 76 def __init__(out self): 77 self.provider = "" 78 self.max_local = HyfMaxLocalProviderRuntimeConfig() 79 self.typesafe = HyfTypesafeProviderRuntimeConfig() 80 81 82 @fieldwise_init 83 struct HyfRuntimeConfig(Copyable, Defaultable, Movable): 84 var service: HyfServiceRuntimeConfig 85 var runtime: HyfExecutionRuntimeConfig 86 var assisted: HyfAssistedRuntimeConfig 87 88 def __init__(out self): 89 self.service = HyfServiceRuntimeConfig() 90 self.runtime = HyfExecutionRuntimeConfig() 91 self.assisted = HyfAssistedRuntimeConfig() 92 93 94 @fieldwise_init 95 struct HyfLoadedRuntimeConfig(Copyable, Movable): 96 var artifact_present: Bool 97 var loaded: Bool 98 var compiled_defaults_active: Bool 99 var load_state: String 100 var load_error: String 101 var effective: HyfRuntimeConfig 102 103 104 def default_runtime_config() -> HyfRuntimeConfig: 105 return HyfRuntimeConfig() 106 107 108 def default_loaded_runtime_config() -> HyfLoadedRuntimeConfig: 109 return HyfLoadedRuntimeConfig( 110 artifact_present=False, 111 loaded=False, 112 compiled_defaults_active=True, 113 load_state="not_found", 114 load_error="", 115 effective=default_runtime_config(), 116 ) 117 118 119 def assisted_execution_enabled(config: HyfLoadedRuntimeConfig) -> Bool: 120 return config.effective.runtime.allow_assisted 121 122 123 def assisted_runtime_configured(config: HyfLoadedRuntimeConfig) -> Bool: 124 if not config.effective.runtime.allow_assisted: 125 return False 126 if config.effective.assisted.provider == "max_local": 127 return config.effective.assisted.max_local.enabled 128 if config.effective.assisted.provider == "typesafe": 129 return config.effective.assisted.typesafe.enabled 130 return False 131 132 133 def operation_enabled( 134 config: HyfLoadedRuntimeConfig, operation: String 135 ) -> Bool: 136 if config.effective.runtime.disable_provider: 137 return False 138 if operation == "farm_update.interpret": 139 return config.effective.runtime.enable_farm_update_interpret 140 if operation == "buyer_request.interpret": 141 return config.effective.runtime.enable_buyer_request_interpret 142 if operation == "buyer_request.match": 143 return config.effective.runtime.enable_buyer_request_match 144 return False 145 146 147 def provider_disabled(config: HyfLoadedRuntimeConfig) -> Bool: 148 return config.effective.runtime.disable_provider 149 150 151 def typesafe_provider_configured(config: HyfLoadedRuntimeConfig) -> Bool: 152 return ( 153 config.effective.runtime.allow_assisted 154 and config.effective.assisted.provider == "typesafe" 155 and config.effective.assisted.typesafe.enabled 156 ) 157 158 159 def max_local_provider_configured(config: HyfLoadedRuntimeConfig) -> Bool: 160 return assisted_runtime_configured(config) 161 162 163 def load_runtime_config(path: String) -> HyfLoadedRuntimeConfig: 164 var defaults = default_runtime_config() 165 if String(path).strip() == "" or not exists(path): 166 return default_loaded_runtime_config() 167 168 try: 169 var config_text = Path(path).read_text() 170 _reject_removed_max_local_route_config(config_text) 171 var config = from_toml[HyfRuntimeConfig](config_text) 172 _validate_runtime_config(config) 173 return HyfLoadedRuntimeConfig( 174 artifact_present=True, 175 loaded=True, 176 compiled_defaults_active=False, 177 load_state="loaded", 178 load_error="", 179 effective=config^, 180 ) 181 except e: 182 return HyfLoadedRuntimeConfig( 183 artifact_present=True, 184 loaded=False, 185 compiled_defaults_active=True, 186 load_state="invalid", 187 load_error=String(e), 188 effective=defaults^, 189 ) 190 191 192 def _validate_runtime_config(config: HyfRuntimeConfig) raises: 193 if config.service.transport != "stdio": 194 raise Error("service.transport must be 'stdio'") 195 196 if config.runtime.default_execution_mode != "deterministic": 197 raise Error( 198 "runtime.default_execution_mode must be 'deterministic' in the" 199 " foundation wave" 200 ) 201 202 if config.assisted.provider != "": 203 _require_no_boundary_whitespace( 204 config.assisted.provider, "assisted.provider" 205 ) 206 207 if config.runtime.allow_assisted: 208 if ( 209 config.assisted.provider != "max_local" 210 and config.assisted.provider != "typesafe" 211 ): 212 raise Error( 213 "assisted.provider must be 'max_local' or 'typesafe' when" 214 " runtime.allow_assisted is true" 215 ) 216 217 if ( 218 config.assisted.provider != "" 219 and config.assisted.provider != "max_local" 220 and config.assisted.provider != "typesafe" 221 ): 222 raise Error("assisted.provider must be 'max_local' or 'typesafe'") 223 224 if config.assisted.typesafe.enabled: 225 if not config.runtime.allow_assisted: 226 raise Error( 227 "runtime.allow_assisted must be true when" 228 " assisted.typesafe.enabled is true" 229 ) 230 if config.assisted.provider != "typesafe": 231 raise Error( 232 "assisted.provider must be 'typesafe' when" 233 " assisted.typesafe.enabled is true" 234 ) 235 _validate_typesafe_provider_config(config.assisted.typesafe) 236 237 if config.assisted.max_local.enabled: 238 if not config.runtime.allow_assisted: 239 raise Error( 240 "runtime.allow_assisted must be true when" 241 " assisted.max_local.enabled is true" 242 ) 243 if config.assisted.provider != "max_local": 244 raise Error( 245 "assisted.provider must be 'max_local' when" 246 " assisted.max_local.enabled is true" 247 ) 248 _validate_max_local_provider_config(config.assisted.max_local) 249 250 251 def _require_non_empty(value: String, context: String) raises: 252 if String(value).strip() == "": 253 raise Error(context + " must not be empty") 254 255 256 def _require_no_boundary_whitespace(value: String, context: String) raises: 257 if String(value) != String(value).strip(): 258 raise Error( 259 context + " must not include leading or trailing whitespace" 260 ) 261 262 263 def _require_http_url(value: String, context: String) raises: 264 if not (value.startswith("http://") or value.startswith("https://")): 265 raise Error(context + " must use http or https") 266 267 268 def _strip_toml_key_quotes(value: String) -> String: 269 var stripped = String(String(value).strip()) 270 if stripped.byte_length() < 2: 271 return stripped^ 272 273 var bytes = stripped.as_bytes() 274 var last_index = stripped.byte_length() - 1 275 if bytes[0] == UInt8(ord('"')) and bytes[last_index] == UInt8(ord('"')): 276 return String(stripped[byte=1:last_index]) 277 if bytes[0] == UInt8(ord("'")) and bytes[last_index] == UInt8(ord("'")): 278 return String(stripped[byte=1:last_index]) 279 return stripped^ 280 281 282 def _normalize_toml_key_path(key: String) -> String: 283 var normalized = String("") 284 for raw_part in key.split("."): 285 var part = _strip_toml_key_quotes(String(String(raw_part).strip())) 286 if normalized == "": 287 normalized = part 288 else: 289 normalized += "." + part 290 return normalized^ 291 292 293 def _toml_delimiter_index_outside_quotes( 294 text: String, delimiter: UInt8, start_index: Int 295 ) -> Int: 296 var bytes = text.as_bytes() 297 var index = start_index 298 var in_basic_string = False 299 var in_literal_string = False 300 var escaped = False 301 while index < text.byte_length(): 302 var byte = bytes[index] 303 if in_basic_string: 304 if escaped: 305 escaped = False 306 elif byte == UInt8(ord("\\")): 307 escaped = True 308 elif byte == UInt8(ord('"')): 309 in_basic_string = False 310 elif in_literal_string: 311 if byte == UInt8(ord("'")): 312 in_literal_string = False 313 else: 314 if byte == UInt8(ord('"')): 315 in_basic_string = True 316 elif byte == UInt8(ord("'")): 317 in_literal_string = True 318 elif byte == delimiter: 319 return index 320 index += 1 321 return -1 322 323 324 def _inline_table_contains_route_key(value: String) -> Bool: 325 var table = String(String(value).strip()) 326 var open_index = _toml_delimiter_index_outside_quotes( 327 table, UInt8(ord("{")), 0 328 ) 329 if open_index < 0: 330 return False 331 var close_index = _toml_delimiter_index_outside_quotes( 332 table, UInt8(ord("}")), open_index + 1 333 ) 334 if close_index < 0 or close_index <= open_index: 335 close_index = table.byte_length() 336 337 var body = String(table[byte = open_index + 1 : close_index]) 338 var field_start = 0 339 while field_start <= body.byte_length(): 340 var comma_index = _toml_delimiter_index_outside_quotes( 341 body, UInt8(ord(",")), field_start 342 ) 343 var field_end = comma_index 344 if field_end < 0: 345 field_end = body.byte_length() 346 347 var field = String(String(body[byte=field_start:field_end]).strip()) 348 var equals_index = _toml_delimiter_index_outside_quotes( 349 field, UInt8(ord("=")), 0 350 ) 351 if equals_index < 0: 352 if comma_index < 0: 353 break 354 field_start = comma_index + 1 355 continue 356 else: 357 var key = String(String(field[byte=0:equals_index]).strip()) 358 if _normalize_toml_key_path(key) == "route": 359 return True 360 361 if comma_index < 0: 362 break 363 field_start = comma_index + 1 364 return False 365 366 367 def _reject_removed_max_local_route_config(config_text: String) raises: 368 var in_max_local = False 369 for raw_line in config_text.splitlines(): 370 var line = String(String(raw_line).strip()) 371 if line == "" or line.startswith("#"): 372 continue 373 if line.startswith("["): 374 var close_index = line.find("]") 375 if close_index < 0: 376 in_max_local = False 377 continue 378 var table_name = String(String(line[byte=1:close_index]).strip()) 379 in_max_local = ( 380 _normalize_toml_key_path(table_name) == "assisted.max_local" 381 ) 382 continue 383 var equals_index = line.find("=") 384 if equals_index < 0: 385 continue 386 var key = _normalize_toml_key_path( 387 String(String(line[byte=0:equals_index]).strip()) 388 ) 389 var value = String(String(line[byte = equals_index + 1 :]).strip()) 390 if ( 391 (in_max_local and key == "route") 392 or key == "assisted.max_local.route" 393 or ( 394 key == "assisted.max_local" 395 and _inline_table_contains_route_key(value) 396 ) 397 ): 398 raise Error( 399 "assisted.max_local.route has been removed; provider route is" 400 " derived by HYF" 401 ) 402 403 404 def _validate_typesafe_provider_config( 405 config: HyfTypesafeProviderRuntimeConfig, 406 ) raises: 407 _require_non_empty(config.base_url, "assisted.typesafe.base_url") 408 _require_no_boundary_whitespace( 409 config.base_url, "assisted.typesafe.base_url" 410 ) 411 if not config.base_url.startswith("https://"): 412 raise Error("assisted.typesafe.base_url must use https") 413 _require_non_empty(config.model, "assisted.typesafe.model") 414 _require_no_boundary_whitespace(config.model, "assisted.typesafe.model") 415 if config.request_timeout_ms <= 0: 416 raise Error( 417 "assisted.typesafe.request_timeout_ms must be greater than zero" 418 ) 419 420 421 def _validate_max_local_provider_config( 422 config: HyfMaxLocalProviderRuntimeConfig, 423 ) raises: 424 _require_non_empty(config.base_url, "assisted.max_local.base_url") 425 _require_no_boundary_whitespace( 426 config.base_url, "assisted.max_local.base_url" 427 ) 428 _require_http_url(config.base_url, "assisted.max_local.base_url") 429 _require_non_empty(config.health_url, "assisted.max_local.health_url") 430 _require_no_boundary_whitespace( 431 config.health_url, "assisted.max_local.health_url" 432 ) 433 _require_http_url(config.health_url, "assisted.max_local.health_url") 434 _require_non_empty(config.model, "assisted.max_local.model") 435 _require_no_boundary_whitespace(config.model, "assisted.max_local.model") 436 if config.request_timeout_ms <= 0: 437 raise Error( 438 "assisted.max_local.request_timeout_ms must be greater than zero" 439 )