A tool server is just a REST API that includes an OpenAPI specification, that the AI can use to navigate how to leverage the API.
Preferrably, the OpenAPI specification and the actual code should only be maintained using a single source of truth.
So far I've only found Reitit which seems to work when using vanilla Clojure: https://github.com/metosin/reitit/tree/master/examples/openapi
I've reduced the Clojure dependencies while still getting an Open API specificatoin, to the following, and highlighted which would cause problems when trying to use Babashka:
- β
http-kit
- π§
metosin/reitit-core
- β
meta-merge
- π§ has a Java class
reitit.trie
- β
- β
metosin/reitit-ring
- π§
metosin/reitit-core
- β
ring/ring-core
- β
org.ring-clojure/ring-core-protocols
- β
org.ring-clojure/ring-websocket-protocols
- β
ring/ring-codec
- π§
commons-io
- β
org.apache.commons/commons-fileupload2-core
- π§
crypto-random
- β
crypto-equality
- β
fi.metosin/reitit-openapi
- π§
β
Works.
π§ Might have workaround.
β A good solution will be though.
The depencency meta-merge
has no dependencies of its own:
https://github.com/weavejester/meta-merge/blob/master/project.clj
But it requries a custom Java class for reitit.trie
for performance.
I wonder how it is done i ClojureScript π€
Is mainly just a combination of problems from reitit-code
and ring-code
.
org.apache.commons/commons-fileupload2-core
is being used for "multipart" file uploads,
which propably isn't a feature that can or should be excluded.
Code for the dependency is here:
https://github.com/apache/commons-fileupload/blob/master/commons-fileupload2-cor
Other dependencies might have easier workarounds.
common-io
is only providing a Java method to convert an InputStream
to a byte array.
The following might not be as performant, but should have the same signature (can/should this be written i Clojure?):
package ring;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.IOException;
public final class IOUtils {
private IOUtils () {}
// https://codingtechroom.com/question/io-utils-to-byte-array-alternatives
public static byte[] toByteArray(final InputStream inputStream) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
byteArrayOutputStream.write(buffer, 0, bytesRead);
}
return byteArrayOutputStream.toByteArray();
}
}
Also, crypto-random
seems to only be included to provide crypto.random/bytes
which could be copied into the source code to avoid the other (unused) Java dependencies.
...
(:import java.security.SecureRandom))
(defn random-bytes
"Returns a random byte array of the specified size."
[size]
(let [seed (byte-array size)]
(.nextBytes (SecureRandom.) seed)
seed))
And (FileUtils/writeStringToFile resource "just testing")
was used in a test
and could be replaced with (spit resource "just testing")
.
There seems be quite a bit of work ahead to get Reitit and its OpenAPI library working with Babashka.
Also the dependencies and setup for Reitit is a bit confusing.
E.g. it isn't obvious that one needs :muuntaja m/instance
and cannot just apply some wrap-json-response
middleware.