diff --git a/deps.edn b/deps.edn index aab44c7..29ee1f0 100644 --- a/deps.edn +++ b/deps.edn @@ -1,6 +1,6 @@ {:paths ["src" "resources"] :deps {org.clojure/clojure {:mvn/version "1.11.1"} - io.replikativ/datahike {:mvn/version "0.6.1558"} + io.replikativ/datahike {:mvn/version "0.6.1576"} clj-python/libpython-clj {:mvn/version "2.025"} morse/morse {:mvn/version "0.4.3"} io.replikativ/kabel {:mvn/version "0.2.2"} @@ -10,10 +10,12 @@ hiccup/hiccup {:mvn/version "2.0.0-RC3"} org.clj-commons/hickory {:mvn/version "0.7.4"} ring/ring-jetty-adapter {:mvn/version "1.12.0"} - etaoin/etaoin {:mvn/version "1.0.40"} - missionary/missionary {:mvn/version "b.34"} + etaoin/etaoin {:mvn/version "1.1.41"} nrepl/nrepl {:mvn/version "1.1.1"} cider/cider-nrepl {:mvn/version,"0.47.1"} + + ;; exploratory + missionary/missionary {:mvn/version "b.34"} pangloss/pattern {:git/url "https://github.com/pangloss/pattern" :sha "affc7f3ac907f5b98de6638574a741e4693f1648"} anglican/anglican {:mvn/version "1.1.0"}} diff --git a/src/ie/simm/processes/build_accounting.clj b/src/ie/simm/processes/build_accounting.clj new file mode 100644 index 0000000..6883c40 --- /dev/null +++ b/src/ie/simm/processes/build_accounting.clj @@ -0,0 +1,119 @@ +(ns ie.simm.processes.build-accounting + (:require [clojure.core.async :as async :refer [timeout]] + [superv.async :refer [go-try go-loop-try "accounting system" + brave/search-brave + brave/extract-url + etaoin/extract-body) + +(etaoin/extract-body "https://en.wikipedia.org/wiki/Accounting") + + +(defn interleave-with-delimiters + ([coll] (interleave-with-delimiters coll "=========================================\n")) + ([coll delimiter] + (str/join "\n" (interleave coll (repeat delimiter))))) + + +(defn feedback [question] + (println question) + (read-line)) + +(defn expert [type question] + (openai/chat "gpt-4o" (interleave-with-delimiters [(format "You are an %s." type) question]))) + +(defn critic [type question answer] + (Integer/parseInt + (openai/chat "gpt-4o" (interleave-with-delimiters [(format "You are a critic for a %s." type) + "We gave the expert this question:" question + "The expert replied with this answer:" answer + "Rate the expert's answer on a scale from 1 to 10. Only reply with a number."])))) + + +;; a building process loop with a fixed point, it is given an environmental context +;; in every loop we first gather and refine requirements +;; we derive subgoals to currently pursue +;; we define tests and progress metrics +;; then we do an iteration given the system so far +;; and measure the progress +;; we then check if we have reached a fixed point + +subgoals (expert expert-role (str "You have this goal: " goal "\nWith these requirements: " requirements "\nAnd these subgoals derived so far:" subgoals "\nUpdate the subgoals if reasonable and enumerate them as a comma separated list: ")) + tests (expert expert-role (str "You have this goal: " goal "\nWith these requirements: " requirements "\nAnd these subgoals: " subgoals "\nAnd these tests derived so far: " tests "\n Update the tests if reasonable and return them as Clojure code string that can be passed to eval: ")) + progress-metrics (expert expert-role (str "You have this goal: " goal "\nWith these requirements: " requirements "\nAnd these subgoals: " subgoals "\nAnd these tests: " tests "\nAnd these progress metrics derived so far: " progress-metrics "\n Update the progress metrics if reasonable and return them only as a single Clojure code string that can be passed to eval directly: ")) + iteration (expert expert-role (str "You have this goal: " goal "\nWith these requirements: " requirements "\nAnd these subgoals: " subgoals "\nAnd these tests: " tests "\nAnd these progress metrics: " progress-metrics "\nAnd this iteration derived so far: " iteration "\n Update the iteration if reasonable and return it as a single Clojure code string that can be passed to eval: ")) + progress (expert expert-role (str "You have this goal: " goal "\nWith these requirements: " requirements "\nAnd these subgoals: " subgoals "\nAnd these tests: " tests "\nAnd these progress metrics: " progress-metrics "\nAnd this iteration: " iteration "\nAnd this progress derived so far: " progress "\n Update the progress metric if reasonable and return it as Clojure code. The progress metric function needs to return a real number: ")) + + +(defn build [ctx goal] + (let [expert-role (openai/chat "gpt-4o" + (interleave-with-delimiters + ["Given this context:" ctx + "What expert would you hire to pursue this goal:" goal + "Answer a descriptive job title."]))] + (loop [requirements "" + subgoals "" + tests "" + progress-metrics "" + iteration "" + progress "" ] + (let [requirements (expert expert-role (interleave-with-delimiters ["You have this goal:" goal + "With these requirements derived so far:" requirements + "What are the requirements?"])) + subgoals (expert expert-role (interleave-with-delimiters ["You have this goal:" goal + "With these requirements:" requirements + "And these subgoals derived so far:" subgoals + "Update the subgoals if reasonable and enumerate them as a comma separated list: "])) + tests (expert expert-role (interleave-with-delimiters ["You have this goal:" goal + "With these requirements:" requirements + "And these subgoals:" subgoals + "And these tests derived so far:" tests + " Update the tests if reasonable and return them as Clojure code string that can be passed to eval: "])) + progress-metrics (expert expert-role (interleave-with-delimiters ["You have this goal:" goal + "With these requirements:" requirements + "And these subgoals:" subgoals + "And these tests:" tests + "And these progress metrics derived so far:" progress-metrics + " Update the progress metrics if reasonable and return them only as a single Clojure code string that can be passed to eval directly: "])) + iteration (expert expert-role (interleave-with-delimiters ["You have this goal:" goal + "With these requirements:" requirements + "And these subgoals:" subgoals + "And these tests:" tests + "And these progress metrics:" progress-metrics + "And this iteration derived so far:" iteration + " Update the iteration if reasonable and return it as a single Clojure code string that can be passed to eval: "])) + progress (expert expert-role (interleave-with-delimiters ["You have this goal:" goal + "With these requirements:" requirements + "And these subgoals:" subgoals + "And these tests:" tests + "And these progress metrics:" progress-metrics + "And this iteration:" iteration + "And this progress derived so far:" progress + " Update the progress metric if reasonable and return it as Clojure code. The progress metric function needs to return a real number: "]))] + (println "Requirements: " requirements) + (println "Subgoals: " subgoals) + (println "Tests: " tests) + (println "Progress Metrics: " progress-metrics) + (println "Iteration: " iteration) + (println "Progress: " progress) + [expert-role requirements subgoals tests progress-metrics iteration progress])))) + + +(comment + + (def build-result (build "exploring games" "Build a Snake game in Clojure without any external libraries. You have clojure.core, core.async and Datahike available.")) + + (let [[expert-role requirements subgoals tests progress-metrics iteration progress] build-result] + (println iteration)) + + ) diff --git a/src/ie/simm/processes/thesis.clj b/src/ie/simm/processes/thesis.clj new file mode 100644 index 0000000..dad7884 --- /dev/null +++ b/src/ie/simm/processes/thesis.clj @@ -0,0 +1,88 @@ +(ns ie.simm.processes.thesis + (:require [clojure.core.async :as async :refer [timeout]] + [superv.async :refer [go-try go-loop-try > (d/q '[:find ?d ?e :in $ ?chat :where @@ -47,7 +47,7 @@ (go-for S [[i note] (partition 2 (interleave (iterate inc 2) note-titles)) :let [[nid body] (first (d/q '[:find ?n ?b :in $ ?t :where [?n :note/title ?t] [(get-else $ ?n :note/body "EMPTY") ?b]] db note)) prompt (format pr/note note body #_summarization conv) - new-body (= (count text) (* 4 (window-sizes model))) (do - (warn "text too long for " model ": " (count text) (window-sizes model)) + (warn "Text too long for " model ": " (count text) (window-sizes model)) (throw (ex-info "Sorry, the text is too long for this model. Please try a shorter text." {:type ::text-too-long :model model :text-start (subs text 0 100) :count (count text)}))) (let [res (create :model model :messages [{:role "system" :content text}])] (py.- (py.- (first (py.- res choices)) message) content)))) @@ -55,16 +56,16 @@ (defn openai [[S peer [in out]]] (let [p (pub in (fn [{:keys [type]}] - (or ({:ie.simm.languages.gen-ai/cheap-llm ::gpt-35-turbo - :ie.simm.languages.gen-ai/reasoner-llm ::gpt-4-turbo + (or ({:ie.simm.languages.gen-ai/cheap-llm ::gpt-4o-mini + :ie.simm.languages.gen-ai/reasoner-llm ::gpt-4o :ie.simm.languages.gen-ai/stt-basic ::whisper-1 :ie.simm.languages.gen-ai/image-gen ::dall-e-3} type) :unrelated))) - gpt-35-turbo (chan) - _ (sub p ::gpt-35-turbo gpt-35-turbo) + gpt-4o-mini (chan) + _ (sub p ::gpt-4o-mini gpt-4o-mini) - gpt-4-turbo (chan) - _ (sub p ::gpt-4-turbo gpt-4-turbo) + gpt-4o (chan) + _ (sub p ::gpt-4o gpt-4o) whisper-1 (chan) _ (sub p ::whisper-1 whisper-1) @@ -76,21 +77,21 @@ _ (sub p :unrelated next-in)] ;; TODO use async http requests for parallelism ;; TODO factor dedicated translator to LLM language - (go-loop-try S [{[m] :args :as s} (