fenix-mcp 0.5.0__py3-none-any.whl → 0.5.1__py3-none-any.whl
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.
- fenix_mcp/__init__.py +1 -1
- fenix_mcp/application/tools/intelligence.py +17 -3
- fenix_mcp/domain/intelligence.py +28 -8
- {fenix_mcp-0.5.0.dist-info → fenix_mcp-0.5.1.dist-info}/METADATA +1 -1
- {fenix_mcp-0.5.0.dist-info → fenix_mcp-0.5.1.dist-info}/RECORD +8 -8
- {fenix_mcp-0.5.0.dist-info → fenix_mcp-0.5.1.dist-info}/WHEEL +0 -0
- {fenix_mcp-0.5.0.dist-info → fenix_mcp-0.5.1.dist-info}/entry_points.txt +0 -0
- {fenix_mcp-0.5.0.dist-info → fenix_mcp-0.5.1.dist-info}/top_level.txt +0 -0
fenix_mcp/__init__.py
CHANGED
|
@@ -155,6 +155,7 @@ class IntelligenceTool(Tool):
|
|
|
155
155
|
async def _handle_smart_create(self, payload: IntelligenceRequest):
|
|
156
156
|
if not payload.title or not payload.content:
|
|
157
157
|
return text("❌ Informe título e conteúdo para criar uma memória.")
|
|
158
|
+
normalized_tags = _ensure_tag_sequence(payload.tags)
|
|
158
159
|
memory = await self._service.smart_create_memory(
|
|
159
160
|
title=payload.title,
|
|
160
161
|
content=payload.content,
|
|
@@ -162,7 +163,7 @@ class IntelligenceTool(Tool):
|
|
|
162
163
|
context=payload.context,
|
|
163
164
|
source=payload.source,
|
|
164
165
|
importance=payload.importance,
|
|
165
|
-
tags=
|
|
166
|
+
tags=normalized_tags,
|
|
166
167
|
)
|
|
167
168
|
lines = [
|
|
168
169
|
"🧠 **Memória criada com sucesso!**",
|
|
@@ -259,17 +260,18 @@ class IntelligenceTool(Tool):
|
|
|
259
260
|
existing = await self._service.get_memory(
|
|
260
261
|
payload.id, include_content=False, include_metadata=True
|
|
261
262
|
)
|
|
263
|
+
normalized_tags = _ensure_tag_sequence(payload.tags)
|
|
262
264
|
metadata = build_metadata(
|
|
263
265
|
payload.metadata,
|
|
264
266
|
importance=payload.importance,
|
|
265
|
-
tags=
|
|
267
|
+
tags=normalized_tags,
|
|
266
268
|
existing=existing.get("metadata") if isinstance(existing, dict) else None,
|
|
267
269
|
)
|
|
268
270
|
update_fields: Dict[str, Any] = {
|
|
269
271
|
"title": payload.title,
|
|
270
272
|
"content": payload.content,
|
|
271
273
|
"metadata": metadata,
|
|
272
|
-
"tags":
|
|
274
|
+
"tags": normalized_tags,
|
|
273
275
|
"documentation_item_id": payload.documentation_item_id,
|
|
274
276
|
"mode_id": payload.mode_id,
|
|
275
277
|
"rule_id": payload.rule_id,
|
|
@@ -313,3 +315,15 @@ def format_percentage(value: Optional[float]) -> str:
|
|
|
313
315
|
if value is None:
|
|
314
316
|
return "N/A"
|
|
315
317
|
return f"{value * 100:.1f}%"
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
def _ensure_tag_sequence(raw: Optional[Any]) -> Optional[List[str]]:
|
|
321
|
+
if raw is None or raw == "":
|
|
322
|
+
return None
|
|
323
|
+
if isinstance(raw, (list, tuple, set)):
|
|
324
|
+
result = [str(item).strip() for item in raw if str(item).strip()]
|
|
325
|
+
return result or None
|
|
326
|
+
if isinstance(raw, str):
|
|
327
|
+
items = [part.strip() for part in raw.split(",") if part.strip()]
|
|
328
|
+
return items or None
|
|
329
|
+
return [str(raw).strip()]
|
fenix_mcp/domain/intelligence.py
CHANGED
|
@@ -5,7 +5,7 @@ from __future__ import annotations
|
|
|
5
5
|
|
|
6
6
|
import asyncio
|
|
7
7
|
from dataclasses import dataclass
|
|
8
|
-
from typing import Any, Dict, Iterable, List, Optional
|
|
8
|
+
from typing import Any, Dict, Iterable, List, Optional, Union
|
|
9
9
|
|
|
10
10
|
from fenix_mcp.infrastructure.fenix_api.client import FenixApiClient
|
|
11
11
|
|
|
@@ -24,13 +24,14 @@ class IntelligenceService:
|
|
|
24
24
|
context: Optional[str],
|
|
25
25
|
source: Optional[str],
|
|
26
26
|
importance: str,
|
|
27
|
-
tags: Optional[Iterable[str]] = None,
|
|
27
|
+
tags: Optional[Union[Iterable[str], str]] = None,
|
|
28
28
|
) -> Dict[str, Any]:
|
|
29
29
|
importance_value = importance or "medium"
|
|
30
|
+
normalized_tags = normalize_tags(tags)
|
|
30
31
|
metadata_str = build_metadata(
|
|
31
32
|
metadata,
|
|
32
33
|
importance=importance_value,
|
|
33
|
-
tags=
|
|
34
|
+
tags=normalized_tags,
|
|
34
35
|
context=context,
|
|
35
36
|
source=source,
|
|
36
37
|
)
|
|
@@ -39,7 +40,7 @@ class IntelligenceService:
|
|
|
39
40
|
"content": content,
|
|
40
41
|
"metadata": metadata_str,
|
|
41
42
|
"priority_score": _importance_to_priority(importance_value),
|
|
42
|
-
"tags":
|
|
43
|
+
"tags": normalized_tags,
|
|
43
44
|
}
|
|
44
45
|
return await self._call(self.api.smart_create_memory, _strip_none(payload))
|
|
45
46
|
|
|
@@ -199,7 +200,7 @@ def build_metadata(
|
|
|
199
200
|
explicit: Optional[str],
|
|
200
201
|
*,
|
|
201
202
|
importance: Optional[str],
|
|
202
|
-
tags: Optional[Iterable[str]],
|
|
203
|
+
tags: Optional[Union[Iterable[str], str]],
|
|
203
204
|
context: Optional[str] = None,
|
|
204
205
|
source: Optional[str] = None,
|
|
205
206
|
existing: Optional[str] = None,
|
|
@@ -258,12 +259,31 @@ def _slugify(value: Optional[str]) -> str:
|
|
|
258
259
|
return "-".join(part for part in sanitized.split() if part).lower()
|
|
259
260
|
|
|
260
261
|
|
|
261
|
-
def _format_tags(tags: Optional[Iterable[str]]) -> str:
|
|
262
|
-
if
|
|
262
|
+
def _format_tags(tags: Optional[Union[Iterable[str], str]]) -> str:
|
|
263
|
+
if tags is None or tags == "":
|
|
263
264
|
return ""
|
|
265
|
+
if isinstance(tags, str):
|
|
266
|
+
iterable: Iterable[str] = [part.strip() for part in tags.split(",")]
|
|
267
|
+
else:
|
|
268
|
+
iterable = tags
|
|
264
269
|
normalized = {
|
|
265
|
-
_slugify(tag) for tag in
|
|
270
|
+
_slugify(tag) for tag in iterable if isinstance(tag, str) and _slugify(tag)
|
|
266
271
|
}
|
|
267
272
|
if not normalized:
|
|
268
273
|
return ""
|
|
269
274
|
return ",".join(sorted(normalized))
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
def normalize_tags(tags: Optional[Union[Iterable[str], str]]) -> Optional[List[str]]:
|
|
278
|
+
if tags is None or tags == "":
|
|
279
|
+
return None
|
|
280
|
+
if isinstance(tags, str):
|
|
281
|
+
parts = [part.strip() for part in tags.split(",") if part.strip()]
|
|
282
|
+
else:
|
|
283
|
+
parts = [str(part).strip() for part in tags if str(part).strip()]
|
|
284
|
+
if not parts:
|
|
285
|
+
return None
|
|
286
|
+
slugged = [_slugify(part) for part in parts if _slugify(part)]
|
|
287
|
+
if not slugged:
|
|
288
|
+
return None
|
|
289
|
+
return sorted(set(slugged))
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
fenix_mcp/__init__.py,sha256=
|
|
1
|
+
fenix_mcp/__init__.py,sha256=Nle0-p8uRDw1ypGPxnoKnAY0Mv0N8_6glE1whGPNnlw,615
|
|
2
2
|
fenix_mcp/main.py,sha256=iJV-9btNMDJMObvcn7wBQdbLLKjkYCQ1ANGEwHGHlMU,2857
|
|
3
3
|
fenix_mcp/application/presenters.py,sha256=fGME54PdCDhTBhXO-JUB9yLdBHiE1aeXLTC2fCuxnxM,689
|
|
4
4
|
fenix_mcp/application/tool_base.py,sha256=qUcb46qx9gHQfrSHgj4RD4NCHW-OIvKQdR5G9uxZ5l4,1316
|
|
@@ -6,12 +6,12 @@ fenix_mcp/application/tool_registry.py,sha256=bPT5g8GfxG_qu28R1WaDOZHvtmG6TPDvZi
|
|
|
6
6
|
fenix_mcp/application/tools/__init__.py,sha256=Gi1YvYh-KdL9HD8gLVrknHrxiKKEOhHBEZ02KBXJaKQ,796
|
|
7
7
|
fenix_mcp/application/tools/health.py,sha256=m5DxhoRbdwl6INzd6PISxv1NAv-ljCrezsr773VB0wE,834
|
|
8
8
|
fenix_mcp/application/tools/initialize.py,sha256=f33DNDn9u8IYwpqiBj6bjJ-wHgaUP1zEuAvUM1rMYPc,4674
|
|
9
|
-
fenix_mcp/application/tools/intelligence.py,sha256=
|
|
9
|
+
fenix_mcp/application/tools/intelligence.py,sha256=DNWGu6NhPYZXahnHDVHIgYYdWn_jCP-Nw9FwS_Tat34,13945
|
|
10
10
|
fenix_mcp/application/tools/knowledge.py,sha256=4ClGoFRqyFIPuzzg2DAg-w2eMvTP37mH0THXDGftinw,44634
|
|
11
11
|
fenix_mcp/application/tools/productivity.py,sha256=2IMkNdZ-Kd1CFAO7geruAVjtf_BWoDdbnwkl76vhtC8,9973
|
|
12
12
|
fenix_mcp/application/tools/user_config.py,sha256=8mPOZuwszO0TapxgrA7Foe15VQE874_mvfQYlGzyv4Y,6230
|
|
13
13
|
fenix_mcp/domain/initialization.py,sha256=AZhdSNITQ7O3clELBuqGvjJc-c8pFKc7zQz-XR2xXPc,6933
|
|
14
|
-
fenix_mcp/domain/intelligence.py,sha256=
|
|
14
|
+
fenix_mcp/domain/intelligence.py,sha256=IyZUA_fbCHDgHaWCgxkahXAaAT5qQlaz5AT7Cw2Gwko,9006
|
|
15
15
|
fenix_mcp/domain/knowledge.py,sha256=fKQOTt20u5aa5Yo7gPeQ1Qxa_K5pBxn1yn8FEfOFltM,20241
|
|
16
16
|
fenix_mcp/domain/productivity.py,sha256=nmHRuVJGRRu1s4eMoAv8vXHKsSauCPl-FvFx3I_yCTE,6661
|
|
17
17
|
fenix_mcp/domain/user_config.py,sha256=LzBDCk31gLMtKHTbBmYb9VoFPHDW6OydpmDXeHHd0Mw,1642
|
|
@@ -22,8 +22,8 @@ fenix_mcp/infrastructure/logging.py,sha256=bHrWlSi_0HshRe3--BK_5nzUszW-gh37q6jsd
|
|
|
22
22
|
fenix_mcp/infrastructure/fenix_api/client.py,sha256=Navi7cGAOradghcbYkFIQQINpjFrdINlNhdfZ4iSSYQ,28338
|
|
23
23
|
fenix_mcp/interface/mcp_server.py,sha256=5UM2NJuNbwHkmCEprIFataJ5nFZiO8efTtP_oW3_iX0,2331
|
|
24
24
|
fenix_mcp/interface/transports.py,sha256=PxdhfjH8UMl03f7nuCLc-M6tMx6-Y-btVz_mSqXKrSI,8138
|
|
25
|
-
fenix_mcp-0.5.
|
|
26
|
-
fenix_mcp-0.5.
|
|
27
|
-
fenix_mcp-0.5.
|
|
28
|
-
fenix_mcp-0.5.
|
|
29
|
-
fenix_mcp-0.5.
|
|
25
|
+
fenix_mcp-0.5.1.dist-info/METADATA,sha256=yvg8J1G-jemzju-BKR2tMd8Y_f5KKjHX6GrNQIONjR0,7260
|
|
26
|
+
fenix_mcp-0.5.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
27
|
+
fenix_mcp-0.5.1.dist-info/entry_points.txt,sha256=o52x_YHBupEd-1Z1GSfUjv3gJrx5_I-EkHhCgt1WBaE,49
|
|
28
|
+
fenix_mcp-0.5.1.dist-info/top_level.txt,sha256=2G1UtKpwjaIGQyE7sRoHecxaGLeuexfjrOUjv9DDKh4,10
|
|
29
|
+
fenix_mcp-0.5.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|