extends Control ## Simple example of chatting with an NPC ## ## This example shows how to: ## - Spawn an NPC ## - Send messages using chat_with_history ## - Handle streaming responses @export var api_base_url: String = "https://npc.gumyum.com" @export var api_key: String = "gumyum-pk-your-public-key" @export var api_secret: String = "gumyum-sk-your-secret-key" @export var universe_id: String = "kingdom" @export var enable_streaming: bool = true var current_npc: GumYumNPC var is_waiting_response: bool = false @onready var chat_input: LineEdit = $VBoxContainer/ChatInput @onready var chat_display: RichTextLabel = $VBoxContainer/ChatDisplay @onready var npc_name_label: Label = $VBoxContainer/NPCInfo/NameLabel @onready var npc_mood_label: Label = $VBoxContainer/NPCInfo/MoodLabel @onready var send_button: Button = $VBoxContainer/SendButton func _ready(): # Connect UI signals send_button.pressed.connect(_on_send_pressed) chat_input.text_submitted.connect(_on_text_submitted) # Initialize GumYum client _setup_client() # Spawn an NPC when ready _spawn_random_npc() func _setup_client(): # Set up authentication GumyumClient.base_url = api_base_url GumyumClient.api_key = api_key GumyumClient.api_secret = api_secret # Optional: Enable debug mode GumyumClient.debug_mode = true chat_display.append_bbcode("[color=green]Connected to GumYum API[/color]\n") func _spawn_random_npc(): chat_display.append_bbcode("[color=yellow]Spawning NPC...[/color]\n") # Use the npcs manager to spawn # The response will be a GumYumNPC object GumyumClient.npcs.spawn(universe_id, 42, null, _on_npc_spawned) # universe # seed (consistent with docs) # Random NPC (null) func _on_npc_spawned(npc: GumYumNPC): if npc == null: push_error("Failed to spawn NPC") chat_display.append_bbcode("[color=red]Failed to spawn NPC![/color]\n") return current_npc = npc # Connect to NPC's dialogue signals npc.dialogue_received.connect(_on_dialogue_received) npc.dialogue_stream_started.connect(_on_stream_started) npc.dialogue_chunk_received.connect(_on_stream_chunk) npc.dialogue_stream_ended.connect(_on_stream_ended) # Update UI npc_name_label.text = "Name: " + npc.name npc_mood_label.text = "Mood: " + npc.get_mood() # Announce spawn chat_display.append_bbcode("\n[b][color=cyan]" + npc.name + " appears![/color][/b]\n") chat_display.append_bbcode("[i]A " + npc.profession + " approaches you.[/i]\n\n") # Enable chat chat_input.editable = true send_button.disabled = false func _on_send_pressed(): _send_message() func _on_text_submitted(_text: String): _send_message() func _send_message(): var message = chat_input.text.strip_edges() if message.is_empty() or is_waiting_response: return # Clear input chat_input.text = "" # Add user message to display chat_display.append_bbcode("[b]You:[/b] " + message + "\n") # Disable input while processing is_waiting_response = true chat_input.editable = false send_button.disabled = true # Send message using NPC's chat_with_history current_npc.chat_with_history( message, # message text 0.8, # temperature 2000, # max_tokens enable_streaming, # streaming _on_dialogue_received if not enable_streaming else Callable() ) func _on_dialogue_received(response): # Handle the API response format if response.has("error"): chat_display.append_bbcode("[color=red]Error: " + response.error + "[/color]\n") elif response.has("choices") and response.choices.size() > 0: var content = response.choices[0]["message"]["content"] chat_display.append_bbcode("[b][color=cyan]" + current_npc.name + ":[/color][/b] ") chat_display.append_bbcode(content + "\n\n") # Check for mood transition in response if response.has("mood_transition"): var new_mood = response.mood_transition.get("new_mood", "") if new_mood: npc_mood_label.text = "Mood: " + new_mood chat_display.append_bbcode("[i][color=gray](mood: " + new_mood + ")[/color][/i]\n") # Re-enable input is_waiting_response = false chat_input.editable = true send_button.disabled = false chat_input.grab_focus() var stream_buffer: String = "" func _on_stream_started(): stream_buffer = "" chat_display.append_bbcode("[b][color=cyan]" + current_npc.name + ":[/color][/b] ") func _on_stream_chunk(chunk: String): stream_buffer += chunk # Clear and rewrite the current line with updated buffer # Note: This is a simple approach - you may want more sophisticated handling chat_display.append_bbcode(chunk) func _on_stream_ended(_full_response: String, _context: Dictionary, mood_transition: Dictionary): chat_display.append_bbcode("\n\n") # Handle mood change if mood_transition and not mood_transition.is_empty(): var new_mood = mood_transition.get("new_mood", "") if new_mood: npc_mood_label.text = "Mood: " + new_mood chat_display.append_bbcode("[i][color=gray](mood: " + new_mood + ")[/color][/i]\n") # Re-enable input is_waiting_response = false chat_input.editable = true send_button.disabled = false chat_input.grab_focus()