Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions README.org
Original file line number Diff line number Diff line change
Expand Up @@ -827,6 +827,14 @@ All of the above settings can be applied on a per-project basis using [[https://
- =C-c C-c= - Interrupt current agent operation
- =TAB and Shift-TAB= - Navigate interactive elements

When an agent asks a question, its form renders in the buffer and =TAB=
stops on each option, field and button:

- =RET= - Pick the option, toggle the checkbox, edit the field, or press
the button at point.
- =C-c C-c= - Interrupt, cancelling any question still waiting for an
answer.

To customize =RET= binding behaviour, you can use something like:

#+begin_src emacs-lisp :lexical no
Expand Down
1,602 changes: 1,602 additions & 0 deletions agent-shell-elicitation.el

Large diffs are not rendered by default.

65 changes: 39 additions & 26 deletions agent-shell-ui.el
Original file line number Diff line number Diff line change
Expand Up @@ -76,20 +76,22 @@ For example, to fold with TAB as well as RET:
Rebind with `define-key' rather than `setq': already rendered text
holds on to this keymap object.")

(defun agent-shell-ui--echo-action-hint (verb)
(defun agent-shell-ui--echo-action-hint (verb &optional command keymap)
"Echo how to run an action described by VERB.

Searches `agent-shell-ui-fragment-map' for whichever key runs
`agent-shell-ui-toggle-fragment', skipping mouse bindings so the hint
names something the user can press.
Searches KEYMAP for whichever key runs COMMAND, skipping mouse bindings
so the hint names something the user can press. COMMAND defaults to
`agent-shell-ui-toggle-fragment' and KEYMAP to
`agent-shell-ui-fragment-map', which is the fold chrome; other chrome
bound to its own shared map passes both.

For example, VERB \"toggle\" echoes \"Press RET to toggle\" with the
default bindings, or \"Press TAB to toggle\" once that map binds TAB."
(when-let* ((keys (seq-remove
(lambda (key) (mouse-event-p (aref key 0)))
(where-is-internal
#'agent-shell-ui-toggle-fragment
(list agent-shell-ui-fragment-map)))))
(or command #'agent-shell-ui-toggle-fragment)
(list (or keymap agent-shell-ui-fragment-map))))))
(message "Press %s to %s" (key-description (seq-first keys)) verb)))

(defun agent-shell-ui--fragment-help-echo (qualified-id)
Expand All @@ -99,6 +101,17 @@ otherwise nil so the id stays hidden from users."
(when agent-shell-ui-debug-enabled
qualified-id))

(defun agent-shell-ui--fragment-help-echo-properties (qualified-id)
"Return `help-echo' properties tagging QUALIFIED-ID, or nil to add none.

Applied across a region, a nil `help-echo' does not merely fail to tag
it: `add-text-properties' sets the property to nil, erasing whatever
help the region's own content carried. A body holds arbitrary rendered
content, which may carry help of its own, so adding no property at all
is what leaves it in place."
(when-let* ((help (agent-shell-ui--fragment-help-echo qualified-id)))
(list 'help-echo help)))

(cl-defun agent-shell-ui-make-fragment-model (&key (namespace-id "global") (block-id "1") label-left label-right body group-id group-label (group-expanded t))
"Create a fragment model alist.
NAMESPACE-ID, BLOCK-ID, LABEL-LEFT, LABEL-RIGHT, and BODY are the keys.
Expand Down Expand Up @@ -438,10 +451,10 @@ match. Explicit `invisible' assignment overrides any value the
new chars might have inherited via rear-stickiness from preceding
trailing-whitespace chars."
(add-text-properties start end
`(agent-shell-ui-section body
help-echo ,(agent-shell-ui--fragment-help-echo qualified-id)
read-only t
front-sticky (read-only)))
(append (list 'agent-shell-ui-section 'body
'read-only t
'front-sticky '(read-only))
(agent-shell-ui--fragment-help-echo-properties qualified-id)))
(when state
(put-text-property start end 'agent-shell-ui-state state))
(put-text-property start end 'invisible (if body-invisible t nil)))
Expand Down Expand Up @@ -636,10 +649,10 @@ be handed in."
:hint "toggle"))
(let ((insert-end (point)))
(add-text-properties insert-start insert-end
`(agent-shell-ui-section ,section
help-echo ,(agent-shell-ui--fragment-help-echo qualified-id)
read-only t
front-sticky (read-only)))
(append (list 'agent-shell-ui-section section
'read-only t
'front-sticky '(read-only))
(agent-shell-ui--fragment-help-echo-properties qualified-id)))
(when state
(put-text-property insert-start insert-end
'agent-shell-ui-state state))))))))
Expand Down Expand Up @@ -1106,10 +1119,10 @@ indents a child's header line under its group header."
:hint "toggle"))
(setq label-left-end (point))
(add-text-properties label-left-start label-left-end
`(agent-shell-ui-section label-left
help-echo ,(agent-shell-ui--fragment-help-echo qualified-id)
read-only t
front-sticky (read-only)))
(append (list 'agent-shell-ui-section 'label-left
'read-only t
'front-sticky '(read-only))
(agent-shell-ui--fragment-help-echo-properties qualified-id)))
(setq need-space t))

(when label-right
Expand All @@ -1121,10 +1134,10 @@ indents a child's header line under its group header."
:hint "toggle"))
(setq label-right-end (point))
(add-text-properties label-right-start label-right-end
`(agent-shell-ui-section label-right
help-echo ,(agent-shell-ui--fragment-help-echo qualified-id)
read-only t
front-sticky (read-only))))
(append (list 'agent-shell-ui-section 'label-right
'read-only t
'front-sticky '(read-only))
(agent-shell-ui--fragment-help-echo-properties qualified-id))))

(when body
(when (or label-left label-right)
Expand All @@ -1141,10 +1154,10 @@ indents a child's header line under its group header."
(insert (agent-shell-ui--indent-text clean-body body-indent)))
(setq body-end (point))
(add-text-properties body-start body-end
`(agent-shell-ui-section body
help-echo ,(agent-shell-ui--fragment-help-echo qualified-id)
read-only t
front-sticky (read-only))))
(append (list 'agent-shell-ui-section 'body
'read-only t
'front-sticky '(read-only))
(agent-shell-ui--fragment-help-echo-properties qualified-id))))
;; Indent a group child's header line under its group header. The
;; body already carries its own (deeper) `line-prefix' from above.
;; A child with neither label has no header line to indent (the
Expand Down
8 changes: 8 additions & 0 deletions agent-shell-viewport.el
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@
(declare-function agent-shell-interaction-at-point "agent-shell")
(declare-function agent-shell-copy-session-id "agent-shell")
(declare-function agent-shell-cycle-session-mode "agent-shell")
(declare-function agent-shell-elicitation-next-field "agent-shell-elicitation")
(declare-function agent-shell-elicitation-previous-field "agent-shell-elicitation")
(declare-function agent-shell-interrupt "agent-shell")
(declare-function agent-shell-interrupt-confirmed-p "agent-shell")
(declare-function agent-shell-open-transcript "agent-shell")
Expand Down Expand Up @@ -638,6 +640,8 @@ in, landing on the item after it rather than on its next cell."
(agent-shell-ui-forward-block)))
(button-pos (save-mark-and-excursion
(agent-shell-next-permission-button)))
(field-pos (save-mark-and-excursion
(agent-shell-elicitation-next-field)))
(image-pos (save-mark-and-excursion
(agent-shell-markdown--next-visible-image)))
(link-pos (save-mark-and-excursion
Expand All @@ -657,6 +661,7 @@ in, landing on the item after it rather than on its next cell."
response-start
block-pos
button-pos
field-pos
image-pos
link-pos
source-block-pos
Expand Down Expand Up @@ -704,6 +709,8 @@ in, as `agent-shell-viewport-next-item' does from its end."
(agent-shell-ui-backward-block)))
(button-pos (save-mark-and-excursion
(agent-shell-previous-permission-button)))
(field-pos (save-mark-and-excursion
(agent-shell-elicitation-previous-field)))
(image-pos (save-mark-and-excursion
(agent-shell-markdown--previous-visible-image)))
(link-pos (save-mark-and-excursion
Expand All @@ -725,6 +732,7 @@ in, as `agent-shell-viewport-next-item' does from its end."
response-start
block-pos
button-pos
field-pos
image-pos
link-pos
source-block-pos
Expand Down
Loading
Loading