feat: plan deterministic generated conversations
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
class_name ConversationSemantic
|
||||
extends RefCounted
|
||||
|
||||
const MAX_ID_LENGTH := 96
|
||||
const MAX_TRACE_SIZE := 32
|
||||
|
||||
|
||||
static func is_valid_id(value: Variant) -> bool:
|
||||
if value is not String and value is not StringName:
|
||||
return false
|
||||
var text := String(value)
|
||||
if text.is_empty() or text.length() > MAX_ID_LENGTH:
|
||||
return false
|
||||
for character in text:
|
||||
if not _is_safe_id_character(character):
|
||||
return false
|
||||
return true
|
||||
|
||||
|
||||
static func normalize_id_array(value: Variant, allow_empty: bool = true) -> Variant:
|
||||
if value is not Array and value is not PackedStringArray:
|
||||
return null
|
||||
var normalized: Array[StringName] = []
|
||||
var seen: Dictionary = {}
|
||||
for item in value:
|
||||
if not is_valid_id(item):
|
||||
return null
|
||||
var semantic_id := StringName(item)
|
||||
if seen.has(semantic_id):
|
||||
continue
|
||||
seen[semantic_id] = true
|
||||
normalized.append(semantic_id)
|
||||
if not allow_empty and normalized.is_empty():
|
||||
return null
|
||||
return normalized
|
||||
|
||||
|
||||
static func normalize_trace(value: Variant) -> Variant:
|
||||
var normalized: Variant = normalize_id_array(value)
|
||||
if normalized == null or normalized.size() > MAX_TRACE_SIZE:
|
||||
return null
|
||||
return normalized
|
||||
|
||||
|
||||
static func duplicate_entity(entity: WorldEntityRef) -> WorldEntityRef:
|
||||
return entity.duplicate_ref() if entity != null else null
|
||||
|
||||
|
||||
static func _is_safe_id_character(character: String) -> bool:
|
||||
var code := character.unicode_at(0)
|
||||
return (
|
||||
(code >= 48 and code <= 57)
|
||||
or (code >= 65 and code <= 90)
|
||||
or (code >= 97 and code <= 122)
|
||||
or character in ["_", "-", ".", ":"]
|
||||
)
|
||||
Reference in New Issue
Block a user