-
Notifications
You must be signed in to change notification settings - Fork 698
Add skill for deck of cards API #538
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Deeptanshu-sankhwar
wants to merge
6
commits into
crestalnetwork:main
from
Deeptanshu-sankhwar:skill/deck-of-cards
Closed
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
0af1f14
add skill for deck of cards API
Deeptanshu-sankhwar 5753a2a
Merge branch 'main' into skill/deck-of-cards
Deeptanshu-sankhwar 932f06e
fix lint checks
Deeptanshu-sankhwar 16a08ce
Merge branch 'main' into skill/deck-of-cards
Deeptanshu-sankhwar d713342
Merge branch 'main' into skill/deck-of-cards
bluntbrain 62df93f
Merge branch 'main' into skill/deck-of-cards
bluntbrain File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| """Deck of Cards skills.""" | ||
|
|
||
| from typing import TypedDict | ||
|
|
||
| from abstracts.skill import SkillStoreABC | ||
| from skills.base import SkillConfig, SkillState | ||
| from skills.deckofcards.add_to_pile import AddToPile | ||
| from skills.deckofcards.base import DeckOfCardsBaseSkill | ||
| from skills.deckofcards.draw_cards import DrawCards | ||
| from skills.deckofcards.draw_from_pile import DrawFromPile | ||
| from skills.deckofcards.list_piles import ListPiles | ||
| from skills.deckofcards.shuffle_deck import ShuffleDeck | ||
|
|
||
| # Cache skills at the system level, because they are stateless | ||
| _cache: dict[str, DeckOfCardsBaseSkill] = {} | ||
|
|
||
|
|
||
| class SkillStates(TypedDict): | ||
| shuffle_deck: SkillState | ||
|
|
||
|
|
||
| class Config(SkillConfig): | ||
| """Configuration for Deck of Cards skills.""" | ||
|
|
||
| states: SkillStates | ||
|
|
||
|
|
||
| async def get_skills( | ||
| config: "Config", | ||
| is_private: bool, | ||
| store: SkillStoreABC, | ||
| **_, | ||
| ) -> list[DeckOfCardsBaseSkill]: | ||
| """Get all Deck of Cards skills.""" | ||
| available_skills = [] | ||
|
|
||
| # Include skills based on their state | ||
| 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) | ||
|
|
||
| # Get each skill using the cached getter | ||
| return [get_deckofcards_skill(name, store) for name in available_skills] | ||
|
|
||
|
|
||
| def get_deckofcards_skill( | ||
| name: str, | ||
| store: SkillStoreABC, | ||
| ) -> DeckOfCardsBaseSkill: | ||
| """Get a Deck of Cards skill by name.""" | ||
| if name not in _cache: | ||
| if name == "shuffle_deck": | ||
| _cache[name] = ShuffleDeck(skill_store=store) | ||
| elif name == "draw_cards": | ||
| _cache[name] = DrawCards(skill_store=store) | ||
| elif name == "add_to_pile": | ||
| _cache[name] = AddToPile(skill_store=store) | ||
| elif name == "draw_from_pile": | ||
| _cache[name] = DrawFromPile(skill_store=store) | ||
| elif name == "list_piles": | ||
| _cache[name] = ListPiles(skill_store=store) | ||
| else: | ||
| raise ValueError(f"Unknown Deck of Cards skill: {name}") | ||
| return _cache[name] | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| from typing import List | ||
|
|
||
| import httpx | ||
|
|
||
| from .base import DeckOfCardsBaseSkill | ||
|
|
||
|
|
||
| class AddToPile(DeckOfCardsBaseSkill): | ||
| """Skill to add cards to a named pile.""" | ||
|
|
||
| name = "add_to_pile" | ||
| description = "Add specified cards to a named pile in the deck" | ||
|
|
||
| async def _arun(self, deck_id: str, pile_name: str, cards: List[str]) -> str: | ||
| """ | ||
| Add cards to a named pile. | ||
|
|
||
| Args: | ||
| deck_id: ID of the deck | ||
| pile_name: Name of the pile to add cards to | ||
| cards: List of card codes to add (e.g., ["AS", "2S"]) | ||
|
|
||
| Returns: | ||
| str: Formatted response containing pile information | ||
| """ | ||
| try: | ||
| # Convert list of cards to comma-separated string | ||
| cards_str = ",".join(cards) | ||
|
|
||
| async with httpx.AsyncClient() as client: | ||
| response = await client.get( | ||
| f"https://deckofcardsapi.com/api/deck/{deck_id}/pile/{pile_name}/add/", | ||
| params={"cards": cards_str}, | ||
| ) | ||
| response.raise_for_status() | ||
| data = response.json() | ||
|
|
||
| if not data["success"]: | ||
| return "Error: Failed to add cards to pile" | ||
|
|
||
| result = [ | ||
| "Cards Added to Pile Successfully", | ||
| f"Deck ID: {data['deck_id']}", | ||
| f"Cards Remaining in Deck: {data['remaining']}", | ||
| "", | ||
| "Pile Status:", | ||
| ] | ||
|
|
||
| # Add information about each pile | ||
| for pile_name, pile_info in data["piles"].items(): | ||
| result.append(f"- {pile_name}: {pile_info['remaining']} cards") | ||
|
|
||
| return "\n".join(result) | ||
|
|
||
| except httpx.HTTPError as e: | ||
| return f"Error adding cards to pile: {str(e)}" | ||
| except Exception as e: | ||
| return f"Unexpected error: {str(e)}" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| from typing import Type | ||
|
|
||
| from pydantic import BaseModel, Field | ||
|
|
||
| from abstracts.skill import SkillStoreABC | ||
| from skills.base import IntentKitSkill | ||
|
|
||
|
|
||
| class DeckOfCardsBaseSkill(IntentKitSkill): | ||
| """Base class for Deck of Cards API tools.""" | ||
|
|
||
| name: str = Field(description="The name of the tool") | ||
| description: str = Field(description="A description of what the tool does") | ||
| args_schema: Type[BaseModel] | ||
| skill_store: SkillStoreABC = Field( | ||
| description="The skill store for persisting data" | ||
| ) | ||
|
|
||
| @property | ||
| def category(self) -> str: | ||
| return "deckofcards" |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| import httpx | ||
|
|
||
| from .base import DeckOfCardsBaseSkill | ||
|
|
||
|
|
||
| class DrawCards(DeckOfCardsBaseSkill): | ||
| """Skill to draw cards from a deck.""" | ||
|
|
||
| name = "draw_cards" | ||
| description = "Draw a specified number of cards from a deck" | ||
|
|
||
| async def _arun(self, deck_id: str, count: int = 1) -> str: | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If there are parameters, you need to declare them in |
||
| """ | ||
| Draw cards from a deck. | ||
|
|
||
| Args: | ||
| deck_id: ID of the deck to draw from | ||
| count: Number of cards to draw (default: 1) | ||
| params: Additional parameters (unused) | ||
|
|
||
| Returns: | ||
| str: Formatted response containing drawn cards information | ||
| """ | ||
| try: | ||
| async with httpx.AsyncClient() as client: | ||
| response = await client.get( | ||
| f"https://deckofcardsapi.com/api/deck/{deck_id}/draw/", | ||
| params={"count": count}, | ||
| ) | ||
| response.raise_for_status() | ||
| data = response.json() | ||
|
|
||
| if not data["success"]: | ||
| return "Error: Failed to draw cards" | ||
|
|
||
| result = [ | ||
| "Cards Drawn Successfully", | ||
| f"Deck ID: {data['deck_id']}", | ||
| f"Cards Remaining: {data['remaining']}", | ||
| "", | ||
| "Drawn Cards:", | ||
| ] | ||
|
|
||
| for card in data["cards"]: | ||
| result.extend( | ||
| [ | ||
| f"- {card['value']} of {card['suit']}", | ||
| f" Image: {card['image']}", | ||
| ] | ||
| ) | ||
|
|
||
| return "\n".join(result) | ||
|
|
||
| except httpx.HTTPError as e: | ||
| return f"Error drawing cards: {str(e)}" | ||
| except Exception as e: | ||
| return f"Unexpected error: {str(e)}" | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| from typing import List | ||
|
|
||
| import httpx | ||
|
|
||
| from .base import DeckOfCardsBaseSkill | ||
|
|
||
|
|
||
| class DrawFromPile(DeckOfCardsBaseSkill): | ||
| """Skill to draw cards from a named pile.""" | ||
|
|
||
| name = "draw_from_pile" | ||
| description = "Draw specified cards from a named pile in the deck" | ||
|
|
||
| async def _arun(self, deck_id: str, pile_name: str, cards: List[str]) -> str: | ||
| """ | ||
| Draw cards from a named pile. | ||
|
|
||
| Args: | ||
| deck_id: ID of the deck | ||
| pile_name: Name of the pile to draw from | ||
| cards: List of card codes to draw (e.g., ["AS", "2S"]) | ||
|
|
||
| Returns: | ||
| str: Formatted response containing drawn cards and pile information | ||
| """ | ||
| try: | ||
| # Convert list of cards to comma-separated string | ||
| cards_str = ",".join(cards) | ||
|
|
||
| async with httpx.AsyncClient() as client: | ||
| response = await client.get( | ||
| f"https://deckofcardsapi.com/api/deck/{deck_id}/pile/{pile_name}/draw/", | ||
| params={"cards": cards_str}, | ||
| ) | ||
| response.raise_for_status() | ||
| data = response.json() | ||
|
|
||
| if not data["success"]: | ||
| return "Error: Failed to draw cards from pile" | ||
|
|
||
| result = [ | ||
| "Cards Drawn from Pile Successfully", | ||
| f"Deck ID: {data['deck_id']}", | ||
| f"Cards Remaining in Deck: {data['remaining']}", | ||
| "", | ||
| "Pile Status:", | ||
| ] | ||
|
|
||
| # Add information about each pile | ||
| for pile_name, pile_info in data["piles"].items(): | ||
| result.append(f"- {pile_name}: {pile_info['remaining']} cards") | ||
|
|
||
| # Add information about drawn cards | ||
| if "cards" in data: | ||
| result.extend(["", "Drawn Cards:"]) | ||
| for card in data["cards"]: | ||
| result.extend( | ||
| [ | ||
| f"- {card['value']} of {card['suit']}", | ||
| f" Image: {card['image']}", | ||
| ] | ||
| ) | ||
|
|
||
| return "\n".join(result) | ||
|
|
||
| except httpx.HTTPError as e: | ||
| return f"Error drawing cards from pile: {str(e)}" | ||
| except Exception as e: | ||
| return f"Unexpected error: {str(e)}" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| import httpx | ||
|
|
||
| from .base import DeckOfCardsBaseSkill | ||
|
|
||
|
|
||
| class ListPiles(DeckOfCardsBaseSkill): | ||
| """Skill to list all piles and their contents in a deck.""" | ||
|
|
||
| name = "list_piles" | ||
| description = "View existing piles and their contents in the deck" | ||
|
|
||
| async def _arun(self, deck_id: str) -> str: | ||
| """ | ||
| List all piles and their contents. | ||
|
|
||
| Args: | ||
| deck_id: ID of the deck | ||
|
|
||
| Returns: | ||
| str: Formatted response containing pile information and contents | ||
| """ | ||
| try: | ||
| async with httpx.AsyncClient() as client: | ||
| response = await client.get( | ||
| f"https://deckofcardsapi.com/api/deck/{deck_id}/pile/list/" | ||
| ) | ||
| response.raise_for_status() | ||
| data = response.json() | ||
|
|
||
| if not data["success"]: | ||
| return "Error: Failed to list piles" | ||
|
|
||
| result = [ | ||
| "Piles Listed Successfully", | ||
| f"Deck ID: {data['deck_id']}", | ||
| f"Cards Remaining in Deck: {data['remaining']}", | ||
| "", | ||
| "Pile Contents:", | ||
| ] | ||
|
|
||
| # Add information about each pile | ||
| for pile_name, pile_info in data["piles"].items(): | ||
| result.append(f"\n{pile_name}:") | ||
| result.append(f"- Cards Remaining: {pile_info['remaining']}") | ||
|
|
||
| # Add card details if available | ||
| if "cards" in pile_info: | ||
| result.append("- Cards:") | ||
| for card in pile_info["cards"]: | ||
| result.extend( | ||
| [ | ||
| f" * {card['value']} of {card['suit']}", | ||
| f" Image: {card['image']}", | ||
| ] | ||
| ) | ||
|
|
||
| return "\n".join(result) | ||
|
|
||
| except httpx.HTTPError as e: | ||
| return f"Error listing piles: {str(e)}" | ||
| except Exception as e: | ||
| return f"Unexpected error: {str(e)}" |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or maybe you just missing others here?