Skip to content

Commit

Permalink
Start conversation with Agents from within Emacs
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
debanjum committed Oct 20, 2024
1 parent d55cba8 commit ac51920
Showing 1 changed file with 51 additions and 16 deletions.
67 changes: 51 additions & 16 deletions src/interface/emacs/khoj.el
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@
(const "image")
(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
Expand All @@ -144,6 +149,9 @@
(defconst khoj--chat-buffer-name "*🏮 Khoj Chat*"
"Name of chat buffer for Khoj.")

(defvar khoj--selected-agent khoj-default-agent
"Currently selected Khoj agent.")

(defvar khoj--content-type "org"
"The type of content to perform search on.")

Expand Down Expand Up @@ -913,14 +921,16 @@ Call CALLBACK func with response and CBARGS."
(let ((selected-session-id (khoj--select-conversation-session "Open")))
(khoj--load-chat-session khoj--chat-buffer-name selected-session-id)))

(defun khoj--create-chat-session ()
"Create new chat session."
(khoj--call-api "/api/chat/sessions" "POST"))
(defun khoj--create-chat-session (&optional agent)
"Create new chat session with AGENT."
(khoj--call-api "/api/chat/sessions"
"POST"
(when agent `(("agent_slug" ,agent)))))

(defun khoj--new-conversation-session ()
"Create new Khoj conversation session."
(defun khoj--new-conversation-session (&optional agent)
"Create new Khoj conversation session with AGENT."
(thread-last
(khoj--create-chat-session)
(khoj--create-chat-session agent)
(assoc 'conversation_id)
(cdr)
(khoj--chat)))
Expand All @@ -935,6 +945,15 @@ Call CALLBACK func with response and CBARGS."
(khoj--select-conversation-session "Delete")
(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)
"Render chat messages as `org-mode' list item.
MESSAGE is the text of the chat message.
Expand Down Expand Up @@ -1246,6 +1265,20 @@ Paragraph only starts at first text after blank line."
;; 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")))

(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)
(interactive (list (transient-args transient-current-command)))
(progn
Expand Down Expand Up @@ -1287,25 +1320,27 @@ Paragraph only starts at first text after blank line."
(interactive (list (transient-args transient-current-command)))
(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."
(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 _)
"Command to select Khoj conversation sessions to delete."
(interactive (list (transient-args transient-current-command)))
(khoj--delete-conversation-session))

(transient-define-prefix khoj--chat-menu ()
"Open the Khoj chat menu."
["Act"
("c" "Chat" khoj--chat-command)
("o" "Open Conversation" khoj--open-conversation-session-command)
("n" "New Conversation" khoj--new-conversation-session-command)
("d" "Delete Conversation" khoj--delete-conversation-session-command)
("q" "Quit" transient-quit-one)
])
"Create the Khoj Chat Menu and Execute Commands."
[["Configure"
("a" "Select Agent" khoj--agent-switch)]]
[["Act"
("c" "Chat" khoj--chat-command)
("o" "Open Conversation" khoj--open-conversation-session-command)
("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 ()
"Create Khoj Menu to Configure and Execute Commands."
Expand Down

0 comments on commit ac51920

Please sign in to comment.