14 | );
15 | };
16 |
17 | export default <%= name %>;
--------------------------------------------------------------------------------
/tests/test_api.py:
--------------------------------------------------------------------------------
1 | """Test rdddy REST API."""
2 |
3 | import httpx
4 | from fastapi.testclient import TestClient
5 |
6 | from rdddy.api import app
7 |
8 | client = TestClient(app)
9 |
10 |
11 | def test_read_root() -> None:
12 | """Test that reading the root is successful."""
13 | response = client.get("/")
14 | assert httpx.codes.is_success(response.status_code)
15 |
--------------------------------------------------------------------------------
/frontend/next.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | async rewrites() {
4 | return [
5 | {
6 | source: '/receive_transcript', // Prefix for your API calls
7 | destination: 'http://localhost:8000/receive_transcript', // Your FastAPI backend
8 | },
9 | ];
10 | },
11 | };
12 |
13 | export default nextConfig;
14 |
--------------------------------------------------------------------------------
/hello_world.py:
--------------------------------------------------------------------------------
1 | from pydantic import BaseModel, Field, validator, root_validator, EmailStr, UrlStr
2 | from typing import List, Optional
3 | from datetime import datetime
4 |
5 |
6 | class HelloWorld(BaseModel):
7 | """A simple Pydantic model for displaying a message."""
8 | message: str = Field(default="Hello, World!", title="", description="A simple message to be displayed.")
9 |
10 |
--------------------------------------------------------------------------------
/src/experiments/ping_pong_module.py:
--------------------------------------------------------------------------------
1 | import dspy
2 |
3 | lm = dspy.OpenAI(max_tokens=500)
4 | dspy.settings.configure(lm=lm)
5 |
6 |
7 | class PingPongModule(dspy.Module):
8 | """A module that simulates a game of ping pong."""
9 |
10 | def forward(self, player1, player2):
11 | pred = dspy.Predict("player1, player2 -> winner")
12 |
13 | result = pred(player1, player2).winner
14 |
15 | return result
16 |
--------------------------------------------------------------------------------
/src/rdddy/thought/openai_usage.log:
--------------------------------------------------------------------------------
1 | Note: NumExpr detected 10 cores but "NUMEXPR_MAX_THREADS" not set, so enforcing safe limit of 8.
2 | NumExpr defaulting to 8 threads.
3 | HTTP Request: POST https://api.openai.com/v1/completions "HTTP/1.1 200 OK"
4 | HTTP Request: POST https://api.openai.com/v1/completions "HTTP/1.1 200 OK"
5 | Note: NumExpr detected 10 cores but "NUMEXPR_MAX_THREADS" not set, so enforcing safe limit of 8.
6 | NumExpr defaulting to 8 threads.
7 |
--------------------------------------------------------------------------------
/frontend/src/app/page.js:
--------------------------------------------------------------------------------
1 | "use client";
2 | import Image from "next/image";
3 | import Dictaphone from "@/component/Dictaphone";
4 |
5 | export default function Home() {
6 | return (
7 |
8 |
9 |
10 |
11 |
12 | );
13 | }
14 |
--------------------------------------------------------------------------------
/src/rdddy/abstract_view.py:
--------------------------------------------------------------------------------
1 | class AbstractView:
2 | """serves as the foundation for user interface components in a reactive system. It outlines methods for rendering
3 | data to the user and reacting to user inputs, enabling the development of dynamic and responsive user interfaces.
4 | Subclasses of AbstractView are tailored to specific UI requirements, responding to changes in the application's
5 | state with real-time updates."""
6 |
7 | pass
8 |
--------------------------------------------------------------------------------
/frontend/src/app/layout.js:
--------------------------------------------------------------------------------
1 | import { Inter } from "next/font/google";
2 | import "./globals.css";
3 |
4 | const inter = Inter({ subsets: ["latin"] });
5 |
6 | export const metadata = {
7 | title: "Create Next App",
8 | description: "Generated by create next app",
9 | };
10 |
11 | export default function RootLayout({ children }) {
12 | return (
13 |
14 | {children}
15 |
16 | );
17 | }
18 |
--------------------------------------------------------------------------------
/src/rdddy/domain_exception.py:
--------------------------------------------------------------------------------
1 | class DomainException(Exception):
2 | """Acts as a base class for defining domain-specific exceptions. These exceptions are used to signal error
3 | conditions in a way that is meaningful within the domain context, providing clear and actionable feedback to the
4 | system or the end-user. Custom exceptions derived from DomainException enhance error handling by incorporating
5 | domain-relevant information and context."""
6 |
7 | pass
8 |
--------------------------------------------------------------------------------
/src/rdddy/signatures/question_answering.py:
--------------------------------------------------------------------------------
1 | from dspy import Signature
2 | from dspy.signatures.field import InputField, OutputField
3 |
4 |
5 | class QuestionAnswering(Signature):
6 | """
7 | Documentation of the task's expected LM function and output.
8 | """
9 |
10 | context = InputField(desc="Contains cited relevant facts.")
11 | question = InputField(desc="The question to be answered.")
12 |
13 | answer = OutputField(desc="Descriptive answer to the question.")
14 |
--------------------------------------------------------------------------------
/src/rdddy/abstract_task.py:
--------------------------------------------------------------------------------
1 | class AbstractTask:
2 | """Outlines the structure for tasks, which are discrete units of logic executed as part of the
3 | system's operations. Tasks encapsulate specific behaviors or processes, such as validation, computation,
4 | or state transitions, facilitating modularity and reuse. By defining tasks as subclasses of AbstractTask,
5 | the system can orchestrate complex operations while maintaining clarity and separation of concerns.
6 | """
7 |
8 | pass
9 |
--------------------------------------------------------------------------------
/src/rdddy/abstract_value_object.py:
--------------------------------------------------------------------------------
1 | from pydantic import BaseModel, ConfigDict
2 | from typing import Any
3 |
4 |
5 | class AbstractValueObject(BaseModel):
6 | model_config = ConfigDict(frozen=True, arbitrary_types_allowed=True)
7 |
8 | # Example of a method that might be common across all value objects
9 | def __eq__(self, other: Any) -> bool:
10 | if isinstance(other, self.__class__):
11 | return self.model_dump() == other.model_dump()
12 | return False
13 |
--------------------------------------------------------------------------------
/frontend/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 | .yarn/install-state.gz
8 |
9 | # testing
10 | /coverage
11 |
12 | # next.js
13 | /.next/
14 | /out/
15 |
16 | # production
17 | /build
18 |
19 | # misc
20 | .DS_Store
21 | *.pem
22 |
23 | # debug
24 | npm-debug.log*
25 | yarn-debug.log*
26 | yarn-error.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
34 | # typescript
35 | *.tsbuildinfo
36 | next-env.d.ts
37 |
--------------------------------------------------------------------------------
/src/rdddy/signatures/product_recommendation.py:
--------------------------------------------------------------------------------
1 | from dspy import Signature
2 | from dspy.signatures.field import InputField, OutputField
3 |
4 |
5 | class ProductRecommendation(Signature):
6 | """
7 | This signature takes in a customer's profile and browsing history and outputs recommended products.
8 | """
9 |
10 | customer_profile = InputField(desc="The customer's profile information.")
11 | browsing_history = InputField(desc="The customer's browsing history.")
12 |
13 | recommended_products = OutputField(desc="The list of recommended products.")
14 |
--------------------------------------------------------------------------------
/frontend/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | module.exports = {
3 | content: [
4 | "./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
5 | "./src/components/**/*.{js,ts,jsx,tsx,mdx}",
6 | "./src/app/**/*.{js,ts,jsx,tsx,mdx}",
7 | ],
8 | theme: {
9 | extend: {
10 | backgroundImage: {
11 | "gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
12 | "gradient-conic":
13 | "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
14 | },
15 | },
16 | },
17 | plugins: [],
18 | };
19 |
--------------------------------------------------------------------------------
/src/elixir/ping_pong/README.md:
--------------------------------------------------------------------------------
1 | # PingPong
2 |
3 | **TODO: Add description**
4 |
5 | ## Installation
6 |
7 | If [available in Hex](https://hex.pm/docs/publish), the package can be installed
8 | by adding `ping_pong` to your list of dependencies in `mix.exs`:
9 |
10 | ```elixir
11 | def deps do
12 | [
13 | {:ping_pong, "~> 0.1.0"}
14 | ]
15 | end
16 | ```
17 |
18 | Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)
19 | and published on [HexDocs](https://hexdocs.pm). Once published, the docs can
20 | be found at .
21 |
22 |
--------------------------------------------------------------------------------
/src/rdddy/signatures/openai_usage.log:
--------------------------------------------------------------------------------
1 | Note: NumExpr detected 10 cores but "NUMEXPR_MAX_THREADS" not set, so enforcing safe limit of 8.
2 | NumExpr defaulting to 8 threads.
3 | Note: NumExpr detected 10 cores but "NUMEXPR_MAX_THREADS" not set, so enforcing safe limit of 8.
4 | NumExpr defaulting to 8 threads.
5 | HTTP Request: POST https://api.openai.com/v1/completions "HTTP/1.1 200 OK"
6 | Note: NumExpr detected 10 cores but "NUMEXPR_MAX_THREADS" not set, so enforcing safe limit of 8.
7 | NumExpr defaulting to 8 threads.
8 | HTTP Request: POST https://api.openai.com/v1/completions "HTTP/1.1 200 OK"
9 |
--------------------------------------------------------------------------------
/src/rdddy/abstract_saga.py:
--------------------------------------------------------------------------------
1 | from rdddy.abstract_actor import AbstractActor
2 |
3 |
4 | class AbstractSaga(AbstractActor):
5 | """Encapsulates the logic for managing long-running, complex business transactions that span multiple services or
6 | bounded contexts. It provides mechanisms for orchestrating sequences of domain events and commands,
7 | ensuring transactional consistency and compensating actions in case of failures. By extending AbstractSaga,
8 | developers can implement coordinated workflows that are robust and aligned with business processes.
9 | """
10 |
11 | pass
12 |
--------------------------------------------------------------------------------
/src/experiments/example/query/list_books.py:
--------------------------------------------------------------------------------
1 | from rdddy.query import Query
2 |
3 |
4 | class ListBooks(Query):
5 | """
6 | The ListBooks class is responsible for handling queries for book data in our reactive ddd system. It contains methods for retrieving a list of books based on various criteria, such as genre, author, or publication date. This class acts as a mediator between the user interface and the database, ensuring efficient and accurate retrieval of book data. It also implements reactive programming principles to ensure responsiveness and scalability in our system.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/rdddy/generators/fastapi_route.py:
--------------------------------------------------------------------------------
1 | from pydantic import BaseModel, validator
2 |
3 |
4 | class FastAPIRouteModel(BaseModel):
5 | path_param: str
6 | query_param: int
7 | request_body: str
8 |
9 | @validator("path_param")
10 | def validate_path_param(cls, v):
11 | # validation logic
12 | return v
13 |
14 | @validator("query_param")
15 | def validate_query_param(cls, v):
16 | # validation logic
17 | return v
18 |
19 | @validator("request_body")
20 | def validate_request_body(cls, v):
21 | # validation logic
22 | return v
23 |
--------------------------------------------------------------------------------
/src/experiments/example/domain_exception/payment_declined_exception.py:
--------------------------------------------------------------------------------
1 | from rdddy.domain_exception import DomainException
2 |
3 |
4 | class PaymentDeclinedException(DomainException):
5 | """
6 | This class represents an exception that is thrown when a payment is declined in a reactive DDD system. It is responsible for handling errors related to payment processing and notifying the system of a declined payment. This class is necessary in a reactive DDD system because it allows for proper handling of payment failures and ensures that the system can react and respond accordingly.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/experiments/example/event/payment_processed.py:
--------------------------------------------------------------------------------
1 | from rdddy.event import Event
2 |
3 |
4 | class PaymentProcessed(Event):
5 | """
6 | The PaymentProcessed class represents a domain event that is triggered when a payment has been successfully processed. It contains information about the payment, such as the amount, date, and payment method used. This class is responsible for notifying other parts of the system about the successful payment, allowing them to react accordingly. It plays a crucial role in maintaining consistency and communication within the reactive DDD system.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/rdddy/signatures/risk_assessment.py:
--------------------------------------------------------------------------------
1 | from dspy import Signature
2 | from dspy.signatures.field import InputField, OutputField
3 |
4 |
5 | class RiskAssessment(Signature):
6 | """
7 | Assess the risk level of an investment portfolio based on market risks.
8 | """
9 |
10 | investment_portfolio = InputField(desc="The investment portfolio to be assessed.")
11 | market_risks = InputField(
12 | desc="The market risks to be considered in the assessment."
13 | )
14 |
15 | risk_level = OutputField(
16 | desc="The calculated risk level of the investment portfolio."
17 | )
18 |
--------------------------------------------------------------------------------
/src/rdddy/signatures/sales_prediction.py:
--------------------------------------------------------------------------------
1 | from dspy import Signature
2 | from dspy.signatures.field import InputField, OutputField
3 |
4 |
5 | class SalesPrediction(Signature):
6 | """
7 | Use historical sales data and current market trends to predict future sales.
8 | """
9 |
10 | historical_sales_data = InputField(desc="Data on past sales performance.")
11 | current_market_trends = InputField(desc="Information on current market trends.")
12 |
13 | future_sales_estimate = OutputField(
14 | desc="Estimated future sales based on historical data and current market trends."
15 | )
16 |
--------------------------------------------------------------------------------
/src/experiments/example/event/order_placed.py:
--------------------------------------------------------------------------------
1 | from rdddy.event import Event
2 |
3 |
4 | class OrderPlaced(Event):
5 | """
6 | This class represents a domain event that is triggered when a new order is placed in the system. It contains information about the order, such as the order ID, customer information, and items ordered. This event is used to notify other parts of the system that a new order has been placed and may trigger further actions or processes. It is an important part of the reactive DDD system as it allows for real-time updates and reactions to changes in the domain.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/experiments/example/abstract_view/customer_profile_view.py:
--------------------------------------------------------------------------------
1 | from rdddy.abstract_view import AbstractView
2 |
3 |
4 | class CustomerProfileView(AbstractView):
5 | """
6 | The CustomerProfileView class is responsible for displaying the customer's profile information to the user and allowing them to make changes to their profile. It receives input from the user and communicates with the application's domain layer to update the customer's profile. This class plays a crucial role in providing a user-friendly and responsive interface for managing customer profiles in a reactive ddd system.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/experiments/example/event/supplier_inventory_update.py:
--------------------------------------------------------------------------------
1 | from rdddy.event import Event
2 |
3 |
4 | class SupplierInventoryUpdate(Event):
5 | """
6 | This class represents an external event that is triggered when the inventory of a supplier needs to be updated in a reactive DDD system. It contains information about the supplier and the updated inventory, and is responsible for notifying the system to update its records accordingly. This class plays a crucial role in maintaining the consistency of data in the system and ensuring that all relevant entities are updated in a timely manner.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/frontend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "frontend",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "next": "14.1.0",
13 | "react": "^18",
14 | "react-dom": "^18",
15 | "react-speech-recognition": "^3.10.0"
16 | },
17 | "devDependencies": {
18 | "autoprefixer": "^10.0.1",
19 | "eslint": "^8",
20 | "eslint-config-next": "14.1.0",
21 | "postcss": "^8",
22 | "prettier": "^3.2.5",
23 | "tailwindcss": "^3.3.0"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/frontend/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/rdddy/signatures/inventory_optimization.py:
--------------------------------------------------------------------------------
1 | from dspy import Signature
2 | from dspy.signatures.field import InputField, OutputField
3 |
4 |
5 | class InventoryOptimization(Signature):
6 | """
7 | Optimize inventory levels based on current inventory levels and sales forecasts.
8 | """
9 |
10 | current_inventory_levels = InputField(
11 | desc="Current inventory levels for each product."
12 | )
13 | sales_forecasts = InputField(desc="Forecasted sales for each product.")
14 |
15 | reorder_recommendations = OutputField(
16 | desc="Recommended reorder quantities for each product."
17 | )
18 |
--------------------------------------------------------------------------------
/src/rdddy/signatures/market_segmentation.py:
--------------------------------------------------------------------------------
1 | from dspy import Signature
2 | from dspy.signatures.field import InputField, OutputField
3 |
4 |
5 | class MarketSegmentation(Signature):
6 | """
7 | Use customer demographics and purchase history to generate segment labels.
8 | """
9 |
10 | customer_demographics = InputField(
11 | desc="Information about the characteristics of customers."
12 | )
13 | purchase_history = InputField(desc="Records of past purchases made by customers.")
14 |
15 | segment_labels = OutputField(
16 | desc="Labels indicating which segment each customer belongs to."
17 | )
18 |
--------------------------------------------------------------------------------
/src/experiments/example/event/order_history_page_loaded.py:
--------------------------------------------------------------------------------
1 | from rdddy.event import Event
2 |
3 |
4 | class OrderHistoryPageLoaded(Event):
5 | """
6 | The OrderHistoryPageLoaded class is responsible for handling the UI event of the order history page being loaded in a reactive DDD system. It triggers the necessary actions in the system to retrieve and display the order history for the user. This class plays a crucial role in ensuring a smooth and efficient user experience by responding to user actions and updating the system accordingly. It is an essential component in the overall architecture of a reactive DDD system.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/typetemp/__init__.py:
--------------------------------------------------------------------------------
1 | import sys
2 |
3 | if sys.version_info[:2] >= (3, 8):
4 | # TODO: Import directly (no need for conditional) when `python_requires = >= 3.8`
5 | from importlib.metadata import PackageNotFoundError, version # pragma: no cover
6 | else:
7 | from importlib_metadata import PackageNotFoundError, version # pragma: no cover
8 |
9 | try:
10 | # Change here if project is renamed and does not equal the package name
11 | dist_name = __name__
12 | __version__ = version(dist_name)
13 | except PackageNotFoundError: # pragma: no cover
14 | __version__ = "unknown"
15 | finally:
16 | del version, PackageNotFoundError
17 |
--------------------------------------------------------------------------------
/src/experiments/example/event/inventory_updated.py:
--------------------------------------------------------------------------------
1 | from rdddy.event import Event
2 |
3 |
4 | class InventoryUpdated(Event):
5 | """
6 | The InventoryUpdated class is responsible for representing an event that indicates a change in the inventory of a product. It contains information such as the product ID, the quantity before and after the update, and the timestamp of the event. This class is used to notify other parts of the system about changes in the inventory, allowing them to react accordingly. It is an essential part of a reactive DDD system as it enables communication and synchronization between different components.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/rdddy/abstract_repository.py:
--------------------------------------------------------------------------------
1 | class AbstractRepository:
2 | """Provides a template for implementing repositories, which abstract the logic required to access domain
3 | aggregates from the underlying storage mechanism. It serves as a bridge between the domain model and data
4 | management layers, enabling the decoupling of domain logic from data persistence concerns. By creating subclasses
5 | of AbstractRepository, developers can ensure smooth interactions with the domain entities, offering a clean,
6 | cohesive API for querying and persisting domain objects, thereby supporting the principles of domain-driven
7 | design."""
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/experiments/example/command/process_payment.py:
--------------------------------------------------------------------------------
1 | from rdddy.command import Command
2 |
3 |
4 | class ProcessPayment(Command):
5 | """
6 | The ProcessPayment class is responsible for handling payment-related commands in a reactive DDD system. It receives commands from the user interface or other parts of the system and processes them to initiate a payment transaction. This class is an essential part of the system's command processing layer and plays a crucial role in maintaining the consistency of the system's state. It also interacts with other classes and components to complete the payment process and provide feedback to the user.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/experiments/example/query/get_order_details.py:
--------------------------------------------------------------------------------
1 | from rdddy.query import Query
2 |
3 |
4 | class GetOrderDetails(Query):
5 | """
6 | The GetOrderDetails class is responsible for retrieving and providing detailed information about an order in a reactive DDD system. It acts as a query handler, receiving requests for order details and returning the relevant data. This class plays a crucial role in the system, as it allows other components to access and use order information without directly interacting with the underlying data store. By encapsulating the logic for retrieving order details, this class promotes a more modular and maintainable architecture.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/experiments/example/abstract_policy/shipping_policy.py:
--------------------------------------------------------------------------------
1 | from rdddy.abstract_policy import AbstractPolicy
2 |
3 |
4 | class ShippingPolicy(AbstractPolicy):
5 | """
6 | The ShippingPolicy class is responsible for defining and enforcing the rules and guidelines for shipping orders in a reactive DDD system. It acts as a central hub for all shipping-related decisions and actions, ensuring that orders are shipped in a timely and efficient manner while also adhering to any business or regulatory requirements. This class is essential for maintaining consistency and reliability in the shipping process, and plays a crucial role in the overall success of the system.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/experiments/example/domain_exception/order_not_found_exception.py:
--------------------------------------------------------------------------------
1 | from rdddy.domain_exception import DomainException
2 |
3 |
4 | class OrderNotFoundException(DomainException):
5 | """
6 | The OrderNotFoundException class is used to represent an exception that occurs when an order cannot be found in the system. This class is typically used in a reactive ddd system to handle errors related to retrieving or processing orders. It contains information about the specific order that could not be found, such as its ID or other identifying details. This class is important for maintaining the integrity of the system and ensuring that errors are handled appropriately.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/rdddy/signatures/employee_performance_evaluation.py:
--------------------------------------------------------------------------------
1 | from dspy import Signature
2 | from dspy.signatures.field import InputField, OutputField
3 |
4 |
5 | class EmployeePerformanceEvaluation(Signature):
6 | """
7 | Generate a performance rating for an employee based on their activities and project outcomes.
8 | """
9 |
10 | employee_activities = InputField(
11 | desc="List of activities performed by the employee."
12 | )
13 | project_outcomes = InputField(
14 | desc="List of outcomes achieved by the employee's projects."
15 | )
16 |
17 | performance_rating = OutputField(
18 | desc="Numeric rating indicating the employee's performance."
19 | )
20 |
--------------------------------------------------------------------------------
/src/elixir/ping_pong/lib/ping_pong/ping_pong_elixir.ex:
--------------------------------------------------------------------------------
1 | defmodule PingPong.Elixir do
2 | use GenServer
3 |
4 | def start_link do
5 | GenServer.start_link(__MODULE__, [], name: :ping_pong)
6 | end
7 |
8 | def init([]) do
9 | port = Port.open({:spawn, 'python/python_side.py'}, [:binary])
10 | {:ok, port}
11 | end
12 |
13 | def handle_call(:ping, _from, port) do
14 | json_msg = Jason.encode!(%{action: "ping"})
15 | send(port, {self(), json_msg})
16 | {:noreply, port}
17 | end
18 |
19 | def handle_info({:pong, json_msg}, port) do
20 | data = Jason.decode!(json_msg)
21 | IO.puts("Elixir: Received pong - Data: #{inspect(data)}")
22 | {:noreply, port}
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/src/experiments/example/event/add_to_cart_button_click.py:
--------------------------------------------------------------------------------
1 | from rdddy.event import Event
2 |
3 |
4 | class AddToCartButtonClick(Event):
5 | """
6 | The AddToCartButtonClick class represents a user interface event that occurs when a user clicks on the "Add to Cart" button. This event is responsible for triggering the addition of an item to the shopping cart in a reactive DDD system. It contains information about the item being added and any other relevant data needed for the addition process. This class plays a crucial role in maintaining the consistency and reactivity of the system, ensuring that the shopping cart is updated in real-time as the user interacts with the interface.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/experiments/example/abstract_policy/refund_policy.py:
--------------------------------------------------------------------------------
1 | from rdddy.abstract_policy import AbstractPolicy
2 |
3 |
4 | class RefundPolicy(AbstractPolicy):
5 | """
6 | The RefundPolicy class is responsible for handling the refund process in a reactive DDD system. It contains the business logic and rules for determining when and how a refund should be issued. This class communicates with other classes and components in the system to gather necessary information and make decisions regarding refunds. It also ensures that all necessary steps are taken to properly process and record refunds. This class plays a crucial role in maintaining the integrity and accuracy of the system's refund process.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/experiments/example/abstract_task/send_order_confirmation_email.py:
--------------------------------------------------------------------------------
1 | from rdddy.abstract_task import AbstractTask
2 |
3 |
4 | class SendOrderConfirmationEmail(AbstractTask):
5 | """
6 | The SendOrderConfirmationEmail class is responsible for sending an email to the customer after an order has been successfully placed. It is a task class in a reactive DDD system, meaning it is triggered by an event and performs a specific action. This class handles the task of composing and sending an email with the necessary information, such as order details and delivery information, to the customer. It ensures that the customer receives a confirmation of their order in a timely and efficient manner.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/rdddy/abstract_policy.py:
--------------------------------------------------------------------------------
1 | from rdddy.abstract_actor import AbstractActor
2 |
3 |
4 | class AbstractPolicy(AbstractActor):
5 | """Outlines the framework for decision-making logic that governs the system's operations, translating business
6 | rules and conditions into actionable guidance. Policies play a crucial role in defining the behavior of the
7 | system under various circumstances, ensuring that operations adhere to the defined business logic and
8 | constraints. Through extending AbstractPolicy, developers can encapsulate and enforce the strategic and
9 | operational rules that drive the domain's functionality, ensuring consistency and alignment with business
10 | objectives."""
11 |
12 | pass
13 |
--------------------------------------------------------------------------------
/src/experiments/example/abstract_view/order_details_view.py:
--------------------------------------------------------------------------------
1 | from rdddy.abstract_view import AbstractView
2 |
3 |
4 | class OrderDetailsView(AbstractView):
5 | """
6 | The OrderDetailsView class is responsible for displaying the details of an order in a reactive ddd system. It receives data from the domain layer and presents it to the user in a user-friendly format. This class is an essential part of the user interface and is responsible for handling user interactions and updating the view accordingly. It also communicates with the application layer to trigger actions based on user input. The OrderDetailsView class plays a crucial role in providing a seamless and intuitive user experience in a reactive ddd system.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/experiments/example/abstract_task/validate_order.py:
--------------------------------------------------------------------------------
1 | from rdddy.abstract_task import AbstractTask
2 |
3 |
4 | class ValidateOrder(AbstractTask):
5 | """
6 | The ValidateOrder class is responsible for validating incoming orders in a reactive DDD system. It ensures that all necessary information is present and correct before the order is processed further. This class plays a crucial role in maintaining data integrity and preventing errors in the system. It also helps to streamline the order processing flow by identifying and handling any potential issues early on. By performing thorough validation, the ValidateOrder class helps to ensure a smooth and efficient order processing experience for both the system and its users.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/elixir/ping_pong/.gitignore:
--------------------------------------------------------------------------------
1 | # The directory Mix will write compiled artifacts to.
2 | /_build/
3 |
4 | # If you run "mix test --cover", coverage assets end up here.
5 | /cover/
6 |
7 | # The directory Mix downloads your dependencies sources to.
8 | /deps/
9 |
10 | # Where third-party dependencies like ExDoc output generated docs.
11 | /doc/
12 |
13 | # Ignore .fetch files in case you like to edit your project deps locally.
14 | /.fetch
15 |
16 | # If the VM crashes, it generates a dump, let's ignore it too.
17 | erl_crash.dump
18 |
19 | # Also ignore archive artifacts (built via "mix archive.build").
20 | *.ez
21 |
22 | # Ignore package tarball (built via "mix hex.build").
23 | ping_pong-*.tar
24 |
25 | # Temporary files, for example, from tests.
26 | /tmp/
27 |
--------------------------------------------------------------------------------
/src/rdddy/signatures/customer_feedback_analysis.py:
--------------------------------------------------------------------------------
1 | from dspy import Signature
2 | from dspy.signatures.field import InputField, OutputField
3 |
4 |
5 | class CustomerFeedbackAnalysis(Signature):
6 | """
7 | Perform sentiment analysis on customer comments.
8 | """
9 | customer_comments = InputField(desc="The comments provided by the customer.")
10 |
11 | sentiment_analysis = OutputField(desc="The sentiment analysis results for the customer comments.")
12 |
13 | class GenerateSearchQuery(dspy.Signature):
14 | """Write a simple search query that will help answer a complex question."""
15 |
16 | context = dspy.InputField(desc="may contain relevant facts")
17 | question = dspy.InputField()
18 | query = dspy.OutputField(dtype=dspy.SearchQuery)
--------------------------------------------------------------------------------
/src/experiments/example/abstract_saga/payment_processing_saga.py:
--------------------------------------------------------------------------------
1 | from rdddy.abstract_saga import AbstractSaga
2 |
3 |
4 | class PaymentProcessingSaga(AbstractSaga):
5 | """
6 | The PaymentProcessingSaga class is responsible for coordinating the payment process in a reactive DDD system. It manages the interactions between different services and entities involved in the payment process, ensuring data consistency and handling any potential errors or failures. This class implements the saga pattern, using a combination of transactions and compensating actions to maintain data integrity and handle complex business logic. It plays a crucial role in ensuring the reliability and consistency of the payment process in a reactive DDD system.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/experiments/example/domain_exception/book_out_of_stock_exception.py:
--------------------------------------------------------------------------------
1 | from rdddy.domain_exception import DomainException
2 |
3 |
4 | class BookOutOfStockException(DomainException):
5 | """
6 | This class represents an exception that is thrown when a book is out of stock in a reactive ddd system. It is used to handle situations where a user tries to purchase a book that is currently unavailable. This class is responsible for notifying the user and providing information on when the book will be back in stock. It also contains relevant information such as the book title and author to help the user make an informed decision. This class plays a crucial role in maintaining the integrity of the system and ensuring a smooth user experience.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/frontend/src/app/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | :root {
6 | --foreground-rgb: 0, 0, 0;
7 | --background-start-rgb: 214, 219, 220;
8 | --background-end-rgb: 255, 255, 255;
9 | }
10 |
11 | @media (prefers-color-scheme: dark) {
12 | :root {
13 | --foreground-rgb: 255, 255, 255;
14 | --background-start-rgb: 0, 0, 0;
15 | --background-end-rgb: 0, 0, 0;
16 | }
17 | }
18 |
19 | body {
20 | color: rgb(var(--foreground-rgb));
21 | background: linear-gradient(
22 | to bottom,
23 | transparent,
24 | rgb(var(--background-end-rgb))
25 | )
26 | rgb(var(--background-start-rgb));
27 | }
28 |
29 | @layer utilities {
30 | .text-balance {
31 | text-wrap: balance;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/experiments/example/abstract_view/book_list_view.py:
--------------------------------------------------------------------------------
1 | from rdddy.abstract_view import AbstractView
2 |
3 |
4 | class BookListView(AbstractView):
5 | """
6 | The BookListView class is responsible for displaying a list of books in the user interface. It receives data from the application layer and renders it in a user-friendly format for the user to interact with. This class is an essential part of the reactive ddd system as it allows users to view and select books, triggering events and actions in the system. It also handles user input and communicates with the application layer to update the state of the system. The BookListView class plays a crucial role in providing a seamless and intuitive user experience in the reactive ddd system.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/experiments/example/command/place_order.py:
--------------------------------------------------------------------------------
1 | from rdddy.command import Command
2 |
3 |
4 | class PlaceOrder(Command):
5 | """
6 | The PlaceOrder class is responsible for handling the command to place an order in a reactive DDD system. It receives input from the user or external system, validates the data, and then triggers the appropriate actions to fulfill the order. This class acts as a mediator between the user and the domain, ensuring that the order is processed correctly and in a timely manner. It also handles any errors or exceptions that may occur during the order placement process. The PlaceOrder class is an essential component of a reactive DDD system, as it enables the system to respond quickly and efficiently to user requests.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/experiments/example/event/external_payment_confirmation.py:
--------------------------------------------------------------------------------
1 | from rdddy.event import Event
2 |
3 |
4 | class ExternalPaymentConfirmation(Event):
5 | """
6 | The ExternalPaymentConfirmation class is responsible for handling payment confirmations from external sources in a reactive DDD system. It receives and processes external events related to payment confirmations, and triggers appropriate actions within the system. This class plays a crucial role in ensuring that the system remains reactive and responsive to external events, allowing for seamless integration with external payment systems. It also helps to maintain the integrity and consistency of the system by handling any errors or discrepancies in the payment confirmation process.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/experiments/example/abstract_value_object/price.py:
--------------------------------------------------------------------------------
1 | from rdddy.abstract_value_object import AbstractValueObject
2 |
3 |
4 | class Price(AbstractValueObject):
5 | """
6 | The Price class is a value object that represents the monetary value of a product or service in a reactive domain-driven design (DDD) system. It is used to encapsulate and manage the price data for various entities within the system, such as products, services, and orders. This class is immutable, meaning its value cannot be changed once it is created, ensuring consistency and preventing unintended modifications. It also contains methods for performing calculations and comparisons with other Price objects, making it a reliable and essential component in the reactive DDD system.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/experiments/example/query/check_order_status.py:
--------------------------------------------------------------------------------
1 | from rdddy.query import Query
2 |
3 |
4 | class CheckOrderStatus(Query):
5 | """
6 | The CheckOrderStatus class is responsible for querying the status of an order in the reactive DDD system. It acts as a mediator between the user interface and the domain layer, retrieving the current status of an order and providing it to the user. This class is essential for providing real-time updates on the status of orders, ensuring a smooth and efficient user experience. It also helps to maintain the integrity of the system by preventing conflicting updates from multiple users. Overall, the CheckOrderStatus class plays a crucial role in the reactive DDD system by providing timely and accurate information to users.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/experiments/example/event/checkout_form_submitted.py:
--------------------------------------------------------------------------------
1 | from rdddy.event import Event
2 |
3 |
4 | class CheckoutFormSubmitted(Event):
5 | """
6 | The CheckoutFormSubmitted class represents a user interface event that is triggered when a user submits a checkout form in a reactive DDD system. This event is responsible for updating the state of the system and triggering any necessary actions, such as processing the payment and updating the order status. It contains information about the submitted form, such as the user's input and selected items, and can be subscribed to by other classes to react to the event. This class plays a crucial role in the reactive DDD system, as it allows for seamless communication between the user interface and the backend logic.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/experiments/actor/assertion.log:
--------------------------------------------------------------------------------
1 | 2024-02-09 16:20:32,273 - dspy.primitives.assertions - ERROR - AssertionError: You need to create a kwargs dict for HygenTemplateSpecificationCommand
2 |
3 | Validation error:
4 | 1 validation error for HygenTemplateSpecificationCommand
5 | template_content
6 | String should have at least 200 characters [type=string_too_short, input_value='This is the template for...he dashboard generator.', input_type=str]
7 | For further information visit https://errors.pydantic.dev/2.5/v/string_too_short
8 | 2024-02-09 16:20:34,397 - dspy.primitives.assertions - ERROR - AssertionError: You need to create a kwargs dict for HygenTemplateSpecificationCommand
9 |
10 | Validation error:
11 | invalid syntax. Perhaps you forgot a comma? (, line 1)
12 |
--------------------------------------------------------------------------------
/src/experiments/leetcode/solution_model2.py:
--------------------------------------------------------------------------------
1 | from pydantic import BaseModel, Field
2 |
3 |
4 | class InterviewCodingChallengeModel(BaseModel):
5 | """A Pydantic model for interview coding challenge pseudocode, solution, and hints."""
6 |
7 | question: str = Field(
8 | default=...,
9 | description="The question in natural language for the coding challenge. No psuedo code!",
10 | min_length=50,
11 | )
12 | solution: str = Field(
13 | default=...,
14 | description="The solution to the coding challenge pseudocode.",
15 | min_length=50,
16 | )
17 | hints: list[str] = Field(
18 | default=...,
19 | title="",
20 | description="Hints for solving the coding challenge pseudocode.",
21 | min_length=3,
22 | )
23 |
--------------------------------------------------------------------------------
/src/experiments/example/abstract_value_object/quantity.py:
--------------------------------------------------------------------------------
1 | from rdddy.abstract_value_object import AbstractValueObject
2 |
3 |
4 | class Quantity(AbstractValueObject):
5 | """
6 | The Quantity class represents a value object in a reactive domain-driven design (DDD) system. It is responsible for encapsulating a specific quantity or amount, such as a number of items or a measurement. This class is immutable and is used to ensure that the quantity remains consistent throughout the system. It is used in conjunction with other classes to perform calculations and make decisions based on the quantity value. The Quantity class is an essential component in a reactive DDD system as it helps maintain data integrity and supports the reactive principles of event-driven and message-driven architectures.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/elixir/ping_pong/mix.exs:
--------------------------------------------------------------------------------
1 | defmodule PingPong.MixProject do
2 | use Mix.Project
3 |
4 | def project do
5 | [
6 | app: :ping_pong,
7 | version: "0.1.0",
8 | elixir: "~> 1.15",
9 | start_permanent: Mix.env() == :prod,
10 | deps: deps()
11 | ]
12 | end
13 |
14 | # Run "mix help compile.app" to learn about applications.
15 | def application do
16 | [
17 | extra_applications: [:logger]
18 | ]
19 | end
20 |
21 | # Run "mix help deps" to learn about dependencies.
22 | defp deps do
23 | [
24 | # {:dep_from_hexpm, "~> 0.3.0"},
25 | # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
26 | ]
27 | end
28 | end
29 |
30 | # ... Existing content in mix.exs ..
31 |
32 | defp deps do
33 | [ {:jason, "~> 1.2"} ]
34 | end
35 |
--------------------------------------------------------------------------------
/src/experiments/example/abstract_aggregate/customer_aggregate.py:
--------------------------------------------------------------------------------
1 | from rdddy.abstract_aggregate import AbstractAggregate
2 |
3 |
4 | class CustomerAggregate(AbstractAggregate):
5 | """
6 | The CustomerAggregate class is responsible for managing the state and behavior of a customer entity in the reactive DDD system. It acts as a container for all related domain objects and business logic, ensuring consistency and integrity of the customer data. This class also serves as the entry point for all external requests and events related to the customer entity, and coordinates the communication between different domain objects within the aggregate. It plays a crucial role in maintaining the reactive nature of the system by reacting to changes in the customer state and triggering appropriate actions.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/experiments/example/event/inventory_updated_integration_event.py:
--------------------------------------------------------------------------------
1 | from rdddy.event import Event
2 |
3 |
4 | class InventoryUpdatedIntegrationEvent(Event):
5 | """
6 | This class represents an integration event that is used to notify other services or components in the reactive DDD system about updates to the inventory. It is responsible for carrying the necessary information about the updated inventory, such as the product ID, quantity, and any other relevant data. This class plays a crucial role in maintaining consistency and ensuring that all services have the most up-to-date information about the inventory. It is an essential component in the reactive DDD system as it enables communication and coordination between different services and helps to maintain a reactive and event-driven architecture.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/experiments/example/event/supplier_inventory_confirmation.py:
--------------------------------------------------------------------------------
1 | from rdddy.event import Event
2 |
3 |
4 | class SupplierInventoryConfirmation(Event):
5 | """
6 | The SupplierInventoryConfirmation class is responsible for handling external events related to supplier inventory confirmation in a reactive DDD system. It receives and processes supplier inventory confirmation events, updating the system's inventory accordingly. This class acts as a bridge between the external event and the system, ensuring that the system's inventory is always up-to-date and accurate. It also communicates with other classes and components in the system to trigger any necessary actions based on the received event. This class plays a crucial role in maintaining the consistency and reliability of the system's inventory data.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Coverage.py
2 | htmlcov/
3 | reports/
4 |
5 | # cruft
6 | *.rej
7 |
8 | # Data
9 | *.csv*
10 | *.dat*
11 | *.pickle*
12 | *.xls*
13 | *.zip*
14 | data/
15 |
16 | # direnv
17 | .envrc
18 |
19 | # dotenv
20 | .env
21 |
22 | # Hypothesis
23 | .hypothesis/
24 |
25 | # Jupyter
26 | *.ipynb
27 | .ipynb_checkpoints/
28 | notebooks/
29 |
30 | # macOS
31 | .DS_Store
32 |
33 | # mypy
34 | .dmypy.json
35 | .mypy_cache/
36 |
37 | # Node.js
38 | node_modules/
39 |
40 | # Poetry
41 | .venv/
42 | dist/
43 |
44 | # PyCharm
45 | .idea/
46 |
47 | # pyenv
48 | .python-version
49 |
50 | # pytest
51 | .pytest_cache/
52 |
53 | # Python
54 | __pycache__/
55 | *.py[cdo]
56 |
57 | # Ruff
58 | .ruff_cache/
59 |
60 | # Terraform
61 | .terraform/
62 |
63 | # VS Code
64 | .vscode/
65 |
66 | .choma/
67 |
68 | frontend/node_modules
69 | frontend/.next
70 |
--------------------------------------------------------------------------------
/src/experiments/example/abstract_task/calculate_shipping_costs.py:
--------------------------------------------------------------------------------
1 | from rdddy.abstract_task import AbstractTask
2 |
3 |
4 | class CalculateShippingCosts(AbstractTask):
5 | """
6 | The CalculateShippingCosts class is a crucial component of a reactive DDD system that handles the calculation of shipping costs. It takes in relevant information such as weight, distance, and shipping method and uses this data to determine the appropriate shipping costs for a given order. This class utilizes reactive principles to ensure that any changes to the order or shipping information are immediately reflected in the calculated shipping costs. It also follows domain-driven design principles to ensure that the logic for calculating shipping costs is encapsulated within this class, making it easy to maintain and modify in the future.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/rdddy/api.py:
--------------------------------------------------------------------------------
1 | """rdddy REST API."""
2 | import logging
3 | import coloredlogs
4 |
5 | import dspy
6 | from pydantic import BaseModel
7 |
8 | from rdddy.signatures.code_interview_solver import CodeInterviewSolver
9 |
10 | from fastapi import FastAPI
11 |
12 | app = FastAPI()
13 |
14 | lm = dspy.OpenAI(max_tokens=1000)
15 | dspy.settings.configure(lm=lm)
16 |
17 |
18 | class TranscriptData(BaseModel):
19 | transcript: str
20 |
21 |
22 | @app.post("/receive_transcript")
23 | async def process_transcript(data: TranscriptData):
24 | transcript = data.transcript
25 | # Process your transcript here
26 | cot = (
27 | dspy.ChainOfThought(CodeInterviewSolver)
28 | .forward(problem_statement=transcript)
29 | .detailed_code_solution
30 | )
31 | print(cot)
32 | return {"message": f"Transcript received: {cot}"}
33 |
--------------------------------------------------------------------------------
/src/experiments/example/abstract_read_model/book_catalog_read_model.py:
--------------------------------------------------------------------------------
1 | from rdddy.abstract_read_model import AbstractReadModel
2 |
3 |
4 | class BookCatalogReadModel(AbstractReadModel):
5 | """
6 | The BookCatalogReadModel class is responsible for managing the read model in a reactive ddd system. It receives events from the domain and updates the read model accordingly. This class acts as a bridge between the domain and the read model, ensuring that the read model is always up-to-date with the latest changes in the domain. It also provides methods for querying the read model, allowing other components to retrieve data from the read model without directly accessing the domain. This class plays a crucial role in maintaining the consistency and integrity of the read model, which is essential for the overall functionality of the system.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/rdddy/async_typer.py:
--------------------------------------------------------------------------------
1 | import inspect
2 | from functools import partial, wraps
3 |
4 | import asyncer
5 | from typer import Typer
6 |
7 |
8 | class AsyncTyper(Typer):
9 | @staticmethod
10 | def maybe_run_async(decorator, f):
11 | if inspect.iscoroutinefunction(f):
12 |
13 | @wraps(f)
14 | def runner(*args, **kwargs):
15 | return asyncer.runnify(f)(*args, **kwargs)
16 |
17 | decorator(runner)
18 | else:
19 | decorator(f)
20 | return f
21 |
22 | def callback(self, *args, **kwargs):
23 | decorator = super().callback(*args, **kwargs)
24 | return partial(self.maybe_run_async, decorator)
25 |
26 | def command(self, *args, **kwargs):
27 | decorator = super().command(*args, **kwargs)
28 | return partial(self.maybe_run_async, decorator)
29 |
--------------------------------------------------------------------------------
/src/experiments/example/abstract_aggregate/book_aggregate.py:
--------------------------------------------------------------------------------
1 | from rdddy.abstract_aggregate import AbstractAggregate
2 |
3 |
4 | class BookAggregate(AbstractAggregate):
5 | """
6 | The BookAggregate class is responsible for managing the state and behavior of a book entity in a reactive DDD system. It acts as a container for all related domain objects and handles all business logic related to the book entity. This class is responsible for maintaining data consistency and ensuring that all changes to the book entity are made through its methods. It also acts as a communication hub between the domain layer and the infrastructure layer, allowing for seamless integration with external systems. Overall, the BookAggregate class plays a crucial role in maintaining the integrity and consistency of the book entity within the reactive DDD system.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/experiments/example/abstract_saga/order_fulfillment_saga.py:
--------------------------------------------------------------------------------
1 | from rdddy.abstract_saga import AbstractSaga
2 |
3 |
4 | class OrderFulfillmentSaga(AbstractSaga):
5 | """
6 | The OrderFulfillmentSaga class is responsible for managing the fulfillment process of an order in a reactive DDD system. It acts as a coordinator between different services and aggregates, ensuring that the order is processed correctly and in a timely manner. This class is responsible for handling any failures or exceptions that may occur during the fulfillment process, and it is designed to be resilient and reactive to changes in the system. It also maintains the state of the order and updates it as the fulfillment process progresses. Overall, the OrderFulfillmentSaga class plays a crucial role in ensuring that orders are fulfilled successfully in a reactive DDD system.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/experiments/example/event/order_placed_integration_event.py:
--------------------------------------------------------------------------------
1 | from rdddy.event import Event
2 |
3 |
4 | class OrderPlacedIntegrationEvent(Event):
5 | """
6 | The OrderPlacedIntegrationEvent class is responsible for representing an event that is triggered when a new order is placed in the system. This class serves as a bridge between the reactive DDD system and external systems, allowing for seamless communication and integration. It contains all the necessary information about the order, such as customer details, order items, and payment information. This class plays a crucial role in maintaining consistency and ensuring that all systems are updated with the latest order information. It also serves as a trigger for other processes and actions within the reactive DDD system, allowing for a reactive and event-driven approach to handling orders.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/rdddy/generators/gen_state.py:
--------------------------------------------------------------------------------
1 | from pydantic import BaseModel, Field
2 |
3 | import dspy
4 | from rdddy.generators.gen_pydantic_instance import GenPydanticInstance
5 |
6 |
7 | class State(BaseModel):
8 | name: str = Field(..., description="The name of the state")
9 | abbreviation: str = Field(
10 | ..., description="The two-letter postal abbreviation for the state"
11 | )
12 | capital: str = Field(..., description="The capital city of the state")
13 |
14 |
15 | class USA(BaseModel):
16 | states: list[State]
17 |
18 |
19 | def main():
20 | lm = dspy.OpenAI(max_tokens=3000)
21 | dspy.settings.configure(lm=lm)
22 |
23 | model_module = GenPydanticInstance(root_model=USA, child_models=[State])
24 | model_inst = model_module(prompt="All of the states")
25 | print(model_inst)
26 |
27 |
28 | if __name__ == "__main__":
29 | main()
30 |
--------------------------------------------------------------------------------
/src/rdddy/generators/templates/module_template.j2:
--------------------------------------------------------------------------------
1 | {# gen_module.j2: Template for generating DSPy Module classes #}
2 | import ast
3 | from dspy import Module, OpenAI, settings, ChainOfThought, Assert
4 |
5 | class Gen{{ name | camelize }}(Module):
6 | def __init__(self, lm=None):
7 | if lm is None:
8 | turbo = OpenAI(max_tokens=500)
9 | settings.configure(lm=turbo)
10 |
11 | super().__init__()
12 |
13 | # Define specific attributes and methods for {{ name | camelize }}
14 | # ...
15 |
16 | def forward(self, *args, **kwargs):
17 | # Implementation of the forward method for {{ name | camelize }}
18 | # ...
19 |
20 | # Add any additional methods or helper functions specific to Gen{{ name | camelize }}
21 | # ...
22 |
23 | # Optionally, include other definitions or utility functions if necessary
24 | # ...
25 |
--------------------------------------------------------------------------------
/src/experiments/example/abstract_saga/book_restock_saga.py:
--------------------------------------------------------------------------------
1 | from rdddy.abstract_saga import AbstractSaga
2 |
3 |
4 | class BookRestockSaga(AbstractSaga):
5 | """
6 | The BookRestockSaga class is responsible for managing the process of restocking books in a reactive DDD system. It coordinates the actions of multiple entities and services in order to ensure that books are restocked in a timely and efficient manner. This class is crucial in a reactive DDD system as it helps to maintain consistency and handle complex business logic related to book restocking. It acts as a mediator between different components of the system and ensures that the restocking process is completed successfully. The BookRestockSaga class is an integral part of the overall architecture of a reactive DDD system and plays a key role in maintaining the system's reactivity and responsiveness.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/experiments/example/abstract_policy/order_cancellation_policy.py:
--------------------------------------------------------------------------------
1 | from rdddy.abstract_policy import AbstractPolicy
2 |
3 |
4 | class OrderCancellationPolicy(AbstractPolicy):
5 | """
6 | The OrderCancellationPolicy class is responsible for handling the cancellation of orders in a reactive DDD system. It is a part of the policy layer, which is responsible for enforcing business rules and constraints. This class is specifically designed to handle the cancellation of orders, ensuring that all necessary steps are taken and all relevant entities are updated accordingly. It communicates with other classes and components in the system to ensure that the cancellation process is executed correctly and in a reactive manner. This class plays a crucial role in maintaining the consistency and integrity of the system, as well as ensuring that all business rules are followed.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/experiments/example/command/update_inventory.py:
--------------------------------------------------------------------------------
1 | from rdddy.command import Command
2 |
3 |
4 | class UpdateInventory(Command):
5 | """
6 | The UpdateInventory class is responsible for handling commands related to updating the inventory in a reactive DDD system. It receives commands from the application layer and coordinates with the domain layer to make the necessary changes to the inventory. This class is an essential part of the system as it ensures that the inventory is always up-to-date and reflects the latest changes made by the users. It also plays a crucial role in maintaining data consistency and ensuring that all business rules related to inventory management are enforced. The UpdateInventory class is designed to be reactive, meaning it can handle a high volume of commands and process them in a timely manner, ensuring a smooth and efficient user experience.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/experiments/example/abstract_read_model/customer_order_history_read_model.py:
--------------------------------------------------------------------------------
1 | from rdddy.abstract_read_model import AbstractReadModel
2 |
3 |
4 | class CustomerOrderHistoryReadModel(AbstractReadModel):
5 | """
6 | The CustomerOrderHistoryReadModel class is responsible for storing and retrieving data related to customer order history in a reactive DDD system. It serves as a read-only representation of the customer order history, providing a way for other components to access and query this data. This class is an essential part of the reactive DDD system, as it allows for efficient and consistent access to customer order history data, enabling other components to make informed decisions and take appropriate actions. It also helps to maintain the separation of concerns between the read and write sides of the system, ensuring that the read side remains scalable and responsive.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/experiments/pyproject_tools.py:
--------------------------------------------------------------------------------
1 | from pathlib import Path
2 |
3 | import toml
4 |
5 |
6 | def load_pyproject():
7 | with open(f"{project_root()}/pyproject.toml") as pyproject_file:
8 | pyproject_data = toml.load(pyproject_file)
9 |
10 | return pyproject_data
11 |
12 |
13 | def get_package_name():
14 | pyproject_data = load_pyproject()
15 |
16 | package_name = pyproject_data["tool"]["poetry"]["name"]
17 | return package_name
18 |
19 |
20 | def project_root() -> str:
21 | return str(Path(__file__).parent.parent.parent)
22 |
23 |
24 | def source_root() -> str:
25 | return str(Path(__file__).parent.parent)
26 |
27 |
28 | def actors_folder() -> str:
29 | return str(Path(__file__).parent.parent / "actors")
30 |
31 |
32 | def messages_folder() -> str:
33 | return str(Path(__file__).parent.parent / "messages")
34 |
35 |
36 | if __name__ == "__main__":
37 | print(actors_folder())
38 |
--------------------------------------------------------------------------------
/summarize_text_module.py:
--------------------------------------------------------------------------------
1 | import dspy
2 | from typer import Typer
3 |
4 | app = Typer()
5 |
6 |
7 | lm = dspy.OpenAI(max_tokens=500)
8 | dspy.settings.configure(lm=lm)
9 |
10 |
11 | class SummarizeText(dspy.Module):
12 | """This module summarizes text using a pre-trained model."""
13 |
14 | def forward(self, text):
15 | pred = dspy.Predict("text -> summary")
16 |
17 | result = pred(text=text).summary
18 | return result
19 |
20 | def main():
21 |
22 | text = "" # Initialize your inputs here. Adjust as necessary.
23 |
24 | summarize_text = SummarizeText()
25 | print(summarize_text.forward(text=text))
26 |
27 |
28 | @app.command()
29 | def module_test(text):
30 | """This module summarizes text using a pre-trained model."""
31 | summarize_text = SummarizeText()
32 |
33 | print(summarize_text.forward(text=text))
34 |
35 |
36 | if __name__ == "__main__":
37 | app()
38 |
--------------------------------------------------------------------------------
/src/experiments/example/abstract_aggregate/order_aggregate.py:
--------------------------------------------------------------------------------
1 | from rdddy.abstract_aggregate import AbstractAggregate
2 |
3 |
4 | class OrderAggregate(AbstractAggregate):
5 | """
6 | The OrderAggregate class is responsible for managing the state and behavior of an order within the reactive DDD system. It acts as a container for all the entities and value objects related to an order, and coordinates their interactions to ensure consistency and integrity of the order. This class is responsible for handling all business logic related to orders, such as creating, updating, and canceling orders, as well as handling any events or commands related to orders. It also serves as the entry point for external systems to interact with orders in the reactive DDD system. Overall, the OrderAggregate class plays a crucial role in maintaining the overall consistency and integrity of orders within the reactive DDD system.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/experiments/example/event/payment_processed_integration_event.py:
--------------------------------------------------------------------------------
1 | from rdddy.event import Event
2 |
3 |
4 | class PaymentProcessedIntegrationEvent(Event):
5 | """
6 | This class represents an integration event that is triggered when a payment is processed in the reactive DDD system. It serves as a means of communication between different components of the system, allowing them to react to the payment being processed. This class contains information about the payment, such as the amount, date, and payment method used. It also includes metadata such as the source of the payment and any relevant identifiers. This class plays a crucial role in maintaining consistency and ensuring that all components of the system are updated with the latest payment information. It is an essential part of the reactive DDD system's architecture, facilitating communication and coordination between different parts of the system.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/experiments/create_yaml.py:
--------------------------------------------------------------------------------
1 | from typetemp.template.smart_template import SmartTemplate
2 | from utils.complete import LLMConfig
3 |
4 |
5 | class Template(SmartTemplate):
6 | source = """
7 | You are a yaml assistant. A hyperdetailed assistant prompt is a tool that helps users generate highly detailed content. This prompt is designed to assist users in converting their content into YAML format. YAML, or ".
8 |
9 | ```prompt
10 | {{ prompt }}
11 | ```
12 |
13 | """
14 |
15 |
16 | async def create_yaml(prompt: str, max_tokens=2000):
17 | """Generate a yaml based on a prompt."""
18 | return await Template(
19 | prompt=prompt, config=LLMConfig(max_tokens=max_tokens)
20 | ).render()
21 |
22 |
23 | async def main():
24 | prompt = input("Enter your prompt: ")
25 | content = await create_yaml(prompt)
26 | print(content)
27 |
28 |
29 | if __name__ == "__main__":
30 | import anyio
31 |
32 | anyio.run(main)
33 |
--------------------------------------------------------------------------------
/src/experiments/create_pydantic.py:
--------------------------------------------------------------------------------
1 | import pyperclip
2 |
3 | from typetemp.template.smart_template import SmartTemplate
4 | from utils.complete import LLMConfig
5 | from utils.file_tools import write
6 |
7 |
8 | class Template(SmartTemplate):
9 | source = """
10 | You are a pydantic assistant. You convert plaintext into pydantic models
11 | ```plaintext
12 | {{ prompt }}
13 | ```
14 |
15 | ```python
16 | """
17 |
18 |
19 | async def render(prompt: str, max_tokens=2000):
20 | """Generate a pydantic based on a prompt."""
21 | return await Template(
22 | prompt=prompt, config=LLMConfig(max_tokens=max_tokens, stop=["```"])
23 | ).render()
24 |
25 |
26 | async def main():
27 | content = await render(pyperclip.paste())
28 | print(content)
29 | filename = await write(content, extension="py")
30 | print(f"Wrote {filename}")
31 |
32 |
33 | if __name__ == "__main__":
34 | import anyio
35 |
36 | anyio.run(main)
37 |
--------------------------------------------------------------------------------
/src/rdddy/assertion.log:
--------------------------------------------------------------------------------
1 | 2024-01-31 16:06:29,589 - dspy.primitives.assertions - ERROR - AssertionError: You need to create a kwargs dict for SignatureModel
2 | 2024-01-31 16:06:30,434 - dspy.primitives.assertions - ERROR - AssertionError: You need to create a kwargs dict for SignatureModel
3 | 2024-01-31 16:08:39,507 - dspy.primitives.assertions - ERROR - AssertionError: You need to create a kwargs dict for SignatureModel
4 | 2024-01-31 16:08:43,071 - dspy.primitives.assertions - ERROR - AssertionError: You need to create a kwargs dict for SignatureModel
5 | 2024-02-09 13:48:26,296 - dspy.primitives.assertions - ERROR - AssertionError: You need to create a kwargs dict for HygenTemplateModel
6 |
7 | Validation error:
8 | 1 validation error for HygenTemplateModel
9 | generator
10 | Field required [type=missing, input_value={'name': 'about', 'action': 'create'}, input_type=dict]
11 | For further information visit https://errors.pydantic.dev/2.5/v/missing
12 |
--------------------------------------------------------------------------------
/src/experiments/actor/messages.py:
--------------------------------------------------------------------------------
1 | from rdddy.messages import *
2 |
3 |
4 | class StartPhaseCommand(AbstractCommand):
5 | phase_name: str
6 |
7 |
8 | class PhaseStartedEvent(AbstractEvent):
9 | phase_name: str
10 |
11 |
12 | class EvaluatePreconditionQuery(AbstractQuery):
13 | phase_name: str
14 |
15 |
16 | class PreconditionEvaluatedEvent(AbstractEvent):
17 | phase_name: str
18 | result: bool
19 |
20 |
21 | class ProcessPhaseCommand(AbstractCommand):
22 | phase_name: str
23 |
24 |
25 | class PhaseProcessedEvent(AbstractEvent):
26 | phase_name: str
27 |
28 |
29 | class EvaluatePostconditionQuery(AbstractQuery):
30 | phase_name: str
31 |
32 |
33 | class PostconditionEvaluatedEvent(AbstractEvent):
34 | phase_name: str
35 | result: bool
36 |
37 |
38 | class PhaseCompletedEvent(AbstractEvent):
39 | phase_name: str
40 |
41 |
42 | class PhaseErrorEvent(AbstractEvent):
43 | phase_name: str
44 | error_message: str
45 |
--------------------------------------------------------------------------------
/src/experiments/example/abstract_read_model/order_summary_read_model.py:
--------------------------------------------------------------------------------
1 | from rdddy.abstract_read_model import AbstractReadModel
2 |
3 |
4 | class OrderSummaryReadModel(AbstractReadModel):
5 | """
6 | The OrderSummaryReadModel class is responsible for retrieving and storing data from the OrderSummary aggregate in a reactive ddd system. It acts as a read-only representation of the OrderSummary aggregate, providing a simplified view of the data for querying and reporting purposes. This class is an essential component of the system, as it allows for efficient and optimized data retrieval without impacting the performance of the write model. It also ensures consistency and accuracy of data by subscribing to events from the write model and updating its data accordingly. Overall, the OrderSummaryReadModel class plays a crucial role in providing a reactive and responsive user experience by efficiently managing and presenting data from the OrderSummary aggregate.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/src/experiments/example/abstract_value_object/address.py:
--------------------------------------------------------------------------------
1 | from rdddy.abstract_value_object import AbstractValueObject
2 |
3 |
4 | class Address(AbstractValueObject):
5 | """
6 | The Address class is a value object that represents a physical address in a reactive DDD system. It is responsible for encapsulating the data related to an address, such as street name, city, state, and zip code. This class is immutable, meaning its values cannot be changed once it is created. It is used to ensure that the system maintains consistency and accuracy when dealing with addresses. The Address class also plays a crucial role in domain logic, as it is often used as a parameter in methods and functions to perform operations related to addresses. Additionally, it is used for validation purposes, ensuring that only valid addresses are accepted by the system. Overall, the Address class is an essential component of a reactive DDD system, providing a reliable and standardized way to handle address data.
7 | """
8 |
9 | pass
10 |
--------------------------------------------------------------------------------
/new_module_5206162896.py:
--------------------------------------------------------------------------------
1 | import dspy
2 | from typer import Typer
3 |
4 | app = Typer()
5 |
6 |
7 | lm = dspy.OpenAI(max_tokens=500)
8 | dspy.settings.configure(lm=lm)
9 |
10 |
11 | class SubjectToBlog(dspy.Module):
12 | """This module takes in a subject and outputs a blog post."""
13 |
14 | def forward(self, subject):
15 | pred = dspy.Predict("subject -> blog_post")
16 |
17 | result = pred(subject=subject).blog_post
18 | return result
19 |
20 | def main():
21 |
22 | subject = "Summer fun" # Initialize your inputs here. Adjust as necessary.
23 |
24 | ds_py_module_template = SubjectToBlog()
25 | print(ds_py_module_template.forward(subject=subject))
26 |
27 |
28 | @app.command()
29 | def module_test(subject):
30 | """This module takes in a subject and outputs a blog post."""
31 | ds_py_module_template = SubjectToBlog()
32 |
33 | print(ds_py_module_template.forward(subject=subject))
34 |
35 |
36 | if __name__ == "__main__":
37 | # app()
38 | main()
39 |
--------------------------------------------------------------------------------
/src/experiments/synth_results.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import pandas as pd
3 |
4 | # Define the number of synthetic samples
5 | num_samples = 100
6 |
7 | # Generate synthetic customer IDs
8 | customer_ids = np.arange(1, num_samples + 1)
9 |
10 | # Generate baseline satisfaction scores (before new design)
11 | baseline_scores = np.random.randint(
12 | 1, 6, num_samples
13 | ) # Assuming a 5-point satisfaction scale
14 |
15 | # Generate post-design satisfaction scores (after new design)
16 | post_design_scores = np.random.randint(
17 | 3, 6, num_samples
18 | ) # Higher scores after the design change
19 |
20 | # Create a DataFrame to store the synthetic results
21 | synthetic_results = pd.DataFrame(
22 | {
23 | "Customer ID": customer_ids,
24 | "Baseline Satisfaction Score": baseline_scores,
25 | "Post-Design Satisfaction Score": post_design_scores,
26 | }
27 | )
28 |
29 | # Save the synthetic results to a CSV file
30 | synthetic_results.to_csv("synthetic_experiment_results.csv", index=False)
31 |
--------------------------------------------------------------------------------
/src/experiments/generated_classes.py:
--------------------------------------------------------------------------------
1 | from rdddy.messages import *
2 |
3 |
4 | class CreateNewRoute(AbstractEvent):
5 | """Event triggered by CreateNewRoute."""
6 |
7 |
8 | class InjectHandler(AbstractEvent):
9 | """Event triggered by InjectHandler."""
10 |
11 |
12 | class ExecuteHealthCheck(AbstractEvent):
13 | """Event triggered by ExecuteHealthCheck."""
14 |
15 |
16 | class ExecuteShazamOperation(AbstractEvent):
17 | """Event triggered by ExecuteShazamOperation."""
18 |
19 |
20 | class ExecuteHygenRouteNew(AbstractCommand):
21 | """Command to execute ExecuteHygenRouteNew."""
22 |
23 |
24 | class LoadModules(AbstractCommand):
25 | """Command to execute LoadModules."""
26 |
27 |
28 | class ConstructRoutes(AbstractCommand):
29 | """Command to execute ConstructRoutes."""
30 |
31 |
32 | class RetrieveHealthStatus(AbstractQuery):
33 | """Query to retrieve RetrieveHealthStatus."""
34 |
35 |
36 | class RetrieveShazamOperation(AbstractQuery):
37 | """Query to retrieve RetrieveShazamOperation."""
38 |
--------------------------------------------------------------------------------
/src/typetemp/environment/typed_native_environment.py:
--------------------------------------------------------------------------------
1 | from jinja2 import FileSystemLoader
2 | from jinja2.nativetypes import NativeEnvironment
3 |
4 | from typetemp.extension.faker_extension import FakerExtension
5 | from typetemp.extension.inflection_extension import InflectionExtension
6 |
7 |
8 | class TypedNativeEnvironment(NativeEnvironment):
9 | def __init__(self, **kwargs):
10 | super(TypedNativeEnvironment, self).__init__(**kwargs)
11 |
12 | self.add_extension(FakerExtension)
13 | self.add_extension(InflectionExtension)
14 | self.add_extension("jinja2_time.TimeExtension")
15 | self.add_extension("jinja2.ext.i18n")
16 | self.add_extension("jinja2.ext.debug")
17 | self.add_extension("jinja2.ext.do")
18 | self.add_extension("jinja2.ext.loopcontrols")
19 |
20 |
21 | file_loader = FileSystemLoader("./templates")
22 |
23 | native_environment = TypedNativeEnvironment(loader=file_loader)
24 |
25 | async_native_environment = TypedNativeEnvironment(enable_async=True, loader=file_loader)
26 |
--------------------------------------------------------------------------------
/tests/actor/test_actor.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 |
3 | import pytest
4 |
5 | from rdddy.abstract_actor import *
6 | from rdddy.actor_system import ActorSystem
7 | from rdddy.messages import *
8 |
9 |
10 | @pytest.fixture()
11 | def actor_system(event_loop):
12 | # Provide the event loop to the actor system
13 | return ActorSystem(event_loop)
14 |
15 |
16 | @pytest.mark.asyncio()
17 | async def test_handler(actor_system):
18 | class DummyActor(AbstractActor):
19 | def __init__(self, actor_system, actor_id=None):
20 | super().__init__(actor_system, actor_id)
21 | self.processed_query = None
22 |
23 | async def handle_query(self, query: AbstractQuery):
24 | self.processed_query = query
25 |
26 | actor = await actor_system.actor_of(DummyActor)
27 |
28 | query = AbstractQuery(actor_id=actor.actor_id, content="Query1")
29 |
30 | await asyncio.sleep(0)
31 |
32 | await actor_system.publish(query)
33 |
34 | await asyncio.sleep(0)
35 |
36 | assert actor.processed_query.actor_id == actor.actor_id
37 |
--------------------------------------------------------------------------------
/src/typetemp/extension/inflection_extension.py:
--------------------------------------------------------------------------------
1 | import inflection
2 | from jinja2.ext import Extension
3 |
4 |
5 | class InflectionExtension(Extension):
6 | def __init__(self, environment):
7 | super(InflectionExtension, self).__init__(environment)
8 |
9 | environment.filters["camelize"] = inflection.camelize
10 | environment.filters["dasherize"] = inflection.dasherize
11 | environment.filters["humanize"] = inflection.humanize
12 | environment.filters["ordinal"] = inflection.ordinal
13 | environment.filters["ordinalize"] = inflection.ordinalize
14 | environment.filters["parameterize"] = inflection.parameterize
15 | environment.filters["pluralize"] = inflection.pluralize
16 | environment.filters["singularize"] = inflection.singularize
17 | environment.filters["tableize"] = inflection.tableize
18 | environment.filters["titleize"] = inflection.titleize
19 | environment.filters["transliterate"] = inflection.transliterate
20 | environment.filters["underscore"] = inflection.underscore
21 |
--------------------------------------------------------------------------------
/src/rdddy/signatures/code_interview_solver.py:
--------------------------------------------------------------------------------
1 | from dspy import Signature
2 | from dspy.signatures.field import InputField, OutputField
3 |
4 |
5 | class CodeInterviewSolver(Signature):
6 | """
7 | This signature should first interpret the problem statement to identify key challenges and requirements.
8 | Each line of the code solution must be accompanied by comments that explain the purpose and logic of that line,
9 | ensuring that the thought process behind the solution is clear and educational. The aim is to not only solve
10 | the interview problem but also to provide a learning experience by demystifying complex solution steps and
11 | fostering a deeper understanding of algorithmic thinking and coding practices. Python PEP8 compliant.
12 | In the style of Luciano Ramahlo author of Fluent Python.
13 | """
14 |
15 | problem_statement = InputField(desc="The problem statement to be solved")
16 |
17 | detailed_code_solution = OutputField(
18 | desc="The detailed code solution with comments explaining each line of code. In the style of Luciano Ramahlo author of Fluent Python."
19 | )
20 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Test
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | - master
8 | pull_request:
9 |
10 | jobs:
11 | test:
12 | runs-on: ubuntu-latest
13 |
14 | strategy:
15 | fail-fast: false
16 | matrix:
17 | python-version: ["3.10"]
18 |
19 | name: Python ${{ matrix.python-version }}
20 |
21 | steps:
22 | - name: Checkout
23 | uses: actions/checkout@v4
24 |
25 | - name: Set up Node.js
26 | uses: actions/setup-node@v4
27 | with:
28 | node-version: 21
29 |
30 | - name: Install @devcontainers/cli
31 | run: npm install --location=global @devcontainers/cli@0.55.0
32 |
33 | - name: Start Dev Container
34 | run: |
35 | git config --global init.defaultBranch main
36 | PYTHON_VERSION=${{ matrix.python-version }} devcontainer up --workspace-folder .
37 |
38 | - name: Test package
39 | run: devcontainer exec --workspace-folder . poe test
40 |
41 | - name: Upload coverage
42 | uses: codecov/codecov-action@v3
43 | with:
44 | files: reports/coverage.xml
45 |
--------------------------------------------------------------------------------
/src/experiments/low_api/requirement_model.py:
--------------------------------------------------------------------------------
1 | from pydantic import BaseModel, Field
2 |
3 |
4 | class Requirement(BaseModel):
5 | id: str = Field(..., description="Unique identifier for the requirement")
6 | description: str = Field(..., description="Detailed description of the requirement")
7 | precondition: str = Field(..., description="Description of the precondition for the requirement")
8 | process: str = Field(
9 | ..., description="Description of the process or action to be taken"
10 | )
11 | postcondition: str = Field(..., description="Expected postcondition or result of the requirement")
12 | acceptance_criteria: list[str] = Field(
13 | ...,
14 | description="Criteria for accepting the requirement as successfully implemented",
15 | )
16 |
17 |
18 | class FunctionalRequirementsSpec(BaseModel):
19 | project_name: str = Field(..., description="Name of the project or system")
20 | version: str = Field(..., description="Version of the requirements specification")
21 | requirements: list[Requirement] = Field(
22 | ..., description="List of individual functional requirements"
23 | )
24 |
--------------------------------------------------------------------------------
/src/typetemp/environment/typed_environment.py:
--------------------------------------------------------------------------------
1 | from jinja2 import Environment, FileSystemLoader
2 |
3 | from typetemp.extension.faker_extension import FakerExtension
4 | from typetemp.extension.inflection_extension import InflectionExtension
5 |
6 |
7 | def to_kwarg(input_name):
8 | return f"{input_name}={input_name}"
9 |
10 |
11 | class TypedEnvironment(Environment):
12 | def __init__(self, **kwargs):
13 | super(TypedEnvironment, self).__init__(
14 | trim_blocks=True, lstrip_blocks=True, **kwargs
15 | )
16 |
17 | self.add_extension(FakerExtension)
18 | self.add_extension(InflectionExtension)
19 | self.add_extension("jinja2_time.TimeExtension")
20 | self.add_extension("jinja2.ext.i18n")
21 | self.add_extension("jinja2.ext.debug")
22 | self.add_extension("jinja2.ext.do")
23 | self.add_extension("jinja2.ext.loopcontrols")
24 |
25 | self.filters['abc'] = to_kwarg
26 |
27 |
28 | file_loader = FileSystemLoader("./templates")
29 |
30 | environment = TypedEnvironment(loader=file_loader)
31 |
32 | async_environment = TypedEnvironment(enable_async=True, loader=file_loader)
33 |
--------------------------------------------------------------------------------
/src/experiments/web/yaml_converter.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 |
3 | import streamlit as st
4 |
5 | from experiments import create_yaml
6 |
7 |
8 | # Define the Streamlit component function
9 | def yaml_converter(yaml_prompt):
10 | # Add a button to trigger the conversion
11 | if st.button("Convert to YAML"):
12 | st.write("Converting...")
13 |
14 | # Run the conversion asynchronously
15 | async def async_conversion():
16 | yaml_data = await create_yaml.render(yaml_prompt)
17 | st.code(yaml_data, language="yaml")
18 |
19 | loop = asyncio.new_event_loop()
20 | asyncio.set_event_loop(loop)
21 | loop.run_until_complete(async_conversion())
22 | st.write("Conversion complete!")
23 |
24 |
25 | # Create a Streamlit component instance
26 | # def yaml_converter_component_func(yaml_prompt):
27 | # with st.container():
28 | # yaml_converter(yaml_prompt)
29 |
30 | # Create a Streamlit app to demonstrate the component
31 | if __name__ == "__main__":
32 | st.title("YAML Converter Streamlit Component")
33 | yaml_prompt = st.text_area("YAML Prompt", "")
34 | yaml_converter(yaml_prompt)
35 |
--------------------------------------------------------------------------------
/src/typetemp/template/typed_template.py:
--------------------------------------------------------------------------------
1 | from typetemp.template.render_mixin import RenderMixin
2 |
3 |
4 | class TypedTemplate(RenderMixin):
5 | """Base class for creating templated classes. Uses the jinja2 templating engine
6 | to render templates. Allows for usage of macros and filters.
7 | """
8 |
9 | template_path: str = "" # The path to the file
10 | source: str = "" # The string template to be rendered
11 | to: str = "" # The "to" property for rendering destination
12 | output: str = "" # The rendered output
13 |
14 | def __init__(self, **kwargs):
15 | if kwargs.get("template_path"):
16 | # Read the template to the source string
17 | with open(kwargs.get("template_path")) as f:
18 | self.source = f.read()
19 |
20 | self.__dict__.update(kwargs)
21 |
22 | def __call__(self, use_native=False, **kwargs) -> str:
23 | # Use NativeEnvironment when use_native is True, else use default Environment
24 | return self._render(use_native, **kwargs)
25 |
26 | def render(self, use_native=False, **kwargs) -> str:
27 | return self._render(use_native, **kwargs)
28 |
--------------------------------------------------------------------------------
/src/typetemp/template/render_funcs.py:
--------------------------------------------------------------------------------
1 | from typing import Any
2 |
3 | import jinja2
4 |
5 | from ..environment.typed_environment import async_environment, environment
6 | from ..environment.typed_native_environment import (
7 | async_native_environment,
8 | native_environment,
9 | )
10 |
11 |
12 | def render_str(source, **kwargs) -> str:
13 | try:
14 | template = environment.from_string(source)
15 | except jinja2.exceptions.TemplateSyntaxError as e:
16 | print(f"Error processing template: {e}")
17 | print(f"Problematic template string: {source}")
18 | raise
19 | return template.render(**kwargs)
20 |
21 |
22 | async def arender_str(source, **kwargs) -> str:
23 | template = async_environment.from_string(source)
24 |
25 | return await template.render_async(**kwargs)
26 |
27 |
28 | def render_py(source, env=native_environment, **kwargs) -> Any:
29 | template = env.from_string(source)
30 |
31 | return template.render(**kwargs)
32 |
33 |
34 | async def arender_py(source, env=async_native_environment, **kwargs) -> Any:
35 | template = env.from_string(source)
36 |
37 | return await template.render_async(**kwargs)
38 |
--------------------------------------------------------------------------------
/src/rdddy/abstract_aggregate.py:
--------------------------------------------------------------------------------
1 | from rdddy.abstract_actor import AbstractActor
2 |
3 |
4 | class AbstractAggregate(AbstractActor):
5 | """Serves as the cornerstone of the domain model within the RDDDY framework, encapsulating a cluster of domain
6 | objects that are treated as a single unit for the purposes of data changes. An aggregate guarantees the
7 | consistency of changes to the domain objects it encompasses by enforcing invariants across the entire group,
8 | making it a critical element in maintaining the integrity and boundaries of the domain model. By extending
9 | AbstractAggregate, developers can define the core logic that governs the state and behavior of an aggregate root
10 | and its associated entities and value objects. This approach not only aids in isolating domain logic from
11 | infrastructure concerns but also supports the implementation of complex business rules and transactions in a way
12 | that aligns with the principles of Domain-Driven Design. Aggregates are pivotal in ensuring that domain logic
13 | remains both encapsulated and correctly partitioned, facilitating a clear and maintainable domain model that can
14 | evolve over time with the business requirements."""
15 |
16 | pass
17 |
--------------------------------------------------------------------------------
/.cruft.json:
--------------------------------------------------------------------------------
1 | {
2 | "template": "https://github.com/radix-ai/poetry-cookiecutter",
3 | "commit": "0168710e9b56ab046cd2cf34b60866805ec41f58",
4 | "checkout": null,
5 | "context": {
6 | "cookiecutter": {
7 | "package_name": "rdddy",
8 | "package_description": "Reactive DDD framework with DSPy",
9 | "package_url": "https://github.com/chatmangpt/rdddy",
10 | "author_name": "Sean Chatman",
11 | "author_email": "info@chatmangpt.com",
12 | "python_version": "3.10",
13 | "docker_image": "python:3.10-slim",
14 | "development_environment": "simple",
15 | "with_conventional_commits": "0",
16 | "with_fastapi_api": "1",
17 | "with_jupyter_lab": "0",
18 | "with_pydantic_typing": "1",
19 | "with_sentry_logging": "0",
20 | "with_streamlit_app": "1",
21 | "with_typer_cli": "1",
22 | "continuous_integration": "GitHub",
23 | "docstring_style": "Google",
24 | "private_package_repository_name": "",
25 | "private_package_repository_url": "",
26 | "__package_name_kebab_case": "rdddy",
27 | "__package_name_snake_case": "rdddy",
28 | "_template": "https://github.com/radix-ai/poetry-cookiecutter"
29 | }
30 | },
31 | "directory": null
32 | }
33 |
--------------------------------------------------------------------------------
/src/autospider/main.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 |
3 | # Assuming the actor classes are defined in a module named `autospider_actors`
4 | from autospider.actors import (
5 | CompletionActor,
6 | ExecutionActor,
7 | InitiationActor,
8 | PreconditionActor,
9 | ProcessingActor,
10 | )
11 | from autospider.messages import StartScrapingCommand
12 | from rdddy.actor_system import ActorSystem
13 |
14 |
15 | async def setup_and_run():
16 | # Create the Actor System
17 | actor_system = ActorSystem()
18 |
19 | # Initialize actors
20 | initiation_actor = await actor_system.actor_of(InitiationActor)
21 | precondition_actor = await actor_system.actor_of(PreconditionActor)
22 | processing_actor = await actor_system.actor_of(ProcessingActor)
23 | execution_actor = await actor_system.actor_of(ExecutionActor)
24 | completion_actor = await actor_system.actor_of(CompletionActor)
25 |
26 | # Start the scraping process by sending a StartScrapingCommand
27 | # Replace 'http://example.com' with the actual URL you want to scrape
28 | await actor_system.publish(StartScrapingCommand(url="http://example.com"))
29 | await asyncio.sleep(60)
30 |
31 |
32 | async def main():
33 | await setup_and_run()
34 |
35 |
36 | if __name__ == "__main__":
37 | asyncio.run(main())
38 |
--------------------------------------------------------------------------------
/frontend/public/next.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_weighted_graph.py:
--------------------------------------------------------------------------------
1 | from practice.shortest_path_weighted_graph import WeightedGraph, dijkstra_with_min_edges
2 |
3 |
4 | def test_simple_path():
5 | graph = WeightedGraph(4)
6 | graph.add_edge(0, 1, 1)
7 | graph.add_edge(1, 2, 2)
8 | graph.add_edge(2, 3, 3)
9 | distance, edges = dijkstra_with_min_edges(graph, 0, 3)
10 | assert distance == 6
11 | assert edges == 3
12 |
13 |
14 | def test_path_with_equal_weights_different_edges():
15 | graph = WeightedGraph(3)
16 | graph.add_edge(0, 1, 2)
17 | graph.add_edge(1, 2, 2)
18 | graph.add_edge(0, 2, 4) # Shorter path in terms of edges but equal weight
19 | distance, edges = dijkstra_with_min_edges(graph, 0, 2)
20 | assert distance == 4
21 | assert edges == 1
22 |
23 |
24 | def test_no_path_exists():
25 | graph = WeightedGraph(3)
26 | graph.add_edge(0, 1, 1)
27 | # No edge from 1 to 2 or from 0 to 2
28 | distance, edges = dijkstra_with_min_edges(graph, 0, 2)
29 | assert distance == float("inf")
30 | assert edges == float("inf")
31 |
32 |
33 | def test_loop_in_graph():
34 | graph = WeightedGraph(4)
35 | graph.add_edge(0, 1, 1)
36 | graph.add_edge(1, 2, 2)
37 | graph.add_edge(2, 1, 1) # Creates a loop
38 | graph.add_edge(2, 3, 4)
39 | distance, edges = dijkstra_with_min_edges(graph, 0, 3)
40 | assert distance == 7
41 | assert edges == 3
42 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3.9"
2 |
3 | services:
4 |
5 | devcontainer:
6 | build:
7 | context: .
8 | target: dev
9 | args:
10 | PYTHON_VERSION: ${PYTHON_VERSION:-3.10}
11 | UID: ${UID:-1000}
12 | GID: ${GID:-1000}
13 | environment:
14 | - POETRY_PYPI_TOKEN_PYPI
15 | volumes:
16 | - ..:/workspaces
17 | - command-history-volume:/home/user/.history/
18 |
19 | dev:
20 | extends: devcontainer
21 | stdin_open: true
22 | tty: true
23 | entrypoint: []
24 | command:
25 | [
26 | "sh",
27 | "-c",
28 | "sudo chown user $$SSH_AUTH_SOCK && cp --update /opt/build/poetry/poetry.lock /workspaces/rdddy/ && mkdir -p /workspaces/rdddy/.git/hooks/ && cp --update /opt/build/git/* /workspaces/rdddy/.git/hooks/ && zsh"
29 | ]
30 | environment:
31 | - POETRY_PYPI_TOKEN_PYPI
32 | - SSH_AUTH_SOCK=/run/host-services/ssh-auth.sock
33 | ports:
34 | - "8000"
35 | volumes:
36 | - ~/.gitconfig:/etc/gitconfig
37 | - ~/.ssh/known_hosts:/home/user/.ssh/known_hosts
38 | - ${SSH_AGENT_AUTH_SOCK:-/run/host-services/ssh-auth.sock}:/run/host-services/ssh-auth.sock
39 | profiles:
40 | - dev
41 |
42 | app:
43 | build:
44 | context: .
45 | target: app
46 | tty: true
47 | ports:
48 | - "8000:8000"
49 | profiles:
50 | - app
51 |
52 | volumes:
53 | command-history-volume:
54 |
--------------------------------------------------------------------------------
/src/rdddy/hello_world_module.py:
--------------------------------------------------------------------------------
1 | import dspy
2 |
3 | lm = dspy.OpenAI(max_tokens=500)
4 | dspy.settings.configure(lm=lm)
5 |
6 |
7 | class SummarizeText(dspy.Module):
8 | """This module summarizes text using a pre-trained model."""
9 |
10 | def forward(self, text):
11 | pred = dspy.Predict("text -> summary")
12 |
13 | result = pred(text=text).summary
14 | return result
15 |
16 |
17 | def main():
18 | text = """
19 | In his famous commencement speech delivered at Stanford University in 2005, Steve Jobs emphasized the importance of connecting the dots in life, reflecting on his own journey of personal and professional development. Jobs highlighted how seemingly unrelated experiences and decisions in the past could later align and lead to significant opportunities and achievements. He spoke about how dropping out of college and attending calligraphy classes eventually influenced the design and typography of the Macintosh computer, illustrating the unpredictable but crucial nature of connecting dots in hindsight. This perspective encouraged listeners to trust in their intuition, follow their passions, and have faith that the dots will connect in the future, even if the path forward isn't always clear at the present moment.""" # Initialize your inputs here. Adjust as necessary.
20 |
21 | summarize_text = SummarizeText()
22 | print(summarize_text.forward(text=text))
23 |
24 |
25 | if __name__ == '__main__':
26 | main()
27 |
--------------------------------------------------------------------------------
/src/experiments/actor_template.py:
--------------------------------------------------------------------------------
1 | from jinja2 import Template
2 |
3 | # Define the actor name and a list of messages
4 | actor_name = "MyActor"
5 | messages = [
6 | {
7 | "name": "RequirementSpecificationCommand",
8 | "type": "Command",
9 | "description": "Description of RequirementSpecificationCommand",
10 | },
11 | {
12 | "name": "ModelGeneratedEvent",
13 | "type": "Event",
14 | "description": "Description of ModelGeneratedEvent",
15 | },
16 | # Add more messages as needed
17 | ]
18 |
19 | # Load and render the template
20 | template_string = '''# actor_template.jinja
21 |
22 | class {{ actor_name }}(Actor):
23 | def __init__(self, actor_system, actor_id=None):
24 | super().__init__(actor_system, actor_id)
25 | # Additional initialization here if necessary
26 |
27 | {% for event in messages %}
28 | async def handle_{{ event.name|lower }}(self, event: {{ event.type }}):
29 | """
30 | Handle {{ event.name }} event.
31 | {% if event.description %}# {{ event.description }}{% endif %}
32 | """
33 | # Logic to handle {{ event.name }} event
34 | pass
35 | {% endfor %}
36 | ''' # The string content of the actor_template.jinja
37 | template = Template(template_string)
38 | rendered_actor_class = template.render(actor_name=actor_name, messages=messages)
39 |
40 | # Output the rendered actor class
41 | print(rendered_actor_class)
42 |
--------------------------------------------------------------------------------
/src/experiments/abstract_aggregate.py:
--------------------------------------------------------------------------------
1 | from rdddy.abstract_actor import AbstractActor
2 |
3 |
4 | class AbstractAggregate(AbstractActor):
5 | def __init__(self, actor_system, actor_id=None):
6 | super().__init__(actor_system, actor_id)
7 |
8 | def apply_event(self, event):
9 | # Apply the event to the aggregate's state
10 | pass
11 |
12 | async def emit_event(self, event):
13 | # Emit the event for event sourcing
14 | await self.actor_system.publish(event)
15 |
16 | def check_version(self, expected_version):
17 | # Check if the expected version matches the current version
18 | return self.version == expected_version
19 |
20 | def validate(self, command):
21 | # Validate the incoming command
22 | pass
23 |
24 | async def handle_error(self, error_message):
25 | # Handle errors or exceptions
26 | pass
27 |
28 | async def initialize(self):
29 | # Perform initialization when an aggregate is created
30 | pass
31 |
32 | async def finalize(self):
33 | # Clean up resources or perform actions when an aggregate is no longer needed
34 | pass
35 |
36 | async def load_snapshot(self, snapshot):
37 | # Load a previously taken snapshot to optimize aggregate initialization
38 | pass
39 |
40 | async def take_snapshot(self):
41 | # Capture a snapshot of the aggregate's state for optimization
42 | pass
43 |
--------------------------------------------------------------------------------
/tests/test_lru_cache.py:
--------------------------------------------------------------------------------
1 | import pytest
2 |
3 | from practice.lru_cache import LRUCache
4 |
5 |
6 | def test_cache_hit():
7 | lru = LRUCache(2)
8 | lru.put(1, 1)
9 | lru.put(2, 2)
10 | assert lru.get(1) == 1, "Cache hit should return the correct value"
11 |
12 |
13 | def test_cache_miss():
14 | lru = LRUCache(2)
15 | lru.put(1, 1)
16 | assert lru.get(3) is None, "Cache miss should return -1"
17 |
18 |
19 | def test_capacity_limit():
20 | lru = LRUCache(2)
21 | lru.put(1, 1)
22 | lru.put(2, 2)
23 | lru.put(3, 3) # This should evict key 1
24 | assert lru.get(1) == None, "Least recently used item should be evicted"
25 |
26 |
27 | def test_update_existing_key():
28 | lru = LRUCache(2)
29 | lru.put(1, 1)
30 | lru.put(1, 10)
31 | assert lru.get(1) == 10, "Updating an existing key should overwrite its value"
32 |
33 |
34 | def test_recently_used_eviction_policy():
35 | lru = LRUCache(2)
36 | lru.put(1, 1)
37 | lru.put(2, 2)
38 | lru.get(1) # This should make key 1 the most recently used
39 | lru.put(3, 3) # This should evict key 2, not key 1
40 | assert (
41 | lru.get(2) == None and lru.get(1) == 1
42 | ), "LRU eviction policy should evict the least recently used item"
43 |
44 |
45 | @pytest.mark.parametrize("key,value", [(4, 4), (5, 5)])
46 | def test_put_with_parametrize(key, value):
47 | lru = LRUCache(3)
48 | lru.put(key, value)
49 | assert lru.get(key) == value, f"Cache should return {value} for key {key}"
50 |
--------------------------------------------------------------------------------
/frontend/README.md:
--------------------------------------------------------------------------------
1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
2 |
3 | ## Getting Started
4 |
5 | First, run the development server:
6 |
7 | ```bash
8 | npm run dev
9 | # or
10 | yarn dev
11 | # or
12 | pnpm dev
13 | # or
14 | bun dev
15 | ```
16 |
17 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
18 |
19 | You can start editing the page by modifying `app/page.js`. The page auto-updates as you edit the file.
20 |
21 | This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
22 |
23 | ## Learn More
24 |
25 | To learn more about Next.js, take a look at the following resources:
26 |
27 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
28 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
29 |
30 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
31 |
32 | ## Deploy on Vercel
33 |
34 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
35 |
36 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
37 |
--------------------------------------------------------------------------------
/.github/workflows/deploy.yml:
--------------------------------------------------------------------------------
1 | name: Deploy
2 |
3 | on:
4 | push:
5 | tags:
6 | - "v*.*.*"
7 | workflow_dispatch:
8 | inputs:
9 | environment:
10 | required: true
11 | description: Deployment environment
12 | default: development
13 | type: choice
14 | options:
15 | - feature
16 | - development
17 | - test
18 | - acceptance
19 | - production
20 |
21 | env:
22 | DEFAULT_DEPLOYMENT_ENVIRONMENT: feature
23 | DOCKER_REGISTRY: ghcr.io
24 |
25 | jobs:
26 | deploy:
27 | runs-on: ubuntu-latest
28 |
29 | if: startsWith(github.ref, 'refs/tags/v')
30 |
31 | steps:
32 | - name: Checkout
33 | uses: actions/checkout@v4
34 |
35 | - name: Log in to the Docker registry
36 | uses: docker/login-action@v3
37 | with:
38 | registry: ${{ env.DOCKER_REGISTRY }}
39 | username: ${{ github.actor }}
40 | password: ${{ secrets.GITHUB_TOKEN }}
41 |
42 | - name: Set Docker image tag
43 | run: echo "GIT_TAG=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
44 |
45 | - name: Build and push Docker image
46 | uses: docker/build-push-action@v5
47 | with:
48 | context: .
49 | push: true
50 | tags: |
51 | ${{ env.DOCKER_REGISTRY }}/${{ github.repository_owner }}/${{ github.repository }}:${{ github.event.inputs.environment || env.DEFAULT_DEPLOYMENT_ENVIRONMENT }}
52 | ${{ env.DOCKER_REGISTRY }}/${{ github.repository_owner }}/${{ github.repository }}:${{ env.GIT_TAG }}
53 | target: app
54 |
--------------------------------------------------------------------------------
/src/typetemp/functional.py:
--------------------------------------------------------------------------------
1 | import os
2 | from pathlib import Path
3 |
4 | from typetemp.environment.typed_environment import environment, to_kwarg
5 | from typetemp.environment.typed_native_environment import native_environment
6 |
7 | _env = environment
8 | _native_env = native_environment
9 |
10 |
11 | def render(tmpl_str_or_path: str | Path, to: str = "", **kwargs) -> str:
12 | """Render a template from a string or a file with the given keyword arguments."""
13 | # Check if tmpl_str_or_path is a path to a file
14 | if os.path.exists(tmpl_str_or_path) and Path(tmpl_str_or_path).is_file():
15 | with open(tmpl_str_or_path) as file:
16 | template_content = file.read()
17 | else:
18 | template_content = str(tmpl_str_or_path)
19 |
20 | template = _env.from_string(template_content)
21 |
22 | rendered = template.render(**kwargs)
23 |
24 | if to:
25 | to_ = _env.from_string(to)
26 | rendered_to = to_.render(**kwargs)
27 |
28 | with open(rendered_to, "w") as file:
29 | file.write(rendered)
30 |
31 | return rendered
32 |
33 |
34 | def render_native(tmpl_str_or_path: str | Path, **kwargs) -> str:
35 | """Render a template from a string or a file with the given keyword arguments."""
36 | # Check if tmpl_str_or_path is a path to a file
37 | if os.path.exists(tmpl_str_or_path) and Path(tmpl_str_or_path).is_file():
38 | with open(tmpl_str_or_path) as file:
39 | template_content = file.read()
40 | else:
41 | template_content = str(tmpl_str_or_path)
42 |
43 | template = _native_env.from_string(template_content)
44 |
45 | return template.render(**kwargs)
46 |
--------------------------------------------------------------------------------
/src/autospider/messages.py:
--------------------------------------------------------------------------------
1 | from rdddy.messages import *
2 |
3 |
4 | class StartScrapingCommand(AbstractCommand):
5 | """Command to initiate scraping for a given URL."""
6 |
7 | url: str
8 |
9 |
10 | class EvaluateScrapingPreconditionQuery(AbstractQuery):
11 | """Query to evaluate if the preconditions for scraping a URL are met."""
12 |
13 | url: str
14 |
15 |
16 | class ScrapingPreconditionEvaluatedEvent(AbstractEvent):
17 | """Event indicating the result of scraping preconditions evaluation."""
18 |
19 | phase_name: str = "Scraping Precondition Evaluation"
20 | url: str
21 | result: bool
22 |
23 |
24 | class ExecuteScrapingCommand(AbstractCommand):
25 | """Command to execute the scraping process for a given URL."""
26 |
27 | url: str
28 |
29 |
30 | class ScrapingErrorEvent(AbstractEvent):
31 | """Event indicating an error occurred during the scraping process."""
32 |
33 | phase_name: str
34 | url: str
35 | error_message: str
36 |
37 |
38 | class EvaluateScrapingPostconditionQuery(AbstractQuery):
39 | """Query to evaluate if the postconditions after scraping a URL are met."""
40 |
41 | url: str
42 |
43 |
44 | class ScrapingPostconditionEvaluatedEvent(AbstractEvent):
45 | """Event indicating the result of scraping postconditions evaluation."""
46 |
47 | phase_name: str = "Scraping Postcondition Evaluation"
48 | url: str
49 | result: bool
50 |
51 |
52 | class ScrapingCompletedEvent(AbstractEvent):
53 | """Event indicating the completion of the scraping process."""
54 |
55 | phase_name: str = "Scraping Completed"
56 | url: str
57 | scraped_data: dict # Assuming scraped data is stored as a dictionary
58 |
--------------------------------------------------------------------------------
/src/experiments/leetcode/solved.py:
--------------------------------------------------------------------------------
1 | def removeElement(nums, val):
2 | """
3 | Removes all occurrences of val in nums in-place and returns the number of elements in nums which are not equal to val.
4 | :param nums: list of integers
5 | :param val: integer
6 | :return: integer
7 | """
8 | # initialize two pointers, one for iterating through the array and one for keeping track of the next non-val index
9 | i = 0
10 | non_val_index = 0
11 |
12 | # iterate through the array
13 | while i < len(nums):
14 | # if the current element is not equal to val, swap it with the element at the next non-val index
15 | if nums[i] != val:
16 | nums[i], nums[non_val_index] = nums[non_val_index], nums[i]
17 | # increment the non-val index
18 | non_val_index += 1
19 | # increment the iterator
20 | i += 1
21 |
22 | # return the non-val index as the number of elements in nums which are not equal to val
23 | return non_val_index
24 |
25 |
26 | # Custom Judge:
27 | # The judge will test your solution with the following code:
28 | nums = [3, 2, 2, 3] # Input array
29 | val = 3 # Value to remove
30 | expectedNums = [2, 2] # The expected answer with correct length.
31 | # It is sorted with no values equaling val.
32 | k = removeElement(nums, val) # Calls your implementation
33 | assert k == len(
34 | expectedNums
35 | ) # Checks if the returned k is equal to the expected length
36 | nums.sort() # Sort the first k elements of nums
37 | for i in range(k):
38 | print(nums[i], expectedNums[i])
39 | assert (
40 | nums[i] == expectedNums[i]
41 | ) # Checks if the first k elements of nums are equal to the expected elements
42 |
--------------------------------------------------------------------------------
/src/practice/shortest_path_weighted_graph.py:
--------------------------------------------------------------------------------
1 | import heapq
2 |
3 |
4 | class WeightedGraph:
5 | def __init__(self, vertices):
6 | self.V = vertices
7 | self.graph = [[] for _ in range(vertices)]
8 |
9 | def add_edge(self, u, v, w):
10 | self.graph[u].append((v, w))
11 |
12 |
13 | def dijkstra_with_min_edges(graph, src, target):
14 | min_heap = [(0, 0, src)]
15 | distances = {i: float("inf") for i in range(graph.V)}
16 | edges_count = {i: float("inf") for i in range(graph.V)}
17 | distances[src] = 0
18 | edges_count[src] = 0
19 |
20 | while min_heap:
21 | current_distance, current_edges, u = heapq.heappop(min_heap)
22 |
23 | if u == target:
24 | break
25 |
26 | for neighbor, weight in graph.graph[u]:
27 | distance = current_distance + weight
28 |
29 | if distance < distances[neighbor] or (
30 | distance == distances[neighbor]
31 | and current_edges + 1 < edges_count[neighbor]
32 | ):
33 | distances[neighbor] = distance
34 | edges_count[neighbor] = current_edges + 1
35 | heapq.heappush(min_heap, (distance, current_edges + 1, neighbor))
36 |
37 | return distances[target], edges_count[target]
38 |
39 |
40 | vertices = 6
41 | graph = WeightedGraph(vertices)
42 | graph.add_edge(0, 1, 1)
43 | graph.add_edge(1, 2, 1)
44 | graph.add_edge(0, 2, 2)
45 | graph.add_edge(1, 3, 1)
46 | graph.add_edge(2, 3, 2)
47 | graph.add_edge(3, 4, 1)
48 | graph.add_edge(4, 5, 1)
49 |
50 | src = 0
51 | target = 5
52 | distance, edges = dijkstra_with_min_edges(graph, src, target)
53 | print(
54 | f"Shortest path from {src} to {target} has distance {distance} using {edges} edges."
55 | )
56 |
--------------------------------------------------------------------------------
/src/practice/lru_cache.py:
--------------------------------------------------------------------------------
1 | class ListNode:
2 | def __init__(self, key=None, value=None):
3 | self.key = key
4 | self.value = value
5 | self.prev = None
6 | self.next = None
7 |
8 |
9 | class LRUCache:
10 | def __init__(self, capacity: int):
11 | self.capacity = capacity
12 | self.cache = {}
13 | self.head = ListNode()
14 | self.tail = ListNode()
15 | self.head.next = self.tail
16 | self.tail.prev = self.head
17 |
18 | def remove_node(self, node: ListNode):
19 | prev = node.prev
20 | nxt = node.next
21 | prev.next, nxt.prev = nxt, prev
22 |
23 | def add_node_to_head(self, node: ListNode):
24 | node.prev = self.head
25 | node.next = self.head.next
26 | self.head.next.prev = node
27 | self.head.next = node
28 |
29 | def move_node_to_head(self, node: ListNode):
30 | self.remove_node(node)
31 | self.add_node_to_head(node)
32 |
33 | def pop_tail(self):
34 | res = self.tail.prev
35 | self.remove_node(res)
36 | return res
37 |
38 | def get(self, key):
39 | node = self.cache.get(key)
40 | if not node:
41 | return None
42 | self.move_node_to_head(node)
43 | return node.value
44 |
45 | def put(self, key, value):
46 | node = self.cache.get(key)
47 | if not node:
48 | newNode = ListNode(key, value)
49 | self.cache[key] = newNode
50 | self.add_node_to_head(newNode)
51 | if len(self.cache) > self.capacity:
52 | tail = self.pop_tail()
53 | del self.cache[tail.key]
54 | else:
55 | node.value = value
56 | self.move_node_to_head(node)
57 |
--------------------------------------------------------------------------------
/src/practice/web_crawler.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 |
3 | from playwright.async_api import async_playwright
4 |
5 |
6 | class AsyncWebCrawler:
7 | def __init__(self, start_url: str):
8 | self.start_url = start_url
9 | self.visited_urls = set()
10 |
11 | async def extract_links(self, page):
12 | """Extract links from the page."""
13 | links = set()
14 | els = await page.query_selector_all("a")
15 | for el in els:
16 | link = await el.get_attribute("href")
17 | if link and link.startswith("http"):
18 | links.add(link)
19 | return links
20 |
21 | async def crawl(self, url, depth=0, max_depth=2):
22 | """Recursively crawl the given url."""
23 | if depth > max_depth or url in self.visited_urls:
24 | return
25 | self.visited_urls.add(url)
26 | print(f"Crawling {url}...")
27 |
28 | async with async_playwright() as p:
29 | browser = await p.chromium.launch()
30 | page = await browser.new_page()
31 | try:
32 | await page.goto(url, wait_until="networkidle")
33 | links = await self.extract_links(page)
34 | for link in links:
35 | await self.crawl(link, depth + 1, max_depth)
36 | except Exception as e:
37 | print(f"Failed to crawl {url}: {e}")
38 | await browser.close()
39 |
40 | async def start(self):
41 | """Starts the web crawling process."""
42 | await self.crawl(self.start_url)
43 |
44 |
45 | async def main():
46 | cr = AsyncWebCrawler("https://google.com")
47 | await cr.start()
48 |
49 |
50 | if __name__ == "__main__":
51 | import asyncio
52 |
53 | asyncio.run(main())
54 |
--------------------------------------------------------------------------------
/src/experiments/workshop_messages.py:
--------------------------------------------------------------------------------
1 | from datetime import datetime
2 | from enum import Enum
3 |
4 | from rdddy.messages import AbstractMessage
5 |
6 |
7 | # Define an enumeration for workshop statuses
8 | class WorkshopStatus(str, Enum):
9 | PLANNED = "Planned"
10 | IN_PROGRESS = "In Progress"
11 | COMPLETED = "Completed"
12 |
13 |
14 | # Base class for messages
15 | class WorkshopMessage(AbstractMessage):
16 | workshop_id: int
17 |
18 |
19 | # Commands
20 | class ScheduleWorkshop(WorkshopMessage):
21 | name: str
22 | start_date: datetime
23 | end_date: datetime
24 |
25 |
26 | class AssignPresenter(WorkshopMessage):
27 | presenter_name: str
28 |
29 |
30 | class SendInvitations(WorkshopMessage):
31 | participant_emails: list
32 |
33 |
34 | class AcceptInvitation(WorkshopMessage):
35 | participant_email: str
36 |
37 |
38 | class UpdateWorkshopDetails(WorkshopMessage):
39 | name: str
40 | description: str
41 |
42 |
43 | class CancelWorkshop(WorkshopMessage):
44 | reason: str
45 |
46 |
47 | # Events
48 | class WorkshopScheduled(WorkshopMessage):
49 | name: str
50 | start_date: datetime
51 | end_date: datetime
52 | status: WorkshopStatus = WorkshopStatus.PLANNED
53 |
54 |
55 | class PresenterAssigned(WorkshopMessage):
56 | presenter_name: str
57 |
58 |
59 | class InvitationsSent(WorkshopMessage):
60 | sent_to: list
61 |
62 |
63 | class InvitationAccepted(WorkshopMessage):
64 | participant_email: str
65 |
66 |
67 | class WorkshopDetailsUpdated(WorkshopMessage):
68 | name: str
69 | description: str
70 |
71 |
72 | class WorkshopCanceled(WorkshopMessage):
73 | reason: str
74 | status: WorkshopStatus = WorkshopStatus.COMPLETED
75 |
76 |
77 | # Queries
78 | class GetWorkshopDetails(WorkshopMessage):
79 | pass
80 |
81 |
82 | class ListWorkshops(WorkshopMessage):
83 | pass
84 |
--------------------------------------------------------------------------------
/src/experiments/gen_api.py:
--------------------------------------------------------------------------------
1 | from typing import Any, Optional
2 |
3 | from pydantic import BaseModel, Field
4 |
5 | import dspy
6 | from rdddy.generators.gen_pydantic_instance import GenPydanticInstance
7 |
8 | api_description = """
9 | Imagine a digital portal where users can inquire about meteorological conditions.
10 | This portal is accessible through a web interface that interacts with a backend service.
11 | The service is invoked by sending a request to a specific endpoint.
12 | This request is crafted using a standard protocol for web communication.
13 | The endpoint's location is a mystery, hidden within the path '/forecast/today'.
14 | Users pose their inquiries by specifying a geographical area of interest,
15 | though the exact format of this specification is left to the user's imagination.
16 | Upon successful request processing, the service responds with a structured
17 | summary of the weather, encapsulating details such as temperature, humidity,
18 | and wind speed. However, the structure of this response and the means of
19 | accessing the weather summary are not explicitly defined.
20 | """
21 |
22 |
23 | class APIEndpoint(BaseModel):
24 | method: str = Field(..., description="HTTP method of the API endpoint")
25 | url: str = Field(..., description="URL of the API endpoint")
26 | description: str = Field(
27 | ..., description="Description of what the API endpoint does"
28 | )
29 | response: str = Field(..., description="Response from the API endpoint")
30 | query_params: Optional[dict[str, Any]] = Field(None, description="Query parameters")
31 |
32 |
33 | def main():
34 | lm = dspy.OpenAI(max_tokens=1000)
35 | dspy.settings.configure(lm=lm)
36 |
37 | gpm = GenPydanticInstance(root_model=APIEndpoint)
38 | result = gpm.forward(prompt=api_description)
39 | print(result)
40 |
41 |
42 | if __name__ == "__main__":
43 | main()
44 |
--------------------------------------------------------------------------------
/src/experiments/generated_cli.py:
--------------------------------------------------------------------------------
1 | import typer
2 |
3 | app = typer.Typer()
4 |
5 |
6 | @app.command(name="generate_module")
7 | def generate_module():
8 | """Generates a new DSPy module with a specified name."""
9 | # Command logic goes here
10 | print("This is the generate_module command.")
11 |
12 |
13 | @app.command(name="generate_signature")
14 | def generate_signature():
15 | """Creates a new signature class for defining input-output behavior in DSPy modules."""
16 | # Command logic goes here
17 | print("This is the generate_signature command.")
18 |
19 |
20 | @app.command(name="generate_chainofthought")
21 | def generate_chainofthought():
22 | """Generates a ChainOfThought module with a standard question-answering signature."""
23 | # Command logic goes here
24 | print("This is the generate_chainofthought command.")
25 |
26 |
27 | @app.command(name="generate_retrieve")
28 | def generate_retrieve():
29 | """Generates a Retrieve module for use in information retrieval tasks within DSPy."""
30 | # Command logic goes here
31 | print("This is the generate_retrieve command.")
32 |
33 |
34 | @app.command(name="generate_teleprompter")
35 | def generate_teleprompter():
36 | """Creates a teleprompter setup for optimizing DSPy programs."""
37 | # Command logic goes here
38 | print("This is the generate_teleprompter command.")
39 |
40 |
41 | @app.command(name="generate_example")
42 | def generate_example():
43 | """Generates an example structure for use in training and testing DSPy modules."""
44 | # Command logic goes here
45 | print("This is the generate_example command.")
46 |
47 |
48 | @app.command(name="generate_assertion")
49 | def generate_assertion():
50 | """Generates a template for creating LM Assertions in DSPy programs."""
51 | # Command logic goes here
52 | print("This is the generate_assertion command.")
53 |
54 |
55 | if __name__ == "__main__":
56 | app()
57 |
--------------------------------------------------------------------------------
/src/experiments/rag_gen_messages.py:
--------------------------------------------------------------------------------
1 | from rdddy.messages import *
2 |
3 |
4 | class DatasetLoaded(AbstractEvent):
5 | """Event triggered by DatasetLoaded."""
6 |
7 |
8 | class PipelineBuilt(AbstractEvent):
9 | """Event triggered by PipelineBuilt."""
10 |
11 |
12 | class PipelineOptimized(AbstractEvent):
13 | """Event triggered by PipelineOptimized."""
14 |
15 |
16 | class PipelineExecuted(AbstractEvent):
17 | """Event triggered by PipelineExecuted."""
18 |
19 |
20 | class PipelineEvaluated(AbstractEvent):
21 | """Event triggered by PipelineEvaluated."""
22 |
23 |
24 | class RetrievalEvaluated(AbstractEvent):
25 | """Event triggered by RetrievalEvaluated."""
26 |
27 |
28 | class LoadDataset(AbstractCommand):
29 | """Command to execute LoadDataset."""
30 |
31 |
32 | class BuildPipeline(AbstractCommand):
33 | """Command to execute BuildPipeline."""
34 |
35 |
36 | class OptimizePipeline(AbstractCommand):
37 | """Command to execute OptimizePipeline."""
38 |
39 |
40 | class ExecutePipeline(AbstractCommand):
41 | """Command to execute ExecutePipeline."""
42 |
43 |
44 | class EvaluatePipeline(AbstractCommand):
45 | """Command to execute EvaluatePipeline."""
46 |
47 |
48 | class EvaluateRetrieval(AbstractCommand):
49 | """Command to execute EvaluateRetrieval."""
50 |
51 |
52 | class GetDataset(AbstractQuery):
53 | """Query to retrieve GetDataset."""
54 |
55 |
56 | class GetPipeline(AbstractQuery):
57 | """Query to retrieve GetPipeline."""
58 |
59 |
60 | class GetOptimizedPipeline(AbstractQuery):
61 | """Query to retrieve GetOptimizedPipeline."""
62 |
63 |
64 | class GetPipelineExecution(AbstractQuery):
65 | """Query to retrieve GetPipelineExecution."""
66 |
67 |
68 | class GetPipelineEvaluation(AbstractQuery):
69 | """Query to retrieve GetPipelineEvaluation."""
70 |
71 |
72 | class GetRetrievalEvaluation(AbstractQuery):
73 | """Query to retrieve GetRetrievalEvaluation."""
74 |
--------------------------------------------------------------------------------
/src/experiments/actor/hygen_cot.py:
--------------------------------------------------------------------------------
1 | import dspy
2 |
3 | lm = dspy.OpenAI(max_tokens=2000)
4 | dspy.settings.configure(lm=lm)
5 |
6 |
7 | class GenerateHygenTemplate(dspy.Signature):
8 | """Generate a Hygen template based on specified requirements.
9 | ---
10 | to: app/emails/<%= name %>.html
11 | ---
12 |
13 |
14 | Hello <%= name %>,
15 | <%= message %>
16 | (version <%= version %>)
17 | """
18 |
19 | requirements = dspy.InputField(
20 | desc="Specifications or requirements for the Hygen template"
21 | )
22 | template = dspy.OutputField(desc="Generated Hygen template code")
23 |
24 |
25 | class HygenTemplateGenerator(dspy.Module):
26 | def __init__(self):
27 | super().__init__()
28 | self.generate_template = dspy.ChainOfThought(GenerateHygenTemplate)
29 |
30 | def forward(self, requirements):
31 | # The ChainOfThought could involve parsing the requirements,
32 | # determining the structure and variables needed for the Hygen template,
33 | # and then constructing the template code.
34 | template_code = self.generate_template(requirements=requirements).template
35 | return dspy.Prediction(template=template_code)
36 |
37 |
38 | def main():
39 | # Example usage
40 | generator = HygenTemplateGenerator()
41 |
42 | # Define your requirements here. This should be a detailed description of what the Hygen template needs to do.
43 |
44 | requirements = """Generate a React component with props, state, and a basic render function. The component should be a functional
45 | component using React Hooks. """
46 |
47 | # Generate the Hygen template
48 | pred = generator(requirements)
49 |
50 | # Output the generated template
51 | print(f"Generated Hygen Template:\n{pred.template}")
52 |
53 | # Write pred.template to disk
54 |
55 | with open("template.ejs.t", "w") as f:
56 | f.write(pred.template)
57 |
58 |
59 | if __name__ == "__main__":
60 | main()
61 |
--------------------------------------------------------------------------------
/tests/dspy/test_gen_python_primative_list.py:
--------------------------------------------------------------------------------
1 | from unittest.mock import MagicMock, patch
2 |
3 | # replace with the actual import
4 | import pytest
5 |
6 | from dspy import DSPyAssertionError, OpenAI, settings
7 | from rdddy.generators.gen_python_primitive import (
8 | GenPythonPrimitive,
9 | )
10 |
11 |
12 | @pytest.fixture()
13 | def gen_python_primitive():
14 | with patch.object(settings, "configure"), patch.object(
15 | OpenAI, "__init__", return_value=None
16 | ):
17 | yield GenPythonPrimitive(list)
18 |
19 |
20 | @patch("dspy.predict.Predict.forward")
21 | @patch("rdddy.generators.gen_module.ChainOfThought")
22 | @patch("ast.literal_eval")
23 | def test_forward_success(
24 | mock_literal_eval, mock_chain_of_thought, mock_predict, gen_python_primitive
25 | ):
26 | # Setup mock responses
27 | mock_predict.return_value.get.return_value = "['Jupiter', 'Saturn']"
28 | mock_chain_of_thought.return_value.get.return_value = "['Jupiter', 'Saturn']"
29 | mock_literal_eval.return_value = ["Jupiter", "Saturn"]
30 |
31 | # Call the method
32 | result = gen_python_primitive.forward(prompt="Create a list of planets")
33 | assert result == ["Jupiter", "Saturn"]
34 |
35 |
36 | @patch("dspy.predict.Predict.forward")
37 | @patch("rdddy.generators.gen_module.ChainOfThought")
38 | @patch("ast.literal_eval", side_effect=SyntaxError)
39 | def test_forward_syntax_error(
40 | mock_literal_eval, mock_chain_of_thought, mock_predict, gen_python_primitive
41 | ):
42 | # Setup mock responses
43 | mock_predict.return_value.get.return_value = "{'Jupiter', 'Saturn'}"
44 | mock_chain_of_thought.side_effect = [
45 | MagicMock(get=MagicMock(return_value="{'Jupiter', 'Saturn'}")), # initial call
46 | MagicMock(
47 | get=MagicMock(return_value="{'Jupiter', 'Saturn'}")
48 | ), # correction call
49 | ]
50 | # Call the method and expect an error
51 | with pytest.raises(DSPyAssertionError):
52 | gen_python_primitive.forward(prompt="Create a list with syntax error")
53 |
--------------------------------------------------------------------------------
/src/experiments/leetcode/solution_model.py:
--------------------------------------------------------------------------------
1 | import inflection
2 | from dspy import OpenAI, settings
3 |
4 | from rdddy.generators.gen_pydantic_class import (
5 | PydanticClassTemplateSpecificationModel,
6 | FieldTemplateSpecificationModel,
7 | class_template_str,
8 | )
9 | from rdddy.generators.gen_pydantic_instance import GenPydanticInstance
10 | from typetemp.functional import render
11 |
12 |
13 | # Define the function to generate and write a Pydantic class based on a prompt
14 | def generate_pydantic_class(prompt: str, filename: str):
15 | # Initialize the LM with DSPy settings
16 | lm = OpenAI(max_tokens=3000)
17 | settings.configure(lm=lm)
18 |
19 | # Define the GenPydanticInstance module with the appropriate root and child models
20 | model_module = GenPydanticInstance(
21 | root_model=PydanticClassTemplateSpecificationModel,
22 | child_models=[FieldTemplateSpecificationModel],
23 | )
24 |
25 | # Generate the Pydantic model instance from the prompt
26 | model_inst = model_module.forward(prompt)
27 |
28 | # Render the Pydantic class from the specification
29 | rendered_class_str = render(class_template_str, model=model_inst)
30 |
31 | # Define a helper function to write the rendered class to a Python file
32 | def write_pydantic_class_to_file(class_str: str, file_path: str):
33 | with open(file_path, "w") as file:
34 | file.write(class_str)
35 |
36 | # Write the rendered class to the specified filename
37 | write_pydantic_class_to_file(rendered_class_str, filename)
38 |
39 | print(f"Pydantic model written to {filename}")
40 |
41 |
42 | # Example usage
43 | if __name__ == "__main__":
44 | # Define your prompt here
45 | prompt = (
46 | "I need a model for interview coding challenge questions, answers, and hints"
47 | )
48 |
49 | # Specify the filename for the generated Pydantic model
50 | filename = "solution_model2.py"
51 |
52 | # Generate the Pydantic class and write it to a file
53 | generate_pydantic_class(prompt, filename)
54 |
--------------------------------------------------------------------------------
/src/experiments/workshop_aggregate.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 |
3 | from experiments.abstract_aggregate import AbstractAggregate
4 | from rdddy.actor_system import ActorSystem
5 | from rdddy.messages import AbstractCommand, AbstractEvent
6 |
7 |
8 | # Domain Events
9 | class WorkshopStarted(AbstractEvent):
10 | workshop_id: str
11 |
12 |
13 | class ParticipantAdded(AbstractEvent):
14 | workshop_id: str
15 | participant_id: str
16 |
17 |
18 | # ... Other domain events ...
19 |
20 |
21 | # Domain Commands
22 | class StartWorkshop(AbstractCommand):
23 | workshop_id: str
24 |
25 |
26 | class AddParticipant(AbstractCommand):
27 | workshop_id: str
28 | participant_id: str
29 |
30 |
31 | # ... Other domain commands ...
32 |
33 |
34 | # Aggregate Root
35 | class WorkshopAggregate(AbstractAggregate):
36 | def __init__(self, actor_system, workshop_id):
37 | super().__init__(actor_system, workshop_id)
38 | self.participants = []
39 | self.events = []
40 |
41 | async def start_workshop(self, command: StartWorkshop):
42 | # Start workshop logic
43 | # Emit WorkshopStarted event
44 | print("Starting workshop")
45 | await self.emit_event(WorkshopStarted(workshop_id=command.workshop_id))
46 |
47 | def add_participant(self, command: AddParticipant):
48 | # Add participant logic
49 | # Emit ParticipantAdded event
50 | self.emit_event(
51 | ParticipantAdded(
52 | workshop_id=command.workshop_id, participant_id=command.participant_id
53 | )
54 | )
55 |
56 |
57 | # Simulation
58 | async def simulate_workshop():
59 | actor_system = ActorSystem()
60 |
61 | # Create WorkshopAggregate
62 | workshop_aggregate = await actor_system.actor_of(
63 | WorkshopAggregate, workshop_id="workshop-123"
64 | )
65 |
66 | # Send commands to the aggregate
67 | start_command = StartWorkshop(workshop_id="workshop")
68 | await actor_system.publish(start_command)
69 |
70 |
71 | if __name__ == "__main__":
72 | asyncio.run(simulate_workshop())
73 |
--------------------------------------------------------------------------------
/src/rdddy/thought/typer_cli.py:
--------------------------------------------------------------------------------
1 | from pydantic import BaseModel, Field
2 |
3 | import dspy
4 | from rdddy.generators.gen_pydantic_instance import GenPydanticInstance
5 |
6 | cli_description = """
7 |
8 | We are building a Typer CLI application named 'DSPyGenerator'. It should include the following commands:
9 |
10 | 1. Command Name: generate_module
11 | Help: Generates a new DSPy module with a specified name.
12 |
13 | 2. Command Name: generate_signature
14 | Help: Creates a new signature class for defining input-output behavior in DSPy modules.
15 |
16 | 3. Command Name: generate_chainofthought
17 | Help: Generates a ChainOfThought module with a standard question-answering signature.
18 |
19 | 4. Command Name: generate_retrieve
20 | Help: Generates a Retrieve module for use in information retrieval tasks within DSPy.
21 |
22 | 5. Command Name: generate_teleprompter
23 | Help: Creates a teleprompter setup for optimizing DSPy programs.
24 |
25 | 6. Command Name: generate_example
26 | Help: Generates an example structure for use in training and testing DSPy modules.
27 |
28 | 7. Command Name: generate_assertion
29 | Help: Generates a template for creating LM Assertions in DSPy programs.
30 |
31 | """
32 |
33 |
34 | class Command(BaseModel):
35 | """Typer CLI command"""
36 |
37 | name: str = Field(..., min_length=1, description="The name of the command")
38 | help: str = Field(..., min_length=1, description="The help text for the command")
39 |
40 |
41 | class TyperCLI(BaseModel):
42 | """Typer CLI name and commands"""
43 |
44 | name: str = Field(..., min_length=1, description="The name of the CLI application")
45 | commands: list[Command] = Field(
46 | ..., description="The commands of the CLI application"
47 | )
48 |
49 |
50 | def main():
51 | lm = dspy.OpenAI(max_tokens=2000)
52 | dspy.settings.configure(lm=lm)
53 | dot = GenPydanticInstance(root_model=TyperCLI, child_models=[Command, TyperCLI])
54 |
55 | cli = dot.forward(prompt=cli_description)
56 |
57 | print(cli)
58 |
59 |
60 | if __name__ == "__main__":
61 | main()
62 |
--------------------------------------------------------------------------------
/src/experiments/test_cli.py:
--------------------------------------------------------------------------------
1 | from typer.testing import CliRunner
2 |
3 | from experiments.generated_cli import app
4 |
5 | runner = CliRunner()
6 |
7 |
8 | def test_generate_module():
9 | result = runner.invoke(app, ["generate_module"])
10 | assert result.exit_code == 0
11 | assert (
12 | "This is the generate_module command." in result.output
13 | ) # Replace with specific expected output
14 |
15 |
16 | def test_generate_signature():
17 | result = runner.invoke(app, ["generate_signature"])
18 | assert result.exit_code == 0
19 | assert (
20 | "This is the generate_signature command." in result.output
21 | ) # Replace with specific expected output
22 |
23 |
24 | def test_generate_chainofthought():
25 | result = runner.invoke(app, ["generate_chainofthought"])
26 | assert result.exit_code == 0
27 | assert (
28 | "This is the generate_chainofthought command." in result.output
29 | ) # Replace with specific expected output
30 |
31 |
32 | def test_generate_retrieve():
33 | result = runner.invoke(app, ["generate_retrieve"])
34 | assert result.exit_code == 0
35 | assert (
36 | "This is the generate_retrieve command." in result.output
37 | ) # Replace with specific expected output
38 |
39 |
40 | def test_generate_teleprompter():
41 | result = runner.invoke(app, ["generate_teleprompter"])
42 | assert result.exit_code == 0
43 | assert (
44 | "This is the generate_teleprompter command." in result.output
45 | ) # Replace with specific expected output
46 |
47 |
48 | def test_generate_example():
49 | result = runner.invoke(app, ["generate_example"])
50 | assert result.exit_code == 0
51 | assert (
52 | "This is the generate_example command." in result.output
53 | ) # Replace with specific expected output
54 |
55 |
56 | def test_generate_assertion():
57 | result = runner.invoke(app, ["generate_assertion"])
58 | assert result.exit_code == 0
59 | assert (
60 | "This is the generate_assertion command." in result.output
61 | ) # Replace with specific expected output
62 |
--------------------------------------------------------------------------------
/src/rdddy/generators/test_cli.py:
--------------------------------------------------------------------------------
1 | from typer.testing import CliRunner
2 |
3 | from experiments.generated_cli import app
4 |
5 | runner = CliRunner()
6 |
7 |
8 | def test_generate_module():
9 | result = runner.invoke(app, ["generate_module"])
10 | assert result.exit_code == 0
11 | assert (
12 | "This is the generate_module command." in result.output
13 | ) # Replace with specific expected output
14 |
15 |
16 | def test_generate_signature():
17 | result = runner.invoke(app, ["generate_signature"])
18 | assert result.exit_code == 0
19 | assert (
20 | "This is the generate_signature command." in result.output
21 | ) # Replace with specific expected output
22 |
23 |
24 | def test_generate_chainofthought():
25 | result = runner.invoke(app, ["generate_chainofthought"])
26 | assert result.exit_code == 0
27 | assert (
28 | "This is the generate_chainofthought command." in result.output
29 | ) # Replace with specific expected output
30 |
31 |
32 | def test_generate_retrieve():
33 | result = runner.invoke(app, ["generate_retrieve"])
34 | assert result.exit_code == 0
35 | assert (
36 | "This is the generate_retrieve command." in result.output
37 | ) # Replace with specific expected output
38 |
39 |
40 | def test_generate_teleprompter():
41 | result = runner.invoke(app, ["generate_teleprompter"])
42 | assert result.exit_code == 0
43 | assert (
44 | "This is the generate_teleprompter command." in result.output
45 | ) # Replace with specific expected output
46 |
47 |
48 | def test_generate_example():
49 | result = runner.invoke(app, ["generate_example"])
50 | assert result.exit_code == 0
51 | assert (
52 | "This is the generate_example command." in result.output
53 | ) # Replace with specific expected output
54 |
55 |
56 | def test_generate_assertion():
57 | result = runner.invoke(app, ["generate_assertion"])
58 | assert result.exit_code == 0
59 | assert (
60 | "This is the generate_assertion command." in result.output
61 | ) # Replace with specific expected output
62 |
--------------------------------------------------------------------------------
/src/experiments/test_generated_cli.py:
--------------------------------------------------------------------------------
1 | from typer.testing import CliRunner
2 |
3 | from experiments.generated_cli import app
4 |
5 | runner = CliRunner()
6 |
7 |
8 | def test_generate_module():
9 | result = runner.invoke(app, ["generate_module"])
10 | assert result.exit_code == 0
11 | assert (
12 | "This is the generate_module command." in result.output
13 | ) # Replace with specific expected output
14 |
15 |
16 | def test_generate_signature():
17 | result = runner.invoke(app, ["generate_signature"])
18 | assert result.exit_code == 0
19 | assert (
20 | "This is the generate_signature command." in result.output
21 | ) # Replace with specific expected output
22 |
23 |
24 | def test_generate_chainofthought():
25 | result = runner.invoke(app, ["generate_chainofthought"])
26 | assert result.exit_code == 0
27 | assert (
28 | "This is the generate_chainofthought command." in result.output
29 | ) # Replace with specific expected output
30 |
31 |
32 | def test_generate_retrieve():
33 | result = runner.invoke(app, ["generate_retrieve"])
34 | assert result.exit_code == 0
35 | assert (
36 | "This is the generate_retrieve command." in result.output
37 | ) # Replace with specific expected output
38 |
39 |
40 | def test_generate_teleprompter():
41 | result = runner.invoke(app, ["generate_teleprompter"])
42 | assert result.exit_code == 0
43 | assert (
44 | "This is the generate_teleprompter command." in result.output
45 | ) # Replace with specific expected output
46 |
47 |
48 | def test_generate_example():
49 | result = runner.invoke(app, ["generate_example"])
50 | assert result.exit_code == 0
51 | assert (
52 | "This is the generate_example command." in result.output
53 | ) # Replace with specific expected output
54 |
55 |
56 | def test_generate_assertion():
57 | result = runner.invoke(app, ["generate_assertion"])
58 | assert result.exit_code == 0
59 | assert (
60 | "This is the generate_assertion command." in result.output
61 | ) # Replace with specific expected output
62 |
--------------------------------------------------------------------------------
/src/experiments/ror_dspy.py:
--------------------------------------------------------------------------------
1 | import typer
2 |
3 | app = typer.Typer()
4 |
5 |
6 | @app.command(name="new")
7 | def new():
8 | """Create a new DSPy project with a default directory structure and configuration."""
9 | # Command logic goes here
10 | print("This is the new command.")
11 |
12 |
13 | @app.command(name="generate")
14 | def generate():
15 | """Generate new components within your DSPy project (e.g., modules, datasets, models)."""
16 | # Command logic goes here
17 | print("This is the generate command.")
18 |
19 |
20 | @app.command(name="server")
21 | def server():
22 | """Start a local server for developing and testing your DSPy application."""
23 | # Command logic goes here
24 | print("This is the server command.")
25 |
26 |
27 | @app.command(name="test")
28 | def test():
29 | """Run tests on your DSPy application, including model evaluations and data validations."""
30 | # Command logic goes here
31 | print("This is the test command.")
32 |
33 |
34 | @app.command(name="deploy")
35 | def deploy():
36 | """Deploy your DSPy application to various environments (development, testing, production)."""
37 | # Command logic goes here
38 | print("This is the deploy command.")
39 |
40 |
41 | @app.command(name="db")
42 | def db():
43 | """Database operations, such as migrations, seeding, and schema loading."""
44 | # Command logic goes here
45 | print("This is the db command.")
46 |
47 |
48 | @app.command(name="data")
49 | def data():
50 | """Manage your datasets, including import, export, and version control."""
51 | # Command logic goes here
52 | print("This is the data command.")
53 |
54 |
55 | @app.command(name="eval")
56 | def eval():
57 | """Evaluate your models or entire pipelines with custom or predefined metrics."""
58 | # Command logic goes here
59 | print("This is the eval command.")
60 |
61 |
62 | @app.command(name="help")
63 | def help():
64 | """Displays help information about the available commands."""
65 | # Command logic goes here
66 | print("This is the help command.")
67 |
68 |
69 | if __name__ == "__main__":
70 | app()
71 |
--------------------------------------------------------------------------------
/src/experiments/output_signature.py:
--------------------------------------------------------------------------------
1 | import dspy
2 |
3 |
4 | class GenJinjaSignature(dspy.Signature):
5 | """This signature transforms source code into Jinja templates, adhering to best practices for template creation.
6 | It is designed to take a source code snippet, analyze its structure, and produce a corresponding Jinja template.
7 | The output template will be well-structured, maintain readability, and include verbose instructions for clarity.
8 |
9 | Best practices incorporated include clear variable naming, usage of control structures for dynamic content,
10 | ample documentation within the template, and maintaining a structure that mirrors the source while allowing for
11 | flexibility and scalability in template rendering.
12 | """
13 |
14 | source = dspy.InputField(
15 | prefix="Convert to a Jinja Template: ",
16 | desc="The source code snippet to be converted into a Jinja template. The source should be a valid Python code structure, such as a class or a function, that you wish to render dynamically using Jinja.",
17 | )
18 | jinja_template = dspy.OutputField(
19 | prefix="```jinja\n",
20 | desc="The Jinja template generated from the provided source. This template will embody best practices in template creation, ensuring clarity, maintainability, and ease of use. The template will include dynamic placeholders, control statements, and documentation comments as necessary.",
21 | )
22 |
23 |
24 | SOURCE = '''class GenerateSearchQuery(dspy.Signature):
25 | """Write a simple search query that will help answer a complex question."""
26 |
27 | context = dspy.InputField(desc="may contain relevant facts")
28 | question = dspy.InputField()
29 | query = dspy.OutputField()
30 |
31 | ### inside your program's __init__ function
32 | self.generate_answer = dspy.ChainOfThought(GenerateSearchQuery)'''
33 |
34 |
35 | def main():
36 | lm = dspy.OpenAI(max_tokens=500)
37 | dspy.settings.configure(lm=lm)
38 | cot = dspy.ChainOfThought(GenJinjaSignature)
39 | template = cot.forward(source=SOURCE).jinja_template
40 | print(template)
41 |
42 |
43 | if __name__ == "__main__":
44 | main()
45 |
--------------------------------------------------------------------------------
/src/rdddy/generators/gen_signature.py:
--------------------------------------------------------------------------------
1 | from jinja2 import Template
2 |
3 | import dspy
4 | from rdddy.generators.gen_pydantic_instance import GenPydanticInstance
5 | from rdddy.signature_factory import (
6 | InputFieldTemplateSpecModel,
7 | OutputFieldTemplateSpecModel,
8 | SignatureTemplateSpecModel,
9 | )
10 |
11 |
12 | def render_signature_class(model, template_str):
13 | template = Template(template_str)
14 | rendered_class = template.render(model=model)
15 | return rendered_class
16 |
17 |
18 | def write_signature_class_to_file(class_str, file_name):
19 | with open(file_name, "w") as file:
20 | file.write(class_str)
21 |
22 |
23 | # Example usage
24 | signature_model_instance = ... # Your SignatureModel instance
25 | template_str = '''import dspy
26 |
27 | class {{ model.name }}(dspy.Signature):
28 | """
29 | {{ model.instructions }}
30 | """
31 | {% for field in model.input_fields %}
32 | {{ field.name }} = dspy.InputField({%- if field.prefix %} prefix="{{ field.prefix }}", {%- endif %} desc="{{ field.desc }}")
33 | {% endfor %}
34 | {% for field in model.output_fields %}
35 | {{ field.name }} = dspy.OutputField({%- if field.prefix %} prefix="{{ field.prefix }}", {%- endif %} desc="{{ field.desc }}")
36 | {% endfor %}
37 | '''
38 |
39 |
40 | def main():
41 | lm = dspy.OpenAI(max_tokens=1000)
42 | dspy.settings.configure(lm=lm)
43 |
44 | sig_prompt = "I need a signature called GenPythonClass that allows input of 'prompt', and output 'source'. The signature needs to create python classes from the prompt."
45 |
46 | sig_module = GenPydanticInstance(
47 | root_model=SignatureTemplateSpecModel,
48 | child_models=[InputFieldTemplateSpecModel, OutputFieldTemplateSpecModel],
49 | )
50 |
51 | sig_inst = sig_module.forward(sig_prompt)
52 | print(f'prompt:\n{lm.history[0].get("prompt")}')
53 | print(f'response:\n{lm.history[0]["response"].choices[0]["text"]}')
54 | rendered_class_str = render_signature_class(sig_inst, template_str)
55 | write_signature_class_to_file(rendered_class_str, "output_signature.py")
56 |
57 |
58 | if __name__ == "__main__":
59 | main()
60 |
--------------------------------------------------------------------------------
/src/rdddy/generators/contact_model.py:
--------------------------------------------------------------------------------
1 | from datetime import datetime
2 |
3 | from pydantic import *
4 |
5 |
6 | class ContactModel(BaseModel):
7 | """A Pydantic model representing a contact in the friend of a friend ontology."""
8 |
9 | name: str = Field(
10 | default="",
11 | title="",
12 | description="The name of the contact.",
13 | min_length=2,
14 | max_length=50,
15 | )
16 | email: EmailStr = Field(
17 | default=...,
18 | title="",
19 | description="The email address of the contact.",
20 | min_length=5,
21 | max_length=50,
22 | )
23 | phone_number: str = Field(
24 | default="",
25 | title="",
26 | description="The phone number of the contact.",
27 | min_length=10,
28 | max_length=15,
29 | )
30 | address: str = Field(
31 | default="",
32 | title="",
33 | description="The address of the contact.",
34 | min_length=10,
35 | max_length=100,
36 | )
37 | birthday: datetime = Field(
38 | default=...,
39 | title="",
40 | description="The birthday of the contact.",
41 | ge=1900,
42 | le=2021,
43 | )
44 | relationship: str = Field(
45 | default="",
46 | title="",
47 | description="The relationship of the contact to the user.",
48 | min_length=2,
49 | max_length=50,
50 | )
51 | notes: str = Field(
52 | default="",
53 | title="",
54 | description="Any additional notes or information about the contact.",
55 | max_length=500,
56 | )
57 | social_media: str = Field(
58 | default="",
59 | title="",
60 | description="The social media accounts of the contact.",
61 | max_length=100,
62 | )
63 | company: str = Field(
64 | default="",
65 | title="",
66 | description="The company the contact works for.",
67 | min_length=2,
68 | max_length=50,
69 | )
70 | job_title: str = Field(
71 | default="",
72 | title="",
73 | description="The job title of the contact.",
74 | min_length=2,
75 | max_length=50,
76 | )
77 |
--------------------------------------------------------------------------------
/src/rdddy/generators/gen_module.py:
--------------------------------------------------------------------------------
1 | import logging # Import the logging module
2 | from typing import Optional
3 |
4 | from dspy import ChainOfThought, Module, OpenAI, settings
5 |
6 | logger = logging.getLogger(__name__) # Create a logger instance
7 | logger.setLevel(
8 | logging.ERROR
9 | ) # Set the logger's level to ERROR or the appropriate level
10 |
11 |
12 | class GenModule(Module):
13 | def __init__(self, output_key, input_keys: Optional[list[str]] = None, lm=None):
14 | if lm is None:
15 | lm = OpenAI(max_tokens=500)
16 | settings.configure(lm=lm)
17 |
18 | if input_keys is None:
19 | self.input_keys = ["prompt"]
20 | else:
21 | self.input_keys = input_keys
22 |
23 | super().__init__()
24 |
25 | self.output_key = output_key
26 |
27 | # Define the generation and correction queries based on generation_type
28 | self.signature = ", ".join(self.input_keys) + f" -> {self.output_key}"
29 | self.correction_signature = (
30 | ", ".join(self.input_keys) + f", error -> {self.output_key}"
31 | )
32 |
33 | # DSPy modules for generation and correction
34 | self.generate = ChainOfThought(self.signature)
35 | self.correct_generate = ChainOfThought(self.correction_signature)
36 |
37 | def forward(self, **kwargs):
38 | # Generate the output using provided inputs
39 | gen_result = self.generate(**kwargs)
40 | output = gen_result.get(self.output_key)
41 |
42 | # Try validating the output
43 | try:
44 | return self.validate_output(output)
45 | except (AssertionError, ValueError, TypeError) as error:
46 | logger.error(error)
47 | logger.error(output)
48 | # Correction attempt
49 | corrected_result = self.correct_generate(**kwargs, error=str(error))
50 | corrected_output = corrected_result.get(self.output_key)
51 | return self.validate_output(corrected_output)
52 |
53 | def validate_output(self, output):
54 | # Implement validation logic or override in subclass
55 | raise NotImplementedError("Validation logic should be implemented in subclass")
56 |
--------------------------------------------------------------------------------
/src/rdddy/generators/ical/valarm_model.py:
--------------------------------------------------------------------------------
1 | from datetime import datetime
2 |
3 | from pydantic import *
4 |
5 |
6 | class VALARMModel(BaseModel):
7 | """A Pydantic model for RFC 5545 compliance."""
8 |
9 | action: str = Field(
10 | default=None, title="", description="The action associated with the alarm."
11 | )
12 | trigger: str = Field(
13 | default=None, title="", description="The trigger for the alarm."
14 | )
15 | duration: str = Field(
16 | default=None, title="", description="The duration of the alarm."
17 | )
18 | repeat: int = Field(
19 | default=None,
20 | title="",
21 | description="The number of times the alarm should be repeated.",
22 | ge=0,
23 | )
24 | description: str = Field(
25 | default=None, title="", description="A description of the alarm."
26 | )
27 | summary: str = Field(default=None, title="", description="A summary of the alarm.")
28 | attendees: list[str] = Field(
29 | default=None, title="", description="A list of attendees for the alarm."
30 | )
31 | acknowledged: datetime = Field(
32 | default=None,
33 | title="",
34 | description="The date and time the alarm was acknowledged.",
35 | )
36 | related_to: str = Field(
37 | default=None, title="", description="The related event or to-do for the alarm."
38 | )
39 | uid: str = Field(
40 | default=None, title="", description="The unique identifier for the alarm."
41 | )
42 | created: datetime = Field(
43 | default=None, title="", description="The date and time the alarm was created."
44 | )
45 | last_modified: datetime = Field(
46 | default=None,
47 | title="",
48 | description="The date and time the alarm was last modified.",
49 | )
50 | sequence: int = Field(
51 | default=None, title="", description="The sequence number for the alarm.", ge=0
52 | )
53 | x_prop: str = Field(
54 | default=None,
55 | title="",
56 | description="Any additional custom properties for the alarm.",
57 | )
58 | attach: list[str] = Field(
59 | default=None, title="", description="A list of attachments for the alarm."
60 | )
61 |
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | # https://pre-commit.com
2 | default_install_hook_types: [commit-msg, pre-commit]
3 | default_stages: [commit, manual]
4 | fail_fast: true
5 | repos:
6 | - repo: meta
7 | hooks:
8 | - id: check-useless-excludes
9 | - repo: https://github.com/pre-commit/pygrep-hooks
10 | rev: v1.10.0
11 | hooks:
12 | - id: python-check-mock-methods
13 | - id: python-use-type-annotations
14 | - id: rst-backticks
15 | - id: rst-directive-colons
16 | - id: rst-inline-touching-normal
17 | - id: text-unicode-replacement-char
18 | - repo: https://github.com/pre-commit/pre-commit-hooks
19 | rev: v4.5.0
20 | hooks:
21 | - id: check-added-large-files
22 | - id: check-ast
23 | - id: check-builtin-literals
24 | - id: check-case-conflict
25 | - id: check-docstring-first
26 | - id: check-json
27 | - id: check-merge-conflict
28 | - id: check-shebang-scripts-are-executable
29 | - id: check-symlinks
30 | - id: check-toml
31 | - id: check-vcs-permalinks
32 | - id: check-xml
33 | - id: check-yaml
34 | - id: debug-statements
35 | - id: destroyed-symlinks
36 | - id: detect-private-key
37 | - id: end-of-file-fixer
38 | types: [python]
39 | - id: fix-byte-order-marker
40 | - id: mixed-line-ending
41 | - id: name-tests-test
42 | args: [--pytest-test-first]
43 | - id: trailing-whitespace
44 | types: [python]
45 | - repo: local
46 | hooks:
47 | - id: ruff-check
48 | name: ruff check
49 | entry: ruff check
50 | args: ["--force-exclude", "--extend-fixable=F401,F841", "--fix-only"]
51 | require_serial: true
52 | language: system
53 | types_or: [python, pyi]
54 | - id: ruff-format
55 | name: ruff format
56 | entry: ruff format
57 | args: [--force-exclude]
58 | require_serial: true
59 | language: system
60 | types_or: [python, pyi]
61 | - id: poetry-check
62 | name: poetry check
63 | entry: poetry check
64 | language: system
65 | pass_filenames: false
66 | - id: mypy
67 | name: mypy
68 | entry: mypy
69 | language: system
70 | types: [python]
71 |
--------------------------------------------------------------------------------
/tests/test_ror_dspy.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from typer.testing import CliRunner
3 | from experiments.ror_dspy import app
4 |
5 | runner = CliRunner()
6 |
7 |
8 | def test_new():
9 | result = runner.invoke(app, ["new"])
10 | assert result.exit_code == 0
11 | assert (
12 | "This is the new command." in result.output
13 | ) # Replace with specific expected output
14 |
15 |
16 | def test_generate():
17 | result = runner.invoke(app, ["generate"])
18 | assert result.exit_code == 0
19 | assert (
20 | "This is the generate command." in result.output
21 | ) # Replace with specific expected output
22 |
23 |
24 | def test_server():
25 | result = runner.invoke(app, ["server"])
26 | assert result.exit_code == 0
27 | assert (
28 | "This is the server command." in result.output
29 | ) # Replace with specific expected output
30 |
31 |
32 | def test_test():
33 | result = runner.invoke(app, ["test"])
34 | assert result.exit_code == 0
35 | assert (
36 | "This is the test command." in result.output
37 | ) # Replace with specific expected output
38 |
39 |
40 | def test_deploy():
41 | result = runner.invoke(app, ["deploy"])
42 | assert result.exit_code == 0
43 | assert (
44 | "This is the deploy command." in result.output
45 | ) # Replace with specific expected output
46 |
47 |
48 | def test_db():
49 | result = runner.invoke(app, ["db"])
50 | assert result.exit_code == 0
51 | assert (
52 | "This is the db command." in result.output
53 | ) # Replace with specific expected output
54 |
55 |
56 | def test_data():
57 | result = runner.invoke(app, ["data"])
58 | assert result.exit_code == 0
59 | assert (
60 | "This is the data command." in result.output
61 | ) # Replace with specific expected output
62 |
63 |
64 | def test_eval():
65 | result = runner.invoke(app, ["eval"])
66 | assert result.exit_code == 0
67 | assert (
68 | "This is the eval command." in result.output
69 | ) # Replace with specific expected output
70 |
71 |
72 | def test_help():
73 | result = runner.invoke(app, ["help"])
74 | assert result.exit_code == 0
75 | assert (
76 | "This is the help command." in result.output
77 | ) # Replace with specific expected output
78 |
--------------------------------------------------------------------------------
/src/rdddy/thought/graph_of_thought.py:
--------------------------------------------------------------------------------
1 | from typing import Optional
2 |
3 | import dspy
4 | from pydantic import BaseModel, Field
5 |
6 | from dspy import Module
7 | # from experiments.web.mer import create_mermaid
8 | from rdddy.generators.gen_pydantic_instance import GenPydanticInstance
9 |
10 |
11 | class GraphNode(BaseModel):
12 | id: str = Field(..., description="Unique identifier for the node")
13 | content: str = Field(
14 | ..., description="Content or question associated with the node"
15 | )
16 | answer: Optional[str] = Field(
17 | None, description="Answer or result of the node's reasoning step"
18 | )
19 |
20 |
21 | class GraphEdge(BaseModel):
22 | source_id: str = Field(..., description="Source node ID")
23 | target_id: str = Field(..., description="Target node ID")
24 | relationship: str = Field(
25 | ..., description="Description of the relationship or reasoning link"
26 | )
27 |
28 |
29 | class GraphOfThoughtModel(BaseModel):
30 | nodes: list[GraphNode] = Field(..., description="List of nodes in the graph")
31 | edges: list[GraphEdge] = Field(..., description="List of edges linking the nodes")
32 |
33 |
34 | class GraphOfThought(Module):
35 | def __init__(self):
36 | super().__init__()
37 |
38 | def forward(self, prompt) -> GraphOfThoughtModel:
39 | return GenPydanticInstance(
40 | root_model=GraphOfThoughtModel, child_models=[GraphNode, GraphEdge]
41 | ).forward(prompt)
42 |
43 |
44 | def main():
45 | lm = dspy.OpenAI(max_tokens=1000)
46 | dspy.settings.configure(lm=lm)
47 |
48 | # prompt = (
49 | # "Decision Model Notation for cancer diagnosis in a 5 step circle with branches"
50 | # )
51 |
52 | prompt = "BPMN for ordering a sandwich"
53 | # prompt = "Explain the water cycle step by step."
54 |
55 | result_graph = GraphOfThought().forward(prompt)
56 | print(result_graph)
57 |
58 |
59 | if __name__ == "__main__":
60 | main()
61 |
62 |
63 | # import asyncio
64 |
65 |
66 | # async def main():
67 | # prompt = (
68 | # "Imagine the interactible elements of the Linkedin homepage"
69 | # )
70 | #
71 | # result = await create_mermaid(prompt)
72 | #
73 | # print(result)
74 |
75 |
76 | # if __name__ == "__main__":
77 | # asyncio.run(main())
78 |
--------------------------------------------------------------------------------
/.devcontainer/devcontainer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rdddy",
3 | "dockerComposeFile": "../docker-compose.yml",
4 | "service": "devcontainer",
5 | "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}/",
6 | "remoteUser": "user",
7 | "overrideCommand": true,
8 | "postStartCommand": "cp --update /opt/build/poetry/poetry.lock /workspaces/${localWorkspaceFolderBasename}/ && mkdir -p /workspaces/${localWorkspaceFolderBasename}/.git/hooks/ && cp --update /opt/build/git/* /workspaces/${localWorkspaceFolderBasename}/.git/hooks/",
9 | "customizations": {
10 | "vscode": {
11 | "extensions": [
12 | "charliermarsh.ruff",
13 | "ms-python.mypy-type-checker",
14 | "ms-python.python",
15 | "ryanluker.vscode-coverage-gutters",
16 | "tamasfe.even-better-toml",
17 | "visualstudioexptteam.vscodeintellicode"
18 | ],
19 | "settings": {
20 | "coverage-gutters.coverageFileNames": [
21 | "reports/coverage.xml"
22 | ],
23 | "editor.codeActionsOnSave": {
24 | "source.fixAll": true,
25 | "source.organizeImports": true
26 | },
27 | "editor.formatOnSave": true,
28 | "[python]": {
29 | "editor.defaultFormatter": "charliermarsh.ruff"
30 | },
31 | "[toml]": {
32 | "editor.formatOnSave": false
33 | },
34 | "editor.rulers": [
35 | 100
36 | ],
37 | "files.autoSave": "onFocusChange",
38 | "mypy-type-checker.importStrategy": "fromEnvironment",
39 | "python.defaultInterpreterPath": "/opt/rdddy-env/bin/python",
40 | "python.terminal.activateEnvironment": false,
41 | "python.testing.pytestEnabled": true,
42 | "ruff.importStrategy": "fromEnvironment",
43 | "terminal.integrated.defaultProfile.linux": "zsh",
44 | "terminal.integrated.profiles.linux": {
45 | "zsh": {
46 | "path": "/usr/bin/zsh"
47 | }
48 | }
49 | }
50 | }
51 | }
52 | }
--------------------------------------------------------------------------------
/src/rdddy/generators/ical/vfreebusy_model.py:
--------------------------------------------------------------------------------
1 | from datetime import datetime
2 |
3 | from pydantic import *
4 |
5 |
6 | class VFREEBUSYModel(BaseModel):
7 | """A Pydantic model for RFC 5545 VFREEBUSY compliance."""
8 |
9 | dtstart: datetime = Field(
10 | default=...,
11 | title="",
12 | description="The start date and time for the VFREEBUSY period.",
13 | )
14 | dtend: datetime = Field(
15 | default=...,
16 | title="",
17 | description="The end date and time for the VFREEBUSY period.",
18 | )
19 | dtstamp: datetime = Field(
20 | default=...,
21 | title="",
22 | description="The date and time when the VFREEBUSY was created.",
23 | )
24 | organizer: str = Field(
25 | default="", title="", description="The organizer of the VFREEBUSY period."
26 | )
27 | uid: str = Field(
28 | default="",
29 | title="",
30 | description="The unique identifier for the VFREEBUSY period.",
31 | )
32 | url: str = Field(
33 | default="", title="", description="The URL for the VFREEBUSY period."
34 | )
35 | freebusy: str = Field(
36 | default="",
37 | title="",
38 | description="The free or busy time periods for the VFREEBUSY period.",
39 | )
40 | attendee: str = Field(
41 | default="", title="", description="The attendees for the VFREEBUSY period."
42 | )
43 | comment: str = Field(
44 | default="",
45 | title="",
46 | description="Any comments or notes for the VFREEBUSY period.",
47 | )
48 | contact: str = Field(
49 | default="",
50 | title="",
51 | description="The contact information for the VFREEBUSY period.",
52 | )
53 | request_status: str = Field(
54 | default="", title="", description="The status of the VFREEBUSY request."
55 | )
56 | sequence: int = Field(
57 | default=0,
58 | title="",
59 | description="The sequence number for the VFREEBUSY period.",
60 | )
61 | x_prop: str = Field(
62 | default="",
63 | title="",
64 | description="Any additional properties for the VFREEBUSY period.",
65 | )
66 | x_component: str = Field(
67 | default="",
68 | title="",
69 | description="Any additional components for the VFREEBUSY period.",
70 | )
71 |
--------------------------------------------------------------------------------
/src/rdddy/generators/ical/vjournal_model.py:
--------------------------------------------------------------------------------
1 | from datetime import datetime
2 |
3 | from pydantic import *
4 |
5 |
6 | class VJOURNALModel(BaseModel):
7 | """A Pydantic model for RFC 5545 VJOURNAL compliance."""
8 |
9 | dtstamp: datetime = Field(
10 | default=None,
11 | title="",
12 | description="The date and time stamp for the creation of the VJOURNAL.",
13 | required=True,
14 | )
15 | uid: str = Field(
16 | default=None,
17 | title="",
18 | description="A unique identifier for the VJOURNAL.",
19 | required=True,
20 | )
21 | dtstart: datetime = Field(
22 | default=None,
23 | title="",
24 | description="The start date and time for the VJOURNAL.",
25 | required=True,
26 | )
27 | summary: str = Field(
28 | default=None, title="", description="A summary of the VJOURNAL.", required=True
29 | )
30 | description: str = Field(
31 | default=None, title="", description="A detailed description of the VJOURNAL."
32 | )
33 | location: str = Field(
34 | default=None, title="", description="The location of the VJOURNAL."
35 | )
36 | categories: list[str] = Field(
37 | default=None, title="", description="A list of categories for the VJOURNAL."
38 | )
39 | status: str = Field(
40 | default=None, title="", description="The status of the VJOURNAL."
41 | )
42 | priority: int = Field(
43 | default=None, title="", description="The priority of the VJOURNAL.", ge=0, le=9
44 | )
45 | url: str = Field(
46 | default=None, title="", description="A URL associated with the VJOURNAL."
47 | )
48 | created: datetime = Field(
49 | default=None,
50 | title="",
51 | description="The creation date and time of the VJOURNAL.",
52 | )
53 | last_modified: datetime = Field(
54 | default=None,
55 | title="",
56 | description="The last modified date and time of the VJOURNAL.",
57 | )
58 | organizer: str = Field(
59 | default=None, title="", description="The organizer of the VJOURNAL."
60 | )
61 | attendees: list[str] = Field(
62 | default=None, title="", description="A list of attendees for the VJOURNAL."
63 | )
64 | related_to: str = Field(
65 | default=None, title="", description="A related event or task for the VJOURNAL."
66 | )
67 |
--------------------------------------------------------------------------------
/src/typetemp/template/render_mixin.py:
--------------------------------------------------------------------------------
1 | import os
2 | from typing import Any
3 |
4 | from ..environment.typed_environment import environment
5 | from ..environment.typed_native_environment import native_environment
6 | from ..template.render_funcs import render_str
7 |
8 |
9 | class RenderMixin:
10 | """A mixin class that encapsulates the render and _render_vars functionality.
11 | This class checks for the required properties 'source', 'env', 'to', and 'output'.
12 | """
13 |
14 | def _render(self, use_native=False, **kwargs) -> Any:
15 | """Render the template. Excludes instance variables that
16 | are not callable (i.e., methods) and don't start with "__".
17 | """
18 | env = native_environment if use_native else environment
19 | template = env.from_string(self.source)
20 |
21 | render_dict = {**self._render_vars(), **kwargs}
22 |
23 | self.output = template.render(**render_dict)
24 |
25 | # Render the "to" property if it's defined
26 | if self.to == "stdout":
27 | print(self.output)
28 | elif self.to:
29 | to_template = env.from_string(self.to)
30 | rendered_to = os.path.join(to_template.render(**render_dict))
31 |
32 | # Create the directory if it doesn't exist
33 | print(rendered_to)
34 |
35 | if not rendered_to.startswith(".") or not rendered_to.startswith("/"):
36 | rendered_to = "./" + str(rendered_to)
37 |
38 | os.makedirs(os.path.dirname(rendered_to), exist_ok=True)
39 |
40 | with open(rendered_to, "w") as file:
41 | file.write(self.output)
42 |
43 | return self.output
44 |
45 | def _render_vars(self) -> dict[str, Any]:
46 | """Get the instance variables (not including methods or dunder methods)."""
47 | # copy the self dict
48 | properties = self.__class__.__dict__.copy()
49 | properties.update(self.__dict__.copy())
50 | del properties["source"]
51 |
52 | # If the value of a property is a TypedTemplate, render it
53 | for name, value in properties.items():
54 | if isinstance(value, RenderMixin):
55 | properties[name] = value._render(**properties)
56 | elif isinstance(value, str):
57 | properties[name] = render_str(value, **properties)
58 |
59 | return properties
60 |
--------------------------------------------------------------------------------
/src/rdddy/thought/of_thought_api.py:
--------------------------------------------------------------------------------
1 | import inspect
2 |
3 | import dspy
4 | from rdddy.generators.gen_pydantic_instance import GenPydanticInstance
5 |
6 | lm = dspy.OpenAI(max_tokens=500)
7 | dspy.settings.configure(lm=lm)
8 |
9 |
10 | import json
11 | from typing import Any, Optional
12 |
13 | from pydantic import BaseModel, Field
14 |
15 | from rdddy.generators.gen_python_primitive import GenStr
16 |
17 | cli_description = """
18 |
19 | Service: Get Current Weather
20 | Action: Retrieve
21 | Path: /weather/current
22 | Description: Fetches the latest weather information.
23 | Parameters: { "location": "Specify a location as text" }
24 | Output: Provides a JSON-based weather report with all the details.
25 |
26 | """
27 |
28 |
29 | class APIEndpoint(BaseModel):
30 | method: str = Field(..., description="HTTP method of the API endpoint")
31 | url: str = Field(..., description="URL of the API endpoint")
32 | description: str = Field(
33 | ..., description="Description of what the API endpoint does"
34 | )
35 | response: str = Field(..., description="Response from the API endpoint")
36 | query_params: Optional[dict[str, Any]] = Field(None, description="Query parameters")
37 |
38 |
39 | def main():
40 | generate_answer = dspy.ChainOfThought("model, prompt -> model_dict")
41 |
42 | # result = generate_answer(model=inspect.getsource(APIEndpoint), prompt=cli_description)
43 |
44 | # print(result.model_dict)
45 |
46 | # cli_data = APIEndpoint.model_validate_json(result.model_dict)
47 |
48 | generate_answer = dspy.ChainOfThought(
49 | f"model, prompt -> {APIEndpoint.__name__.lower()}_dict"
50 | )
51 |
52 | result = generate_answer(
53 | model=inspect.getsource(APIEndpoint), prompt=cli_description
54 | )
55 |
56 | print(result.get(f"{APIEndpoint.__name__.lower()}_dict"))
57 |
58 | cli_data = APIEndpoint.model_validate_json(
59 | result.get(f"{APIEndpoint.__name__.lower()}_dict")
60 | )
61 |
62 | endpoint_name = GenStr()(cli_description + "\nEndpoint URL")
63 |
64 | # endpoint_names = GenList()(cli_description + "\nEndpoint Names?")
65 |
66 | dot = GenPydanticInstance(root_model=APIEndpoint, child_models=[APIEndpoint])
67 |
68 | api_dict = dot.forward(cli_description)
69 |
70 | print(json.dumps(api_dict, indent=2))
71 |
72 | cli_data = APIEndpoint(**api_dict)
73 |
74 | print(cli_data)
75 |
76 |
77 | if __name__ == "__main__":
78 | main()
79 |
--------------------------------------------------------------------------------
/frontend/src/component/Dictaphone.js:
--------------------------------------------------------------------------------
1 | "use client";
2 | import React, { useState } from "react";
3 | import "regenerator-runtime/runtime";
4 |
5 | import SpeechRecognition, {
6 | useSpeechRecognition,
7 | } from "react-speech-recognition";
8 |
9 | import AceEditor from "react-ace"; // Import AceEditor
10 |
11 | import "brace/mode/python"; // Load Python language mode
12 | import "brace/theme/monokai"; // Load a theme (optional)
13 |
14 | const Dictaphone = () => {
15 | const {
16 | transcript,
17 | listening,
18 | resetTranscript,
19 | browserSupportsSpeechRecognition,
20 | } = useSpeechRecognition();
21 |
22 | // We declare state variable to save the response from server
23 | const [serverResponse, setServerResponse] = useState(null);
24 | const [pythonCode, setPythonCode] = useState(null); // State for the code editor
25 |
26 | const sendTranscript = async () => {
27 | const response = await fetch("/receive_transcript", {
28 | method: "POST",
29 | headers: {
30 | "Content-Type": "application/json",
31 | },
32 | body: JSON.stringify({ transcript }),
33 | });
34 |
35 | if (response.ok) {
36 | const data = await response.json();
37 | console.log(data.message); // Log the response from your server
38 |
39 | // Set the server response to the state variable
40 | console.log("Setting message", data.message);
41 | setServerResponse(data.message);
42 | setPythonCode(data.message);
43 | } else {
44 | console.error("Error sending transcript");
45 | }
46 | };
47 |
48 | return (
49 |
50 |
Microphone: {listening ? "on" : "off"}
51 |
52 |
53 |
54 |
55 |
{transcript}
56 |
57 | {/* Display the server response */}
58 | {/*{serverResponse &&