Implement executing tasks
This commit is contained in:
@@ -48,6 +48,8 @@ from core.models import (
|
||||
PlatformChatLink,
|
||||
WorkspaceConversation,
|
||||
)
|
||||
from core.presence import get_settings as get_availability_settings
|
||||
from core.presence import spans_for_range
|
||||
from core.realtime.typing_state import get_person_typing_state
|
||||
from core.translation.engine import process_inbound_translation
|
||||
from core.views.workspace import (
|
||||
@@ -101,6 +103,36 @@ def _default_service(service: str | None) -> str:
|
||||
return "signal"
|
||||
|
||||
|
||||
def _identifier_variants(service: str, identifier: str) -> list[str]:
|
||||
value = str(identifier or "").strip()
|
||||
if not value:
|
||||
return []
|
||||
service_key = _default_service(service)
|
||||
variants = [value]
|
||||
|
||||
bare = value.split("@", 1)[0].strip()
|
||||
if bare and bare not in variants:
|
||||
variants.append(bare)
|
||||
|
||||
if service_key == "signal":
|
||||
digits = re.sub(r"[^0-9]", "", value)
|
||||
if digits and digits not in variants:
|
||||
variants.append(digits)
|
||||
if digits:
|
||||
plus = f"+{digits}"
|
||||
if plus not in variants:
|
||||
variants.append(plus)
|
||||
elif service_key == "whatsapp":
|
||||
if bare:
|
||||
direct = f"{bare}@s.whatsapp.net"
|
||||
group = f"{bare}@g.us"
|
||||
if direct not in variants:
|
||||
variants.append(direct)
|
||||
if group not in variants:
|
||||
variants.append(group)
|
||||
return variants
|
||||
|
||||
|
||||
def _safe_limit(raw) -> int:
|
||||
try:
|
||||
value = int(raw or 40)
|
||||
@@ -136,6 +168,24 @@ def _format_ts_label(ts_value: int) -> str:
|
||||
return str(ts_value or "")
|
||||
|
||||
|
||||
def _serialize_availability_spans(spans):
|
||||
rows = []
|
||||
for row in list(spans or []):
|
||||
rows.append(
|
||||
{
|
||||
"id": int(getattr(row, "id", 0) or 0),
|
||||
"service": str(getattr(row, "service", "") or ""),
|
||||
"state": str(getattr(row, "state", "unknown") or "unknown"),
|
||||
"start_ts": int(getattr(row, "start_ts", 0) or 0),
|
||||
"end_ts": int(getattr(row, "end_ts", 0) or 0),
|
||||
"confidence_start": float(getattr(row, "confidence_start", 0.0) or 0.0),
|
||||
"confidence_end": float(getattr(row, "confidence_end", 0.0) or 0.0),
|
||||
"payload": dict(getattr(row, "payload", {}) or {}),
|
||||
}
|
||||
)
|
||||
return rows
|
||||
|
||||
|
||||
def _is_outgoing(msg: Message) -> bool:
|
||||
is_outgoing = str(msg.custom_author or "").upper() in {"USER", "BOT"}
|
||||
if not is_outgoing:
|
||||
@@ -672,14 +722,19 @@ THREAD_METRIC_COPY_OVERRIDES = {
|
||||
def _workspace_conversation_for_person(user, person):
|
||||
if person is None:
|
||||
return None
|
||||
return (
|
||||
WorkspaceConversation.objects.filter(
|
||||
user=user,
|
||||
participants=person,
|
||||
try:
|
||||
from core.views.workspace import _conversation_for_person
|
||||
|
||||
return _conversation_for_person(user, person)
|
||||
except Exception:
|
||||
return (
|
||||
WorkspaceConversation.objects.filter(
|
||||
user=user,
|
||||
participants=person,
|
||||
)
|
||||
.order_by("-last_event_ts", "-created_at")
|
||||
.first()
|
||||
)
|
||||
.order_by("-last_event_ts", "-created_at")
|
||||
.first()
|
||||
)
|
||||
|
||||
|
||||
def _counterpart_identifiers_for_person(user, person):
|
||||
@@ -1522,14 +1577,15 @@ def _engage_source_from_ref(plan, source_ref):
|
||||
|
||||
|
||||
def _context_base(user, service, identifier, person):
|
||||
identifier_variants = _identifier_variants(service, identifier)
|
||||
person_identifier = None
|
||||
if person is not None:
|
||||
if identifier:
|
||||
if identifier_variants:
|
||||
person_identifier = PersonIdentifier.objects.filter(
|
||||
user=user,
|
||||
person=person,
|
||||
service=service,
|
||||
identifier=identifier,
|
||||
identifier__in=identifier_variants,
|
||||
).first()
|
||||
if person_identifier is None:
|
||||
person_identifier = (
|
||||
@@ -1544,7 +1600,7 @@ def _context_base(user, service, identifier, person):
|
||||
person_identifier = PersonIdentifier.objects.filter(
|
||||
user=user,
|
||||
service=service,
|
||||
identifier=identifier,
|
||||
identifier__in=identifier_variants or [identifier],
|
||||
).first()
|
||||
|
||||
if person_identifier:
|
||||
@@ -2496,6 +2552,35 @@ def _panel_context(
|
||||
counterpart_identifiers=counterpart_identifiers,
|
||||
conversation=conversation,
|
||||
)
|
||||
availability_slices = []
|
||||
availability_enabled = False
|
||||
availability_settings = get_availability_settings(request.user)
|
||||
if (
|
||||
base["person"] is not None
|
||||
and availability_settings.enabled
|
||||
and availability_settings.show_in_chat
|
||||
):
|
||||
range_start = (
|
||||
int(session_bundle["messages"][0].ts or 0) if session_bundle["messages"] else 0
|
||||
)
|
||||
range_end = (
|
||||
int(session_bundle["messages"][-1].ts or 0) if session_bundle["messages"] else 0
|
||||
)
|
||||
if range_start <= 0 or range_end <= 0:
|
||||
now_ts = int(time.time() * 1000)
|
||||
range_start = now_ts - (24 * 60 * 60 * 1000)
|
||||
range_end = now_ts
|
||||
availability_enabled = True
|
||||
availability_slices = _serialize_availability_spans(
|
||||
spans_for_range(
|
||||
user=request.user,
|
||||
person=base["person"],
|
||||
start_ts=range_start,
|
||||
end_ts=range_end,
|
||||
service=base["service"],
|
||||
limit=200,
|
||||
)
|
||||
)
|
||||
glance_items = _build_glance_items(
|
||||
serialized_messages,
|
||||
person_id=(base["person"].id if base["person"] else None),
|
||||
@@ -2665,6 +2750,22 @@ def _panel_context(
|
||||
if base["person"]
|
||||
else reverse("ai_workspace")
|
||||
),
|
||||
"ai_workspace_graphs_url": (
|
||||
reverse(
|
||||
"ai_workspace_insight_graphs",
|
||||
kwargs={"type": "page", "person_id": base["person"].id},
|
||||
)
|
||||
if base["person"]
|
||||
else ""
|
||||
),
|
||||
"ai_workspace_info_url": (
|
||||
reverse(
|
||||
"ai_workspace_information",
|
||||
kwargs={"type": "page", "person_id": base["person"].id},
|
||||
)
|
||||
if base["person"]
|
||||
else ""
|
||||
),
|
||||
"ai_workspace_widget_url": (
|
||||
(
|
||||
f"{reverse('ai_workspace_person', kwargs={'type': 'widget', 'person_id': base['person'].id})}"
|
||||
@@ -2676,6 +2777,9 @@ def _panel_context(
|
||||
"manual_icon_class": "fa-solid fa-paper-plane",
|
||||
"panel_id": f"compose-panel-{unique}",
|
||||
"typing_state_json": json.dumps(typing_state),
|
||||
"availability_enabled": availability_enabled,
|
||||
"availability_slices": availability_slices,
|
||||
"availability_slices_json": json.dumps(availability_slices),
|
||||
"command_options": command_options,
|
||||
"bp_binding_summary": bp_binding_summary,
|
||||
"platform_options": platform_options,
|
||||
@@ -3133,6 +3237,31 @@ class ComposeThread(LoginRequiredMixin, View):
|
||||
counterpart_identifiers = _counterpart_identifiers_for_person(
|
||||
request.user, base["person"]
|
||||
)
|
||||
availability_slices = []
|
||||
availability_settings = get_availability_settings(request.user)
|
||||
if (
|
||||
base["person"] is not None
|
||||
and availability_settings.enabled
|
||||
and availability_settings.show_in_chat
|
||||
):
|
||||
range_start = (
|
||||
int(messages[0].ts or 0) if messages else max(0, int(after_ts or 0))
|
||||
)
|
||||
range_end = int(latest_ts or 0)
|
||||
if range_start <= 0 or range_end <= 0:
|
||||
now_ts = int(time.time() * 1000)
|
||||
range_start = now_ts - (24 * 60 * 60 * 1000)
|
||||
range_end = now_ts
|
||||
availability_slices = _serialize_availability_spans(
|
||||
spans_for_range(
|
||||
user=request.user,
|
||||
person=base["person"],
|
||||
start_ts=range_start,
|
||||
end_ts=range_end,
|
||||
service=base["service"],
|
||||
limit=200,
|
||||
)
|
||||
)
|
||||
payload = {
|
||||
"messages": _serialize_messages_with_artifacts(
|
||||
messages,
|
||||
@@ -3141,6 +3270,7 @@ class ComposeThread(LoginRequiredMixin, View):
|
||||
seed_previous=seed_previous,
|
||||
),
|
||||
"last_ts": latest_ts,
|
||||
"availability_slices": availability_slices,
|
||||
"typing": get_person_typing_state(
|
||||
user_id=request.user.id,
|
||||
person_id=base["person"].id if base["person"] else None,
|
||||
|
||||
Reference in New Issue
Block a user