From 030bbfb2f956cedcb80706fa421e2fb458b4ab1c Mon Sep 17 00:00:00 2001 From: wildanmuhib Date: Wed, 16 Apr 2025 22:01:03 +0700 Subject: [PATCH 1/3] add weird dream_interpreter skill --- skills/weird/__init__.py | 4 ++++ skills/weird/base.py | 4 ++++ skills/weird/dream_interpreter_skill.py | 27 +++++++++++++++++++++++++ skills/weird/schema.json | 11 ++++++++++ 4 files changed, 46 insertions(+) create mode 100644 skills/weird/__init__.py create mode 100644 skills/weird/base.py create mode 100644 skills/weird/dream_interpreter_skill.py create mode 100644 skills/weird/schema.json diff --git a/skills/weird/__init__.py b/skills/weird/__init__.py new file mode 100644 index 00000000..840d786b --- /dev/null +++ b/skills/weird/__init__.py @@ -0,0 +1,4 @@ +from .dream_interpreter_skill import DreamInterpreter + +def get_skills(): + return [DreamInterpreter()] diff --git a/skills/weird/base.py b/skills/weird/base.py new file mode 100644 index 00000000..926d2e03 --- /dev/null +++ b/skills/weird/base.py @@ -0,0 +1,4 @@ +from abstracts.skill import IntentKitSkill + +class WeirdSkill(IntentKitSkill): + category = "weird" diff --git a/skills/weird/dream_interpreter_skill.py b/skills/weird/dream_interpreter_skill.py new file mode 100644 index 00000000..6145d9f5 --- /dev/null +++ b/skills/weird/dream_interpreter_skill.py @@ -0,0 +1,27 @@ +from skills.weird.base import WeirdSkill +from pydantic import BaseModel +from typing import Type +import random + +class DreamInput(BaseModel): + dream_description: str + +class DreamOutput(BaseModel): + interpretation: str + error: str | None = None + +class DreamInterpreter(WeirdSkill): + name: str = "dream_interpreter" + description: str = "Interprets weird dreams poetically." + args_schema: Type[BaseModel] = DreamInput + + def _run(self, dream_description: str) -> DreamOutput: + try: + interpretations = [ + "You are a watermelon in a parallel universe.", + "Your soul craves to surf cosmic spaghetti.", + "A duck in your mind has declared independence." + ] + return DreamOutput(interpretation=random.choice(interpretations)) + except Exception as e: + return DreamOutput(interpretation="", error=str(e)) diff --git a/skills/weird/schema.json b/skills/weird/schema.json new file mode 100644 index 00000000..a78d5aed --- /dev/null +++ b/skills/weird/schema.json @@ -0,0 +1,11 @@ +{ + "type": "object", + "properties": { + "dream_description": { + "type": "string", + "description": "The content of the user's dream" + } + }, + "required": ["dream_description"] + } + \ No newline at end of file From e1b17a31be1a59e605d941ef8ea1ab389a5ec177 Mon Sep 17 00:00:00 2001 From: wildanmuhib Date: Thu, 24 Apr 2025 20:33:22 +0700 Subject: [PATCH 2/3] add weatherwise weatherwise_skill --- pyproject.toml | 112 +----------------------- setup.py | 11 +++ skills/weatherwise/__init__.py | 1 + skills/weatherwise/base.py | 15 ++++ skills/weatherwise/schema.json | 50 +++++++++++ skills/weatherwise/weatherwise_skill.py | 43 +++++++++ skills/weird/__init__.py | 4 - skills/weird/base.py | 4 - skills/weird/dream_interpreter_skill.py | 27 ------ skills/weird/schema.json | 11 --- 10 files changed, 122 insertions(+), 156 deletions(-) create mode 100644 setup.py create mode 100644 skills/weatherwise/__init__.py create mode 100644 skills/weatherwise/base.py create mode 100644 skills/weatherwise/schema.json create mode 100644 skills/weatherwise/weatherwise_skill.py delete mode 100644 skills/weird/__init__.py delete mode 100644 skills/weird/base.py delete mode 100644 skills/weird/dream_interpreter_skill.py delete mode 100644 skills/weird/schema.json diff --git a/pyproject.toml b/pyproject.toml index 3e4aa4a5..9787c3bd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,111 +1,3 @@ -[project] -name = "intentkit" -version = "0.1.19" -description = "Intent-based AI Agent Platform" -authors = [{name = "Ruihua", email = "ruihua@crestal.network"}] -readme = "README.md" -requires-python = ">=3.12,<4.0" -dependencies = [ - "langgraph (>=0.3.8,<0.4.0)", - "uvicorn>=0.34.0,<0.35.0", - "fastapi>=0.115.8", - "gunicorn>=23.0.0", - "pydantic>=2.10.6", - "pydantic-settings>=2.8.1", - "sqlalchemy[asyncio]>=2.0.37", - "psycopg>=3.2.3", - "psycopg2-binary>=2.9.10,<3.0.0", - "psycopg-pool>=3.2.4", - "alembic>=1.14.0", - "pgvector>=0.3.6", - "langchain (>=0.3.20,<0.4.0)", - "langchain-core>=0.3.43", - "langchain-openai>=0.3.8", - "langchain-postgres>=0.0.13", - "langchain-community>=0.3.19", - "langgraph-checkpoint>=2.0.18", - "langgraph-checkpoint-postgres>=2.0.16", - "openai>=1.59.6", - "cdp-sdk==0.17.0", - "tweepy[async]>=4.15.0", - "python-dotenv>=1.0.1", - "APScheduler>=3.11.0", - "anyio>=4.8.0", - "slack-sdk>=3.34.0", - "requests>=2.32.3", - "aws-secretsmanager-caching>=1.1.3", - "botocore>=1.35.97", - "aiogram>=3.17.0", - "epyxid>=0.3.3", - "sentry-sdk[fastapi]>=2.20.0", - "asyncpg>=0.30.0", - "goat-sdk>=0.1.4", - "goat-sdk-adapter-langchain", - "goat-sdk-wallet-crossmint", - "goat-sdk-wallet-evm", - "goat-sdk-wallet-web3", - "goat-sdk-wallet-solana", - "goat-sdk-plugin-1inch", - "goat-sdk-plugin-allora", - "goat-sdk-plugin-coingecko", - "goat-sdk-plugin-dexscreener", - "goat-sdk-plugin-erc20", - "goat-sdk-plugin-farcaster", - "goat-sdk-plugin-jsonrpc", - "goat-sdk-plugin-jupiter", - "goat-sdk-plugin-nansen", - "goat-sdk-plugin-opensea", - "goat-sdk-plugin-rugcheck", - "goat-sdk-plugin-spl-token", - "goat-sdk-plugin-superfluid", - "goat-sdk-plugin-uniswap", - "pyyaml>=6.0.2", - "python-multipart>=0.0.20", - "langchain-xai>=0.2.1", - "coinbase-agentkit==0.1.4.dev202502250", - "coinbase-agentkit-langchain>=0.1.0", - "jsonref>=1.1.0", - "pytz>=2025.1", - "redis (>=5.2.1,<6.0.0)", - "telegramify-markdown (>=0.5.0,<0.6.0)", - "langchain-mcp-adapters (>=0.0.5,<0.0.6)", - "pillow (>=11.1.0,<12.0.0)", - "cron-validator (>=1.0.8,<2.0.0)", - "boto3 (>=1.37.23,<2.0.0)", - "mypy-boto3-s3 (>=1.37.24,<2.0.0)" -] - -[tool.poetry] -package-mode = false - -[tool.poetry.group.dev] -optional = true - -[tool.poetry.group.dev.dependencies] -ruff = "^0.11.4" -jsonschema = "^4.21.1" - -[tool.ruff.lint] -extend-select = ["I"] - -[tool.mypy] -python_version = "3.12" -warn_return_any = true -warn_unused_configs = true -disallow_untyped_defs = true -disallow_incomplete_defs = true -check_untyped_defs = true -disallow_untyped_decorators = true -no_implicit_optional = true -warn_redundant_casts = true -warn_unused_ignores = true -warn_no_return = true -warn_unreachable = true -ignore_missing_imports = true -explicit_package_bases = true -namespace_packages = true -mypy_path = "." - [build-system] -requires = ["poetry-core"] -build-backend = "poetry.core.masonry.api" +requires = ["setuptools", "wheel"] +build-backend = "setuptools.build_meta" diff --git a/setup.py b/setup.py new file mode 100644 index 00000000..2716e59b --- /dev/null +++ b/setup.py @@ -0,0 +1,11 @@ +from setuptools import setup, find_packages + +setup( + name='intentkit', + version='0.1', + packages=find_packages(), + install_requires=[ + # Misalnya, jika ada dependensi lain seperti: + # 'pydantic', + ], +) diff --git a/skills/weatherwise/__init__.py b/skills/weatherwise/__init__.py new file mode 100644 index 00000000..38da7f0f --- /dev/null +++ b/skills/weatherwise/__init__.py @@ -0,0 +1 @@ +from .weatherwise_skill import WeatherWise diff --git a/skills/weatherwise/base.py b/skills/weatherwise/base.py new file mode 100644 index 00000000..859fda00 --- /dev/null +++ b/skills/weatherwise/base.py @@ -0,0 +1,15 @@ +from intentkit.agent.skills.base import BaseSkill +from .weatherpulse_skill import FetchWeatherForecast, FetchWeatherAlerts + + +class WeatherPulseSkill(BaseSkill): + """ + WeatherPulseSkill adalah kumpulan fungsi untuk mendapatkan prakiraan cuaca dan peringatan cuaca + dari sumber API eksternal. + """ + + def __init__(self, config): + super().__init__(config=config) + + self.add_state("fetch_weather_forecast", FetchWeatherForecast(config)) + self.add_state("fetch_weather_alerts", FetchWeatherAlerts(config)) diff --git a/skills/weatherwise/schema.json b/skills/weatherwise/schema.json new file mode 100644 index 00000000..9caebd69 --- /dev/null +++ b/skills/weatherwise/schema.json @@ -0,0 +1,50 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "title": "WeatherWise Skill", + "description": "Analyze current weather conditions based on location input.", + "x-icon": "https://ai.service.crestal.dev/skills/weatherwise/weatherwise.png", + "x-tags": ["Data", "Weather"], + "x-api-key": "required", + "properties": { + "enabled": { + "type": "boolean", + "title": "Enabled", + "description": "Whether this skill is enabled", + "default": false + }, + "states": { + "type": "object", + "properties": { + "analyze_weather": { + "type": "string", + "title": "Analyze Weather", + "enum": ["disabled", "public", "private"], + "x-enum-title": ["Disabled", "Agent Owner + All Users", "Agent Owner Only"], + "default": "disabled", + "description": "Fetches and interprets current weather conditions." + } + }, + "description": "States for each WeatherWise skill (disabled, public, or private)" + }, + "api_key": { + "type": "string", + "title": "OpenWeather API Key", + "x-link": "[Get your API key](https://openweathermap.org/api)", + "x-sensitive": true, + "description": "API key for accessing OpenWeather API" + } + }, + "required": ["enabled", "states"], + "if": { + "properties": { + "enabled": { + "const": true + } + } + }, + "then": { + "required": ["api_key"] + }, + "additionalProperties": true +} diff --git a/skills/weatherwise/weatherwise_skill.py b/skills/weatherwise/weatherwise_skill.py new file mode 100644 index 00000000..d6a2cfab --- /dev/null +++ b/skills/weatherwise/weatherwise_skill.py @@ -0,0 +1,43 @@ +from pydantic import BaseModel, Field +from langchain_core.runnables import RunnableConfig +import requests + +from intentkit.core.tool import IntentKitTool +from intentkit.core.skill_config import SkillConfig +from intentkit.core.skill_states import SkillStates + +class Config(SkillConfig): + states: SkillStates + api_key: str + +class WeatherWiseInput(BaseModel): + location: str = Field(description="Location (city name or city,country_code) to fetch weather for.") + +class WeatherWise(IntentKitTool): + name = "analyze_weather" + description = "Get and analyze current weather conditions for a given location." + input_schema = WeatherWiseInput + + def __init__(self, config: Config): + self.api_key = config.api_key + super().__init__() + + async def _arun(self, config: RunnableConfig, location: str) -> str: + context = self.context_from_config(config) + url = f"http://api.openweathermap.org/data/2.5/weather?q={location}&appid={self.api_key}&units=metric" + response = requests.get(url) + if response.status_code != 200: + return f"Failed to fetch weather for {location}. Please check the location and try again." + + data = response.json() + desc = data["weather"][0]["description"] + temp = data["main"]["temp"] + humidity = data["main"]["humidity"] + + return ( + f"Current weather in {location}:\n" + f"- Condition: {desc}\n" + f"- Temperature: {temp}°C\n" + f"- Humidity: {humidity}%\n" + f"This information may help you plan your day better!" + ) diff --git a/skills/weird/__init__.py b/skills/weird/__init__.py deleted file mode 100644 index 840d786b..00000000 --- a/skills/weird/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from .dream_interpreter_skill import DreamInterpreter - -def get_skills(): - return [DreamInterpreter()] diff --git a/skills/weird/base.py b/skills/weird/base.py deleted file mode 100644 index 926d2e03..00000000 --- a/skills/weird/base.py +++ /dev/null @@ -1,4 +0,0 @@ -from abstracts.skill import IntentKitSkill - -class WeirdSkill(IntentKitSkill): - category = "weird" diff --git a/skills/weird/dream_interpreter_skill.py b/skills/weird/dream_interpreter_skill.py deleted file mode 100644 index 6145d9f5..00000000 --- a/skills/weird/dream_interpreter_skill.py +++ /dev/null @@ -1,27 +0,0 @@ -from skills.weird.base import WeirdSkill -from pydantic import BaseModel -from typing import Type -import random - -class DreamInput(BaseModel): - dream_description: str - -class DreamOutput(BaseModel): - interpretation: str - error: str | None = None - -class DreamInterpreter(WeirdSkill): - name: str = "dream_interpreter" - description: str = "Interprets weird dreams poetically." - args_schema: Type[BaseModel] = DreamInput - - def _run(self, dream_description: str) -> DreamOutput: - try: - interpretations = [ - "You are a watermelon in a parallel universe.", - "Your soul craves to surf cosmic spaghetti.", - "A duck in your mind has declared independence." - ] - return DreamOutput(interpretation=random.choice(interpretations)) - except Exception as e: - return DreamOutput(interpretation="", error=str(e)) diff --git a/skills/weird/schema.json b/skills/weird/schema.json deleted file mode 100644 index a78d5aed..00000000 --- a/skills/weird/schema.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "type": "object", - "properties": { - "dream_description": { - "type": "string", - "description": "The content of the user's dream" - } - }, - "required": ["dream_description"] - } - \ No newline at end of file From bb8866676cf639cf297113b25d52fe7529972770 Mon Sep 17 00:00:00 2001 From: wildanmuhib Date: Thu, 24 Apr 2025 20:37:37 +0700 Subject: [PATCH 3/3] add weatherwise weatherwise_skill --- pyproject.toml | 113 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 111 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 9787c3bd..e6945ce0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,112 @@ +[project] +name = "intentkit" +version = "0.1.19" +description = "Intent-based AI Agent Platform" +authors = [{name = "Ruihua", email = "ruihua@crestal.network"}] +readme = "README.md" +requires-python = ">=3.12,<4.0" +dependencies = [ + "langgraph (>=0.3.8,<0.4.0)", + "uvicorn>=0.34.0,<0.35.0", + "fastapi>=0.115.8", + "gunicorn>=23.0.0", + "pydantic>=2.10.6", + "pydantic-settings>=2.8.1", + "sqlalchemy[asyncio]>=2.0.37", + "psycopg>=3.2.3", + "psycopg2-binary>=2.9.10,<3.0.0", + "psycopg-pool>=3.2.4", + "alembic>=1.14.0", + "pgvector>=0.3.6", + "langchain (>=0.3.20,<0.4.0)", + "langchain-core>=0.3.43", + "langchain-openai>=0.3.8", + "langchain-postgres>=0.0.13", + "langchain-community>=0.3.19", + "langgraph-checkpoint>=2.0.18", + "langgraph-checkpoint-postgres>=2.0.16", + "openai>=1.59.6", + "cdp-sdk==0.17.0", + "tweepy[async]>=4.15.0", + "python-dotenv>=1.0.1", + "APScheduler>=3.11.0", + "anyio>=4.8.0", + "slack-sdk>=3.34.0", + "requests>=2.32.3", + "aws-secretsmanager-caching>=1.1.3", + "botocore>=1.35.97", + "aiogram>=3.17.0", + "epyxid>=0.3.3", + "sentry-sdk[fastapi]>=2.20.0", + "asyncpg>=0.30.0", + "goat-sdk>=0.1.4", + "goat-sdk-adapter-langchain", + "goat-sdk-wallet-crossmint", + "goat-sdk-wallet-evm", + "goat-sdk-wallet-web3", + "goat-sdk-wallet-solana", + "goat-sdk-plugin-1inch", + "goat-sdk-plugin-allora", + "goat-sdk-plugin-coingecko", + "goat-sdk-plugin-dexscreener", + "goat-sdk-plugin-erc20", + "goat-sdk-plugin-farcaster", + "goat-sdk-plugin-jsonrpc", + "goat-sdk-plugin-jupiter", + "goat-sdk-plugin-nansen", + "goat-sdk-plugin-opensea", + "goat-sdk-plugin-rugcheck", + "goat-sdk-plugin-spl-token", + "goat-sdk-plugin-superfluid", + "goat-sdk-plugin-uniswap", + "pyyaml>=6.0.2", + "python-multipart>=0.0.20", + "langchain-xai>=0.2.1", + "coinbase-agentkit==0.1.4.dev202502250", + "coinbase-agentkit-langchain>=0.1.0", + "jsonref>=1.1.0", + "pytz>=2025.1", + "redis (>=5.2.1,<6.0.0)", + "telegramify-markdown (>=0.5.0,<0.6.0)", + "langchain-mcp-adapters (>=0.0.5,<0.0.6)", + "pillow (>=11.1.0,<12.0.0)", + "cron-validator (>=1.0.8,<2.0.0)", + "boto3 (>=1.37.23,<2.0.0)", + "mypy-boto3-s3 (>=1.37.24,<2.0.0)", + "filetype (>=1.2.0,<2.0.0)" +] + +[tool.poetry] +package-mode = false + +[tool.poetry.group.dev] +optional = true + +[tool.poetry.group.dev.dependencies] +ruff = "^0.11.4" +jsonschema = "^4.21.1" + +[tool.ruff.lint] +extend-select = ["I"] + +[tool.mypy] +python_version = "3.12" +warn_return_any = true +warn_unused_configs = true +disallow_untyped_defs = true +disallow_incomplete_defs = true +check_untyped_defs = true +disallow_untyped_decorators = true +no_implicit_optional = true +warn_redundant_casts = true +warn_unused_ignores = true +warn_no_return = true +warn_unreachable = true +ignore_missing_imports = true +explicit_package_bases = true +namespace_packages = true +mypy_path = "." + [build-system] -requires = ["setuptools", "wheel"] -build-backend = "setuptools.build_meta" +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" \ No newline at end of file