57 lines
No EOL
1.8 KiB
Python
57 lines
No EOL
1.8 KiB
Python
"""
|
|
thread_assignment.py — Ensure every message has a valid opaque thread UUID.
|
|
|
|
The envelope.xsd requires <thread>, but external clients may:
|
|
- Omit it (first message)
|
|
- Send invalid format
|
|
- Send duplicate/malformed UUID
|
|
|
|
This step enforces:
|
|
- Presence of a valid UUID v4 string in <thread>
|
|
- If missing or invalid → generate a new one (new root thread)
|
|
- Store it in state.thread_id for all downstream use
|
|
|
|
This guarantees thread continuity and privacy (external parties never see internal hierarchy).
|
|
|
|
Part of AgentServer v2.1 message pump.
|
|
"""
|
|
|
|
import uuid
|
|
from agentserver.message_bus.message_state import MessageState
|
|
|
|
|
|
def _is_valid_uuid(val: str) -> bool:
|
|
"""Simple UUID v4 validation — accepts standard string formats."""
|
|
try:
|
|
uuid_obj = uuid.UUID(val, version=4)
|
|
return str(uuid_obj) == val # Ensures canonical lowercase format
|
|
except ValueError:
|
|
return False
|
|
|
|
|
|
async def thread_assignment_step(state: MessageState) -> MessageState:
|
|
"""
|
|
Assign or validate the thread UUID.
|
|
|
|
- If state.thread_id is already set and valid → keep it
|
|
- Else → generate new UUID v4
|
|
- Always normalizes to lowercase canonical string
|
|
|
|
This is the source of truth for thread identity throughout the organism.
|
|
"""
|
|
if state.thread_id and _is_valid_uuid(state.thread_id):
|
|
# Already valid — nothing to do
|
|
return state
|
|
|
|
# Invalid, missing, or malformed — generate new root thread
|
|
new_thread_id = str(uuid.uuid4())
|
|
|
|
# Optional: log warning if external client sent bad thread
|
|
if state.thread_id:
|
|
state.metadata.setdefault("diagnostics", []).append(
|
|
f"Invalid external thread ID '{state.thread_id}' — replaced with new root thread"
|
|
)
|
|
|
|
state.thread_id = new_thread_id
|
|
|
|
return state |