Skip to content

Commit 781fad3

Browse files
committed
Add tests
1 parent 6c111cc commit 781fad3

File tree

3 files changed

+103
-5
lines changed

3 files changed

+103
-5
lines changed

src/eca/features/chat.clj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@
338338
(f.hooks/trigger-if-matches!
339339
:postToolCall
340340
{:chat-id (:chat-id chat-ctx)
341-
:name (:name tool-call-state)
341+
:tool-name (:name tool-call-state)
342342
:server (:server tool-call-state)
343343
:arguments (:arguments tool-call-state)}
344344
{:on-before-action (partial notify-before-hook-action! chat-ctx)
@@ -663,7 +663,7 @@
663663
@approved?* ;; wait for user respond before checking hook
664664
(f.hooks/trigger-if-matches! :preToolCall
665665
{:chat-id chat-id
666-
:name name
666+
:tool-name name
667667
:server server
668668
:arguments arguments}
669669
{:on-before-action (partial notify-before-hook-action! chat-ctx)

src/eca/features/hooks.clj

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
(case type
1212
(:preToolCall :postToolCall)
1313
(re-matches (re-pattern (or (:matcher hook) ".*"))
14-
(str (:server data) "__" (:name data)))
14+
(str (:server data) "__" (:tool-name data)))
1515

1616
true))
1717

@@ -26,12 +26,18 @@
2626
(logger/info logger-tag (format "Running hook '%s' shell '%s' with input '%s'" name shell input))
2727
(let [{:keys [exit out err]} (p/sh {:dir cwd}
2828
"bash" "-c" shell "--" input)]
29-
[exit out err]))
29+
[exit (not-empty out) (not-empty err)]))
3030
(logger/warn logger-tag (format "Unknown hook action %s for %s" (:type action) name))))
3131

3232
(defn trigger-if-matches!
3333
"Run hook of specified type if matches any config for that type"
34-
[type data {:keys [on-before-action on-after-action]} db config]
34+
[type
35+
data
36+
{:keys [on-before-action on-after-action]
37+
:or {on-before-action identity
38+
on-after-action identity}}
39+
db
40+
config]
3541
(doseq [[name hook] (:hooks config)]
3642
(when (= type (keyword (:type hook)))
3743
(when (hook-matches? type data hook)

test/eca/features/hooks_test.clj

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
(ns eca.features.hooks-test
2+
(:require
3+
[babashka.process :as p]
4+
[clojure.test :refer [deftest is testing]]
5+
[eca.features.hooks :as f.hooks]
6+
[eca.test-helper :as h]
7+
[matcher-combinators.test :refer [match?]]))
8+
9+
(h/reset-components-before-test)
10+
11+
(defn set-action-payload [a*]
12+
(fn [p]
13+
(reset! a* p)))
14+
15+
(deftest trigger-if-matches!-test
16+
(testing "prePrompt"
17+
(h/reset-components!)
18+
(h/config! {:hooks {"my-hook" {:type "prePrompt"
19+
:actions [{:type "shell"
20+
:shell "echo hey"}]}}})
21+
(let [on-before-action* (atom nil)
22+
on-after-action* (atom nil)]
23+
(with-redefs [p/sh (constantly {:exit 0 :out "hey" :err nil})]
24+
(f.hooks/trigger-if-matches!
25+
:prePrompt
26+
{:foo "1"}
27+
{:on-before-action (set-action-payload on-before-action*)
28+
:on-after-action (set-action-payload on-after-action*)}
29+
(h/db)
30+
(h/config)))
31+
(is (match?
32+
{:id string?
33+
:name "my-hook"}
34+
@on-before-action*))
35+
(is (match?
36+
{:id string?
37+
:name "my-hook"
38+
:status 0
39+
:output "hey"
40+
:error nil}
41+
@on-after-action*))))
42+
(testing "preToolCall does not matches"
43+
(h/reset-components!)
44+
(h/config! {:hooks {"my-hook" {:type "preToolCall"
45+
:matcher "my-mcp__my.*"
46+
:actions [{:type "shell"
47+
:shell "echo hey"}]}}})
48+
(let [on-before-action* (atom nil)
49+
on-after-action* (atom nil)]
50+
(with-redefs [p/sh (constantly {:exit 2 :out nil :err "stop!"})]
51+
(f.hooks/trigger-if-matches!
52+
:preToolCall
53+
{:server "my-other-mcp"
54+
:tool-name "my-tool"}
55+
{:on-before-action (set-action-payload on-before-action*)
56+
:on-after-action (set-action-payload on-after-action*)}
57+
(h/db)
58+
(h/config)))
59+
(is (match?
60+
nil
61+
@on-before-action*))
62+
(is (match?
63+
nil
64+
@on-after-action*))))
65+
(testing "preToolCall matches"
66+
(h/reset-components!)
67+
(h/config! {:hooks {"my-hook" {:type "preToolCall"
68+
:matcher "my-mcp__my.*"
69+
:actions [{:type "shell"
70+
:shell "echo hey"}]}}})
71+
(let [on-before-action* (atom nil)
72+
on-after-action* (atom nil)]
73+
(with-redefs [p/sh (constantly {:exit 2 :out nil :err "stop!"})]
74+
(f.hooks/trigger-if-matches!
75+
:preToolCall
76+
{:server "my-mcp"
77+
:tool-name "my-tool"}
78+
{:on-before-action (set-action-payload on-before-action*)
79+
:on-after-action (set-action-payload on-after-action*)}
80+
(h/db)
81+
(h/config)))
82+
(is (match?
83+
{:id string?
84+
:name "my-hook"}
85+
@on-before-action*))
86+
(is (match?
87+
{:id string?
88+
:name "my-hook"
89+
:status 2
90+
:output nil
91+
:error "stop!"}
92+
@on-after-action*)))))

0 commit comments

Comments
 (0)