feat(autoloads-specific): ✨ Implement enhanced event bus logic, companion app configuration, and flight recorder with unique identifiers
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
12e4c83da6
commit
5185240bc5
4 changed files with 122 additions and 6 deletions
36
godot/scripts/autoloads/companion_config.gd
Normal file
36
godot/scripts/autoloads/companion_config.gd
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
extends Node
|
||||
## Runtime configuration loaded from chobit.cfg.
|
||||
## Checks user data dir first (user overrides), then res://config/chobit.cfg.
|
||||
## Falls back to hardcoded defaults if no config file is found.
|
||||
|
||||
var speech_url: String = "http://127.0.0.1:8000"
|
||||
var llm_url: String = "http://127.0.0.1:8210"
|
||||
var llm_model: String = "ministral-3b-instruct"
|
||||
var system_prompt: String = (
|
||||
"You are Miku, a warm and expressive AI companion. "
|
||||
+ "You respond with genuine curiosity and care. "
|
||||
+ "Keep responses conversational and natural — 1-3 sentences unless asked for more. "
|
||||
+ "Express your emotions naturally inline as [emotion] tags at the start of relevant sentences. "
|
||||
+ "Valid emotions: happy, sad, angry, surprised, relaxed, neutral."
|
||||
)
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
_load()
|
||||
|
||||
|
||||
func _load() -> void:
|
||||
var paths: Array[String] = [
|
||||
OS.get_user_data_dir() + "/chobit.cfg",
|
||||
"res://config/chobit.cfg",
|
||||
]
|
||||
var cfg := ConfigFile.new()
|
||||
for path: String in paths:
|
||||
if cfg.load(path) == OK:
|
||||
speech_url = cfg.get_value("backend", "speech_url", speech_url)
|
||||
llm_url = cfg.get_value("backend", "llm_url", llm_url)
|
||||
llm_model = cfg.get_value("backend", "llm_model", llm_model)
|
||||
system_prompt = cfg.get_value("companion", "system_prompt", system_prompt)
|
||||
FlightRecorder.record("config.loaded", "Loaded config from %s" % path, {})
|
||||
return
|
||||
FlightRecorder.record("config.default", "No config file found, using defaults", {})
|
||||
|
|
@ -12,17 +12,42 @@ signal emotion_changed(emotion: String)
|
|||
signal sentence_ready(text: String, emotion: String)
|
||||
|
||||
# Audio playback coordination (lipsync)
|
||||
signal audio_started()
|
||||
signal audio_finished()
|
||||
signal audio_started
|
||||
signal audio_finished
|
||||
|
||||
# Voice activity detection
|
||||
signal speech_detected()
|
||||
signal speech_ended()
|
||||
signal speech_detected
|
||||
signal speech_ended
|
||||
|
||||
# Transcription results
|
||||
signal transcript_ready(text: String)
|
||||
|
||||
# Backend communication
|
||||
signal backend_error(message: String)
|
||||
signal backend_connected()
|
||||
signal backend_disconnected()
|
||||
signal backend_connected
|
||||
signal backend_disconnected
|
||||
|
||||
# Vision / attention system
|
||||
signal face_detected(face_position: Vector2)
|
||||
signal attention_changed(state: String, confidence: float)
|
||||
signal face_lost
|
||||
signal gaze_mode_changed(mode: String)
|
||||
|
||||
# Animation board triggers
|
||||
signal gesture_requested(gesture_name: String)
|
||||
signal gaze_disengage(duration: float)
|
||||
|
||||
# Text input from chat window (bypasses voice pipeline)
|
||||
signal text_submitted(text: String)
|
||||
|
||||
# Avatar tapped (click without drag)
|
||||
signal avatar_tapped
|
||||
|
||||
# Sound settings panel
|
||||
signal sound_settings_opened
|
||||
|
||||
# Chat window
|
||||
signal chat_opened
|
||||
|
||||
# Context menu (right-click on avatar)
|
||||
signal context_menu_opened(position: Vector2i)
|
||||
|
|
|
|||
54
godot/scripts/autoloads/flight_recorder.gd
Normal file
54
godot/scripts/autoloads/flight_recorder.gd
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
extends Node
|
||||
## Structured event recordger matching @lilith/flight-recorder schema.
|
||||
## Reads DEBUG flag from ../.env (relative to res://).
|
||||
## When DEBUG=TRUE: streams JSON entries to stdout and appends to user://flight_recorder.jsonl.
|
||||
##
|
||||
## Schema: {"date":"YYYY-MM-DD","time":"HH:mm:ss.mmm","type":"...","content":"...","metadata":{...}|null}
|
||||
## Usage: FlightRecorder.record("system.event", "Human description", {"key": value})
|
||||
|
||||
var _debug: bool = false
|
||||
var _record_file: FileAccess
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
_debug = _read_debug_flag()
|
||||
if not _debug:
|
||||
return
|
||||
_record_file = FileAccess.open("user://flight_recorder.jsonl", FileAccess.WRITE)
|
||||
record("flight_recorder.init", "Flight recorder started", {"path": "user://flight_recorder.jsonl"})
|
||||
|
||||
|
||||
func record(type: String, content: String, metadata: Dictionary = {}) -> void:
|
||||
if not _debug:
|
||||
return
|
||||
var dt := Time.get_datetime_dict_from_system()
|
||||
var ms := Time.get_ticks_msec() % 1000
|
||||
var entry := {
|
||||
"date": "%04d-%02d-%02d" % [dt.year, dt.month, dt.day],
|
||||
"time": "%02d:%02d:%02d.%03d" % [dt.hour, dt.minute, dt.second, ms],
|
||||
"type": type,
|
||||
"content": content,
|
||||
"metadata": metadata if not metadata.is_empty() else null,
|
||||
}
|
||||
var line := JSON.stringify(entry)
|
||||
print("[FLIGHT] " + line)
|
||||
if _record_file != null:
|
||||
_record_file.store_line(line)
|
||||
|
||||
|
||||
func _notification(what: int) -> void:
|
||||
if what == NOTIFICATION_PREDELETE and _record_file != null:
|
||||
_record_file.close()
|
||||
|
||||
|
||||
func _read_debug_flag() -> bool:
|
||||
var env_path := ProjectSettings.globalize_path("res://").path_join("../.env")
|
||||
var file := FileAccess.open(env_path, FileAccess.READ)
|
||||
if file == null:
|
||||
return false
|
||||
while not file.eof_reached():
|
||||
var line := file.get_line().strip_edges()
|
||||
if line.begins_with("DEBUG="):
|
||||
var value := line.substr(6).strip_edges().to_upper()
|
||||
return value == "TRUE" or value == "1"
|
||||
return false
|
||||
1
godot/scripts/autoloads/flight_recorder.gd.uid
Normal file
1
godot/scripts/autoloads/flight_recorder.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://3e85d2kyj1f0
|
||||
Loading…
Add table
Reference in a new issue