Skip to content

Commit a0d5feb

Browse files
authored
Merge branch 'master' into advanced-hooks
2 parents 381e9c7 + 8042060 commit a0d5feb

File tree

8 files changed

+48
-11
lines changed

8 files changed

+48
-11
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
- Enhanced hooks documentation with new types (sessionStart, sessionEnd, chatStart, chatEnd), JSON input/output schemas, execution options (timeout)
55

66
- Fix custom tools to support argument numbers.
7+
- Improve read_file summary to mention offset being read.
78

89
## 0.84.2
910

docs/configuration.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,13 +267,17 @@ Placeholders in the format `{{argument_name}}` within the `command` string will
267267
You can configure custom command prompts for project, global or via `commands` config pointing to the path of the commands.
268268
Prompts can use variables like `$ARGUMENTS`, `$ARG1`, `ARG2`, to replace in the prompt during command call.
269269

270+
You can configure in multiple different ways:
271+
270272
=== "Local custom commands"
271273

272274
A `.eca/commands` folder from the workspace root containing `.md` files with the custom prompt.
273275

274276
```markdown title=".eca/commands/check-performance.md"
275277
Check for performance issues in $ARG1 and optimize if needed.
276278
```
279+
280+
ECA will make available a `/check-performance` command after creating that file.
277281

278282
=== "Global custom commands"
279283

@@ -282,6 +286,8 @@ Prompts can use variables like `$ARGUMENTS`, `$ARG1`, `ARG2`, to replace in the
282286
```markdown title="~/.config/eca/commands/check-performance.md"
283287
Check for performance issues in $ARG1 and optimize if needed.
284288
```
289+
290+
ECA will make available a `/check-performance` command after creating that file.
285291

286292
=== "Config"
287293

@@ -292,6 +298,8 @@ Prompts can use variables like `$ARGUMENTS`, `$ARG1`, `ARG2`, to replace in the
292298
"commands": [{"path": "my-custom-prompt.md"}]
293299
}
294300
```
301+
302+
ECA will make available a `/my-custom-prompt` command after creating that file.
295303

296304
## Rules
297305

resources/prompts/additional_system_info.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
## Project Environment Context
22

3-
Workspaces: {workspaceRoots}
3+
Workspaces: {{workspaceRoots}}
44

55
**Path Resolution & Context:**
66
*Workspaces:* Directories containing code or data relevant to this session.

src/eca/features/prompt.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
(defn ^:private replace-vars [s vars]
3636
(reduce
3737
(fn [p [k v]]
38-
(string/replace p (str "{" (name k) "}") (str v)))
38+
(string/replace p (str "{{" (name k) "}}") (str v)))
3939
s
4040
vars))
4141

src/eca/features/tools.clj

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
eca native tools and MCP servers."
44
(:require
55
[clojure.string :as string]
6+
[clojure.walk :as walk]
67
[eca.features.tools.chat :as f.tools.chat]
78
[eca.features.tools.custom :as f.tools.custom]
89
[eca.features.tools.editor :as f.tools.editor]
@@ -38,14 +39,29 @@
3839
(fn [tool]
3940
(assoc-some tool :disabled (contains? disabled-tools (:name tool))))))
4041

42+
(defn ^:private replace-string-values-with-vars
43+
"walk through config parsing dynamic string contents if value is a string."
44+
[m vars]
45+
(walk/postwalk
46+
(fn [x]
47+
(if (string? x)
48+
(reduce
49+
(fn [s [k v]]
50+
(string/replace s (str "{{" (name k) "}}") (str v)))
51+
x
52+
vars)
53+
x))
54+
m))
55+
4156
(defn ^:private native-definitions [db config]
4257
(into
4358
{}
4459
(map (fn [[name tool]]
4560
[name (-> tool
4661
(assoc :name name)
47-
(update :description #(-> %
48-
(string/replace #"\{workspaceRoots\}" (constantly (tools.util/workspace-roots-strs db))))))]))
62+
(replace-string-values-with-vars
63+
{:workspaceRoots (tools.util/workspace-roots-strs db)
64+
:readFileMaxLines (get-in config [:toolCall :readFile :maxLines])}))]))
4965
(merge {}
5066
f.tools.filesystem/definitions
5167
f.tools.shell/definitions

src/eca/features/tools/filesystem.clj

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070
["path" (complement fs/directory?) "$path is a directory, not a file"]]))
7171
(let [line-offset (or (get arguments "line_offset") 0)
7272
limit (->> [(get arguments "limit")
73-
(get-in config [:toolCall :readFile :maxLines] 2000)]
73+
(get-in config [:toolCall :readFile :maxLines])]
7474
(filter number?)
7575
(apply min))
7676
full-content-lines (string/split-lines (slurp (fs/file (fs/canonicalize (get arguments "path")))))
@@ -89,9 +89,19 @@
8989
" parameter to read more content.")
9090
content)))))
9191

92-
(defn ^:private read-file-summary [{:keys [args]}]
92+
(defn ^:private read-file-summary [{:keys [args config]}]
9393
(if-let [path (get args "path")]
94-
(str "Reading file " (fs/file-name (fs/file path)))
94+
(let [line-offset (get args "line_offset" 0)
95+
limit (get args "limit" (get-in config [:toolCall :readFile :maxLines]))
96+
sub-read (or line-offset limit)]
97+
(format "Reading file %s %s"
98+
(fs/file-name (fs/file path))
99+
(str
100+
(when sub-read
101+
(format "(%s-%s)"
102+
line-offset
103+
limit))
104+
)))
95105
"Reading file"))
96106

97107
(defn ^:private write-file [arguments _]
@@ -321,7 +331,7 @@
321331
"line_offset" {:type "integer"
322332
:description "Line to start reading from (default: 0)"}
323333
"limit" {:type "integer"
324-
:description "Maximum lines to read (default: configured in tools.readFile.maxLines, defaults to 2000)"}}
334+
:description "Maximum lines to read (default: {{readFileMaxLines}})"}}
325335
:required ["path"]}
326336
:handler #'read-file
327337
:require-approval-fn (tools.util/require-approval-when-outside-workspace ["path"])

test/eca/features/tools/filesystem_test.clj

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@
8585
fs/directory? (constantly false)]
8686
((get-in f.tools.filesystem/definitions ["read_file" :handler])
8787
{"path" (h/file-path "/foo/qux")}
88-
{:db {:workspace-folders [{:uri (h/file-uri "file:///foo/bar/baz") :name "foo"}]}})))))
88+
{:db {:workspace-folders [{:uri (h/file-uri "file:///foo/bar/baz") :name "foo"}]}
89+
:config {:toolCall {:readFile {:maxLines 2000}}}})))))
8990
(testing "with line_offset"
9091
(is (match?
9192
{:error false
@@ -96,7 +97,8 @@
9697
fs/readable? (constantly true)]
9798
((get-in f.tools.filesystem/definitions ["read_file" :handler])
9899
{"path" (h/file-path "/foo/qux") "line_offset" 2}
99-
{:db {:workspace-folders [{:uri (h/file-uri "file:///foo/bar/baz") :name "foo"}]}})))))
100+
{:db {:workspace-folders [{:uri (h/file-uri "file:///foo/bar/baz") :name "foo"}]}
101+
:config {:toolCall {:readFile {:maxLines 2000}}}})))))
100102
(testing "with limit"
101103
(is (match?
102104
{:error false

test/eca/features/tools_test.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
:description (format "Only in %s" (h/file-path "/path/to/project/foo"))
6262
:parameters some?
6363
:origin :native}])
64-
(with-redefs [f.tools.filesystem/definitions {"directory_tree" {:description "Only in {workspaceRoots}"
64+
(with-redefs [f.tools.filesystem/definitions {"directory_tree" {:description "Only in {{workspaceRoots}}"
6565
:parameters {}}}]
6666
(f.tools/all-tools "123" "agent" {:workspace-folders [{:name "foo" :uri (h/file-uri "file:///path/to/project/foo")}]}
6767
{}))))))

0 commit comments

Comments
 (0)