From 366226e69bb96a3f0bf5bdf5bb6a124802372886 Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Tue, 3 Feb 2026 12:09:00 +0800 Subject: [PATCH] add #Agent and #Project --- AGENTS.md | 1 + .../agents/07-m7-agent-assignment-ui.md | 9 +++--- deps/db-sync/scripts/start-weather-session.sh | 5 +++ .../src/logseq/db_sync/malli_schema.cljs | 12 ++++++- .../src/logseq/db_sync/worker/agent/do.cljs | 6 +++- .../logseq/db_sync/worker/agent/request.cljs | 1 + .../logseq/db_sync/agent_request_test.cljs | 17 ++++++++-- deps/db/src/logseq/db/frontend/class.cljs | 12 ++++++- deps/db/src/logseq/db/frontend/property.cljs | 32 ++++++++++++++++++- deps/db/src/logseq/db/frontend/schema.cljs | 2 +- .../db/src/logseq/db/sqlite/create_graph.cljs | 2 +- src/main/frontend/extensions/zip.cljs | 2 +- src/main/frontend/reaction.cljs | 20 ++++++++---- src/main/frontend/ui.cljs | 10 +++--- src/main/frontend/worker/db/migrate.cljs | 9 +++++- src/test/frontend/worker/migrate_test.cljs | 23 ++++++++++++- 16 files changed, 137 insertions(+), 26 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 4e5318c013..aa11b7b3e1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -37,3 +37,4 @@ - DB-sync protocol reference: `docs/agent-guide/db-sync/protocol.md`. - New properties should be added to `logseq.db.frontend.property/built-in-properties`. - Avoid creating new class or property unless you have to. +- Create db migration when adding new properties/classes. diff --git a/deps/db-sync/docs/milestones/agents/07-m7-agent-assignment-ui.md b/deps/db-sync/docs/milestones/agents/07-m7-agent-assignment-ui.md index 1624e2bb58..c44948264f 100644 --- a/deps/db-sync/docs/milestones/agents/07-m7-agent-assignment-ui.md +++ b/deps/db-sync/docs/milestones/agents/07-m7-agent-assignment-ui.md @@ -1,14 +1,15 @@ # M7: Agent Assignment + Session Start UI ## Target -Allow users to assign an agent to a task and start a session from Logseq UI. +Allow users to start a session from Logseq UI. ## Scope -- UI control on `#Task` to select agent + project. +- Able to run task (when both Agent and Project title && Git repo specified) - Create simplified sessions/create payload from task data. -- Display session status on the task card. +- Map session status to task status real-time ## Acceptance 1) User can pick an agent for a task and start a session. -2) Task shows status (created/running/paused/etc.). +2) Task shows status 3) Session created uses simplified payload shape. +4) UI should be intuitive and fit the current ui diff --git a/deps/db-sync/scripts/start-weather-session.sh b/deps/db-sync/scripts/start-weather-session.sh index 356949eb01..68e4142f52 100755 --- a/deps/db-sync/scripts/start-weather-session.sh +++ b/deps/db-sync/scripts/start-weather-session.sh @@ -13,6 +13,11 @@ create_payload() { "node-title": "Check weather in Hangzhou", "content": "Tell me the weather today in Hangzhou.", "attachments": [], + "project": { + "id": "project-weather", + "title": "Weather Demo", + "repo-url": "https://github.com/logseq/logseq" + }, "agent": { "provider": "codex", "mode": "build", diff --git a/deps/db-sync/src/logseq/db_sync/malli_schema.cljs b/deps/db-sync/src/logseq/db_sync/malli_schema.cljs index a8131b9d69..f0ff9f37a7 100644 --- a/deps/db-sync/src/logseq/db_sync/malli_schema.cljs +++ b/deps/db-sync/src/logseq/db_sync/malli_schema.cljs @@ -224,7 +224,17 @@ [:node-title :string] [:content :string] [:attachments [:sequential :string]] - [:agent [:or :string :map]]]) + [:project [:map + [:id :string] + [:title :string] + [:repo-url :string]]] + [:agent [:or :string + [:map + [:provider {:optional true} :string] + [:mode {:optional true} :string] + [:permission-mode {:optional true} :string] + [:api-token {:optional true} :string] + [:auth-json {:optional true} :string]]]]]) (def sessions-message-request-schema [:map diff --git a/deps/db-sync/src/logseq/db_sync/worker/agent/do.cljs b/deps/db-sync/src/logseq/db_sync/worker/agent/do.cljs index 8592d30343..f940cba025 100644 --- a/deps/db-sync/src/logseq/db_sync/worker/agent/do.cljs +++ b/deps/db-sync/src/logseq/db_sync/worker/agent/do.cljs @@ -207,7 +207,11 @@ :else (let [session (session/initial-session task audit now) - [session events _event] (session/append-event session [] {:type "session.created" :data {:requested-by user-id} :ts now})] + [session events _event] (session/append-event session [] {:type "session.created" + :data {:requested-by user-id + :project (:project task) + :agent (:agent task)} + :ts now})] (p/let [_ ( Tag, classes-tx depends on logseq.property.class/extends, properties-tx depends on Property - bootstrap-class? (fn [c] (contains? #{:logseq.class/Root :logseq.class/Property :logseq.class/Tag :logseq.class/Template} (:db/ident c))) + bootstrap-class? (fn [c] (contains? #{:logseq.class/Root :logseq.class/Property :logseq.class/Tag :logseq.class/Template :logseq.class/Agent :logseq.class/Project} (:db/ident c))) bootstrap-classes (filter bootstrap-class? default-classes) bootstrap-class-ids (map #(select-keys % [:db/ident :block/uuid]) bootstrap-classes) classes-tx (concat (map #(dissoc % :db/ident) bootstrap-classes) diff --git a/src/main/frontend/extensions/zip.cljs b/src/main/frontend/extensions/zip.cljs index 13c66c44fb..b62987aee5 100644 --- a/src/main/frontend/extensions/zip.cljs +++ b/src/main/frontend/extensions/zip.cljs @@ -20,6 +20,6 @@ :compression compression}] (p/let [zip-blob (.generateAsync zip opts (when progress-fn - (fn [metadata] + (fn [^js metadata] (progress-fn (.-percent metadata)))))] (make-file zip-blob (str zip-filename ".zip") {:type "application/zip"})))) diff --git a/src/main/frontend/reaction.cljs b/src/main/frontend/reaction.cljs index 81d8801f8f..b9babe3af2 100644 --- a/src/main/frontend/reaction.cljs +++ b/src/main/frontend/reaction.cljs @@ -26,7 +26,15 @@ :else nil))) reaction-username (fn [reaction] (let [user (:logseq.property/created-by-ref reaction)] - (:block/title (db/entity (:db/id user))))) + (cond + (map? user) + (if (:db/id user) + (:logseq.property.user/name user) + (or (:logseq.property.user/name user) + (:block/title user))) + (number? user) + (:logseq.property.user/name (db/entity user)) + :else nil))) summary (reduce (fn [acc reaction] (let [emoji-id (:logseq.property.reaction/emoji-id reaction) user-id (reaction-user-id reaction) @@ -43,10 +51,10 @@ reactions)] (->> summary (map (fn [[emoji-id {:keys [count reacted-by-me? usernames]}]] - {:emoji-id emoji-id - :count count - :reacted-by-me? (boolean reacted-by-me?) - :usernames (when (seq usernames) - (->> usernames sort vec))})) + (cond-> {:emoji-id emoji-id + :count count + :reacted-by-me? (boolean reacted-by-me?)} + (seq usernames) + (assoc :usernames (->> usernames sort vec))))) (sort-by (juxt (comp - :count) :emoji-id)) vec))) diff --git a/src/main/frontend/ui.cljs b/src/main/frontend/ui.cljs index 6a89a5b08e..49a6d49a88 100644 --- a/src/main/frontend/ui.cljs +++ b/src/main/frontend/ui.cljs @@ -945,11 +945,11 @@ fade-in? true root-margin 100}}] (let [[visible? set-visible!] (rum/use-state initial-state) - inViewState (useInView #js {:initialInView initial-state - :rootMargin (str root-margin "px") - :triggerOnce trigger-once? - :onChange (fn [in-view? _entry] - (set-visible! in-view?))}) + ^js inViewState (useInView #js {:initialInView initial-state + :rootMargin (str root-margin "px") + :triggerOnce trigger-once? + :onChange (fn [in-view? _entry] + (set-visible! in-view?))}) ref (.-ref inViewState)] (lazy-visible-inner visible? content-fn ref fade-in? placeholder)))) diff --git a/src/main/frontend/worker/db/migrate.cljs b/src/main/frontend/worker/db/migrate.cljs index 4f7cc9a1f5..92e6b7a174 100644 --- a/src/main/frontend/worker/db/migrate.cljs +++ b/src/main/frontend/worker/db/migrate.cljs @@ -189,7 +189,14 @@ ["65.20" {:properties [:logseq.property.class/bidirectional-property-title :logseq.property.class/enable-bidirectional?]}] ["65.21" {:properties [:logseq.property.sync/large-title-object]}] ["65.22" {:properties [:logseq.property.reaction/emoji-id - :logseq.property.reaction/target]}]]) + :logseq.property.reaction/target]}] + ["65.23" {:classes [:logseq.class/Project + :logseq.class/Agent] + :properties [:logseq.property/project + :logseq.property/agent + :logseq.property/git-repo + :logseq.property/agent-api-token + :logseq.property/agent-auth-json]}]]) (let [[major minor] (last (sort (map (comp (juxt :major :minor) db-schema/parse-schema-version first) schema-version->updates)))] diff --git a/src/test/frontend/worker/migrate_test.cljs b/src/test/frontend/worker/migrate_test.cljs index 7d383ce39f..fab867f8f8 100644 --- a/src/test/frontend/worker/migrate_test.cljs +++ b/src/test/frontend/worker/migrate_test.cljs @@ -3,7 +3,8 @@ [cljs.test :refer [deftest is]] [datascript.core :as d] [frontend.worker.db.migrate :as db-migrate] - [logseq.db :as ldb])) + [logseq.db :as ldb] + [logseq.db.test.helper :as db-test])) (deftest ensure-built-in-data-exists! (let [db-transit (str (fs-node/readFileSync "src/test/migration/64.8.transit")) @@ -20,3 +21,23 @@ (is (= graph-created-at (:kv/value (d/entity @conn :logseq.kv/graph-created-at))) "Graph created at not changed by fn"))) + +(deftest migrate-adds-project-agent-builtins + (let [conn (db-test/create-conn) + _ (d/transact! conn [{:db/ident :logseq.kv/schema-version + :kv/value {:major 65 :minor 22}}]) + remove-idents [:logseq.class/Project + :logseq.class/Agent + :logseq.property/project + :logseq.property/git-repo + :logseq.property/agent-api-token + :logseq.property/agent-auth-json] + _ (doseq [ident remove-idents + :let [eid (d/entid @conn ident)] + :when eid] + (d/transact! conn [[:db/retractEntity eid]])) + _ (db-migrate/migrate conn :target-version "65.23")] + (is (= {:major 65 :minor 23} + (:kv/value (d/entity @conn :logseq.kv/schema-version)))) + (doseq [ident remove-idents] + (is (some? (d/entity @conn ident))))))