about summary refs log tree commit diff
diff options
context:
space:
mode:
authorArun Isaac2026-11-04 22:56:54 +0000
committerArun Isaac2026-11-05 00:10:14 +0000
commitc688ce130414b10af92c1cfd7372216896c3c45a (patch)
tree32cf16abf3a968f0cc1b3ba3c243adc9ac1523ff
parentd1ef7871b9a2040c3194fa0ad821ec39e3a4f1a9 (diff)
downloadkaagum-c688ce130414b10af92c1cfd7372216896c3c45a.tar.gz
kaagum-c688ce130414b10af92c1cfd7372216896c3c45a.tar.lz
kaagum-c688ce130414b10af92c1cfd7372216896c3c45a.zip
Allow custom tools.
-rw-r--r--README.md48
-rwxr-xr-xbin/kaagum7
2 files changed, 55 insertions, 0 deletions
diff --git a/README.md b/README.md
index 045598c..67a3ad2 100644
--- a/README.md
+++ b/README.md
@@ -34,6 +34,54 @@ Install the `kaagum` and `emacs-agent-shell-kaagum` packages from Guix. Then, pu
 ```
 Change to the directory you want to work in. kaagum will only have access to that directory and its contents. Run `M-x agent-shell` and select `kaagum` from the menu.
 
+# Using custom tools with kaagum
+
+kaagum empowers you to equip your agents with custom tools specific to your needs. To do this, you write a scheme file (let's call it `custom-tools.scm`) that defines your custom tools. Then, you pass that file on to kaagum using the `--more-tools=custom-tools.scm` parameter.
+
+What should your custom tools file look like? Here's an example:
+```scheme
+(use-modules (kaagum tools))
+
+(define %string-length
+  (tool #:description "Compute the length of a string."
+        #:parameters `(("str" . ,(tool-parameter
+                                  #:type "string"
+                                  #:description "String whose length to compute"
+                                  #:required? #t)))
+        #:proc (lambda* (#:key str)
+                 (format #t "~a~%" (string-length str)))
+        #:title (lambda* (#:key str)
+                  (format #f "string-length ~s" str))
+        #:kind "other"))
+
+`(("string-length" . ,%string-length))
+```
+The file must return an association list mapping tool names to definitions (`<tool>` objects) as its final expression.
+
+`<tool>` objects are defined using `tool` from `(kaagum tools)`. `tool` takes the following keyword arguments:
+- **description:** string that describes the tool; this is read by the LLM to decide whether and how to use the tool—make it a detailed documentation of the tool and the parameters that it takes.
+- **parameters:** association list mapping tool parameter names to `<tool-parameter>` objects.
+- **proc:** the actual function run if the tool is executed; parameters are passed to it as keyword arguments, and output must be written to standard output
+- **title:** human-readable string describing what the tool is doing; this is used by the ACP client in its UI
+- **kind:** category of tool—one of `"read"`, `"edit"`, `"delete"`, `"move"`, `"search"`, `"execute"`, `"think"`, `"fetch"`, `"switch_mode"`, or `"other"`; this is also used by the ACP client in its UI
+- **container-mappings:** list of Guix `<file-system-mapping>` objects representing file system paths to mount into the container of the tool call process
+- **container-namespaces:** list of namespaces to create for the container—should be like `%namespaces` from Guix's `(gnu build linux-container)`
+
+`<tool-parameter>` objects are defined using `tool-parameter` from `(kaagum tools)`. tool-parameter takes the following keyword arguments:
+- **type:** parameter type—`"string"`, `"boolean"`, etc.
+- **description:** string describing the tool parameter
+- **required?:** `#t` if this parameter is required (that is, mandatory), else `#f`; if the parameter is not required, the default argument must be specified in the `lambda*` function in `#:proc` and `#:title`.
+
+See definitions of built-in tools under `kaagum/tools/*.scm` for examples.
+
+If your custom tools require other Guile packages or modules, you may provide access by setting the `GUILE_LOAD_PATH` and `GUILE_LOAD_COMPILED_PATH` environment variables. If you're using Emacs agent shell, you can do this by setting the `agent-shell-kaagum-environment` variable.
+```elisp
+(setq agent-shell-kaagum-environment
+      (agent-shell-make-environment-variables
+       "GUILE_LOAD_PATH" "/some/path/"
+       "GUILE_LOAD_COMPILED_PATH" "/some/path/"))
+```
+
 # Contributing
 
 Please report issues or send patches to the public inbox at [kaagum@systemreboot.net](https://lists.systemreboot.net/kaagum/).
diff --git a/bin/kaagum b/bin/kaagum
index 75e837f..2c8c9ee 100755
--- a/bin/kaagum
+++ b/bin/kaagum
@@ -50,6 +50,9 @@ exec guile --no-auto-compile -e main -s "$0" "$@"
         (option (list #\k "api-key-command") #t #f
                 (lambda (opt name arg result)
                   (acons 'api-key-command arg result)))
+        (option (list #\t "more-tools") #t #f
+                (lambda (opt name arg result)
+                  (acons 'more-tools arg result)))
         (option (list "kagi-api-key-command") #t #f
                 (lambda (opt name arg result)
                   (acons 'kagi-api-key-command arg result)))
@@ -75,6 +78,7 @@ Run kaagum AI agent.
   -k, --api-key-command=COMMAND  command to run to get API key
   -m, --model=MODEL              LLM model name to start new sessions with
                                  (default: \"anthropic/claude-opus-4.8\")
+  -t, --more-tools=FILE          scheme file providing more tools to the agent
 
   --kagi-api-key-command=COMMAND command to run to get Kagi API key
 
@@ -128,6 +132,9 @@ Run kaagum AI agent.
                                   %forge-tools
                                   (if kagi-api-key-command
                                       %kagi-tools
+                                      '())
+                                  (if (assq-ref args 'more-tools)
+                                      (load (assq-ref args 'more-tools))
                                       '())))))
          (parameterize ((%kagi-api-key (and kagi-api-key-command
                                             (get-api-key kagi-api-key-command))))