nexo-brain 7.34.0 → 7.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -157,12 +157,42 @@ def _requires_external_real_world_check(task: dict, *parts: str) -> bool:
157
157
  if str(task.get("task_type") or "").strip() not in ACTION_TASKS:
158
158
  return False
159
159
  text = _external_real_world_text(task, *parts)
160
+ if _is_local_only_followup_runner_close(task, text):
161
+ return False
160
162
  return any(
161
163
  _contains_external_action_keyword(text, keyword)
162
164
  for keyword in EXTERNAL_REAL_WORLD_ACTION_KEYWORDS
163
165
  )
164
166
 
165
167
 
168
+ def _is_local_only_followup_runner_close(task: dict, text: str) -> bool:
169
+ area = str(task.get("area") or "").lower()
170
+ goal = str(task.get("goal") or "").lower()
171
+ if "followup-runner" not in f"{area} {goal} {text}":
172
+ return False
173
+
174
+ local_only_markers = (
175
+ "sin envio externo",
176
+ "sin envío externo",
177
+ "no envio externo",
178
+ "no envío externo",
179
+ "no external send",
180
+ "no external delivery",
181
+ "internal followup-runner",
182
+ "followup-runner interna",
183
+ "followup-runner internas",
184
+ "solo lectura db",
185
+ "solo lectura de db",
186
+ "solo lectura bd",
187
+ "solo lectura de bd",
188
+ "archivos locales",
189
+ "local files",
190
+ "db/archivos locales",
191
+ "db/local files",
192
+ )
193
+ return any(marker in text for marker in local_only_markers)
194
+
195
+
166
196
  def _has_external_real_world_evidence(text: str) -> bool:
167
197
  lowered = str(text or "").lower()
168
198
  if _is_trivial_evidence(lowered)[0]:
@@ -0,0 +1,66 @@
1
+ """Ola 4 — SCHEMA-ABSTRACTION plugin tools.
2
+
3
+ Thin MCP surface over ``schema_abstraction`` (the distiller). Templates are
4
+ non-authoritative GUIDANCE: they prime a complete diagnosis when a recurring
5
+ incident archetype reappears; they never block. Precision-first / anti-noise:
6
+ a template is minted only from a genuinely recurring cluster (>= 3 distinct
7
+ incidents of the same archetype, high confidence).
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import json
13
+
14
+ import schema_abstraction as sa
15
+
16
+
17
+ def _dump(value) -> str:
18
+ return json.dumps(value, ensure_ascii=False)
19
+
20
+
21
+ def handle_schema_abstraction_distill() -> str:
22
+ """Run the distillation pass: cluster recurring incidents → mint diagnostic
23
+ templates (idempotent). Safe to re-run; returns a report including anti-noise
24
+ skips (clusters below the recurrence/confidence threshold)."""
25
+ return _dump(sa.distill_templates())
26
+
27
+
28
+ def handle_schema_abstraction_templates(status: str = "active", limit: int = 50) -> str:
29
+ """List distilled diagnostic templates."""
30
+ return _dump({"templates": sa.list_templates(status=status, limit=limit)})
31
+
32
+
33
+ def handle_schema_abstraction_match(query: str = "", area: str = "", limit: int = 1) -> str:
34
+ """Return the diagnostic template(s) whose archetype clearly matches an
35
+ action (the same match used to prime pre-action context)."""
36
+ return _dump({"matches": sa.match_templates_for_action(query=query, area=area, limit=limit)})
37
+
38
+
39
+ def handle_schema_abstraction_retire(template_uid: str, reason: str = "") -> str:
40
+ """Retire a diagnostic template (lifecycle). Guidance-only; never deletes
41
+ the underlying incidents."""
42
+ return _dump(sa.retire_template(template_uid, reason=reason))
43
+
44
+
45
+ TOOLS = [
46
+ (
47
+ handle_schema_abstraction_distill,
48
+ "nexo_schema_abstraction_distill",
49
+ "Distill recurring incident archetypes into reusable diagnostic templates (idempotent clustering pass)",
50
+ ),
51
+ (
52
+ handle_schema_abstraction_templates,
53
+ "nexo_schema_abstraction_templates",
54
+ "List distilled diagnostic templates",
55
+ ),
56
+ (
57
+ handle_schema_abstraction_match,
58
+ "nexo_schema_abstraction_match",
59
+ "Match an action against diagnostic-template archetypes (primed diagnosis)",
60
+ ),
61
+ (
62
+ handle_schema_abstraction_retire,
63
+ "nexo_schema_abstraction_retire",
64
+ "Retire a diagnostic template (lifecycle, guidance-only)",
65
+ ),
66
+ ]