From 5ddf9d83efd399d30fcba528203e7882005575e3 Mon Sep 17 00:00:00 2001 From: Christian Weilbach Date: Fri, 12 Apr 2024 21:01:50 +0000 Subject: [PATCH] Add HTTP server and prototype interface. --- .gitignore | 1 + README.md | 9 --- deps.edn | 1 + resources/public/index.html | 91 ++++++++++++++++++++++++ resources/public/simmie.png | Bin 0 -> 5099 bytes src/ie/simm/http.clj | 28 ++++++++ src/ie/simm/runtimes/assistance.clj | 37 +++++++--- src/ie/simm/runtimes/telegram.clj | 26 ++++--- src/ie/simm/runtimes/text_extractor.clj | 1 - src/ie/simm/simmie.clj | 18 +++-- 10 files changed, 181 insertions(+), 31 deletions(-) create mode 100644 resources/public/index.html create mode 100644 resources/public/simmie.png create mode 100644 src/ie/simm/http.clj diff --git a/.gitignore b/.gitignore index a163afe..4f62e42 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,7 @@ databases/ notes/ +downloads/ .clj-kondo/ resources/config.edn *.log diff --git a/README.md b/README.md index 16915c2..8549d97 100644 --- a/README.md +++ b/README.md @@ -10,15 +10,6 @@ Make sure to define your credentials in `resources/config.edn`. Prompts are stor Just start a REPL and explore the `towers` namespace. -## Agenda - -- add scheduling -- add accounting -- abstract message format -- renamte 'tag' to entity or something more serious -- update schema in prototype on next reset -- add payments - ## License Copyright © 2024 Christian Weilbach diff --git a/deps.edn b/deps.edn index e127bca..400174a 100644 --- a/deps.edn +++ b/deps.edn @@ -5,6 +5,7 @@ morse/morse {:mvn/version "0.4.3"} io.replikativ/kabel {:mvn/version "0.2.2"} http-kit/http-kit {:mvn/version "2.7.0"} + metosin/reitit {:mvn/version "0.7.0-alpha7"} compojure/compojure {:mvn/version "1.7.1"} ring/ring-jetty-adapter {:mvn/version "1.12.0"} etaoin/etaoin {:mvn/version "1.0.40"} diff --git a/resources/public/index.html b/resources/public/index.html new file mode 100644 index 0000000..69a5131 --- /dev/null +++ b/resources/public/index.html @@ -0,0 +1,91 @@ + + + + + + Simmie + + + + +
+
+ +
+
+
+
+

Hey!

+

Simmie is a conversational AI system that combines different forms of intelligence to help you pursue your goals or just have fun.

+
+
+
+
+
+
+

Copyright © 2024 Christian Weilbach. All rights reserved.

+
+
+
+
+ + + diff --git a/resources/public/simmie.png b/resources/public/simmie.png new file mode 100644 index 0000000000000000000000000000000000000000..e534e9a19db93294281dfbb661bdc957bc90f3c5 GIT binary patch literal 5099 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 V3Dwqyca1uLhMKNw-BZ}x{{rrMq4@v+ literal 0 HcmV?d00001 diff --git a/src/ie/simm/http.clj b/src/ie/simm/http.clj new file mode 100644 index 0000000..89ffb75 --- /dev/null +++ b/src/ie/simm/http.clj @@ -0,0 +1,28 @@ +(ns ie.simm.http + (:require [muuntaja.core :as m] + [reitit.ring :as ring] + [reitit.coercion.spec] + [reitit.ring.coercion :as rrc] + [reitit.ring.middleware.muuntaja :as muuntaja] + [reitit.ring.middleware.parameters :as parameters])) + +(defn website-routes [] + [["/hello" {:get (fn [request] + {:status 200 + :body "Hello, world!"})}]]) + +(defn ring-handler [routes] + (let [routes (concat (vec (apply concat (vals routes))) (website-routes))] + (prn "ROUTES" routes) + (ring/ring-handler + (ring/router + routes + {:data {:coercion reitit.coercion.spec/coercion + :muuntaja m/instance + :middleware [parameters/parameters-middleware + rrc/coerce-request-middleware + muuntaja/format-response-middleware + rrc/coerce-response-middleware]}}) + (ring/routes + (ring/create-resource-handler {:path "/"}) + (ring/create-default-handler))))) diff --git a/src/ie/simm/runtimes/assistance.clj b/src/ie/simm/runtimes/assistance.clj index e9969e3..3d49045 100644 --- a/src/ie/simm/runtimes/assistance.clj +++ b/src/ie/simm/runtimes/assistance.clj @@ -91,6 +91,9 @@ (.close zip-out) zip-file)) + +(def base-url "https://ec2-34-218-223-7.us-west-2.compute.amazonaws.com") + (defn assistance "This interpreter can derive facts and effects through a relational database." [[S peer [in out]]] @@ -113,7 +116,26 @@ _ (tap mo out) pub-out (chan) _ (tap mo pub-out) - po (pub pub-out :type)] + po (pub pub-out :type) + + ;; TODO figure out prefix, here conflict if notes/ + routes [["/download/notes/:chat-id/notes.zip" + {:get (fn [{{:keys [chat-id]} :path-params}] + {:status 200 :body (zip-notes chat-id)})}] + ["/notes/:chat-id" + {:get (fn [{{:keys [chat-id]} :path-params}] + ;; list the notes in basic HTML + {:status 200 + :body (str "

Notes

Download
    " + (str/join "" (map (fn [f] (str "
  • " f "
  • ")) + (rest (file-seq (io/file (str "notes/" chat-id)))))) + "
")})}] + ;; access each individual node link as referenced above + ["/notes/:chat-id/:note" + {:get (fn [{{:keys [chat-id note]} :path-params}] + {:status 200 + :body (slurp (io/file (str "notes/" chat-id "/" note)))})}]]] + (swap! peer assoc-in [:http :routes :assistance] routes) ;; we will continuously interpret the messages (go-loop-try S [m (txs (:result (txs (:result (txs (:result reply-msg)))]))] - ) + _ (d/transact conn (msg->txs (:result reply-msg)))]))]) (catch Exception e (let [error-id (uuid)] (error "Could not process message(" error-id "): " m e) diff --git a/src/ie/simm/runtimes/telegram.clj b/src/ie/simm/runtimes/telegram.clj index e8a3e27..36adf83 100644 --- a/src/ie/simm/runtimes/telegram.clj +++ b/src/ie/simm/runtimes/telegram.clj @@ -10,7 +10,6 @@ [compojure.core :refer [routes POST]] [compojure.route :as route] [jsonista.core :as json] - [ring.adapter.jetty :refer [run-jetty]] [superv.async :refer [go-try S body slurp (json/read-value json/keyword-keys-object-mapper) :message) @@ -49,11 +48,22 @@ (put? S in m) {:body "Thanks!"})) (route/not-found "Not Found")) - _ (debug "starting jetty telegram server") - server (run-jetty telegram-routes {:port 8080 :join? false})] - #(.stop server))) - -(defn long-polling [in] + telegram-routes [["/telegram-callback" {:post + (fn [{:keys [body]}] + (let [msg (-> body slurp (json/read-value json/keyword-keys-object-mapper) :message)] + (debug "received telegram message:" msg) + (put? S in {:type ::message :request-id (uuid) :msg (fetch-voice! msg)}) + {:status 200 :body "Success."})) + #_{:parameters {:body [:map]} + :responses {200 {:body [:map]}} + :handler _}}]] + _ (debug "created telegram routes") + ;;server (run-jetty telegram-routes {:port 8080 :join? false}) + ] + (swap! peer assoc-in [:http :routes :telegram] telegram-routes) + #(fn []))) + +(defn long-polling [peer in] (let [_ (h/defhandler bot-api (h/message-fn (fn [message] (debug "received telegram message:" message) @@ -68,7 +78,7 @@ ([[S peer [in out]]] (telegram server [S peer [in out]])) ([mechanism [S peer [in out]]] - (let [stop-fn (mechanism in) + (let [stop-fn (mechanism peer in) p (pub in (fn [_] :always)) next-in (chan) _ (sub p :always next-in) diff --git a/src/ie/simm/runtimes/text_extractor.clj b/src/ie/simm/runtimes/text_extractor.clj index 94c7049..f5639df 100644 --- a/src/ie/simm/runtimes/text_extractor.clj +++ b/src/ie/simm/runtimes/text_extractor.clj @@ -99,7 +99,6 @@ text (? S next-in m)) (catch Exception e (let [error-id (uuid)] diff --git a/src/ie/simm/simmie.clj b/src/ie/simm/simmie.clj index 3551705..5aef04a 100644 --- a/src/ie/simm/simmie.clj +++ b/src/ie/simm/simmie.clj @@ -2,14 +2,14 @@ (:require [taoensso.timbre :as log] [taoensso.timbre.appenders.core :as appenders] [superv.async :refer [S go-try