Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions skills/huggingface/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# HuggingFace Skill Category

This skill category enables natural language understanding tools via HuggingFace Transformers.

## Included Skills

### 🧠 Sentiment Analysis

**Description:**
Analyzes the sentiment of input text (e.g., "I love this!") and returns a label (`POSITIVE`, `NEGATIVE`, etc.) along with a confidence score.

## Configuration Example

```yaml
skills:
huggingface:
states:
sentiment_analysis: public

36 changes: 36 additions & 0 deletions skills/huggingface/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from typing import TypedDict
from abstracts.skill import SkillStoreABC
from skills.base import SkillConfig, SkillState
from skills.huggingface.base import HuggingFaceBaseTool
from skills.huggingface.sentiment_analysis import SentimentAnalysis

_cache: dict[str, HuggingFaceBaseTool] = {}

class SkillStates(TypedDict):
sentiment_analysis: SkillState

class Config(SkillConfig):
states: SkillStates

async def get_skills(
config: "Config",
is_private: bool,
store: SkillStoreABC,
**_,
) -> list[HuggingFaceBaseTool]:
available_skills = []
for skill_name, state in config["states"].items():
if state == "disabled":
continue
elif state == "public" or (state == "private" and is_private):
available_skills.append(skill_name)

return [get_huggingface_skill(name, store) for name in available_skills]

def get_huggingface_skill(name: str, store: SkillStoreABC) -> HuggingFaceBaseTool:
if name == "sentiment_analysis":
if name not in _cache:
_cache[name] = SentimentAnalysis(skill_store=store)
return _cache[name]
raise ValueError(f"Unknown HuggingFace skill: {name}")

17 changes: 17 additions & 0 deletions skills/huggingface/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from typing import Type
from pydantic import BaseModel, Field
from abstracts.skill import SkillStoreABC
from skills.base import IntentKitSkill

class HuggingFaceBaseTool(IntentKitSkill):
"""Base class for HuggingFace NLP tools."""

name: str = Field(description="Tool name")
description: str = Field(description="What the tool does")
args_schema: Type[BaseModel]
skill_store: SkillStoreABC = Field(description="Skill store for data persistence")

@property
def category(self) -> str:
return "huggingface"

Binary file added skills/huggingface/huggingface.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 23 additions & 0 deletions skills/huggingface/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"title": "HuggingFace Skills",
"description": "Configuration schema for HuggingFace-powered skills",
"properties": {
"states": {
"type": "object",
"properties": {
"sentiment_analysis": {
"type": "string",
"title": "Sentiment Analysis",
"enum": ["disabled", "public", "private"],
"description": "State of the sentiment analysis skill"
}
},
"description": "States for HuggingFace skills"
}
},
"required": ["states"],
"additionalProperties": true
}

22 changes: 22 additions & 0 deletions skills/huggingface/sentiment_analysis.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from typing import Type
from pydantic import BaseModel, Field
from skills.huggingface.base import HuggingFaceBaseTool
from transformers import pipeline

class SentimentAnalysisInput(BaseModel):
text: str = Field(description="Text to analyze sentiment for")

class SentimentAnalysis(HuggingFaceBaseTool):
name: str = "sentiment_analysis"
description: str = "Analyze sentiment of a given text using HuggingFace Transformers"
args_schema: Type[BaseModel] = SentimentAnalysisInput

_analyzer = pipeline("sentiment-analysis")

async def _arun(self, text: str, **kwargs) -> str:
try:
result = self._analyzer(text)[0]
return f"Sentiment: {result['label']} with score {result['score']:.2f}"
except Exception as e:
return f"Failed to analyze sentiment: {str(e)}"