about summary refs log tree commit diff
diff options
context:
space:
mode:
authorArun Isaac2026-04-09 22:22:56 +0100
committerArun Isaac2026-04-10 00:24:20 +0100
commit8c351cc7743a8bd35c027503fbf71cea1201f93e (patch)
tree65b1621115c455002552607bdf1c605c4d76ba9b
parentd14afa811cd0f4b1c191f90695017db74de382e9 (diff)
downloadkaagum-8c351cc7743a8bd35c027503fbf71cea1201f93e.tar.gz
kaagum-8c351cc7743a8bd35c027503fbf71cea1201f93e.tar.lz
kaagum-8c351cc7743a8bd35c027503fbf71cea1201f93e.zip
Refactor permission selection decoding.
Refactor permission selection decoding to be less tightly coupled to
the JSON from the client.
-rw-r--r--kaakaa/tea.scm57
1 files changed, 43 insertions, 14 deletions
diff --git a/kaakaa/tea.scm b/kaakaa/tea.scm
index 46b2e31..a5ae456 100644
--- a/kaakaa/tea.scm
+++ b/kaakaa/tea.scm
@@ -17,6 +17,7 @@
 ;;; along with kaakaa.  If not, see <https://www.gnu.org/licenses/>.
 
 (define-module (kaakaa tea)
+  #:use-module ((rnrs base) #:select (assertion-violation))
   #:use-module (rnrs exceptions)
   #:use-module (rnrs io ports)
   #:use-module (rnrs records syntactic)
@@ -302,10 +303,25 @@ and a list of effects."
              state)
       => (lambda (tool-call)
            (let* ((session-id (tool-call-session-id tool-call))
-                  (outcome (focus (in "result" "outcome")
+                  (outcome (focus (in "result" "outcome" "outcome")
                                   response))
-                  (outcome-type (focus (key-ref "outcome")
-                                       outcome))
+                  (option-id (focus (in "result" "outcome" "optionId")
+                                    response))
+                  ;; Decode permission selection to symbol.
+                  (selection
+                   (cond
+                    ((and (string=? outcome "selected")
+                          (string=? option-id
+                                    (focus (key-ref "optionId") %tool-allow-once)))
+                     'allow-once)
+                    ((and (string=? outcome "selected")
+                          (string=? option-id
+                                    (focus (key-ref "optionId") %tool-reject-once)))
+                     'reject-once)
+                    ;; We don't explicitly look for "cancelled". We defensively
+                    ;; assume anything other than "selected" is "cancelled".
+                    ;; This protects us from buggy clients.
+                    (else 'cancel)))
                   (state
                    (-> state
                        ;; Update tool status.
@@ -314,20 +330,33 @@ and a list of effects."
                                                       session-id))
                             ;; TODO: Implement other tool permissions.
                             (cond
-                             ((string=? outcome-type "cancelled")
-                              'cancelled)
-                             ((and (string=? outcome-type "selected")
-                                   (string=? (focus (key-ref "optionId")
-                                                    outcome)
-                                             (focus (key-ref "optionId")
-                                                    %tool-allow-once)))
+                             ((eq? selection 'cancel) 'cancelled)
+                             ((eq? selection 'allow-once) 'approved)
+                             ((eq? selection 'reject-once) 'rejected)
+                             ;; This branch should be unreachable.
+                             (else
+                              (assertion-violation selection
+                                                   "Invalid selection")))
+                            <>)
+                       ;; Update tool status.
+                       (put (compose tool-call-status
+                                     (state-tool-call (tool-call-id tool-call)
+                                                      session-id))
+                            (cond
+                             ((eq? selection 'cancel) 'cancelled)
+                             ((memq selection '(allow-once allow-always))
                               'approved)
-                             (else 'rejected))
+                             ((memq selection '(reject-once reject-always))
+                              'rejected)
+                             ;; This branch should be unreachable.
+                             (else
+                              (assertion-violation selection
+                                                   "Invalid selection")))
                             <>)
-                       ;; If the tool call was cancelled, set the cancelling
-                       ;; flag to indicate that a cancellation is in progress.
+                       ;; If the tool call was cancelled, set the cancelling flag
+                       ;; to indicate that a cancellation is in progress.
                        (put (state-session-cancelling? session-id)
-                            (string=? outcome-type "cancelled")
+                            (eq? selection 'cancel)
                             <>)
                        ;; Unregister request corresponding to this response.
                        (alist-delete-over state-requests-alist