Skip to content
Draft
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
3 changes: 3 additions & 0 deletions pkgs/base/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ class MyConcreteClass(LLMBase):
### prompt_templates
- [`PromptTemplateBase.py`](./swarmauri_base/prompt_templates/PromptTemplateBase.py): Base class for prompt templates.

### prompt_samplers
- [`PromptSamplerBase.py`](./swarmauri_base/prompt_samplers/PromptSamplerBase.py): Base class for prompt samplers, exposing helper methods for managing an optional prompt list.

### schema_converters
- [`SchemaConverterBase.py`](./swarmauri_base/schema_converters/SchemaConverterBase.py): Base class for schema converters.

Expand Down
1 change: 1 addition & 0 deletions pkgs/base/swarmauri_base/ComponentBase.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,4 @@ class ResourceTypes(Enum):
SIMILARITY = "Similarity"
PSEUDOMETRIC = "PseudoMetric"
SEMINORM = "SemiNorm"
PROMPT_SAMPLER = "PromptSampler"
46 changes: 46 additions & 0 deletions pkgs/base/swarmauri_base/prompt_samplers/PromptSamplerBase.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from typing import Sequence, Optional, List, Literal
from pydantic import Field

from swarmauri_core.prompt_samplers.IPromptSampler import IPromptSampler
from swarmauri_base.ComponentBase import ComponentBase, ResourceTypes


@ComponentBase.register_model()
class PromptSamplerBase(IPromptSampler, ComponentBase):
"""Abstract base class for prompt samplers."""

prompts: Optional[List[str]] = None
resource: Optional[str] = Field(default=ResourceTypes.PROMPT_SAMPLER.value, frozen=True)
type: Literal["PromptSamplerBase"] = "PromptSamplerBase"

def sample(self, prompts: Optional[Sequence[str]] = None) -> str: # pragma: no cover - base method
raise NotImplementedError

def set_prompts(self, prompts: Sequence[str]) -> None:
self.prompts = list(prompts)

def add_prompt(self, prompt: str) -> None:
if self.prompts is None:
self.prompts = [prompt]
else:
self.prompts.append(prompt)

def add_prompts(self, prompts: Sequence[str]) -> None:
if self.prompts is None:
self.prompts = list(prompts)
else:
self.prompts.extend(prompts)

def remove_prompt(self, prompt: str) -> None:
if not self.prompts:
raise ValueError("No prompts stored.")
try:
self.prompts.remove(prompt)
except ValueError as exc:
raise ValueError(f"Prompt '{prompt}' not found.") from exc

def clear_prompts(self) -> None:
self.prompts = None

def show(self) -> Sequence[str]:
return self.prompts or []
Empty file.
41 changes: 41 additions & 0 deletions pkgs/core/swarmauri_core/prompt_samplers/IPromptSampler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from abc import ABC, abstractmethod
from typing import Sequence, Optional


class IPromptSampler(ABC):
"""Interface for sampling prompts from a collection."""

@abstractmethod
def sample(self, prompts: Optional[Sequence[str]] = None) -> str:
"""Return a sampled prompt from the provided sequence or internal store."""
pass

@abstractmethod
def set_prompts(self, prompts: Sequence[str]) -> None:
"""Replace the internal prompt collection with a new list."""
pass

@abstractmethod
def add_prompt(self, prompt: str) -> None:
"""Add a single prompt to the internal collection."""
pass

@abstractmethod
def add_prompts(self, prompts: Sequence[str]) -> None:
"""Extend the internal collection with multiple prompts."""
pass

@abstractmethod
def remove_prompt(self, prompt: str) -> None:
"""Remove a prompt from the internal collection."""
pass

@abstractmethod
def clear_prompts(self) -> None:
"""Remove all stored prompts."""
pass

@abstractmethod
def show(self) -> Sequence[str]:
"""Return all stored prompts."""
pass
Empty file.
3 changes: 3 additions & 0 deletions pkgs/swarmauri_standard/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,9 @@ agents using predefined configurations.
### Prompt Templates
- [PromptTemplate.py](swarmauri_standard/prompt_templates/PromptTemplate.py): Defines templates for generating prompts.

### Prompt Samplers
- [PromptSampler.py](swarmauri_standard/prompt_samplers/PromptSampler.py): Randomly selects a prompt either from provided values or the sampler's internal list.

### Schema Converters
- [AnthropicSchemaConverter.py](swarmauri_standard/schema_converters/AnthropicSchemaConverter.py): Converts schemas for Anthropic models.
- [CohereSchemaConverter.py](swarmauri_standard/schema_converters/CohereSchemaConverter.py): Converts schemas for Cohere models.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from typing import Literal, Sequence, Optional
import random

from swarmauri_base.prompt_samplers.PromptSamplerBase import PromptSamplerBase
from swarmauri_base.ComponentBase import ComponentBase


@ComponentBase.register_type(PromptSamplerBase, "PromptSampler")
class PromptSampler(PromptSamplerBase):
"""Sample a random prompt from a sequence."""

type: Literal["PromptSampler"] = "PromptSampler"

def sample(self, prompts: Optional[Sequence[str]] = None) -> str:
prompts = list(prompts) if prompts is not None else list(self.prompts or [])
return random.choice(prompts) if prompts else ""
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import pytest
from swarmauri_standard.prompt_samplers.PromptSampler import PromptSampler


@pytest.mark.unit
def test_ubc_resource():
sampler = PromptSampler()
assert sampler.resource == "PromptSampler"


@pytest.mark.unit
def test_ubc_type():
sampler = PromptSampler()
assert sampler.type == "PromptSampler"


@pytest.mark.unit
def test_serialization():
sampler = PromptSampler(prompts=["a"])
assert sampler.id == PromptSampler.model_validate_json(sampler.model_dump_json()).id


@pytest.mark.unit
def test_sampling_with_argument():
sampler = PromptSampler()
prompts = ["a", "b", "c"]
assert sampler.sample(prompts) in prompts


@pytest.mark.unit
def test_sampling_from_attribute():
sampler = PromptSampler(prompts=["a", "b", "c"])
assert sampler.sample() in ["a", "b", "c"]


@pytest.mark.unit
def test_manipulation_methods():
sampler = PromptSampler(prompts=["a"])
sampler.add_prompt("b")
sampler.add_prompts(["c", "d"])
assert sampler.show() == ["a", "b", "c", "d"]
sampler.remove_prompt("c")
assert sampler.show() == ["a", "b", "d"]
sampler.clear_prompts()
assert sampler.show() == []
Loading