Skip to content

Commit f22f404

Browse files
committed
Support visible field in hooks configuration to show or not in client.
1 parent 02b8cc6 commit f22f404

File tree

5 files changed

+63
-16
lines changed

5 files changed

+63
-16
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## Unreleased
44

5+
- Support `visible` field in hooks configuration to show or not in client.
6+
57
## 0.70.3
68

79
- Deprecate prePrompt and postPrompt in favor of preRequest and prePrompt.

docs/configuration.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,8 @@ __Output__: All hook actions allow printing output (stdout) and errors (stderr)
370370

371371
__Matcher__: Specify whether to apply this hook checking a regex applying to `mcp__tool-name`, applicable only for `*ToolCall` hooks.
372372

373+
__Visible__: whether to show or not this hook in chat when executing, defaults to true.
374+
373375
Examples:
374376

375377
=== "Notify after prompt finish"
@@ -398,6 +400,7 @@ Examples:
398400
"check-my-tool": {
399401
"type": "preToolCall",
400402
"matcher": "my-mcp__some-tool",
403+
"visible": false,
401404
"actions": [
402405
{
403406
"type": "shell",
@@ -446,6 +449,7 @@ To configure, add your OTLP collector config via `:otlp` map following [otlp aut
446449
hooks?: {[key: string]: {
447450
type: 'preToolCall' | 'postToolCall' | 'preRequest' | 'postRequest';
448451
matcher: string;
452+
visible?: boolean;
449453
actions: {
450454
type: 'shell';
451455
shell: string;

src/eca/features/chat.clj

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,22 +34,24 @@
3434
:role role
3535
:content content}))
3636

37-
(defn ^:private notify-before-hook-action! [chat-ctx {:keys [id name type]}]
38-
(send-content! chat-ctx :system
39-
{:type :hookActionStarted
40-
:action-type type
41-
:name name
42-
:id id}))
37+
(defn ^:private notify-before-hook-action! [chat-ctx {:keys [id name type visible?]}]
38+
(when visible?
39+
(send-content! chat-ctx :system
40+
{:type :hookActionStarted
41+
:action-type type
42+
:name name
43+
:id id})))
4344

44-
(defn ^:private notify-after-hook-action! [chat-ctx {:keys [id name output error status type]}]
45-
(send-content! chat-ctx :system
46-
{:type :hookActionFinished
47-
:action-type type
48-
:id id
49-
:name name
50-
:status status
51-
:output output
52-
:error error}))
45+
(defn ^:private notify-after-hook-action! [chat-ctx {:keys [id name output error status type visible?]}]
46+
(when visible?
47+
(send-content! chat-ctx :system
48+
{:type :hookActionFinished
49+
:action-type type
50+
:id id
51+
:name name
52+
:status status
53+
:output output
54+
:error error})))
5355

5456
(defn finish-chat-prompt! [status {:keys [message chat-id db* metrics config on-finished-side-effect] :as chat-ctx}]
5557
(swap! db* assoc-in [:chats chat-id :status] status)

src/eca/features/hooks.clj

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,18 +55,22 @@
5555
type (:type action)
5656
name (if (> 1 (count (:actions hook)))
5757
(str name "-" (inc i))
58-
name)]
58+
name)
59+
visible? (get hook :visible true)]
5960
(on-before-action {:id id
61+
:visible? visible?
6062
:name name})
6163
(if-let [[status output error] (run-hook-action! action name data db)]
6264
(on-after-action {:id id
6365
:name name
6466
:type type
67+
:visible? visible?
6568
:status status
6669
:output output
6770
:error error})
6871
(on-after-action {:id id
6972
:name name
73+
:visible? visible?
7074
:type type
7175
:status -1}))))
7276
(:actions hook))))))

test/eca/features/hooks_test.clj

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,13 @@
3030
(h/config)))
3131
(is (match?
3232
{:id string?
33+
:visible? true
3334
:name "my-hook"}
3435
@on-before-action*))
3536
(is (match?
3637
{:id string?
3738
:name "my-hook"
39+
:visible? true
3840
:status 0
3941
:output "hey"
4042
:error nil}
@@ -56,11 +58,42 @@
5658
(h/config)))
5759
(is (match?
5860
{:id string?
61+
:visible? true
5962
:name "my-hook"}
6063
@on-before-action*))
6164
(is (match?
6265
{:id string?
6366
:name "my-hook"
67+
:visible? true
68+
:status 0
69+
:output "hey"
70+
:error nil}
71+
@on-after-action*))))
72+
(testing "when visible is false"
73+
(h/reset-components!)
74+
(h/config! {:hooks {"my-hook" {:type "preRequest"
75+
:visible false
76+
:actions [{:type "shell"
77+
:shell "echo hey"}]}}})
78+
(let [on-before-action* (atom nil)
79+
on-after-action* (atom nil)]
80+
(with-redefs [p/sh (constantly {:exit 0 :out "hey" :err nil})]
81+
(f.hooks/trigger-if-matches!
82+
:preRequest
83+
{:foo "1"}
84+
{:on-before-action (set-action-payload on-before-action*)
85+
:on-after-action (set-action-payload on-after-action*)}
86+
(h/db)
87+
(h/config)))
88+
(is (match?
89+
{:id string?
90+
:visible? false
91+
:name "my-hook"}
92+
@on-before-action*))
93+
(is (match?
94+
{:id string?
95+
:name "my-hook"
96+
:visible? false
6497
:status 0
6598
:output "hey"
6699
:error nil}
@@ -107,11 +140,13 @@
107140
(h/config)))
108141
(is (match?
109142
{:id string?
143+
:visible? true
110144
:name "my-hook"}
111145
@on-before-action*))
112146
(is (match?
113147
{:id string?
114148
:name "my-hook"
149+
:visible? true
115150
:status 2
116151
:output nil
117152
:error "stop!"}

0 commit comments

Comments
 (0)