Skip to content

Commit 3c20fdf

Browse files
committed
Improve ECA prompt to be more precise and output with better quality
1 parent 758bb63 commit 3c20fdf

File tree

15 files changed

+170
-135
lines changed

15 files changed

+170
-135
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
- Include eca as a server with tools.
66
- Support disable tools via config.
7+
- Improve ECA prompt to be more precise and output with better quality
78

89
## 0.8.1
910

resources/META-INF/native-image/eca/eca/native-image.properties

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ Args=-J-Dborkdude.dynaload.aot=true \
66
--initialize-at-build-time=com.fasterxml.jackson \
77
-H:-CheckToolchain \
88
-H:Log=registerResource: \
9-
-H:IncludeResources=ECA_VERSION
9+
-H:IncludeResources=ECA_VERSION \
10+
-H:IncludeResources=eca_prompt.txt

resources/eca_prompt.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
You are ECA (Editor Code Assistant), an AI coding assistant that operates on a editor.
2+
3+
You are pair programming with a USER to solve their coding task. Each time the USER sends a message, we may automatically attach some context information about their current state, such as passed contexts, rules defined by USER, project structure, and more. This information may or may not be relevant to the coding task, it is up for you to decide.
4+
5+
{behavior}
6+
7+
<communication>
8+
The chat is markdown mode.
9+
When using markdown in assistant messages, use backticks to format file, directory, function, and class names. Use \( and \) for inline math, \[ and \] for block math.
10+
Pay attention to the langauge name after the code block backticks start, use the full language name like 'javascript' instead of 'js'.
11+
</communication>
12+
13+
<tool_calling>
14+
You have tools at your disposal to solve the coding task. Follow these rules regarding tool calls:
15+
1. ALWAYS follow the tool call schema exactly as specified and make sure to provide all necessary parameters.
16+
2. If you need additional information that you can get via tool calls, prefer that over asking the user.
17+
3. If you are not sure about file content or codebase structure pertaining to the user's request, use your tools to read files and gather the relevant information: do NOT guess or make up an answer.
18+
</tool_calling>

src/eca/features/chat.clj

Lines changed: 4 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
[clojure.set :as set]
66
[clojure.string :as string]
77
[eca.features.index :as f.index]
8+
[eca.features.prompt :as f.prompt]
89
[eca.features.rules :as f.rules]
910
[eca.features.tools :as f.tools]
1011
[eca.llm-api :as llm-api]
@@ -32,31 +33,6 @@
3233
"repoMap" [{:type :repoMap}]))
3334
contexts))
3435

35-
(defn ^:private build-context-str [refined-contexts rules repo-map*]
36-
(str
37-
"<rules>\n"
38-
(reduce
39-
(fn [rule-str {:keys [name content]}]
40-
(str rule-str (format "<rule name=\"%s\">%s</rule>\n" name content)))
41-
""
42-
rules)
43-
"</rules>\n"
44-
"<contexts>\n"
45-
(reduce
46-
(fn [context-str {:keys [type path content]}]
47-
(str context-str (case type
48-
:file (format "<file path=\"%s\">%s</file>\n" path content)
49-
:repoMap (format "<repoMap description=\"Workspaces structure in a tree view, spaces represent file hierarchy\" >%s</repoMap>" @repo-map*)
50-
"")))
51-
""
52-
refined-contexts)
53-
"</contexts>"))
54-
55-
(defn ^:private behavior->behavior-str [behavior]
56-
(case behavior
57-
"chat" "Help with code changes only if user requested/agreed, ask first before do changes, answer questions, and provide explanations."
58-
"agent" "Help with code changes when applicable, suggesting you do the changes itself, answer questions, and provide explanations."))
59-
6036
(defn default-model [db config]
6137
(llm-api/default-model db config))
6238

@@ -115,13 +91,11 @@
11591
:state :running
11692
:text "Parsing given context"}))
11793
db @db*
118-
rules (f.rules/all config
119-
(:workspace-folders db)
120-
{:behavior (behavior->behavior-str (or behavior (:chat-default-behavior db)))})
94+
rules (f.rules/all config (:workspace-folders db))
12195
refined-contexts (raw-contexts->refined contexts)
12296
manual-approval? (get-in config [:toolCall :manualApproval] false)
12397
repo-map* (delay (f.index/repo-map db {:as-string? true}))
124-
context-str (build-context-str refined-contexts rules repo-map*)
98+
instructions (f.prompt/build-instructions refined-contexts rules repo-map* (or behavior (:chat-default-behavior db)))
12599
chosen-model (or model (default-model db config))
126100
past-messages (get-in db [:chats chat-id :messages] [])
127101
user-prompt message
@@ -140,7 +114,7 @@
140114
{:model chosen-model
141115
:model-config (get-in db [:models chosen-model])
142116
:user-prompt user-prompt
143-
:context context-str
117+
:instructions instructions
144118
:past-messages past-messages
145119
:config config
146120
:tools all-tools

src/eca/features/prompt.clj

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
(ns eca.features.prompt
2+
(:require
3+
[clojure.java.io :as io]
4+
[clojure.string :as string]
5+
[eca.shared :refer [multi-str]]))
6+
7+
(defn ^:private eca-prompt-template* [] (slurp (io/resource "eca_prompt.txt")))
8+
9+
(def ^:private eca-prompt-template (memoize eca-prompt-template*))
10+
11+
(defn ^:private eca-prompt [behavior]
12+
(let [prompt (eca-prompt-template)]
13+
(reduce
14+
(fn [p [k v]]
15+
(string/replace p (str "{" (name k) "}") v))
16+
prompt
17+
{:behavior (case behavior
18+
"chat" "Answer questions, and provide explanations."
19+
"agent" "You are an agent - please keep going until the user's query is completely resolved, before ending your turn and yielding back to the user. Only terminate your turn when you are sure that the problem is solved. Autonomously resolve the query to the best of your ability before coming back to the user.")})))
20+
21+
(defn build-instructions [refined-contexts rules repo-map* behavior]
22+
(multi-str
23+
(eca-prompt behavior)
24+
"<rules>"
25+
(reduce
26+
(fn [rule-str {:keys [name content]}]
27+
(str rule-str (format "<rule name=\"%s\">%s</rule>\n" name content)))
28+
""
29+
rules)
30+
"</rules>"
31+
""
32+
"<contexts>"
33+
(reduce
34+
(fn [context-str {:keys [type path content]}]
35+
(str context-str (case type
36+
:file (format "<file path=\"%s\">%s</file>\n" path content)
37+
:repoMap (format "<repoMap description=\"Workspaces structure in a tree view, spaces represent file hierarchy\" >%s</repoMap>" @repo-map*)
38+
"")))
39+
""
40+
refined-contexts)
41+
"</contexts>"))

src/eca/features/rules.clj

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
(:require
33
[babashka.fs :as fs]
44
[clojure.java.io :as io]
5-
[clojure.string :as string]
65
[eca.config :as config]
76
[eca.shared :as shared]))
87

@@ -53,22 +52,7 @@
5352
(flatten)
5453
(remove nil?)))
5554

56-
(defn ^:private system-rules []
57-
[{:name "ECA System"
58-
:type :system
59-
:content (str "You are an expert AI coding tool called ECA (Editor Code Assistant). "
60-
"Your behavior is to '<behavior>'. "
61-
"The chat is markdown mode. "
62-
"When responding code blocks, pay attention to use valid markdown languages following Github markdown.")}])
63-
64-
(defn all [config roots variables]
65-
(mapv (fn [rule]
66-
(reduce
67-
(fn [rule [k v]]
68-
(update rule :content #(string/replace % (str "<" (name k) ">") v)))
69-
rule
70-
variables))
71-
(concat (system-rules)
72-
(config-rules config roots)
73-
(global-file-rules)
74-
(local-file-rules roots))))
55+
(defn all [config roots]
56+
(concat (config-rules config roots)
57+
(global-file-rules)
58+
(local-file-rules roots)))

src/eca/llm_api.clj

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
:type "function"))
6666

6767
(defn complete!
68-
[{:keys [model model-config context user-prompt config on-first-response-received
68+
[{:keys [model model-config instructions user-prompt config on-first-response-received
6969
on-message-received on-error on-prepare-tool-call on-tool-called on-reason
7070
past-messages tools]}]
7171
(let [first-response-received* (atom false)
@@ -101,7 +101,7 @@
101101
"gpt-4.1"} model)
102102
(llm-providers.openai/completion!
103103
{:model model
104-
:context context
104+
:instructions instructions
105105
:user-prompt user-prompt
106106
:past-messages past-messages
107107
:tools tools
@@ -115,7 +115,7 @@
115115
"claude-3-5-haiku-latest"} model)
116116
(llm-providers.anthropic/completion!
117117
{:model model
118-
:context context
118+
:instructions instructions
119119
:user-prompt user-prompt
120120
:past-messages past-messages
121121
:tools tools
@@ -129,7 +129,7 @@
129129
{:host (-> config :ollama :host)
130130
:port (-> config :ollama :port)
131131
:model (string/replace-first model config/ollama-model-prefix "")
132-
:context context
132+
:instructions instructions
133133
:user-prompt user-prompt
134134
:past-messages past-messages
135135
:tools tools}
@@ -146,7 +146,7 @@
146146
key (or (:key provider-config) (config/get-env (:keyEnv provider-config)))]
147147
(provider-fn
148148
{:model model
149-
:context context
149+
:instructions instructions
150150
:user-prompt user-prompt
151151
:past-messages past-messages
152152
:tools tools

src/eca/llm_providers/anthropic.clj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
#(assoc-in % [:content 0 :cache_control] {:type "ephemeral"})))
7777

7878
(defn completion!
79-
[{:keys [model user-prompt temperature context max-tokens
79+
[{:keys [model user-prompt temperature instructions max-tokens
8080
api-url api-key past-messages tools web-search]
8181
:or {max-tokens 4096
8282
temperature 1.0}}
@@ -91,7 +91,7 @@
9191
;; TODO support :thinking
9292
:stream true
9393
:tools (->tools tools web-search)
94-
:system [{:type "text" :text context :cache_control {:type "ephemeral"}}]}
94+
:system [{:type "text" :text instructions :cache_control {:type "ephemeral"}}]}
9595
on-response-fn
9696
(fn handle-response [event data content-block*]
9797
(case event

src/eca/llm_providers/ollama.clj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,10 @@
7575
msg))
7676
past-messages)))
7777

78-
(defn completion! [{:keys [model user-prompt context host port past-messages tools]}
78+
(defn completion! [{:keys [model user-prompt instructions host port past-messages tools]}
7979
{:keys [on-message-received on-error on-prepare-tool-call on-tool-called]}]
8080
(let [messages (concat
81-
(past-messages->messages past-messages context)
81+
(past-messages->messages past-messages instructions)
8282
[{:role "user" :content user-prompt}])
8383
body {:model model
8484
:messages messages
@@ -106,7 +106,7 @@
106106
(base-completion-request!
107107
{:rid (llm-util/gen-rid)
108108
:url url
109-
:body (assoc body :messages (past-messages->messages new-messages context))
109+
:body (assoc body :messages (past-messages->messages new-messages instructions))
110110
:on-error on-error
111111
:on-response handle-response}))
112112
(on-message-received {:type :finish

src/eca/llm_providers/openai.clj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
msg))
5555
past-messages))
5656

57-
(defn completion! [{:keys [model user-prompt context temperature api-key api-url past-messages tools web-search]
57+
(defn completion! [{:keys [model user-prompt instructions temperature api-key api-url past-messages tools web-search]
5858
:or {temperature 1.0}}
5959
{:keys [on-message-received on-error on-prepare-tool-call on-tool-called on-reason]}]
6060
(let [input (conj (past-messages->input past-messages)
@@ -64,7 +64,7 @@
6464
body {:model model
6565
:input input
6666
:user (str (System/getProperty "user.name") "@ECA")
67-
:instructions context
67+
:instructions instructions
6868
:temperature temperature
6969
:tools tools
7070
:stream true}

0 commit comments

Comments
 (0)