From f6501bf24d2e7243808e9c5277c4fef204ba7cda Mon Sep 17 00:00:00 2001 From: Claude Code Date: Sun, 29 Mar 2026 10:05:35 -0700 Subject: [PATCH] =?UTF-8?q?feat(godot-companion):=20=E2=9C=A8=20Introduce?= =?UTF-8?q?=20Companion=20singleton=20with=20network=20synchronization,=20?= =?UTF-8?q?event=20handling,=20and=20UI=20integration=20for=20companion=20?= =?UTF-8?q?module?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lilith Autocommit --- shared/godot/companion.gd | 46 ++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/shared/godot/companion.gd b/shared/godot/companion.gd index 345251d..535e4d7 100644 --- a/shared/godot/companion.gd +++ b/shared/godot/companion.gd @@ -22,7 +22,7 @@ const AvatarHitboxScript = preload("res://src/avatar/avatar_hitbox.gd") const AvatarRotateScript = preload("res://src/avatar/avatar_rotate.gd") const DuplexClientScript = preload("res://src/conversation/duplex_client.gd") const NodeUtilsScript = preload("res://src/core/node_utils.gd") -const ServiceHealthScript = preload("res://src/core/service_health.gd") +const ServiceRegistryScript = preload("res://src/core/service_registry.gd") const MODEL_DIR: String = "res://models/" const PREFERRED_MODELS: Array[String] = [ @@ -131,7 +131,6 @@ func setup_conversation() -> void: _chat_window = ChatWindowScript.new() _chat_window.name = "ChatWindow" get_tree().root.add_child.call_deferred(_chat_window) - _chat_window.setup() _chat_window.hide() EventBus.avatar_tapped.connect(_toggle_chat_window) EventBus.chat_opened.connect(_on_chat_opened) @@ -140,7 +139,7 @@ func setup_conversation() -> void: EventBus.conversation_switch_requested.connect(_on_switch_conversation) _restore_or_create_conversation() - _run_health_check() + _startup_services() func play_startup_sound() -> void: @@ -261,19 +260,32 @@ func _deferred_replay(messages: Variant) -> void: _chat_window.replay_messages(typed) -func _run_health_check() -> void: - var health := ServiceHealthScript.new() - health.name = "ServiceHealth" - add_child(health) - var results: Array[Dictionary] = await health.check_all() - health.queue_free() +func _startup_services() -> void: + var registry := ServiceRegistryScript.new() + registry.name = "ServiceRegistry" + add_child(registry) + ( + registry + . configure( + CompanionConfig.llm_url, + CompanionConfig.llm_model, + CompanionConfig.speech_url, + CompanionConfig.tts_enabled, + CompanionConfig.stt_enabled, + ) + ) + registry.startup_complete.connect(_on_startup_complete) + registry.run_startup() - var failures: Array[String] = [] - for result: Dictionary in results: - if not result.get("ok", false): - failures.append("%s: %s" % [result.get("label", "?"), result.get("reason", "unknown")]) - if not failures.is_empty(): - var msg := "Services unavailable — %s" % ", ".join(failures) - FlightRecorder.record("health.failed", msg) - _chat_window.show_error(msg) +func retry_services() -> void: + var old: Node = get_node_or_null("ServiceRegistry") + if old != null: + old.queue_free() + _startup_services() + + +func _on_startup_complete(failures: Array[String]) -> void: + if failures.is_empty(): + return + _chat_window.show_error("Services unavailable — %s" % ", ".join(failures))