diff --git a/services/llm-client/diplomat/http_client.py b/services/llm-client/diplomat/http_client.py index 21296d0..3ff2c72 100644 --- a/services/llm-client/diplomat/http_client.py +++ b/services/llm-client/diplomat/http_client.py @@ -14,7 +14,7 @@ def complete(rendered_prompt : RenderedPrompt): "url": f"data:image/jpeg;base64,{image}" } } for image in rendered_prompt.images] - + print(rendered_prompt.prompt) completion = client.chat.completions.create( model="gpt-4o-mini", messages=[ diff --git a/services/llm-client/migrations/scripts/003_insert_tick_shopping_items_prompt.py b/services/llm-client/migrations/scripts/003_insert_tick_shopping_items_prompt.py index f1084dd..6d9fdee 100644 --- a/services/llm-client/migrations/scripts/003_insert_tick_shopping_items_prompt.py +++ b/services/llm-client/migrations/scripts/003_insert_tick_shopping_items_prompt.py @@ -6,7 +6,7 @@ def run_migration(session): VALUES('mark_shopping_items', 'You are an assistant that is helping the customer to mark items on their shopping list, you received a json containing the items with their respective ids, they are the products the customer need to buy, and an image with the items they added on the cart. You must only return a json, nothing more than it. -The list products that the customer has in his list will be presented to you in a json with the name and the id of each product: \{\{products\}\} +The list products that the customer has in his list will be presented to you in a json with the name and the id of each product: {{products}} You need to: diff --git a/services/llm-client/migrations/scripts/__pycache__/003_insert_tick_shopping_items_prompt.cpython-39.pyc b/services/llm-client/migrations/scripts/__pycache__/003_insert_tick_shopping_items_prompt.cpython-39.pyc index c6ffb7e..dc8ff0a 100644 Binary files a/services/llm-client/migrations/scripts/__pycache__/003_insert_tick_shopping_items_prompt.cpython-39.pyc and b/services/llm-client/migrations/scripts/__pycache__/003_insert_tick_shopping_items_prompt.cpython-39.pyc differ diff --git a/src/purchase_listinator/modules/shopping/adapters/in/cart.clj b/src/purchase_listinator/modules/shopping/adapters/in/cart.clj index c7c3da7..1c66ab4 100644 --- a/src/purchase_listinator/modules/shopping/adapters/in/cart.clj +++ b/src/purchase_listinator/modules/shopping/adapters/in/cart.clj @@ -1,9 +1,31 @@ (ns purchase-listinator.modules.shopping.adapters.in.cart (:require [purchase-listinator.modules.shopping.schemas.models.cart :as models.internal.cart] + [purchase-listinator.modules.shopping.schemas.models.cart-events :as internal.cart-events] + [purchase-listinator.modules.shopping.schemas.models.shopping-list :as models.internal.shopping-list] [purchase-listinator.modules.shopping.schemas.wires.in.cart :as wires.in.cart] [schema.core :as s])) (s/defn wire->internal :- models.internal.cart/Cart [wire :- wires.in.cart/Cart] - wire) \ No newline at end of file + wire) + +(s/defn ^:private item->change-item-event :- internal.cart-events/ChangeItemEvent + [{:keys [id quantity quantity-in-cart price ] } :- models.internal.shopping-list/ShoppingItem + {:keys [purchase-list-id user-id ] :as shopping} :- models.internal.shopping-list/ShoppingList + now :- s/Num] + {:id id + :moment now + :event-type :change-item + :user-id user-id + :shopping-id (:id shopping) + :item-id id + :price price + :quantity-changed (- quantity quantity-in-cart) + :purchase-list-id purchase-list-id}) + +(s/defn items->change-item-event :- [internal.cart-events/ChangeItemEvent] + [items :- [models.internal.shopping-list/ShoppingItem] + shopping :- models.internal.shopping-list/ShoppingList + now :- s/Num] + (map #(item->change-item-event % shopping now) items)) \ No newline at end of file diff --git a/src/purchase_listinator/modules/shopping/adapters/in/llm.clj b/src/purchase_listinator/modules/shopping/adapters/in/llm.clj index 2343419..0019485 100644 --- a/src/purchase_listinator/modules/shopping/adapters/in/llm.clj +++ b/src/purchase_listinator/modules/shopping/adapters/in/llm.clj @@ -1,11 +1,13 @@ (ns purchase-listinator.modules.shopping.adapters.in.llm (:require [clojure.data.json :as json] + [purchase-listinator.adapters.misc :as adapters.misc] [schema.core :as s] [purchase-listinator.modules.shopping.schemas.wires.in.llm :as shopping.schemas.wires.in.llm])) (s/defn wire->model :- [s/Uuid] [wire :- shopping.schemas.wires.in.llm/InteractionResponse] (when wire - (-> (:response wire) - (json/read-str)))) \ No newline at end of file + (->> (:response wire) + (json/read-str) + (map adapters.misc/string->uuid)))) \ No newline at end of file diff --git a/src/purchase_listinator/modules/shopping/core.clj b/src/purchase_listinator/modules/shopping/core.clj index 596ea2a..31499ad 100644 --- a/src/purchase_listinator/modules/shopping/core.clj +++ b/src/purchase_listinator/modules/shopping/core.clj @@ -41,13 +41,14 @@ :shopping/mongo (component/using (components.mongo/new-mongo-fake) [:config])}) (def request-routes - {:price-suggestion/items (or (System/getenv "PRICE_SUGGESTION_ITEMS_URL") "http://localhost:3000/api/price-suggestion/by/items") - :purchase-list/allowed-lists (or (System/getenv "PURCHASE_LIST_URL") "http://localhost:3000/api/lists/allowed") - :shopping-cart/receive-events (or (System/getenv "SHOPPING_CART_RECEIVE_EVENTS") "http://localhost:3000/api/shopping-cart/events") - :shopping-cart/init-cart (or (System/getenv "SHOPPING_CART_INITIATE_CART") "http://localhost:3000/api/shopping-cart/initiate") - :shopping-cart/cart (or (System/getenv "SHOPPING_CART_GET_CART") "http://localhost:3000/api/shopping-cart/by/:list-id/:shopping-id") - :shopping-cart/exclusive-cart (or (System/getenv "SHOPPING_CART_GET_EXCLUSIVE_CART") "http://localhost:3000/api/shopping-cart/exclusive-by/:list-id/:shopping-id") - :llm-client/interactions (or (System/getenv "LLM_CLIENT_INTERACTION") "http://localhost:3100/api/llm/interactions")}) + {:price-suggestion/items (or (System/getenv "PRICE_SUGGESTION_ITEMS_URL") "http://localhost:3000/api/price-suggestion/by/items") + :purchase-list/allowed-lists (or (System/getenv "PURCHASE_LIST_URL") "http://localhost:3000/api/lists/allowed") + :shopping-cart/receive-events (or (System/getenv "SHOPPING_CART_RECEIVE_EVENTS") "http://localhost:3000/api/shopping-cart/events") + :shopping-cart/receive-events-in-batch (or (System/getenv "SHOPPING_CART_RECEIVE_EVENTS_IN_BATCH") "http://localhost:3000/api/shopping-cart/batch-events") + :shopping-cart/init-cart (or (System/getenv "SHOPPING_CART_INITIATE_CART") "http://localhost:3000/api/shopping-cart/initiate") + :shopping-cart/cart (or (System/getenv "SHOPPING_CART_GET_CART") "http://localhost:3000/api/shopping-cart/by/:list-id/:shopping-id") + :shopping-cart/exclusive-cart (or (System/getenv "SHOPPING_CART_GET_EXCLUSIVE_CART") "http://localhost:3000/api/shopping-cart/exclusive-by/:list-id/:shopping-id") + :llm-client/interactions (or (System/getenv "LLM_CLIENT_INTERACTION") "http://localhost:3100/api/llm/interactions")}) (def system-config diff --git a/src/purchase_listinator/modules/shopping/diplomat/http/client.clj b/src/purchase_listinator/modules/shopping/diplomat/http/client.clj index 7cb471a..29e60e0 100644 --- a/src/purchase_listinator/modules/shopping/diplomat/http/client.clj +++ b/src/purchase_listinator/modules/shopping/diplomat/http/client.clj @@ -69,7 +69,20 @@ :result-schema wires.in.cart/Cart}) (adapters.in.cart/wire->internal))) -(s/defn post-interaction :- models.internal.cart/Cart +(s/defn post-cart-events-in-batch :- models.internal.cart/Cart + [shopping :- models.internal.shopping-list/ShoppingList + items :- [models.internal.shopping-list/ShoppingItem] + now :- s/Num + user-id :- s/Uuid + http :- components.http/IHttp] + (-> (components.http/request http {:method :post + :url :shopping-cart/receive-events-in-batch + :user-id user-id + :query-params (adapters.in.cart/items->change-item-event items shopping now) + :result-schema wires.in.cart/Cart}) + (adapters.in.cart/wire->internal))) + +(s/defn post-interaction :- (s/maybe [s/Uuid]) [request-id :- s/Uuid shopping :- models.internal.shopping-list/ShoppingList image :- s/Str diff --git a/src/purchase_listinator/modules/shopping/flows/shopping.clj b/src/purchase_listinator/modules/shopping/flows/shopping.clj index 7c67212..b4ec1ac 100644 --- a/src/purchase_listinator/modules/shopping/flows/shopping.clj +++ b/src/purchase_listinator/modules/shopping/flows/shopping.clj @@ -110,5 +110,9 @@ (let [allowed-lists-ids (http.client.shopping/get-allowed-lists user-id http) {:keys [list-id]} (datomic.shopping/get-by-id shopping-id allowed-lists-ids main-db) shopping (cart-module-management list-id user-id shopping-id http) - response (http.client.shopping/post-interaction request-id shopping image user-id http)] + item-ids (http.client.shopping/post-interaction request-id shopping image user-id http) + items-marked-by-ia (logic.shopping/get-items shopping item-ids) + now (misc.date/numb-now) + response (http.client.shopping/post-cart-events-in-batch shopping items-marked-by-ia now user-id http)] + (clojure.pprint/pprint response))) \ No newline at end of file diff --git a/src/purchase_listinator/modules/shopping/logic/shopping.clj b/src/purchase_listinator/modules/shopping/logic/shopping.clj index a5236f6..ac0a327 100644 --- a/src/purchase_listinator/modules/shopping/logic/shopping.clj +++ b/src/purchase_listinator/modules/shopping/logic/shopping.clj @@ -55,4 +55,10 @@ (s/defn finish :- models.internal.shopping/Shopping [shopping :- models.internal.shopping/Shopping] - (assoc shopping :status :done)) \ No newline at end of file + (assoc shopping :status :done)) + +(s/defn get-items :- [models.internal.shopping-item/ShoppingItem] + [shopping :- models.internal.shopping-list/ShoppingList + items-ids :- [s/Uuid]] + (->> (mapcat :items (:categories shopping)) + (filter #(contains? (set items-ids) (:id %))))) \ No newline at end of file diff --git a/src/purchase_listinator/modules/shopping/schemas/wires/out/shopping_cart_event.clj b/src/purchase_listinator/modules/shopping/schemas/wires/out/shopping_cart_event.clj new file mode 100644 index 0000000..bf3014b --- /dev/null +++ b/src/purchase_listinator/modules/shopping/schemas/wires/out/shopping_cart_event.clj @@ -0,0 +1,11 @@ +(ns purchase-listinator.modules.shopping.schemas.wires.out.shopping-cart-event + (:require [schema.core :as s])) + +(s/defschema ChangeItemEvent + {:event-id s/Str + :event-type s/Str + :shopping-id s/Str + :item-id s/Str + :purchase-list-id s/Str + :price s/Num + :quantity-changed s/Int}) \ No newline at end of file diff --git a/src/purchase_listinator/modules/shopping_cart/adapters/in/cart_events.clj b/src/purchase_listinator/modules/shopping_cart/adapters/in/cart_events.clj index fa54ee4..6a18ef6 100644 --- a/src/purchase_listinator/modules/shopping_cart/adapters/in/cart_events.clj +++ b/src/purchase_listinator/modules/shopping_cart/adapters/in/cart_events.clj @@ -47,4 +47,10 @@ :id (adapters.misc/string->uuid event-id) :moment moment :user-id user-id) - (dissoc :event-id))) \ No newline at end of file + (dissoc :event-id))) + +(s/defn batch-wire->list-internal :- [internal.cart-events/CartEvent] + [wire-list + moment :- s/Num + user-id :- s/Uuid] + (map #(wire->internal % moment user-id) wire-list)) \ No newline at end of file diff --git a/src/purchase_listinator/modules/shopping_cart/diplomat/http/server.clj b/src/purchase_listinator/modules/shopping_cart/diplomat/http/server.clj index 20749e3..77ea29a 100644 --- a/src/purchase_listinator/modules/shopping_cart/diplomat/http/server.clj +++ b/src/purchase_listinator/modules/shopping_cart/diplomat/http/server.clj @@ -56,10 +56,22 @@ cart-event (adapters.in.cart-events/wire->internal wire now user-id)] (flows.cart-events-reception/receive-cart-event-by-list cart-event component))))) +(s/defn receive-events-in-batch + [{component :component + wire-list :json-params + user-id :user-id}] + (misc.http/default-branch + (misc.either/try-right + (let [now (misc.date/numb-now) + user-id (adapters.misc/string->uuid user-id) + cart-events (adapters.in.cart-events/batch-wire->list-internal wire-list now user-id)] + (flows.cart-events-reception/receive-cart-event-in-batch-by-list cart-events component))))) + (def routes #{["/api/shopping-cart/version" :get [get-version] :route-name :get-shopping-cart-version] ["/api/shopping-cart/initiate" :post [start-cart] :route-name :post-start-cart] ["/api/shopping-cart/events" :post [receive-events] :route-name :receive-cart-events] + ["/api/shopping-cart/batch-events" :post [receive-events-in-batch] :route-name :receive-cart-events-in-batch] ["/api/shopping-cart/by/:list-id/:shopping-id" :get [get-cart] :route-name :get-cart] ["/api/shopping-cart/exclusive-by/:list-id/:shopping-id" :get [get-exclusive-cart] :route-name :get-exclusive-cart]}) diff --git a/src/purchase_listinator/modules/shopping_cart/flows/cart_events_reception.clj b/src/purchase_listinator/modules/shopping_cart/flows/cart_events_reception.clj index dfcbfbf..3c54d1a 100644 --- a/src/purchase_listinator/modules/shopping_cart/flows/cart_events_reception.clj +++ b/src/purchase_listinator/modules/shopping_cart/flows/cart_events_reception.clj @@ -15,3 +15,9 @@ (println e) (throw e))) event) + +(s/defn receive-cart-event-in-batch-by-list + [events :- [internal.cart-events/CartEvent] + {:keys [shopping-cart/redis]}] + (map #(receive-cart-event-by-list % redis) events) + events)