Я пытаюсь подключиться через Nrepl к неясной базе знаний с открытым исходным кодом, написанной на Clojure, которая на самом деле официально пока не поддерживает этот тип взаимодействия. Все шло хорошо, но потом выясняется, что значения ответов включают недопустимые токены Clojure, такие как ""
Через командную строку взаимодействие будет выглядеть так:
csneps.core.snuser=> (assert! '(Isa Fido Dog))
wft17!: (Isa Fido Dog)
csneps.core.snuser=> (ask '(Isa Fido Dog))
I wonder if wft17!: (Isa Fido Dog)
I know that wft17!: (Isa Fido Dog)
#{wft17!: (Isa Fido Dog)}
Когда я пытаюсь через Nrepl, я получаю эту проблему:
my-project.example => (respond-1 "(ask '(Isa Fido Dog))")
RuntimeException Invalid token: wft17!:
clojure.lang.Util.runtimeException (Util.java:221)
Функция response-1 выглядит следующим образом:
(defn respond-1
([text] (respond-1 text df-nrepl-port))
([text nport] (with-open [conn (nrepl/connect :port nport)]
(-> (nrepl/client conn 1000)
(nrepl/message {:op :eval :code text})
(nrepl/response-values)))))
Я подозреваю, что проблема в том, что Nrepl пытается оценить строку в своей реализации значений ответа:
https://github.com/nrepl/nrepl/blob/master/src/clojure/nrepl/core.clj
(defn read-response-value
"Returns the provided response message, replacing its :value string
with the result of (read)ing it.
Returns the message unchanged if the :value slot is empty or not a
string."
[{:keys [value] :as msg}]
(if-not (string? value)
msg
(try
(assoc msg :value (read-string value))
(catch Exception e
(throw (IllegalStateException. (str "Could not read response value: " value) e))))))
(defn response-values
"Given a seq of responses (as from response-seq or returned from
any function returned by client or client-session), returns a seq
of values read from :value slots found therein."
[responses]
(->> responses
(map read-response-value)
combine-responses
:value))
Полагаю, наилучшим вариантом было бы, чтобы разработчики базы знаний решили проблему и фактически поддержали взаимодействие с nrepl, но, оставив это в стороне, я хотел бы спросить, какой вариант лучше. Должен ли я ветвить nrepl, чтобы реализовать значение read-response-value, которое экранирует символы плохих токенов, написать небольшой клиент Nrepl на Java вместо Clojure, чтобы у меня не было этих ограничений, а затем получить из него экранированные результаты локально или что-то совсем другое?
Заранее спасибо!