Skip to content

Commit ad3549e

Browse files
committed
Fix absolute paths being interpreted as commands.
Fixes #199
1 parent 9e41637 commit ad3549e

File tree

3 files changed

+48
-36
lines changed

3 files changed

+48
-36
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+
- Fix absolute paths being interpreted as commands. #199
6+
57
## 0.78.4
68

79
- Fix regression exceptions on specific corner cases with log obfuscation.

src/eca/features/chat.clj

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -505,22 +505,26 @@
505505
(map (fn [[_ quoted unquoted]] (or quoted unquoted)))
506506
(vec))))
507507

508-
(defn ^:private message->decision [message]
509-
(let [slash? (string/starts-with? message "/")]
510-
(if slash?
511-
(let [command (subs message 1)
512-
tokens (let [toks (tokenize-args command)] (if (seq toks) toks [""]))
513-
first-token (first tokens)
514-
args (vec (rest tokens))]
515-
(if (and first-token (string/includes? first-token ":"))
516-
(let [[server prompt] (string/split first-token #":" 2)]
517-
{:type :mcp-prompt
518-
:server server
519-
:prompt prompt
520-
:args args})
521-
{:type :eca-command
522-
:command first-token
523-
:args args}))
508+
(defn ^:private message->decision [message db config]
509+
(let [all-command-names (->> (f.commands/all-commands db config)
510+
(map :name)
511+
set)
512+
slash? (string/starts-with? message "/")
513+
possible-command (when slash? (subs message 1))
514+
[command-name & args] (when possible-command
515+
(let [toks (tokenize-args possible-command)] (if (seq toks) toks [""])))
516+
args (vec args)
517+
command? (contains? all-command-names command-name)]
518+
(if command?
519+
(if (and command-name (string/includes? command-name ":"))
520+
(let [[server prompt] (string/split command-name #":" 2)]
521+
{:type :mcp-prompt
522+
:server server
523+
:prompt prompt
524+
:args args})
525+
{:type :eca-command
526+
:command command-name
527+
:args args})
524528
{:type :prompt-message
525529
:message message})))
526530

@@ -991,7 +995,7 @@
991995
:metrics metrics
992996
:config config
993997
:messenger messenger}
994-
decision (message->decision message)
998+
decision (message->decision message db config)
995999
hook-outputs* (atom [])
9961000
_ (f.hooks/trigger-if-matches! :preRequest
9971001
{:chat-id chat-id

test/eca/features/chat_test.clj

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -500,31 +500,37 @@
500500
(testing "plain prompt message"
501501
(is (= {:type :prompt-message
502502
:message "Hello world"}
503-
(#'f.chat/message->decision "Hello world"))))
503+
(#'f.chat/message->decision "Hello world" {} {}))))
504+
(testing "message starting with a absolute path"
505+
(is (= {:type :prompt-message
506+
:message "/path/to/file check this out"}
507+
(#'f.chat/message->decision "/path/to/file check this out" {} {}))))
504508
(testing "ECA command without args"
505509
(is (= {:type :eca-command
506-
:command "help"
510+
:command "doctor"
507511
:args []}
508-
(#'f.chat/message->decision "/help"))))
512+
(#'f.chat/message->decision "/doctor" {} {}))))
509513
(testing "ECA command with args"
510514
(is (= {:type :eca-command
511-
:command "search"
515+
:command "login"
512516
:args ["foo" "bar"]}
513-
(#'f.chat/message->decision "/search foo bar"))))
517+
(#'f.chat/message->decision "/login foo bar" {} {}))))
514518
(testing "ECA command with args with spaces in quotes"
515519
(is (= {:type :eca-command
516-
:command "search"
520+
:command "login"
517521
:args ["foo bar" "baz" "qux bla blow"]}
518-
(#'f.chat/message->decision "/search \"foo bar\" baz \"qux bla blow\""))))
519-
(testing "MCP prompt without args"
520-
(is (= {:type :mcp-prompt
521-
:server "server"
522-
:prompt "prompt"
523-
:args []}
524-
(#'f.chat/message->decision "/server:prompt"))))
525-
(testing "MCP prompt with args"
526-
(is (= {:type :mcp-prompt
527-
:server "server"
528-
:prompt "prompt"
529-
:args ["arg1" "arg2"]}
530-
(#'f.chat/message->decision "/server:prompt arg1 arg2")))))
522+
(#'f.chat/message->decision "/login \"foo bar\" baz \"qux bla blow\"" {} {}))))
523+
(with-redefs [f.mcp/all-prompts (constantly [{:name "prompt"
524+
:server "server"}])]
525+
(testing "MCP prompt without args"
526+
(is (= {:type :mcp-prompt
527+
:server "server"
528+
:prompt "prompt"
529+
:args []}
530+
(#'f.chat/message->decision "/server:prompt" {} {}))))
531+
(testing "MCP prompt with args"
532+
(is (= {:type :mcp-prompt
533+
:server "server"
534+
:prompt "prompt"
535+
:args ["arg1" "arg2"]}
536+
(#'f.chat/message->decision "/server:prompt arg1 arg2" {} {}))))))

0 commit comments

Comments
 (0)