branch: externals/ellama
commit c6cdb86950fafcf9902da067f2314997fd1f7b94
Merge: c491bf4c5b 1fd26a56e5
Author: Sergey Kostyaev <[email protected]>
Commit: GitHub <[email protected]>
Merge pull request #370 from s-kostyaev/file-based-blueprints
File based blueprints
---
NEWS.org | 10 ++++
README.org | 11 +++++
blueprints/changelog.ellama-blueprint | 21 ++++++++
docs/changelog.org | 3 --
ellama-blueprint.el | 82 ++++++++++++++++++++++++++-----
ellama-tools.el | 28 +++++++++++
ellama.el | 2 +-
ellama.info | 92 +++++++++++++++++++++--------------
8 files changed, 197 insertions(+), 52 deletions(-)
diff --git a/NEWS.org b/NEWS.org
index 830120061d..710e9bd0ff 100644
--- a/NEWS.org
+++ b/NEWS.org
@@ -1,3 +1,13 @@
+* Version 1.10.12
+- Added prepend_file tool that allows prepending content to files. This expands
+ the set of file manipulation utilities available through the ellama tools.
+- Introduced customizable global and local directories for storing blueprint
+ files. Added support for configurable file extensions and utility functions
to
+ locate, read, and load blueprints from files. This provides a flexible,
+ project-aware mechanism for discovering and loading blueprint resources.
+- Switched to backquote quoting for ellama-blueprint font-lock. This adjustment
+ ensures the regex is evaluated correctly and the font-lock face is applied as
+ intended.
* Version 1.10.11
- Remove explicit handling of numeric arguments in ellama-tools.
- Add argument processing and type wrapping to tool definitions.
diff --git a/README.org b/README.org
index c51399e195..1c46bc2672 100644
--- a/README.org
+++ b/README.org
@@ -379,6 +379,11 @@ argument generated text string.
will work without user confirmation.
- ~ellama-tools-argument-max-length~: Max length of function argument in the
confirmation prompt. Default value 50.
+- ~ellama-blueprint-global-dir~: Global directory for storing blueprint files.
+- ~ellama-blueprint-local-dir~: Local directory name for project-specific
+ blueprints.
+- ~ellama-blueprint-file-extensions~: File extensions recognized as blueprint
+ files.
* Context Management
@@ -623,6 +628,12 @@ Ellama provides several functions to create, select, and
manage blueprints:
from the collection of blueprints. It filters prompts based on whether they
are for developers and their source (user-defined, community, or all).
+** Blueprints files
+
+You can also store blueprints as plain text files. You can store it globally
+inside ~ellama-blueprint-global-dir~ or locally in the project local directory
+~ellama-blueprint-local-dir~ with ~ellama-blueprint-file-extensions~.
+
** Variable Management
Blueprints can include variables that need to be filled before running the chat
diff --git a/blueprints/changelog.ellama-blueprint
b/blueprints/changelog.ellama-blueprint
new file mode 100644
index 0000000000..a99656cb60
--- /dev/null
+++ b/blueprints/changelog.ellama-blueprint
@@ -0,0 +1,21 @@
+Call shell_command tool with "git log --reverse main..HEAD" argument. Based on
+the output write short changelog in org-mode list format. Use "~tildas~"
quoting
+instead of "`backticks`" quoting. Do not add any anknowledgements. Every
+changelog element should be ended with full stop. Changelog shouldn't be too
+short or too long, use detailed description for major changes and concise
+description for minor changes. Write it to ./NEWS.org using prepend_file tool
+with header:
+
+* Version {version}
+
+After header should be changelog content. Content should ends with single
+newline.
+Example:
+ ```text
+* Version {version}
+- Some change description. Some additional information.
+- Major change detailed description. This change improves ~ellama-something~.
+ Some additional information.
+- Third change description.
+- Some fix in ~ellama-example-command~ description.
+```
diff --git a/docs/changelog.org b/docs/changelog.org
deleted file mode 100644
index 9cfaa62fb4..0000000000
--- a/docs/changelog.org
+++ /dev/null
@@ -1,3 +0,0 @@
-Based on shell_command "git log --reverse main..HEAD" output write short
-changelog in markdown list format. Do not add any headings or anknowledgements.
-Every changelog element should be ended with full stop.
diff --git a/ellama-blueprint.el b/ellama-blueprint.el
index 685ab534a5..79afea10da 100644
--- a/ellama-blueprint.el
+++ b/ellama-blueprint.el
@@ -37,6 +37,70 @@
:group 'ellama
:type '(repeat plist))
+(defcustom ellama-blueprint-global-dir
+ (expand-file-name "ellama/blueprints" user-emacs-directory)
+ "Global directory for storing blueprint files."
+ :group 'ellama
+ :type 'directory)
+
+(defcustom ellama-blueprint-local-dir "blueprints"
+ "Local directory name for project-specific blueprints.
+When set to a string like \"blueprints\", it will look for this
+directory in the current project root."
+ :group 'ellama
+ :type 'string)
+
+(defcustom ellama-blueprint-file-extensions '("ellama-blueprint" "blueprint")
+ "File extensions recognized as blueprint files."
+ :group 'ellama
+ :type '(repeat string))
+
+(defun ellama-blueprint-get-local-dir ()
+ "Get local blueprint directory for current project."
+ (let ((project-root (ellama-tools-project-root-tool)))
+ (expand-file-name ellama-blueprint-local-dir project-root)))
+
+(defun ellama-blueprint-find-files (&optional dir extensions)
+ "Find blueprint files in DIR with given EXTENSIONS."
+ (let* ((search-dir (or dir ellama-blueprint-global-dir))
+ (exts (or extensions ellama-blueprint-file-extensions))
+ (files '()))
+ (when (file-exists-p search-dir)
+ (dolist (ext exts)
+ (setq files (append files
+ (directory-files-recursively
+ search-dir (concat "\\." ext "\\'"))))))
+ files))
+
+(defun ellama-blueprint-load-from-files ()
+ "Load blueprints from files."
+ (let ((global-files (ellama-blueprint-find-files
ellama-blueprint-global-dir))
+ (local-files (ellama-blueprint-find-files
(ellama-blueprint-get-local-dir)))
+ blueprints)
+ (dolist (file (append global-files local-files))
+ (when-let ((content (ellama-blueprint-read-file file))
+ (name (file-name-sans-extension (file-name-nondirectory
file)))
+ (prompt (string-trim content)))
+ (push `(:act ,name :prompt ,prompt :file ,file) blueprints)))
+ blueprints))
+
+(defun ellama-blueprint-read-file (file)
+ "Read blueprint content from FILE."
+ (when (file-exists-p file)
+ (with-temp-buffer
+ (insert-file-contents file)
+ (buffer-string))))
+
+(defun ellama-blueprint-get-all-sources ()
+ "Get blueprints from all sources."
+ (let ((file-blueprints (ellama-blueprint-load-from-files))
+ (variable-blueprints ellama-blueprints)
+ (community-blueprints (ellama-community-prompts-ensure)))
+ (seq-uniq
+ (append file-blueprints variable-blueprints community-blueprints)
+ (lambda (b1 b2)
+ (string= (plist-get b1 :act) (plist-get b2 :act))))))
+
;;;###autoload
(defun ellama-blueprint-set-system-kill-buffer ()
"Set system message from current buffer and kill it."
@@ -62,10 +126,6 @@
"{\\([[:alnum:]_-]+\\)}"
"Regular expression to match blueprint variables like {var_name}.")
-(defvar ellama-blueprint-font-lock-keywords
- '((,ellama-blueprint-variable-regexp 1 'font-lock-keyword-face))
- "Highlight variables in curly braces for Ellama Blueprint Mode.")
-
;;;###autoload
(define-derived-mode ellama-blueprint-mode
text-mode
@@ -73,7 +133,7 @@
"Toggle Ellama Blueprint mode."
:keymap ellama-blueprint-mode-map
:group 'ellama
- (setq font-lock-defaults '(((,ellama-blueprint-variable-regexp 1
font-lock-keyword-face t))))
+ (setq font-lock-defaults `(((,ellama-blueprint-variable-regexp 1
font-lock-keyword-face t))))
(setq header-line-format
(concat
(propertize
@@ -102,6 +162,9 @@
(define-key m [mode-line mouse-1]
#'ellama-kill-current-buffer)
m)))))
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.ellama-blueprint\\'" .
ellama-blueprint-mode))
+
(defvar ellama-blueprint-buffer "*ellama-blueprint-buffer*"
"Buffer for prompt blueprint.")
@@ -151,13 +214,8 @@ ARGS contains keys for fine control.
(collection (pcase source
('user ellama-blueprints)
('community (ellama-community-prompts-ensure))
- (_ (seq-union
- ellama-blueprints
- (ellama-community-prompts-ensure)
- (lambda (blueprint1 blueprint2)
- (string=
- (plist-get blueprint1 :act)
- (plist-get blueprint2 :act)))))))
+ ('files (ellama-blueprint-load-from-files))
+ (_ (ellama-blueprint-get-all-sources))))
selected-act
selected-prompt)
;; Collect unique acts from the filtered collection
diff --git a/ellama-tools.el b/ellama-tools.el
index 47db0e700a..a2b6b63e59 100644
--- a/ellama-tools.el
+++ b/ellama-tools.el
@@ -303,6 +303,34 @@ TOOL-PLIST is a property list in the format expected by
`llm-make-tool'."
:description
"Append CONTENT to the file located at the specified PATH."))
+(defun ellama-tools-prepend-file-tool (path content)
+ "Prepend CONTENT to the file located at the specified PATH."
+ (with-current-buffer (find-file-noselect path)
+ (goto-char (point-min))
+ (insert content)
+ (save-buffer)))
+
+(ellama-tools-define-tool
+ '(:function
+ ellama-tools-prepend-file-tool
+ :name
+ "prepend_file"
+ :args
+ ((:name
+ "path"
+ :type
+ string
+ :description
+ "Path to the file.")
+ (:name
+ "content"
+ :type
+ string
+ :description
+ "Content to prepend to the file."))
+ :description
+ "Prepend CONTENT to the file located at the specified PATH."))
+
(defun ellama-tools-directory-tree-tool (dir &optional depth)
"Return a string representing the directory tree under DIR.
DEPTH is the current recursion depth, used internally."
diff --git a/ellama.el b/ellama.el
index b02659d5f4..23f41ece93 100644
--- a/ellama.el
+++ b/ellama.el
@@ -6,7 +6,7 @@
;; URL: http://github.com/s-kostyaev/ellama
;; Keywords: help local tools
;; Package-Requires: ((emacs "28.1") (llm "0.24.0") (plz "0.8") (transient
"0.7") (compat "29.1"))
-;; Version: 1.10.11
+;; Version: 1.10.12
;; SPDX-License-Identifier: GPL-3.0-or-later
;; Created: 8th Oct 2023
diff --git a/ellama.info b/ellama.info
index 31d09b1732..ec605322b7 100644
--- a/ellama.info
+++ b/ellama.info
@@ -101,6 +101,7 @@ Using Blueprints
* Key Components of Ellama Blueprints::
* Creating and Managing Blueprints::
+* Blueprints files::
* Variable Management::
* Keymap and Mode::
* Transient Menus::
@@ -503,6 +504,12 @@ argument generated text string.
this list will work without user confirmation.
• ‘ellama-tools-argument-max-length’: Max length of function argument
in the confirmation prompt. Default value 50.
+ • ‘ellama-blueprint-global-dir’: Global directory for storing
+ blueprint files.
+ • ‘ellama-blueprint-local-dir’: Local directory name for
+ project-specific blueprints.
+ • ‘ellama-blueprint-file-extensions’: File extensions recognized as
+ blueprint files.
File: ellama.info, Node: Context Management, Next: Minor modes, Prev:
Configuration, Up: Top
@@ -813,6 +820,7 @@ for interactions.
* Key Components of Ellama Blueprints::
* Creating and Managing Blueprints::
+* Blueprints files::
* Variable Management::
* Keymap and Mode::
* Transient Menus::
@@ -836,7 +844,7 @@ needed to guide the conversation.
developers.
-File: ellama.info, Node: Creating and Managing Blueprints, Next: Variable
Management, Prev: Key Components of Ellama Blueprints, Up: Using Blueprints
+File: ellama.info, Node: Creating and Managing Blueprints, Next: Blueprints
files, Prev: Key Components of Ellama Blueprints, Up: Using Blueprints
7.2 Creating and Managing Blueprints
====================================
@@ -859,9 +867,20 @@ blueprints:
community, or all).
-File: ellama.info, Node: Variable Management, Next: Keymap and Mode, Prev:
Creating and Managing Blueprints, Up: Using Blueprints
+File: ellama.info, Node: Blueprints files, Next: Variable Management, Prev:
Creating and Managing Blueprints, Up: Using Blueprints
-7.3 Variable Management
+7.3 Blueprints files
+====================
+
+You can also store blueprints as plain text files. You can store it
+globally inside ‘ellama-blueprint-global-dir’ or locally in the project
+local directory ‘ellama-blueprint-local-dir’ with
+‘ellama-blueprint-file-extensions’.
+
+
+File: ellama.info, Node: Variable Management, Next: Keymap and Mode, Prev:
Blueprints files, Up: Using Blueprints
+
+7.4 Variable Management
=======================
Blueprints can include variables that need to be filled before running
@@ -873,7 +892,7 @@ the chat session. Ellama provides command to fill these
variables:
File: ellama.info, Node: Keymap and Mode, Next: Transient Menus, Prev:
Variable Management, Up: Using Blueprints
-7.4 Keymap and Mode
+7.5 Keymap and Mode
===================
Ellama provides a local keymap ‘ellama-blueprint-mode-map’ for managing
@@ -897,7 +916,7 @@ available:
File: ellama.info, Node: Transient Menus, Next: Running Blueprints
programmatically, Prev: Keymap and Mode, Up: Using Blueprints
-7.5 Transient Menus
+7.6 Transient Menus
===================
Ellama includes transient menus for easy access to blueprint commands.
@@ -910,7 +929,7 @@ main menu, providing a comprehensive interface for all
Ellama commands.
File: ellama.info, Node: Running Blueprints programmatically, Prev:
Transient Menus, Up: Using Blueprints
-7.6 Running Blueprints programmatically
+7.7 Running Blueprints programmatically
=======================================
The ‘ellama-blueprint-run’ function initiates a chat session using a
@@ -1471,36 +1490,37 @@ their use in free software.
Tag Table:
Node: Top1379
-Node: Installation3633
-Node: Commands8641
-Node: Keymap16080
-Node: Configuration18913
-Node: Context Management24921
-Node: Transient Menus for Context Management25829
-Node: Managing the Context27443
-Node: Considerations28218
-Node: Minor modes28811
-Node: ellama-context-header-line-mode30799
-Node: ellama-context-header-line-global-mode31624
-Node: ellama-context-mode-line-mode32344
-Node: ellama-context-mode-line-global-mode33192
-Node: Ellama Session Header Line Mode33896
-Node: Enabling and Disabling34465
-Node: Customization34912
-Node: Ellama Session Mode Line Mode35200
-Node: Enabling and Disabling (1)35785
-Node: Customization (1)36232
-Node: Using Blueprints36526
-Node: Key Components of Ellama Blueprints37145
-Node: Creating and Managing Blueprints37752
-Node: Variable Management38733
-Node: Keymap and Mode39202
-Node: Transient Menus40138
-Node: Running Blueprints programmatically40684
-Node: MCP Integration41271
-Node: Acknowledgments42296
-Node: Contributions43008
-Node: GNU Free Documentation License43394
+Node: Installation3654
+Node: Commands8662
+Node: Keymap16101
+Node: Configuration18934
+Node: Context Management25234
+Node: Transient Menus for Context Management26142
+Node: Managing the Context27756
+Node: Considerations28531
+Node: Minor modes29124
+Node: ellama-context-header-line-mode31112
+Node: ellama-context-header-line-global-mode31937
+Node: ellama-context-mode-line-mode32657
+Node: ellama-context-mode-line-global-mode33505
+Node: Ellama Session Header Line Mode34209
+Node: Enabling and Disabling34778
+Node: Customization35225
+Node: Ellama Session Mode Line Mode35513
+Node: Enabling and Disabling (1)36098
+Node: Customization (1)36545
+Node: Using Blueprints36839
+Node: Key Components of Ellama Blueprints37479
+Node: Creating and Managing Blueprints38086
+Node: Blueprints files39064
+Node: Variable Management39485
+Node: Keymap and Mode39938
+Node: Transient Menus40874
+Node: Running Blueprints programmatically41420
+Node: MCP Integration42007
+Node: Acknowledgments43032
+Node: Contributions43744
+Node: GNU Free Documentation License44130
End Tag Table