Start conversation with Agents from within Emacs

Exposes a transient switch with available agents as selectable options
in the Khoj chat sub-menu.

Currently shows agent slugs instead of agent names as options. This
isn't the cleanest but gets the job done for now.

Only new conversations with a different agent can be started. Existing
conversations will continue with the original agent it was created with.
The ability to switch the conversation's agent doesn't exist on the
server yet.
This commit is contained in:
Debanjum Singh Solanky 2024-10-20 14:34:42 -07:00
parent d55cba8627
commit ac51920859

View file

@ -127,6 +127,11 @@
(const "image") (const "image")
(const "pdf"))) (const "pdf")))
(defcustom khoj-default-agent "khoj"
"The default agent to chat with. See https://app.khoj.dev/agents for available options."
:group 'khoj
:type 'string)
;; -------------------------- ;; --------------------------
;; Khoj Dynamic Configuration ;; Khoj Dynamic Configuration
@ -144,6 +149,9 @@
(defconst khoj--chat-buffer-name "*🏮 Khoj Chat*" (defconst khoj--chat-buffer-name "*🏮 Khoj Chat*"
"Name of chat buffer for Khoj.") "Name of chat buffer for Khoj.")
(defvar khoj--selected-agent khoj-default-agent
"Currently selected Khoj agent.")
(defvar khoj--content-type "org" (defvar khoj--content-type "org"
"The type of content to perform search on.") "The type of content to perform search on.")
@ -913,14 +921,16 @@ Call CALLBACK func with response and CBARGS."
(let ((selected-session-id (khoj--select-conversation-session "Open"))) (let ((selected-session-id (khoj--select-conversation-session "Open")))
(khoj--load-chat-session khoj--chat-buffer-name selected-session-id))) (khoj--load-chat-session khoj--chat-buffer-name selected-session-id)))
(defun khoj--create-chat-session () (defun khoj--create-chat-session (&optional agent)
"Create new chat session." "Create new chat session with AGENT."
(khoj--call-api "/api/chat/sessions" "POST")) (khoj--call-api "/api/chat/sessions"
"POST"
(when agent `(("agent_slug" ,agent)))))
(defun khoj--new-conversation-session () (defun khoj--new-conversation-session (&optional agent)
"Create new Khoj conversation session." "Create new Khoj conversation session with AGENT."
(thread-last (thread-last
(khoj--create-chat-session) (khoj--create-chat-session agent)
(assoc 'conversation_id) (assoc 'conversation_id)
(cdr) (cdr)
(khoj--chat))) (khoj--chat)))
@ -935,6 +945,15 @@ Call CALLBACK func with response and CBARGS."
(khoj--select-conversation-session "Delete") (khoj--select-conversation-session "Delete")
(khoj--delete-chat-session))) (khoj--delete-chat-session)))
(defun khoj--get-agents ()
"Get list of available Khoj agents."
(let* ((response (khoj--call-api "/api/agents" "GET"))
(agents (mapcar (lambda (agent)
(cons (cdr (assoc 'name agent))
(cdr (assoc 'slug agent))))
response)))
agents))
(defun khoj--render-chat-message (message sender &optional receive-date) (defun khoj--render-chat-message (message sender &optional receive-date)
"Render chat messages as `org-mode' list item. "Render chat messages as `org-mode' list item.
MESSAGE is the text of the chat message. MESSAGE is the text of the chat message.
@ -1246,6 +1265,20 @@ Paragraph only starts at first text after blank line."
;; dynamically set choices to content types enabled on khoj backend ;; dynamically set choices to content types enabled on khoj backend
:choices (or (ignore-errors (mapcar #'symbol-name (khoj--get-enabled-content-types))) '("all" "org" "markdown" "pdf" "image"))) :choices (or (ignore-errors (mapcar #'symbol-name (khoj--get-enabled-content-types))) '("all" "org" "markdown" "pdf" "image")))
(transient-define-argument khoj--agent-switch ()
:class 'transient-switches
:argument-format "--agent=%s"
:argument-regexp ".+"
:init-value (lambda (obj)
(oset obj value (format "--agent=%s" khoj--selected-agent)))
:choices (or (ignore-errors (mapcar #'cdr (khoj--get-agents))) '("khoj"))
:reader (lambda (prompt initial-input history)
(let* ((agents (khoj--get-agents))
(selected (completing-read prompt agents nil t initial-input history))
(slug (cdr (assoc selected agents))))
(setq khoj--selected-agent slug)
slug)))
(transient-define-suffix khoj--search-command (&optional args) (transient-define-suffix khoj--search-command (&optional args)
(interactive (list (transient-args transient-current-command))) (interactive (list (transient-args transient-current-command)))
(progn (progn
@ -1287,10 +1320,11 @@ Paragraph only starts at first text after blank line."
(interactive (list (transient-args transient-current-command))) (interactive (list (transient-args transient-current-command)))
(khoj--open-conversation-session)) (khoj--open-conversation-session))
(transient-define-suffix khoj--new-conversation-session-command (&optional _) (transient-define-suffix khoj--new-conversation-session-command (&optional args)
"Command to select Khoj conversation sessions to open." "Command to select Khoj conversation sessions to open."
(interactive (list (transient-args transient-current-command))) (interactive (list (transient-args transient-current-command)))
(khoj--new-conversation-session)) (let ((agent-slug (transient-arg-value "--agent=" args)))
(khoj--new-conversation-session agent-slug)))
(transient-define-suffix khoj--delete-conversation-session-command (&optional _) (transient-define-suffix khoj--delete-conversation-session-command (&optional _)
"Command to select Khoj conversation sessions to delete." "Command to select Khoj conversation sessions to delete."
@ -1298,14 +1332,15 @@ Paragraph only starts at first text after blank line."
(khoj--delete-conversation-session)) (khoj--delete-conversation-session))
(transient-define-prefix khoj--chat-menu () (transient-define-prefix khoj--chat-menu ()
"Open the Khoj chat menu." "Create the Khoj Chat Menu and Execute Commands."
["Act" [["Configure"
("c" "Chat" khoj--chat-command) ("a" "Select Agent" khoj--agent-switch)]]
("o" "Open Conversation" khoj--open-conversation-session-command) [["Act"
("n" "New Conversation" khoj--new-conversation-session-command) ("c" "Chat" khoj--chat-command)
("d" "Delete Conversation" khoj--delete-conversation-session-command) ("o" "Open Conversation" khoj--open-conversation-session-command)
("q" "Quit" transient-quit-one) ("n" "New Conversation" khoj--new-conversation-session-command)
]) ("d" "Delete Conversation" khoj--delete-conversation-session-command)
("q" "Quit" transient-quit-one)]])
(transient-define-prefix khoj--menu () (transient-define-prefix khoj--menu ()
"Create Khoj Menu to Configure and Execute Commands." "Create Khoj Menu to Configure and Execute Commands."