Improve chat experience and begin search implementation
This commit is contained in:
@@ -155,6 +155,55 @@ INSIGHT_METRICS = {
|
||||
"values often precede misunderstandings or withdrawal cycles."
|
||||
),
|
||||
},
|
||||
"reciprocity_score": {
|
||||
"title": "Reciprocity Component",
|
||||
"group": "stability",
|
||||
"history_field": "reciprocity_score",
|
||||
"calculation": (
|
||||
"100 * (1 - |inbound - outbound| / total_messages). Higher means "
|
||||
"more balanced participation."
|
||||
),
|
||||
"psychology": (
|
||||
"Lower reciprocity can reflect perceived asymmetry and rising pursuit/"
|
||||
"withdraw cycles."
|
||||
),
|
||||
},
|
||||
"continuity_score": {
|
||||
"title": "Continuity Component",
|
||||
"group": "stability",
|
||||
"history_field": "continuity_score",
|
||||
"calculation": (
|
||||
"100 * min(1, distinct_sample_days / span_days). Higher means steadier "
|
||||
"day-to-day continuity."
|
||||
),
|
||||
"psychology": (
|
||||
"Drops can signal communication becoming episodic or reactive."
|
||||
),
|
||||
},
|
||||
"response_score": {
|
||||
"title": "Response Component",
|
||||
"group": "stability",
|
||||
"history_field": "response_score",
|
||||
"calculation": (
|
||||
"Average of inbound and outbound response-lag scores, each mapped from "
|
||||
"median lag to a 0-100 curve."
|
||||
),
|
||||
"psychology": (
|
||||
"Lower response score can indicate delayed repair loops during tension."
|
||||
),
|
||||
},
|
||||
"volatility_score": {
|
||||
"title": "Volatility Component",
|
||||
"group": "stability",
|
||||
"history_field": "volatility_score",
|
||||
"calculation": (
|
||||
"Derived from coefficient of variation of daily message counts and "
|
||||
"inverted to a 0-100 stability signal."
|
||||
),
|
||||
"psychology": (
|
||||
"High volatility can suggest inconsistent rhythm and reduced predictability."
|
||||
),
|
||||
},
|
||||
"stability_confidence": {
|
||||
"title": "Stability Confidence",
|
||||
"group": "confidence",
|
||||
@@ -219,6 +268,52 @@ INSIGHT_METRICS = {
|
||||
"Estimates user follow-through and consistency toward the counterpart."
|
||||
),
|
||||
},
|
||||
"inbound_response_score": {
|
||||
"title": "Inbound Response Score",
|
||||
"group": "commitment",
|
||||
"history_field": "inbound_response_score",
|
||||
"calculation": (
|
||||
"Response-speed score built from median lag between user outbound and "
|
||||
"counterpart inbound replies."
|
||||
),
|
||||
"psychology": (
|
||||
"Lower values suggest delayed reciprocity from counterpart direction."
|
||||
),
|
||||
},
|
||||
"outbound_response_score": {
|
||||
"title": "Outbound Response Score",
|
||||
"group": "commitment",
|
||||
"history_field": "outbound_response_score",
|
||||
"calculation": (
|
||||
"Response-speed score built from median lag between counterpart inbound "
|
||||
"and user outbound replies."
|
||||
),
|
||||
"psychology": "Lower values suggest slower follow-through from user direction.",
|
||||
},
|
||||
"balance_inbound_score": {
|
||||
"title": "Inbound Balance Score",
|
||||
"group": "commitment",
|
||||
"history_field": "balance_inbound_score",
|
||||
"calculation": (
|
||||
"100 * min(1, inbound_messages / outbound_messages). Captures inbound "
|
||||
"participation parity."
|
||||
),
|
||||
"psychology": (
|
||||
"Lower values can indicate one-sided conversational load from user side."
|
||||
),
|
||||
},
|
||||
"balance_outbound_score": {
|
||||
"title": "Outbound Balance Score",
|
||||
"group": "commitment",
|
||||
"history_field": "balance_outbound_score",
|
||||
"calculation": (
|
||||
"100 * min(1, outbound_messages / inbound_messages). Captures outbound "
|
||||
"participation parity."
|
||||
),
|
||||
"psychology": (
|
||||
"Lower values can indicate one-sided conversational load from counterpart side."
|
||||
),
|
||||
},
|
||||
"commitment_confidence": {
|
||||
"title": "Commit Confidence",
|
||||
"group": "confidence",
|
||||
@@ -334,6 +429,78 @@ INSIGHT_GRAPH_SPECS = [
|
||||
"y_min": 0,
|
||||
"y_max": None,
|
||||
},
|
||||
{
|
||||
"slug": "reciprocity_score",
|
||||
"title": "Reciprocity Component",
|
||||
"field": "reciprocity_score",
|
||||
"group": "stability",
|
||||
"y_min": 0,
|
||||
"y_max": 100,
|
||||
},
|
||||
{
|
||||
"slug": "continuity_score",
|
||||
"title": "Continuity Component",
|
||||
"field": "continuity_score",
|
||||
"group": "stability",
|
||||
"y_min": 0,
|
||||
"y_max": 100,
|
||||
},
|
||||
{
|
||||
"slug": "response_score",
|
||||
"title": "Response Component",
|
||||
"field": "response_score",
|
||||
"group": "stability",
|
||||
"y_min": 0,
|
||||
"y_max": 100,
|
||||
},
|
||||
{
|
||||
"slug": "volatility_score",
|
||||
"title": "Volatility Component",
|
||||
"field": "volatility_score",
|
||||
"group": "stability",
|
||||
"y_min": 0,
|
||||
"y_max": 100,
|
||||
},
|
||||
{
|
||||
"slug": "inbound_response_score",
|
||||
"title": "Inbound Response Score",
|
||||
"field": "inbound_response_score",
|
||||
"group": "commitment",
|
||||
"y_min": 0,
|
||||
"y_max": 100,
|
||||
},
|
||||
{
|
||||
"slug": "outbound_response_score",
|
||||
"title": "Outbound Response Score",
|
||||
"field": "outbound_response_score",
|
||||
"group": "commitment",
|
||||
"y_min": 0,
|
||||
"y_max": 100,
|
||||
},
|
||||
{
|
||||
"slug": "balance_inbound_score",
|
||||
"title": "Inbound Balance Score",
|
||||
"field": "balance_inbound_score",
|
||||
"group": "commitment",
|
||||
"y_min": 0,
|
||||
"y_max": 100,
|
||||
},
|
||||
{
|
||||
"slug": "balance_outbound_score",
|
||||
"title": "Outbound Balance Score",
|
||||
"field": "balance_outbound_score",
|
||||
"group": "commitment",
|
||||
"y_min": 0,
|
||||
"y_max": 100,
|
||||
},
|
||||
{
|
||||
"slug": "last_event",
|
||||
"title": "Last Event Timestamp",
|
||||
"field": "source_event_ts",
|
||||
"group": "timeline",
|
||||
"y_min": None,
|
||||
"y_max": None,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
@@ -487,7 +654,10 @@ def _to_float(value):
|
||||
return float(value)
|
||||
|
||||
|
||||
def _format_metric_value(conversation, metric_slug):
|
||||
def _format_metric_value(conversation, metric_slug, latest_snapshot=None):
|
||||
snapshot = latest_snapshot
|
||||
if snapshot is None:
|
||||
snapshot = conversation.metric_snapshots.first()
|
||||
if metric_slug == "platform":
|
||||
return conversation.get_platform_type_display() or "-"
|
||||
if metric_slug == "thread":
|
||||
@@ -498,6 +668,14 @@ def _format_metric_value(conversation, metric_slug):
|
||||
return conversation.get_stability_state_display()
|
||||
if metric_slug == "stability_score":
|
||||
return conversation.stability_score
|
||||
if metric_slug == "reciprocity_score":
|
||||
return snapshot.reciprocity_score if snapshot else None
|
||||
if metric_slug == "continuity_score":
|
||||
return snapshot.continuity_score if snapshot else None
|
||||
if metric_slug == "response_score":
|
||||
return snapshot.response_score if snapshot else None
|
||||
if metric_slug == "volatility_score":
|
||||
return snapshot.volatility_score if snapshot else None
|
||||
if metric_slug == "stability_confidence":
|
||||
return conversation.stability_confidence
|
||||
if metric_slug == "sample_messages":
|
||||
@@ -510,6 +688,14 @@ def _format_metric_value(conversation, metric_slug):
|
||||
return conversation.commitment_inbound_score
|
||||
if metric_slug == "commitment_outbound":
|
||||
return conversation.commitment_outbound_score
|
||||
if metric_slug == "inbound_response_score":
|
||||
return snapshot.inbound_response_score if snapshot else None
|
||||
if metric_slug == "outbound_response_score":
|
||||
return snapshot.outbound_response_score if snapshot else None
|
||||
if metric_slug == "balance_inbound_score":
|
||||
return snapshot.balance_inbound_score if snapshot else None
|
||||
if metric_slug == "balance_outbound_score":
|
||||
return snapshot.balance_outbound_score if snapshot else None
|
||||
if metric_slug == "commitment_confidence":
|
||||
return conversation.commitment_confidence
|
||||
if metric_slug == "commitment_computed":
|
||||
@@ -2713,7 +2899,8 @@ class AIWorkspaceInsightDetail(LoginRequiredMixin, View):
|
||||
|
||||
person = get_object_or_404(Person, pk=person_id, user=request.user)
|
||||
conversation = _conversation_for_person(request.user, person)
|
||||
value = _format_metric_value(conversation, metric)
|
||||
latest_snapshot = conversation.metric_snapshots.first()
|
||||
value = _format_metric_value(conversation, metric, latest_snapshot)
|
||||
group = INSIGHT_GROUPS[spec["group"]]
|
||||
points = []
|
||||
if spec["history_field"]:
|
||||
@@ -2773,6 +2960,7 @@ class AIWorkspaceInsightHelp(LoginRequiredMixin, View):
|
||||
|
||||
person = get_object_or_404(Person, pk=person_id, user=request.user)
|
||||
conversation = _conversation_for_person(request.user, person)
|
||||
latest_snapshot = conversation.metric_snapshots.first()
|
||||
metrics = []
|
||||
for slug, spec in INSIGHT_METRICS.items():
|
||||
metrics.append(
|
||||
@@ -2783,7 +2971,11 @@ class AIWorkspaceInsightHelp(LoginRequiredMixin, View):
|
||||
"group_title": INSIGHT_GROUPS[spec["group"]]["title"],
|
||||
"calculation": spec["calculation"],
|
||||
"psychology": spec["psychology"],
|
||||
"value": _format_metric_value(conversation, slug),
|
||||
"value": _format_metric_value(
|
||||
conversation,
|
||||
slug,
|
||||
latest_snapshot,
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user