├── src ├── autospider │ ├── __init__.py │ ├── main.py │ └── messages.py ├── experiments │ ├── PyModule.log │ ├── __init__.py │ ├── actor │ │ ├── __init__.py │ │ ├── dashboard generator │ │ │ └── about.ejs.t │ │ ├── query │ │ │ ├── list_books.py │ │ │ ├── get_order_details.py │ │ │ └── check_order_status.py │ │ ├── event │ │ │ ├── order_placed.py │ │ │ ├── inventory_updated.py │ │ │ ├── payment_processed.py │ │ │ ├── order_history_page_loaded.py │ │ │ ├── supplier_inventory_update.py │ │ │ ├── checkout_form_submitted.py │ │ │ ├── order_placed_integration_event.py │ │ │ ├── supplier_inventory_confirmation.py │ │ │ ├── add_to_cart_button_click.py │ │ │ ├── external_payment_confirmation.py │ │ │ ├── inventory_updated_integration_event.py │ │ │ └── payment_processed_integration_event.py │ │ ├── command │ │ │ ├── place_order.py │ │ │ ├── process_payment.py │ │ │ └── update_inventory.py │ │ ├── abstract_task │ │ │ ├── validate_order.py │ │ │ ├── calculate_shipping_costs.py │ │ │ └── send_order_confirmation_email.py │ │ ├── abstract_view │ │ │ ├── book_list_view.py │ │ │ ├── order_details_view.py │ │ │ └── customer_profile_view.py │ │ ├── order │ │ │ └── __init__.py │ │ ├── abstract_policy │ │ │ ├── refund_policy.py │ │ │ ├── shipping_policy.py │ │ │ └── order_cancellation_policy.py │ │ ├── abstract_saga │ │ │ ├── book_restock_saga.py │ │ │ ├── order_fulfillment_saga.py │ │ │ └── payment_processing_saga.py │ │ ├── abstract_value_object │ │ │ ├── price.py │ │ │ ├── address.py │ │ │ └── quantity.py │ │ ├── abstract_aggregate │ │ │ ├── book_aggregate.py │ │ │ ├── order_aggregate.py │ │ │ └── customer_aggregate.py │ │ ├── domain_exception │ │ │ ├── order_not_found_exception.py │ │ │ ├── book_out_of_stock_exception.py │ │ │ └── payment_declined_exception.py │ │ ├── abstract_read_model │ │ │ ├── book_catalog_read_model.py │ │ │ ├── order_summary_read_model.py │ │ │ └── customer_order_history_read_model.py │ │ ├── template.ejs.t │ │ ├── assertion.log │ │ ├── messages.py │ │ └── hygen_cot.py │ ├── example │ │ ├── __init__.py │ │ ├── assertion.log │ │ ├── query │ │ │ ├── list_books.py │ │ │ ├── get_order_details.py │ │ │ └── check_order_status.py │ │ ├── domain_exception │ │ │ ├── payment_declined_exception.py │ │ │ ├── order_not_found_exception.py │ │ │ └── book_out_of_stock_exception.py │ │ ├── event │ │ │ ├── payment_processed.py │ │ │ ├── order_placed.py │ │ │ ├── supplier_inventory_update.py │ │ │ ├── order_history_page_loaded.py │ │ │ ├── inventory_updated.py │ │ │ ├── add_to_cart_button_click.py │ │ │ ├── external_payment_confirmation.py │ │ │ ├── checkout_form_submitted.py │ │ │ ├── inventory_updated_integration_event.py │ │ │ ├── supplier_inventory_confirmation.py │ │ │ ├── order_placed_integration_event.py │ │ │ └── payment_processed_integration_event.py │ │ ├── abstract_view │ │ │ ├── customer_profile_view.py │ │ │ ├── order_details_view.py │ │ │ └── book_list_view.py │ │ ├── command │ │ │ ├── process_payment.py │ │ │ ├── place_order.py │ │ │ └── update_inventory.py │ │ ├── abstract_policy │ │ │ ├── shipping_policy.py │ │ │ ├── refund_policy.py │ │ │ └── order_cancellation_policy.py │ │ ├── abstract_task │ │ │ ├── send_order_confirmation_email.py │ │ │ ├── validate_order.py │ │ │ └── calculate_shipping_costs.py │ │ ├── abstract_saga │ │ │ ├── payment_processing_saga.py │ │ │ ├── order_fulfillment_saga.py │ │ │ └── book_restock_saga.py │ │ ├── abstract_value_object │ │ │ ├── price.py │ │ │ ├── quantity.py │ │ │ └── address.py │ │ ├── abstract_aggregate │ │ │ ├── customer_aggregate.py │ │ │ ├── book_aggregate.py │ │ │ └── order_aggregate.py │ │ └── abstract_read_model │ │ │ ├── book_catalog_read_model.py │ │ │ ├── customer_order_history_read_model.py │ │ │ └── order_summary_read_model.py │ ├── leetcode │ │ ├── __init__.py │ │ ├── solution_model2.py │ │ ├── solved.py │ │ └── solution_model.py │ ├── low_api │ │ ├── __init__.py │ │ └── requirement_model.py │ ├── ping_pong_module.py │ ├── pyproject_tools.py │ ├── create_yaml.py │ ├── create_pydantic.py │ ├── synth_results.py │ ├── generated_classes.py │ ├── web │ │ └── yaml_converter.py │ ├── actor_template.py │ ├── abstract_aggregate.py │ ├── workshop_messages.py │ ├── gen_api.py │ ├── generated_cli.py │ ├── rag_gen_messages.py │ ├── workshop_aggregate.py │ ├── test_cli.py │ ├── test_generated_cli.py │ ├── ror_dspy.py │ ├── output_signature.py │ ├── gen_cmd.py │ └── sqlmodel_crud_tools.py ├── rdddy │ ├── generators │ │ ├── __init__.py │ │ ├── openai_usage.log │ │ ├── output_signature.py │ │ ├── fastapi_route.py │ │ ├── gen_state.py │ │ ├── templates │ │ │ └── module_template.j2 │ │ ├── test_cli.py │ │ ├── gen_signature.py │ │ ├── contact_model.py │ │ ├── gen_module.py │ │ └── ical │ │ │ ├── valarm_model.py │ │ │ ├── vfreebusy_model.py │ │ │ ├── vjournal_model.py │ │ │ ├── vavailability_model.py │ │ │ └── vtodo_model.py │ ├── signatures │ │ ├── assertion.log │ │ ├── question_answering.py │ │ ├── product_recommendation.py │ │ ├── openai_usage.log │ │ ├── risk_assessment.py │ │ ├── sales_prediction.py │ │ ├── inventory_optimization.py │ │ ├── market_segmentation.py │ │ ├── employee_performance_evaluation.py │ │ ├── customer_feedback_analysis.py │ │ └── code_interview_solver.py │ ├── __init__.py │ ├── app.py │ ├── browser │ │ └── run_chatgpt.py │ ├── thought │ │ ├── openai_usage.log │ │ ├── typer_cli.py │ │ ├── graph_of_thought.py │ │ └── of_thought_api.py │ ├── abstract_view.py │ ├── domain_exception.py │ ├── abstract_task.py │ ├── abstract_value_object.py │ ├── abstract_saga.py │ ├── abstract_repository.py │ ├── abstract_policy.py │ ├── api.py │ ├── async_typer.py │ ├── assertion.log │ ├── abstract_aggregate.py │ └── hello_world_module.py ├── typetemp │ ├── template │ │ ├── __init__.py │ │ ├── python │ │ ├── typed_template.py │ │ ├── render_funcs.py │ │ ├── render_mixin.py │ │ ├── typed_prompt.py │ │ └── async_render_mixin.py │ ├── environment │ │ ├── __init__.py │ │ ├── typed_native_environment.py │ │ └── typed_environment.py │ ├── extension │ │ ├── __init__.py │ │ └── inflection_extension.py │ ├── __init__.py │ └── functional.py ├── elixir │ └── ping_pong │ │ ├── test │ │ ├── test_helper.exs │ │ └── ping_pong_test.exs │ │ ├── .formatter.exs │ │ ├── lib │ │ ├── ping_pong.ex │ │ └── ping_pong │ │ │ └── ping_pong_elixir.ex │ │ ├── README.md │ │ ├── .gitignore │ │ └── mix.exs ├── utils │ └── example.py └── practice │ ├── shortest_path_weighted_graph.py │ ├── lru_cache.py │ └── web_crawler.py ├── tests ├── __init__.py ├── test_import.py ├── test_api.py ├── actor │ ├── test_actor.py │ └── test_browser_process_supervisor.py ├── test_weighted_graph.py ├── test_lru_cache.py ├── dspy │ └── test_gen_python_primative_list.py └── test_ror_dspy.py ├── .dockerignore ├── frontend ├── .eslintrc.json ├── src │ ├── app │ │ ├── favicon.ico │ │ ├── page.js │ │ ├── layout.js │ │ └── globals.css │ └── component │ │ └── Dictaphone.js ├── jsconfig.json ├── postcss.config.js ├── next.config.mjs ├── .gitignore ├── tailwind.config.js ├── package.json ├── public │ ├── vercel.svg │ └── next.svg └── README.md ├── hello_world.py ├── .gitignore ├── summarize_text_module.py ├── new_module_5206162896.py ├── .github └── workflows │ ├── test.yml │ └── deploy.yml ├── .cruft.json ├── docker-compose.yml ├── .pre-commit-config.yaml ├── .devcontainer └── devcontainer.json └── assertion.log /src/autospider/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/experiments/PyModule.log: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/experiments/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/experiments/actor/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/rdddy/generators/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/typetemp/template/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/experiments/example/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/experiments/example/assertion.log: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/experiments/leetcode/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/experiments/low_api/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/rdddy/signatures/assertion.log: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/typetemp/environment/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/typetemp/extension/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/rdddy/__init__.py: -------------------------------------------------------------------------------- 1 | """rdddy package.""" 2 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | """rdddy test suite.""" 2 | -------------------------------------------------------------------------------- /src/elixir/ping_pong/test/test_helper.exs: -------------------------------------------------------------------------------- 1 | ExUnit.start() 2 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | # Caches 2 | .*_cache/ 3 | 4 | # Git 5 | .git/ 6 | -------------------------------------------------------------------------------- /frontend/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /src/experiments/actor/dashboard generator/about.ejs.t: -------------------------------------------------------------------------------- 1 | new action for about route -------------------------------------------------------------------------------- /frontend/src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seanchatmangpt/rdddy/HEAD/frontend/src/app/favicon.ico -------------------------------------------------------------------------------- /frontend/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "paths": { 4 | "@/*": ["./src/*"] 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /frontend/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /src/elixir/ping_pong/.formatter.exs: -------------------------------------------------------------------------------- 1 | # Used by "mix format" 2 | [ 3 | inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] 4 | ] 5 | -------------------------------------------------------------------------------- /src/utils/example.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | 3 | 4 | async def main(): 5 | print("main") 6 | # await 7 | 8 | 9 | if __name__ == "__main__": 10 | asyncio.run(main()) 11 | -------------------------------------------------------------------------------- /src/experiments/actor/query/list_books.py: -------------------------------------------------------------------------------- 1 | from rdddy.query import Query 2 | 3 | 4 | class ListBooks(Query): 5 | """Generated class for ListBooks, inheriting from Query.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/rdddy/app.py: -------------------------------------------------------------------------------- 1 | """Streamlit app.""" 2 | 3 | from importlib.metadata import version 4 | 5 | import streamlit as st 6 | 7 | st.title(f"rdddy v{version('rdddy')}") # type: ignore[no-untyped-call] 8 | -------------------------------------------------------------------------------- /src/rdddy/browser/run_chatgpt.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | 3 | 4 | async def main(): 5 | print("main") 6 | # await 7 | 8 | 9 | if __name__ == "__main__": 10 | asyncio.run(main()) 11 | -------------------------------------------------------------------------------- /src/experiments/actor/event/order_placed.py: -------------------------------------------------------------------------------- 1 | from rdddy.event import Event 2 | 3 | 4 | class OrderPlaced(Event): 5 | """Generated class for OrderPlaced, inheriting from Event.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /tests/test_import.py: -------------------------------------------------------------------------------- 1 | """Test rdddy.""" 2 | 3 | import rdddy 4 | 5 | 6 | def test_import() -> None: 7 | """Test that the package can be imported.""" 8 | assert isinstance(rdddy.__name__, str) 9 | -------------------------------------------------------------------------------- /src/experiments/actor/command/place_order.py: -------------------------------------------------------------------------------- 1 | from rdddy.command import Command 2 | 3 | 4 | class PlaceOrder(Command): 5 | """Generated class for PlaceOrder, inheriting from Command.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/elixir/ping_pong/test/ping_pong_test.exs: -------------------------------------------------------------------------------- 1 | defmodule PingPongTest do 2 | use ExUnit.Case 3 | doctest PingPong 4 | 5 | test "greets the world" do 6 | assert PingPong.hello() == :world 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /src/experiments/actor/query/get_order_details.py: -------------------------------------------------------------------------------- 1 | from rdddy.query import Query 2 | 3 | 4 | class GetOrderDetails(Query): 5 | """Generated class for GetOrderDetails, inheriting from Query.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/event/inventory_updated.py: -------------------------------------------------------------------------------- 1 | from rdddy.event import Event 2 | 3 | 4 | class InventoryUpdated(Event): 5 | """Generated class for InventoryUpdated, inheriting from Event.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/event/payment_processed.py: -------------------------------------------------------------------------------- 1 | from rdddy.event import Event 2 | 3 | 4 | class PaymentProcessed(Event): 5 | """Generated class for PaymentProcessed, inheriting from Event.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/query/check_order_status.py: -------------------------------------------------------------------------------- 1 | from rdddy.query import Query 2 | 3 | 4 | class CheckOrderStatus(Query): 5 | """Generated class for CheckOrderStatus, inheriting from Query.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/command/process_payment.py: -------------------------------------------------------------------------------- 1 | from rdddy.command import Command 2 | 3 | 4 | class ProcessPayment(Command): 5 | """Generated class for ProcessPayment, inheriting from Command.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/command/update_inventory.py: -------------------------------------------------------------------------------- 1 | from rdddy.command import Command 2 | 3 | 4 | class UpdateInventory(Command): 5 | """Generated class for UpdateInventory, inheriting from Command.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/event/order_history_page_loaded.py: -------------------------------------------------------------------------------- 1 | from rdddy.event import Event 2 | 3 | 4 | class OrderHistoryPageLoaded(Event): 5 | """Generated class for OrderHistoryPageLoaded, inheriting from Event.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/event/supplier_inventory_update.py: -------------------------------------------------------------------------------- 1 | from rdddy.event import Event 2 | 3 | 4 | class SupplierInventoryUpdate(Event): 5 | """Generated class for SupplierInventoryUpdate, inheriting from Event.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/abstract_task/validate_order.py: -------------------------------------------------------------------------------- 1 | from rdddy.abstract_task import AbstractTask 2 | 3 | 4 | class ValidateOrder(AbstractTask): 5 | """Generated class for ValidateOrder, inheriting from AbstractTask.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/abstract_view/book_list_view.py: -------------------------------------------------------------------------------- 1 | from rdddy.abstract_view import AbstractView 2 | 3 | 4 | class BookListView(AbstractView): 5 | """Generated class for BookListView, inheriting from AbstractView.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/order/__init__.py: -------------------------------------------------------------------------------- 1 | from rdddy.abstract_saga import AbstractSaga 2 | 3 | 4 | class OrderFulfillmentSaga(AbstractSaga): 5 | """Generated class for OrderFulfillmentSaga, inheriting from AbstractSaga.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/abstract_policy/refund_policy.py: -------------------------------------------------------------------------------- 1 | from rdddy.abstract_policy import AbstractPolicy 2 | 3 | 4 | class RefundPolicy(AbstractPolicy): 5 | """Generated class for RefundPolicy, inheriting from AbstractPolicy.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/abstract_saga/book_restock_saga.py: -------------------------------------------------------------------------------- 1 | from rdddy.abstract_saga import AbstractSaga 2 | 3 | 4 | class BookRestockSaga(AbstractSaga): 5 | """Generated class for BookRestockSaga, inheriting from AbstractSaga.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/abstract_view/order_details_view.py: -------------------------------------------------------------------------------- 1 | from rdddy.abstract_view import AbstractView 2 | 3 | 4 | class OrderDetailsView(AbstractView): 5 | """Generated class for OrderDetailsView, inheriting from AbstractView.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/event/checkout_form_submitted.py: -------------------------------------------------------------------------------- 1 | from rdddy.messages import AbstractEvent 2 | 3 | 4 | class CheckoutFormSubmitted(AbstractEvent): 5 | """Generated class for CheckoutFormSubmitted, inheriting from Event.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/event/order_placed_integration_event.py: -------------------------------------------------------------------------------- 1 | from rdddy.event import Event 2 | 3 | 4 | class OrderPlacedIntegrationEvent(Event): 5 | """Generated class for OrderPlacedIntegrationEvent, inheriting from Event.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/abstract_policy/shipping_policy.py: -------------------------------------------------------------------------------- 1 | from rdddy.abstract_policy import AbstractPolicy 2 | 3 | 4 | class ShippingPolicy(AbstractPolicy): 5 | """Generated class for ShippingPolicy, inheriting from AbstractPolicy.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/abstract_value_object/price.py: -------------------------------------------------------------------------------- 1 | from rdddy.abstract_value_object import AbstractValueObject 2 | 3 | 4 | class Price(AbstractValueObject): 5 | """Generated class for Price, inheriting from AbstractValueObject.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/event/supplier_inventory_confirmation.py: -------------------------------------------------------------------------------- 1 | from rdddy.event import Event 2 | 3 | 4 | class SupplierInventoryConfirmation(Event): 5 | """Generated class for SupplierInventoryConfirmation, inheriting from Event.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/rdddy/generators/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/chat/completions "HTTP/1.1 200 OK" 4 | -------------------------------------------------------------------------------- /src/experiments/actor/abstract_value_object/address.py: -------------------------------------------------------------------------------- 1 | from rdddy.abstract_value_object import AbstractValueObject 2 | 3 | 4 | class Address(AbstractValueObject): 5 | """Generated class for Address, inheriting from AbstractValueObject.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/abstract_view/customer_profile_view.py: -------------------------------------------------------------------------------- 1 | from rdddy.abstract_view import AbstractView 2 | 3 | 4 | class CustomerProfileView(AbstractView): 5 | """Generated class for CustomerProfileView, inheriting from AbstractView.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/event/add_to_cart_button_click.py: -------------------------------------------------------------------------------- 1 | from rdddy.event import Event 2 | 3 | 4 | class AddToCartButtonClick(Event): 5 | """Generated class for AddToCartButtonClick, inheriting from Event.""" 6 | book -> cart (add command) 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/abstract_aggregate/book_aggregate.py: -------------------------------------------------------------------------------- 1 | from rdddy.abstract_aggregate import AbstractAggregate 2 | 3 | 4 | class BookAggregate(AbstractAggregate): 5 | """Generated class for BookAggregate, inheriting from AbstractAggregate.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/abstract_saga/order_fulfillment_saga.py: -------------------------------------------------------------------------------- 1 | from rdddy.abstract_saga import AbstractSaga 2 | 3 | 4 | class OrderFulfillmentSaga(AbstractSaga): 5 | """Generated class for OrderFulfillmentSaga, inheriting from AbstractSaga.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/abstract_saga/payment_processing_saga.py: -------------------------------------------------------------------------------- 1 | from rdddy.abstract_saga import AbstractSaga 2 | 3 | 4 | class PaymentProcessingSaga(AbstractSaga): 5 | """Generated class for PaymentProcessingSaga, inheriting from AbstractSaga.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/abstract_value_object/quantity.py: -------------------------------------------------------------------------------- 1 | from rdddy.abstract_value_object import AbstractValueObject 2 | 3 | 4 | class Quantity(AbstractValueObject): 5 | """Generated class for Quantity, inheriting from AbstractValueObject.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/event/external_payment_confirmation.py: -------------------------------------------------------------------------------- 1 | from rdddy.messages import AbstractEvent 2 | 3 | 4 | class ExternalPaymentConfirmation(AbstractEvent): 5 | """Generated class for ExternalPaymentConfirmation, inheriting from Event.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/event/inventory_updated_integration_event.py: -------------------------------------------------------------------------------- 1 | from rdddy.event import Event 2 | 3 | 4 | class InventoryUpdatedIntegrationEvent(Event): 5 | """Generated class for InventoryUpdatedIntegrationEvent, inheriting from Event.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/event/payment_processed_integration_event.py: -------------------------------------------------------------------------------- 1 | from rdddy.event import Event 2 | 3 | 4 | class PaymentProcessedIntegrationEvent(Event): 5 | """Generated class for PaymentProcessedIntegrationEvent, inheriting from Event.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/typetemp/template/python: -------------------------------------------------------------------------------- 1 | hello world -m smart_template --hygen-vars {"hello": "world"} --to my-project/readme.md --from- shared/docs/readme.md --force --unless-exists --inject --after devDependencies --skip-if myPackage --sh echo 'Hello this is a shell command!'''' 2 | -------------------------------------------------------------------------------- /src/experiments/actor/abstract_aggregate/order_aggregate.py: -------------------------------------------------------------------------------- 1 | from rdddy.abstract_aggregate import AbstractAggregate 2 | 3 | 4 | class OrderAggregate(AbstractAggregate): 5 | """Generated class for OrderAggregate, inheriting from AbstractAggregate.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/abstract_task/calculate_shipping_costs.py: -------------------------------------------------------------------------------- 1 | from rdddy.abstract_task import AbstractTask 2 | 3 | 4 | class CalculateShippingCosts(AbstractTask): 5 | """Generated class for CalculateShippingCosts, inheriting from AbstractTask.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/abstract_aggregate/customer_aggregate.py: -------------------------------------------------------------------------------- 1 | from rdddy.abstract_aggregate import AbstractAggregate 2 | 3 | 4 | class CustomerAggregate(AbstractAggregate): 5 | """Generated class for CustomerAggregate, inheriting from AbstractAggregate.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/abstract_policy/order_cancellation_policy.py: -------------------------------------------------------------------------------- 1 | from rdddy.abstract_policy import AbstractPolicy 2 | 3 | 4 | class OrderCancellationPolicy(AbstractPolicy): 5 | """Generated class for OrderCancellationPolicy, inheriting from AbstractPolicy.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/abstract_task/send_order_confirmation_email.py: -------------------------------------------------------------------------------- 1 | from rdddy.abstract_task import AbstractTask 2 | 3 | 4 | class SendOrderConfirmationEmail(AbstractTask): 5 | """Generated class for SendOrderConfirmationEmail, inheriting from AbstractTask.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/domain_exception/order_not_found_exception.py: -------------------------------------------------------------------------------- 1 | from rdddy.domain_exception import DomainException 2 | 3 | 4 | class OrderNotFoundException(DomainException): 5 | """Generated class for OrderNotFoundException, inheriting from DomainException.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/abstract_read_model/book_catalog_read_model.py: -------------------------------------------------------------------------------- 1 | from rdddy.abstract_read_model import AbstractReadModel 2 | 3 | 4 | class BookCatalogReadModel(AbstractReadModel): 5 | """Generated class for BookCatalogReadModel, inheriting from AbstractReadModel.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/domain_exception/book_out_of_stock_exception.py: -------------------------------------------------------------------------------- 1 | from rdddy.domain_exception import DomainException 2 | 3 | 4 | class BookOutOfStockException(DomainException): 5 | """Generated class for BookOutOfStockException, inheriting from DomainException.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/domain_exception/payment_declined_exception.py: -------------------------------------------------------------------------------- 1 | from rdddy.domain_exception import DomainException 2 | 3 | 4 | class PaymentDeclinedException(DomainException): 5 | """Generated class for PaymentDeclinedException, inheriting from DomainException.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/abstract_read_model/order_summary_read_model.py: -------------------------------------------------------------------------------- 1 | from rdddy.abstract_read_model import AbstractReadModel 2 | 3 | 4 | class OrderSummaryReadModel(AbstractReadModel): 5 | """Generated class for OrderSummaryReadModel, inheriting from AbstractReadModel.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/experiments/actor/abstract_read_model/customer_order_history_read_model.py: -------------------------------------------------------------------------------- 1 | from rdddy.abstract_read_model import AbstractReadModel 2 | 3 | 4 | class CustomerOrderHistoryReadModel(AbstractReadModel): 5 | """Generated class for CustomerOrderHistoryReadModel, inheriting from AbstractReadModel.""" 6 | 7 | pass 8 | -------------------------------------------------------------------------------- /src/elixir/ping_pong/lib/ping_pong.ex: -------------------------------------------------------------------------------- 1 | defmodule PingPong do 2 | @moduledoc """ 3 | Documentation for `PingPong`. 4 | """ 5 | 6 | @doc """ 7 | Hello world. 8 | 9 | ## Examples 10 | 11 | iex> PingPong.hello() 12 | :world 13 | 14 | """ 15 | def hello do 16 | :world 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /src/rdddy/generators/output_signature.py: -------------------------------------------------------------------------------- 1 | import dspy 2 | 3 | 4 | class GenPythonClass(dspy.Signature): 5 | """This signature creates python classes from the prompt.""" 6 | 7 | prompt = dspy.InputField(desc="The prompt used to generate python classes.") 8 | 9 | source = dspy.OutputField(desc="The generated python classes.") 10 | -------------------------------------------------------------------------------- /src/experiments/actor/template.ejs.t: -------------------------------------------------------------------------------- 1 | --- 2 | to: src/components/<%= name %>.js 3 | --- 4 | 5 | import React, { useState } from 'react'; 6 | 7 | const <%= name %> = (props) => { 8 | const [state, setState] = useState(); 9 | 10 | return ( 11 |
12 | {/* Component code here */} 13 |
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 &&

Server response: {serverResponse}

}*/} 59 | {pythonCode && ( 60 | setPythonCode(newCode)} // Update state on changes 64 | value={pythonCode} 65 | name="python-code-editor" 66 | editorProps={{ $blockScrolling: true }} 67 | width="100%" // Adjust the width as needed 68 | /> 69 | )} 70 |
71 | ); 72 | }; 73 | export default Dictaphone; 74 | -------------------------------------------------------------------------------- /src/typetemp/template/typed_prompt.py: -------------------------------------------------------------------------------- 1 | from typing import Union 2 | 3 | from typetemp.template.render_mixin import RenderMixin 4 | from utils.complete import create 5 | 6 | 7 | class TypedPrompt(RenderMixin): 8 | """This class extends TypedTemplate to incorporate a TypedPrompt functionality 9 | along with the Chat class for conversational capabilities. 10 | 11 | - user_input: Stores the input from the user. 12 | - chat_inst: An instance of the Chat class for conversational capabilities. 13 | - output: Holds the output returned from the Chat class. 14 | - sys_msg: A system message to indicate the role of this instance. 15 | - model: The model version to be used in the Chat class. Default is "3". 16 | """ 17 | 18 | source: str = "" # The string template to be rendered 19 | user_input: str = "" # Input from the user 20 | output: str = "" # To hold the output from the chat 21 | sys_msg: str = "You are a prompt AI assistant." # System message to define the role 22 | model: str = "3i" # Model version for the Chat class, default is "3" 23 | to: str = "" # Output medium for the output 24 | 25 | def __init__(self, **kwargs): 26 | self.__dict__.update(kwargs) 27 | 28 | def __call__(self, use_native=False, **kwargs) -> Union[str, dict]: 29 | """This method is invoked when the class instance is called. It performs the following: 30 | 1. Calls the _render() method from the mixin class TypedTemplate to generate a rendered prompt. 31 | 2. Passes the rendered prompt to the Chat instance for user interaction. 32 | 3. Saves and optionally prints the output from the Chat instance. 33 | 34 | **kwargs: Keyword arguments for replacing variables in the template. 35 | """ 36 | # Render the prompt using _render() from TypedTemplate 37 | rendered_prompt = self._render(use_native, **kwargs) 38 | 39 | # Pass the rendered prompt to the Chat instance for OpenAI interaction 40 | self.output = create(prompt=rendered_prompt, model=self.model) 41 | 42 | return self.output 43 | 44 | 45 | if __name__ == "__main__": 46 | # Instantiate TypedPrompt class 47 | typed_prompt = TypedPrompt( 48 | source="Hello, I am {{ name }}! How are you doing today?\n\nHello, I am an AGI and I feel ", 49 | to="stdout", 50 | ) 51 | 52 | # Call the instance to render the prompt and interact with the user 53 | user_input = typed_prompt(name="John Doe") 54 | 55 | print(f"User input: {user_input}") # Print the collected user input 56 | -------------------------------------------------------------------------------- /src/rdddy/generators/ical/vavailability_model.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | 3 | from pydantic import * 4 | 5 | 6 | class VAVAILABILITYModel(BaseModel): 7 | """A Pydantic model for RFC 5545 compliance.""" 8 | 9 | dtstart: datetime = Field( 10 | default=None, 11 | title="", 12 | description="The start date and time of the event.", 13 | required=True, 14 | ) 15 | dtend: datetime = Field( 16 | default=None, 17 | title="", 18 | description="The end date and time of the event.", 19 | required=True, 20 | ) 21 | summary: str = Field( 22 | default=None, 23 | title="", 24 | description="A brief summary or title of the event.", 25 | max_length=255, 26 | ) 27 | description: str = Field( 28 | default=None, title="", description="A detailed description of the event." 29 | ) 30 | location: str = Field( 31 | default=None, title="", description="The location of the event." 32 | ) 33 | rrule: str = Field( 34 | default=None, title="", description="A recurrence rule for the event." 35 | ) 36 | exdate: datetime = Field( 37 | default=None, 38 | title="", 39 | description="A list of dates to exclude from the recurrence rule.", 40 | ) 41 | uid: str = Field( 42 | default=None, 43 | title="", 44 | description="A unique identifier for the event.", 45 | required=True, 46 | ) 47 | created: datetime = Field( 48 | default=None, title="", description="The date and time the event was created." 49 | ) 50 | last_modified: datetime = Field( 51 | default=None, 52 | title="", 53 | description="The date and time the event was last modified.", 54 | ) 55 | sequence: int = Field( 56 | default=0, title="", description="The sequence number of the event.", ge=0 57 | ) 58 | status: str = Field( 59 | default="CONFIRMED", 60 | title="", 61 | description="The status of the event.", 62 | allowed_values=["CONFIRMED", "TENTATIVE", "CANCELLED"], 63 | ) 64 | organizer: str = Field( 65 | default=None, title="", description="The organizer of the event." 66 | ) 67 | attendees: list[str] = Field( 68 | default=None, title="", description="A list of attendees for the event." 69 | ) 70 | categories: list[str] = Field( 71 | default=None, title="", description="A list of categories for the event." 72 | ) 73 | url: str = Field(default=None, title="", description="A URL for the event.") 74 | -------------------------------------------------------------------------------- /src/rdddy/generators/ical/vtodo_model.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | 3 | from pydantic import * 4 | 5 | 6 | class VTODOModel(BaseModel): 7 | """A Pydantic model for RFC 5545 compliance.""" 8 | 9 | dtstamp: datetime = Field( 10 | default=None, 11 | title="", 12 | description="The date and time stamp for the creation of the VTODO.", 13 | required=True, 14 | ) 15 | uid: str = Field( 16 | default=None, 17 | title="", 18 | description="A unique identifier for the VTODO.", 19 | required=True, 20 | ) 21 | dtstart: datetime = Field( 22 | default=None, 23 | title="", 24 | description="The start date and time for the VTODO.", 25 | required=True, 26 | ) 27 | due: datetime = Field( 28 | default=None, 29 | title="", 30 | description="The due date and time for the VTODO.", 31 | required=True, 32 | ) 33 | summary: str = Field( 34 | default=None, title="", description="A summary of the VTODO.", required=True 35 | ) 36 | description: str = Field( 37 | default=None, title="", description="A detailed description of the VTODO." 38 | ) 39 | priority: int = Field( 40 | default=0, 41 | title="", 42 | description="The priority of the VTODO, with 0 being the lowest and 9 being the highest.", 43 | ge=0, 44 | le=9, 45 | ) 46 | status: str = Field( 47 | description="The status of the VTODO, with options such as 'NEEDS-ACTION', 'COMPLETED', or 'CANCELLED'." 48 | ) 49 | categories: list[str] = Field( 50 | default=None, title="", description="A list of categories for the VTODO." 51 | ) 52 | location: str = Field( 53 | default=None, title="", description="The location of the VTODO." 54 | ) 55 | url: str = Field( 56 | default=None, title="", description="A URL associated with the VTODO." 57 | ) 58 | rrule: str = Field( 59 | default=None, 60 | title="", 61 | description="A recurrence rule for the VTODO, specified as a string.", 62 | ) 63 | exdate: list[datetime] = Field( 64 | default=None, 65 | title="", 66 | description="A list of dates to exclude from the recurrence rule.", 67 | ) 68 | duration: str = Field( 69 | default=None, 70 | title="", 71 | description="The duration of the VTODO, specified as a string.", 72 | ) 73 | attach: list[str] = Field( 74 | default=None, title="", description="A list of attachments for the VTODO." 75 | ) 76 | -------------------------------------------------------------------------------- /assertion.log: -------------------------------------------------------------------------------- 1 | 2024-02-18 15:52:14,533 - dspy.primitives.assertions - ERROR - AssertionError: You need to create a kwargs dict for APIEndpoint 2 | 3 | Validation error: 4 | None 5 | 2024-02-18 15:52:14,533 - dspy.primitives.assertions - ERROR - AssertionError: You need to create a kwargs dict for APIEndpoint 6 | 7 | Validation error: 8 | None 9 | 2024-02-18 15:52:14,541 - dspy.primitives.assertions - ERROR - AssertionError: You need to create a valid python list primitive type for 10 | list_str_for_ast_literal_eval 11 | You will be penalized for not returning only a list for list_str_for_ast_literal_eval 12 | 2024-02-18 15:52:14,542 - dspy.primitives.assertions - ERROR - AssertionError: You need to create a valid python list primitive type for 13 | list_str_for_ast_literal_eval 14 | You will be penalized for not returning only a list for list_str_for_ast_literal_eval 15 | 2024-02-18 16:01:06,450 - dspy.primitives.assertions - ERROR - AssertionError: You need to create a kwargs dict for APIEndpoint 16 | 17 | Validation error: 18 | None 19 | 2024-02-18 16:01:06,452 - dspy.primitives.assertions - ERROR - AssertionError: You need to create a kwargs dict for APIEndpoint 20 | 21 | Validation error: 22 | None 23 | 2024-02-18 16:01:06,459 - dspy.primitives.assertions - ERROR - AssertionError: You need to create a valid python list primitive type for 24 | list_str_for_ast_literal_eval 25 | You will be penalized for not returning only a list for list_str_for_ast_literal_eval 26 | 2024-02-18 16:01:06,460 - dspy.primitives.assertions - ERROR - AssertionError: You need to create a valid python list primitive type for 27 | list_str_for_ast_literal_eval 28 | You will be penalized for not returning only a list for list_str_for_ast_literal_eval 29 | 2024-02-18 16:27:03,069 - dspy.primitives.assertions - ERROR - AssertionError: You need to create a kwargs dict for APIEndpoint 30 | 31 | Validation error: 32 | None 33 | 2024-02-18 16:27:03,070 - dspy.primitives.assertions - ERROR - AssertionError: You need to create a kwargs dict for APIEndpoint 34 | 35 | Validation error: 36 | None 37 | 2024-02-18 16:27:03,077 - dspy.primitives.assertions - ERROR - AssertionError: You need to create a valid python list primitive type for 38 | list_str_for_ast_literal_eval 39 | You will be penalized for not returning only a list for list_str_for_ast_literal_eval 40 | 2024-02-18 16:27:03,077 - dspy.primitives.assertions - ERROR - AssertionError: You need to create a valid python list primitive type for 41 | list_str_for_ast_literal_eval 42 | You will be penalized for not returning only a list for list_str_for_ast_literal_eval 43 | -------------------------------------------------------------------------------- /src/experiments/gen_cmd.py: -------------------------------------------------------------------------------- 1 | import pyperclip 2 | import typer 3 | 4 | from typetemp.template.render_funcs import render_str 5 | from utils.create_prompts import spr 6 | 7 | app = typer.Typer() 8 | 9 | 10 | class TemplateSpec: 11 | def __init__( 12 | self, 13 | name: str, 14 | prompt: str, 15 | max_tokens: int = 2000, 16 | output_format: str = "python", 17 | ): 18 | self.name = name 19 | self.prompt = prompt 20 | self.max_tokens = max_tokens 21 | self.output_format = output_format 22 | 23 | 24 | @app.command(help="Generate a SmartTemplate from a prompt.") 25 | def smart( 26 | name: str = typer.Option(..., "--name", "-n"), 27 | prompt: str = typer.Option(..., "--prompt", "-p"), 28 | output_format: str = typer.Option("python", "--output", "-o"), 29 | max_tokens: int = 2000, 30 | ): 31 | asyncio.run(_render_smart_template(name, prompt, max_tokens, output_format)) 32 | 33 | 34 | @app.command( 35 | help="Generate a TypedTemplate from a prompt. Can use the clipboard to copy the content." 36 | ) 37 | def static( 38 | name: str = typer.Option(..., "--name", "-n"), 39 | paste: bool = typer.Option(False, "--paste", is_flag=True), 40 | ): 41 | asyncio.run(_render_typed_template(name, paste)) 42 | 43 | 44 | async def _render_smart_template( 45 | name: str, prompt: str, max_tokens: int, output_format: str 46 | ): 47 | """Renders a SmartTemplate to the filesystem""" 48 | prompt = await spr( 49 | prompt=f"ChatGPT Assistant that {prompt}", 50 | encode=False, 51 | max_tokens=40, 52 | model="3i", 53 | ) 54 | 55 | template_name = render_str("{{ name | underscore }}_smart_template.py", name=name) 56 | 57 | # await smart_template_template.render( 58 | # name, 59 | # prompt=prompt, 60 | # # config=LLMConfig(max_tokens=max_tokens, model="chatgpt"), 61 | # output_format=output_format, 62 | # to=template_name, 63 | # ) 64 | 65 | typer.echo(f"Created {template_name}.") 66 | 67 | 68 | async def _render_typed_template(name, paste): 69 | """Renders a TypedTemplate to the filesystem""" 70 | template_name = render_str("{{ name | underscore }}_typed_template.py", name=name) 71 | 72 | if paste is not None: 73 | content = pyperclip.paste() 74 | else: 75 | content = None 76 | 77 | typer.echo(f"Created {template_name}.") 78 | 79 | 80 | import asyncio 81 | 82 | 83 | async def main(): 84 | await _render_smart_template("git_commit", "Short commit message", 20, "text") 85 | 86 | 87 | if __name__ == "__main__": 88 | asyncio.run(main()) 89 | -------------------------------------------------------------------------------- /tests/actor/test_browser_process_supervisor.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | from typing import cast 3 | from unittest.mock import MagicMock, patch 4 | 5 | import pytest 6 | 7 | from rdddy.actor_system import ActorSystem 8 | from rdddy.browser.browser_domain import * 9 | from rdddy.browser.browser_process_supervisor import BrowserProcessSupervisor 10 | 11 | 12 | class MockAsyncProcess: 13 | def __init__(self): 14 | self.returncode = None 15 | # self._populate_stderr() 16 | self._mock_stderr = MagicMock() 17 | self._mock_stderr.readline.side_effect = self._simulate_errors() 18 | 19 | def _simulate_errors(self): 20 | yield "Normal log line\n" 21 | yield "[ERROR] Simulated Error\n" 22 | while True: 23 | yield "" 24 | 25 | async def _populate_stderr(self): 26 | await self._mock_stderr.put("Normal log line\n") 27 | await self._mock_stderr.put("[ERROR] Simulated Error\n") 28 | # Simulate end of stream after error by not putting any more items 29 | 30 | async def communicate(self): 31 | return "", "" 32 | 33 | @property 34 | def stderr(self): 35 | return self 36 | 37 | async def readline(self): 38 | return await self._mock_stderr.get() 39 | 40 | def terminate(self): 41 | print("terminate") 42 | self.returncode = -1 43 | 44 | def poll(self): 45 | return self.returncode 46 | 47 | 48 | @pytest.fixture() 49 | def actor_system(event_loop): 50 | return ActorSystem(event_loop) 51 | 52 | 53 | @pytest.mark.asyncio() 54 | async def test_chrome_browser_restart(actor_system): 55 | mock_process = MockAsyncProcess() 56 | 57 | with patch("asyncio.create_subprocess_exec", return_value=mock_process): 58 | supervisor = await actor_system.actor_of(BrowserProcessSupervisor) 59 | 60 | await actor_system.publish(StartBrowserCommand()) 61 | 62 | # Allow time for the actor to process the logs and restart Chrome Browser 63 | await asyncio.sleep(0.1) # Adjust sleep time if necessary 64 | 65 | mock_process.terminate() 66 | 67 | message: BrowserStatusEvent = cast( 68 | BrowserStatusEvent, await actor_system.wait_for_message(BrowserStatusEvent) 69 | ) 70 | 71 | assert message.status == "dead" 72 | 73 | start_cmd = cast( 74 | StartBrowserCommand, 75 | await actor_system.wait_for_message(StartBrowserCommand), 76 | ) 77 | 78 | mock_process.returncode = None 79 | 80 | message = cast( 81 | BrowserStatusEvent, await actor_system.wait_for_message(BrowserStatusEvent) 82 | ) 83 | 84 | assert message.status == "alive" 85 | -------------------------------------------------------------------------------- /src/typetemp/template/async_render_mixin.py: -------------------------------------------------------------------------------- 1 | from typing import Any 2 | 3 | import anyio 4 | 5 | from typetemp.environment.typed_environment import async_environment 6 | from typetemp.environment.typed_native_environment import async_native_environment 7 | from typetemp.template.render_funcs import arender_str 8 | from utils.complete import acreate 9 | from utils.file_tools import write 10 | 11 | 12 | class AsyncRenderMixin: 13 | """An async mixin class that encapsulates the render and _render_vars functionality.""" 14 | 15 | def __init__(self): 16 | self.source = "" 17 | self.to = "" 18 | self.config = None 19 | 20 | async def _render(self, use_native=False, **kwargs) -> Any: 21 | """Render the template.""" 22 | self._env = async_native_environment if use_native else async_environment 23 | 24 | template = self._env.from_string( 25 | self.source 26 | ) # Assuming self.env is a jinja2.Environment 27 | 28 | render_dict = kwargs.copy() 29 | render_dict.update(await self._render_vars()) 30 | 31 | self.output = await template.render_async(**render_dict) 32 | # print("render output", self.output) 33 | 34 | await self._llm_call() 35 | 36 | if self.to == "stdout": 37 | print(self.output) 38 | elif self.to: 39 | # to_template = self._env.from_string(self.to) 40 | try: 41 | await write(self.output, filename=self.to) 42 | except FileNotFoundError as e: 43 | print("Did you include the correct path?") 44 | raise e 45 | 46 | return self.output 47 | 48 | async def _render_vars(self) -> dict[str, Any]: 49 | properties = self.__class__.__dict__.copy() 50 | properties.update(self.__dict__.copy()) 51 | # print(properties) 52 | 53 | async with anyio.create_task_group() as tg: 54 | for name, value in properties.items(): 55 | if isinstance(value, AsyncRenderMixin): 56 | tg.start_soon(self._concurrent_render, name, value, properties) 57 | elif isinstance(value, str): 58 | properties[name] = await arender_str(value) 59 | 60 | return properties 61 | 62 | async def _concurrent_render( 63 | self, name: str, value: "AsyncRenderMixin", properties: dict[str, Any] 64 | ): 65 | properties[name] = await value._render() 66 | 67 | async def _llm_call(self): 68 | """Use a LLM to render the template as a prompt.""" 69 | if self.config: 70 | # print(self.output) 71 | self.output = await acreate(prompt=self.output, config=self.config) 72 | -------------------------------------------------------------------------------- /src/experiments/sqlmodel_crud_tools.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | import os 3 | from contextlib import contextmanager 4 | 5 | from sqlalchemy import create_engine 6 | from sqlmodel import Session 7 | 8 | current_dir = os.path.dirname(os.path.abspath(__file__)) 9 | 10 | 11 | db_path = os.path.join(current_dir, "dev.db") 12 | 13 | DATABASE_URL = f"sqlite:///{db_path}" 14 | 15 | engine = create_engine(DATABASE_URL) 16 | 17 | 18 | def get_session(): 19 | return Session(engine) 20 | 21 | 22 | def get_model(model_cls, model_id): 23 | session = get_session() 24 | model = session.get(model_cls, model_id) 25 | return model 26 | 27 | 28 | def delete_model(model_cls, model_id): 29 | session = get_session() 30 | model = session.get(model_cls, model_id) 31 | if model: 32 | session.delete(model) 33 | 34 | doc_id = hashlib.sha256(str(model_id).encode()).hexdigest()[:20] 35 | # get_mem_store().delete( 36 | # collection_id=f"{model.__class__.__name__}_collection", doc_id=doc_id 37 | # ) 38 | 39 | session.commit() 40 | 41 | 42 | def add_model(model): 43 | session = get_session() # Assuming you have a function to get a database session 44 | try: 45 | session.add(model) # Add the provided model to the session 46 | session.commit() # Commit changes on success 47 | session.refresh(model) # Refresh the provided model 48 | 49 | # get_mem_store().add( 50 | # collection_id=f"{model.__class__.__name__}_collection", 51 | # document=json.dumps(model.dict(), default=str), 52 | # metadatas={"model_id": model.id}, 53 | # ) 54 | except Exception as e: 55 | session.rollback() # Rollback changes on failure 56 | raise e 57 | finally: 58 | session.close() 59 | 60 | 61 | @contextmanager 62 | def update_model(model_cls, model_id): 63 | session = get_session() # Assuming you have a function to get a database session 64 | try: 65 | existing_model = session.query(model_cls).get(model_id) 66 | if existing_model is None: 67 | raise ValueError(f"{model_cls.__name__} with ID {model_id} not found") 68 | 69 | yield existing_model 70 | 71 | doc_id = hashlib.sha256(str(model_id).encode()).hexdigest()[:20] 72 | # get_mem_store().update( 73 | # collection_id=f"{model_cls.__name__}_collection", 74 | # doc_ids=[doc_id], 75 | # documents=[json.dumps(existing_model.dict(), default=str)], 76 | # metadatas=[{"model_id": model_id}], 77 | # ) 78 | 79 | session.commit() 80 | except Exception as e: 81 | session.rollback() 82 | raise e 83 | finally: 84 | session.close() 85 | --------------------------------------------------------------------------------