Release OpenClaw HA integration 0.1.66
This commit is contained in:
@@ -41,7 +41,12 @@ from .const import (
|
||||
from .coordinator import OpenClawCoordinator
|
||||
from .exposure import apply_context_policy, build_exposed_entities_context
|
||||
from .helpers import extract_text_recursive
|
||||
from .routing import normalize_ha_user_id, resolve_agent_id, resolve_model_override
|
||||
from .routing import (
|
||||
build_scoped_session_id,
|
||||
normalize_ha_user_id,
|
||||
resolve_agent_id,
|
||||
resolve_model_override,
|
||||
)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@@ -126,7 +131,11 @@ class OpenClawConversationAgent(conversation.AbstractConversationAgent):
|
||||
ha_user_id = normalize_ha_user_id(getattr(context, "user_id", None))
|
||||
options = self.entry.options
|
||||
resolved_agent_id = resolve_agent_id(ha_user_id)
|
||||
conversation_id = self._resolve_conversation_id(user_input, resolved_agent_id)
|
||||
conversation_id = self._resolve_conversation_id(
|
||||
user_input,
|
||||
ha_user_id,
|
||||
resolved_agent_id,
|
||||
)
|
||||
active_model = resolve_model_override(options.get("active_model"))
|
||||
include_context = options.get(
|
||||
CONF_INCLUDE_EXPOSED_CONTEXT,
|
||||
@@ -218,9 +227,10 @@ class OpenClawConversationAgent(conversation.AbstractConversationAgent):
|
||||
def _resolve_conversation_id(
|
||||
self,
|
||||
user_input: conversation.ConversationInput,
|
||||
ha_user_id: str | None,
|
||||
agent_id: str | None,
|
||||
) -> str:
|
||||
"""Return conversation id from HA with conservative agent namespacing."""
|
||||
"""Return an OpenClaw agent-scoped session key for HA Assist."""
|
||||
configured_session_id = self._normalize_optional_text(
|
||||
self.entry.options.get(
|
||||
CONF_ASSIST_SESSION_ID,
|
||||
@@ -228,27 +238,37 @@ class OpenClawConversationAgent(conversation.AbstractConversationAgent):
|
||||
)
|
||||
)
|
||||
if configured_session_id:
|
||||
return configured_session_id
|
||||
if configured_session_id.lower().startswith("agent:"):
|
||||
return configured_session_id
|
||||
return build_scoped_session_id(configured_session_id, ha_user_id, agent_id)
|
||||
|
||||
agent_suffix = self._normalize_optional_text(agent_id)
|
||||
|
||||
if user_input.conversation_id:
|
||||
if agent_suffix:
|
||||
return f"{user_input.conversation_id}:{agent_suffix}"
|
||||
return user_input.conversation_id
|
||||
if user_input.conversation_id.lower().startswith("agent:"):
|
||||
return user_input.conversation_id
|
||||
raw_session = (
|
||||
f"{user_input.conversation_id}:{agent_suffix}"
|
||||
if agent_suffix
|
||||
else user_input.conversation_id
|
||||
)
|
||||
return build_scoped_session_id(raw_session, ha_user_id, agent_id)
|
||||
|
||||
context = getattr(user_input, "context", None)
|
||||
user_id = getattr(context, "user_id", None)
|
||||
if user_id:
|
||||
base_id = f"assist_user_{user_id}"
|
||||
return f"{base_id}:{agent_suffix}" if agent_suffix else base_id
|
||||
raw_session = f"{base_id}:{agent_suffix}" if agent_suffix else base_id
|
||||
return build_scoped_session_id(raw_session, ha_user_id, agent_id)
|
||||
|
||||
device_id = getattr(user_input, "device_id", None)
|
||||
if device_id:
|
||||
base_id = f"assist_device_{device_id}"
|
||||
return f"{base_id}:{agent_suffix}" if agent_suffix else base_id
|
||||
raw_session = f"{base_id}:{agent_suffix}" if agent_suffix else base_id
|
||||
return build_scoped_session_id(raw_session, ha_user_id, agent_id)
|
||||
|
||||
return f"assist_default:{agent_suffix}" if agent_suffix else "assist_default"
|
||||
raw_session = f"assist_default:{agent_suffix}" if agent_suffix else "assist_default"
|
||||
return build_scoped_session_id(raw_session, ha_user_id, agent_id)
|
||||
|
||||
def _normalize_optional_text(self, value: Any) -> str | None:
|
||||
"""Return a stripped string or None for blank values."""
|
||||
@@ -310,7 +330,7 @@ class OpenClawConversationAgent(conversation.AbstractConversationAgent):
|
||||
|
||||
# Check if the response ends with a question mark
|
||||
# (allow trailing punctuation like quotes, parens, or emoji)
|
||||
if re.search(r"\?\s*[\"'""»)\]]*\s*$", text):
|
||||
if re.search("\\?\\s*[\"'»)\\]]*\\s*$", text):
|
||||
return True
|
||||
|
||||
# Common follow-up patterns (EN + DE)
|
||||
|
||||
Reference in New Issue
Block a user