Skip to content

Commit 024004c

Browse files
committed
Refine contexts at prompt and append as message
1 parent bac296d commit 024004c

File tree

3 files changed

+70
-46
lines changed

3 files changed

+70
-46
lines changed

src/eca/features/chat.clj

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -863,7 +863,9 @@
863863
(send-content! {:messenger messenger :chat-id chat-id} :system {:type :progress
864864
:state :running
865865
:text "Parsing given context"}))
866-
refined-contexts (f.context/raw-contexts->refined contexts db config)
866+
refined-contexts (concat
867+
(f.context/agents-file-contexts db)
868+
(f.context/raw-contexts->refined contexts db))
867869
repo-map* (delay (f.index/repo-map db config {:as-string? true}))
868870
instructions (f.prompt/build-instructions refined-contexts
869871
rules
@@ -883,7 +885,11 @@
883885
decision (message->decision message)
884886
image-contents (->> refined-contexts
885887
(filter #(= :image (:type %))))
888+
expanded-prompt-contexts (when-let [contexts-str (-> (f.context/contexts-str-from-prompt message db)
889+
(f.prompt/contexts-str repo-map*))]
890+
[{:type :text :text contexts-str}])
886891
user-messages [{:role "user" :content (concat [{:type :text :text message}]
892+
expanded-prompt-contexts
887893
image-contents)}]]
888894
(swap! db* assoc-in [:chats chat-id :status] :running)
889895
(send-content! chat-ctx :user {:type :text

src/eca/features/context.clj

Lines changed: 42 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515

1616
(def ^:private logger-tag "[CONTEXT]")
1717

18-
(defn ^:private agents-file-contexts
18+
(defn agents-file-contexts
1919
"Search for AGENTS.md file both in workspaceRoot and global config dir."
20-
[db _config]
20+
[db]
2121
;; TODO make it customizable by behavior
2222
(let [agent-file "AGENTS.md"
2323
local-agent-files (keep (fn [{:keys [uri]}]
@@ -52,32 +52,46 @@
5252
:content (llm-api/refine-file-context path lines-range)}
5353
:partial lines-range))))
5454

55-
(defn raw-contexts->refined [contexts db config]
56-
(concat (agents-file-contexts db config)
57-
(mapcat (fn [{:keys [type path lines-range position uri]}]
58-
(case (name type)
59-
"file" [(file->refined-context path lines-range)]
60-
"directory" (->> (fs/glob path "**")
61-
(remove fs/directory?)
62-
(map (fn [path]
63-
(let [filename (str (fs/canonicalize path))]
64-
(file->refined-context filename nil)))))
65-
"repoMap" [{:type :repoMap}]
66-
"cursor" [{:type :cursor
67-
:path path
68-
:position position}]
69-
"mcpResource" (try
70-
(mapv
71-
(fn [{:keys [text]}]
72-
{:type :mcpResource
73-
:uri uri
74-
:content text})
75-
(:contents (f.mcp/get-resource! uri db)))
76-
(catch Exception e
77-
(logger/warn logger-tag (format "Error getting MCP resource %s: %s" uri (.getMessage e)))
78-
[]))
79-
nil))
80-
contexts)))
55+
(defn raw-contexts->refined [contexts db]
56+
(mapcat (fn [{:keys [type path lines-range position uri]}]
57+
(case (name type)
58+
"file" [(file->refined-context path lines-range)]
59+
"directory" (->> (fs/glob path "**")
60+
(remove fs/directory?)
61+
(map (fn [path]
62+
(let [filename (str (fs/canonicalize path))]
63+
(file->refined-context filename nil)))))
64+
"repoMap" [{:type :repoMap}]
65+
"cursor" [{:type :cursor
66+
:path path
67+
:position position}]
68+
"mcpResource" (try
69+
(mapv
70+
(fn [{:keys [text]}]
71+
{:type :mcpResource
72+
:uri uri
73+
:content text})
74+
(:contents (f.mcp/get-resource! uri db)))
75+
(catch Exception e
76+
(logger/warn logger-tag (format "Error getting MCP resource %s: %s" uri (.getMessage e)))
77+
[]))
78+
nil))
79+
contexts))
80+
81+
(defn contexts-str-from-prompt
82+
"Extract all contexts (@something) and refine them."
83+
[prompt db]
84+
(let [context-pattern #"[@]([^\s]+)"
85+
matches (re-seq context-pattern prompt)]
86+
(when (seq matches)
87+
(let [raw-contexts (mapv (fn [[full-match path]]
88+
(let [type (if (string/starts-with? full-match "@")
89+
"file"
90+
"file")]
91+
{:type type
92+
:path path}))
93+
matches)]
94+
(raw-contexts->refined raw-contexts db)))))
8195

8296
(defn ^:private all-files-from* [root-filename] (fs/glob root-filename "**"))
8397
(def ^:private all-files-from (memoize all-files-from*))

src/eca/features/prompt.clj

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,26 @@
5959
:else
6060
(load-builtin-prompt "agent_behavior.md"))))
6161

62+
(defn contexts-str [refined-contexts repo-map*]
63+
(multi-str
64+
"<contexts description=\"Manually Provided by user. Their content is current and accurate. You MUST use this information first before using tools to read them.\">"
65+
(reduce
66+
(fn [context-str {:keys [type path position content partial uri]}]
67+
(str context-str (case type
68+
:file (if partial
69+
(format "<file partial=true path=\"%s\">...\n%s\n...</file>\n" path content)
70+
(format "<file path=\"%s\">%s</file>\n" path content))
71+
:repoMap (format "<repoMap description=\"Workspaces structure in a tree view, spaces represent file hierarchy\" >%s</repoMap>\n" @repo-map*)
72+
:cursor (format "<cursor description=\"User editor cursor position (line:character)\" path=\"%s\" start=\"%s\" end=\"%s\"/>\n"
73+
path
74+
(str (:line (:start position)) ":" (:character (:start position)))
75+
(str (:line (:end position)) ":" (:character (:end position))))
76+
:mcpResource (format "<resource uri=\"%s\">%s</resource>\n" uri content)
77+
"")))
78+
""
79+
refined-contexts)
80+
"</contexts>"))
81+
6282
(defn build-instructions [refined-contexts rules repo-map* behavior config]
6383
(multi-str
6484
(eca-prompt behavior config)
@@ -72,23 +92,7 @@
7292
"</rules>"])
7393
""
7494
(when (seq refined-contexts)
75-
["<contexts description=\"Manually provided by user, usually when provided user knows that your task is related to those files, so consider reliying on it, if not enough, use tools to read/gather any extra files/contexts.\">"
76-
(reduce
77-
(fn [context-str {:keys [type path position content partial uri]}]
78-
(str context-str (case type
79-
:file (if partial
80-
(format "<file partial=true path=\"%s\">...\n%s\n...</file>\n" path content)
81-
(format "<file path=\"%s\">%s</file>\n" path content))
82-
:repoMap (format "<repoMap description=\"Workspaces structure in a tree view, spaces represent file hierarchy\" >%s</repoMap>\n" @repo-map*)
83-
:cursor (format "<cursor description=\"User editor cursor position (line:character)\" path=\"%s\" start=\"%s\" end=\"%s\"/>\n"
84-
path
85-
(str (:line (:start position)) ":" (:character (:start position)))
86-
(str (:line (:end position)) ":" (:character (:end position))))
87-
:mcpResource (format "<resource uri=\"%s\">%s</resource>\n" uri content)
88-
"")))
89-
""
90-
refined-contexts)
91-
"</contexts>"])))
95+
[(contexts-str refined-contexts repo-map*)])))
9296

9397
(defn init-prompt [db]
9498
(replace-vars

0 commit comments

Comments
 (0)