ghostdrive1's picture
Upload folder using huggingface_hub
116524e verified
Raw
History Blame Contribute Delete
3.64 kB
"""Prompts and report generation for skill deduplication."""
from __future__ import annotations
from typing import TYPE_CHECKING, List, Tuple
if TYPE_CHECKING:
from ..core.skillbook import Skill
SIMILARITY_REPORT_HEADER = """
## Similar Skills Detected
The following skill pairs have high semantic similarity and may need consolidation.
Work your way methodologically through each pair. For each pair, you can decide to:
- **MERGE**: Combine into a single improved skill (provide merged_content and keep_id)
- **DELETE**: Remove one as redundant (specify skill_id to delete)
- **KEEP**: Keep both separate if they serve different purposes (explain differentiation)
- **UPDATE**: Refine one skill's content to clarify the difference (provide new_content)
"""
PAIR_TEMPLATE = """### Pair {index}: {similarity:.0%} similar
**Skill A** [{id_a}]
> {content_a}
**Skill B** [{id_b}]
> {content_b}
"""
def generate_similarity_report(
similar_pairs: List[Tuple["Skill", "Skill", float]],
) -> str:
"""Generate a human-readable similarity report for the SkillManager.
Args:
similar_pairs: List of (skill_a, skill_b, similarity_score) tuples.
Returns:
Formatted report string to include in SkillManager prompt.
"""
if not similar_pairs:
return ""
parts = [SIMILARITY_REPORT_HEADER]
for i, (skill_a, skill_b, similarity) in enumerate(similar_pairs, 1):
parts.append(
PAIR_TEMPLATE.format(
index=i,
similarity=similarity,
id_a=skill_a.id,
content_a=skill_a.insight or skill_a.issue,
id_b=skill_b.id,
content_b=skill_b.insight or skill_b.issue,
)
)
parts.append("""
## Consolidation Operations Format
Include consolidation operations in your response under a `consolidation_operations` key.
Each operation should have a `type` field and relevant fields for that type:
```json
{
"consolidation_operations": [
{
"type": "MERGE",
"source_ids": ["skill-id-1", "skill-id-2"],
"keep_id": "skill-id-1",
"merged_content": "Improved combined strategy text",
"reasoning": "Why merging improves the skillbook"
},
{
"type": "DELETE",
"skill_id": "skill-id-to-remove",
"reasoning": "Why this skill is redundant"
},
{
"type": "KEEP",
"skill_ids": ["skill-id-1", "skill-id-2"],
"differentiation": "How they differ in purpose",
"reasoning": "Why both are needed"
},
{
"type": "UPDATE",
"skill_id": "skill-id-to-update",
"new_content": "Refined content with context tag like [Batch] or [API]",
"reasoning": "How this clarifies the distinction"
}
]
}
```
**Guidelines:**
- MERGE when skills are semantically identical or near-identical
- KEEP when they serve different contexts (batch vs real-time, different APIs, etc.)
- UPDATE to add context tags like "[Batch Jobs]" or "[User-Facing API]" to differentiate
- DELETE only when one is clearly redundant with no unique value
""")
return "".join(parts)
def format_pair_for_logging(
skill_a: "Skill", skill_b: "Skill", similarity: float
) -> str:
"""Format a single pair for logging output."""
text_a = skill_a.insight or skill_a.issue
text_b = skill_b.insight or skill_b.issue
return (
f"[{skill_a.id}] '{text_a[:50]}...' "
f"<-> [{skill_b.id}] '{text_b[:50]}...' "
f"({similarity:.0%} similar)"
)