branch: externals/ellama
commit f0f4589c72fa2ff01e6bde3bf3c93408a3af9d3f
Merge: c6cdb86950 4868cf4333
Author: Sergey Kostyaev <[email protected]>
Commit: GitHub <[email protected]>
Merge pull request #372 from s-kostyaev/implement-skills
Add skills system to Ellama
---
NEWS.org | 4 ++
README.org | 56 +++++++++++++++++
ellama-skills.el | 123 ++++++++++++++++++++++++++++++++++++
ellama.el | 14 ++++-
ellama.info | 156 +++++++++++++++++++++++++++++++++++-----------
skills/changelog/SKILL.md | 35 +++++++++++
6 files changed, 349 insertions(+), 39 deletions(-)
diff --git a/NEWS.org b/NEWS.org
index 710e9bd0ff..0b7cadbbb6 100644
--- a/NEWS.org
+++ b/NEWS.org
@@ -1,3 +1,7 @@
+* Version 1.11.0
+- Add skills system to Ellama.
+- Add Agent Skills to the documentation.
+- Add changelog generation skill to the project.
* 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.
diff --git a/README.org b/README.org
index 1c46bc2672..e3f7ceb6d2 100644
--- a/README.org
+++ b/README.org
@@ -384,6 +384,10 @@ argument generated text string.
blueprints.
- ~ellama-blueprint-file-extensions~: File extensions recognized as blueprint
files.
+- ~ellama-skills-global-path~: Path to the global directory containing Agent
+ Skills.
+- ~ellama-skills-local-path~: Project-relative path for local Agent Skills.
+ Default value is ~"skills"~.
* Context Management
@@ -711,6 +715,58 @@ to ~ellama~ you can add duckduckgo mcp server
tools)))))
#+end_src
+* Agent Skills
+
+Ellama supports *Agent Skills*, a lightweight format for extending AI
+capabilities. Skills are loaded into context only when needed (Progressive
+Disclosure).
+
+** Directory Structure
+
+Ellama looks for skills in two locations:
+1. *Global*: =~/.emacs.d/ellama/skills/= (Customizable via
+~ellama-skills-global-path~)
+2. *Project-Local*: ~skills/~ inside your project root (Customizable via
+~ellama-skills-local-path~)
+
+A skill is a directory containing a ~SKILL.md~ file. This file includes
metadata
+(~name~ and ~description~, at minimum) and instructions that tell an agent how
+to perform a specific task. Skills can also bundle scripts, templates, and
+reference materials.
+
+#+begin_src
+my-project/
+└──skills/
+ └── pdf-processing/
+ ├── SKILL.md # Required: instructions + metadata
+ ├── scripts/ # Optional: executable code
+ ├── references/ # Optional: documentation
+ └── assets/ # Optional: templates, resources
+#+end_src
+
+** Creating a Skill
+
+SKILL.md must contain YAML frontmatter:
+
+#+begin_src markdown
+---
+name: pdf-processing
+description: Extract text from PDFs and summarize them.
+---
+
+# PDF Processing Instructions
+To extract text from a PDF...
+#+end_src
+
+** How it works
+
+*Auto-Discovery*: Ellama scans skill directories automatically whenever a chat
+ starts.
+*Context*: Skill metadata (name, description, location) is injected into the
+ system prompt.
+*Activation*: The LLM uses the read_file tool to load the SKILL.md content when
+ needed.
+
* Acknowledgments
Thanks [[https://github.com/jmorganca][Jeffrey Morgan]] for excellent project
[[https://github.com/jmorganca/ollama][ollama]]. This project
diff --git a/ellama-skills.el b/ellama-skills.el
new file mode 100644
index 0000000000..a58c2c3f63
--- /dev/null
+++ b/ellama-skills.el
@@ -0,0 +1,123 @@
+;;; ellama-skills.el --- Working with skills -*- lexical-binding: t;
package-lint-main-file: "ellama.el"; -*-
+
+;; Copyright (C) 2023-2026 Free Software Foundation, Inc.
+
+;; Author: Sergey Kostyaev <[email protected]>
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; This file is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; Ellama is a tool for interacting with large language models from Emacs.
+;; It allows you to ask questions and receive responses from the
+;; LLMs. Ellama can perform various tasks such as translation, code
+;; review, summarization, enhancing grammar/spelling or wording and
+;; more through the Emacs interface. Ellama natively supports streaming
+;; output, making it effortless to use with your preferred text editor.
+;;
+
+;;; Code:
+(require 'cl-lib)
+(require 'ellama-tools)
+(require 'yaml)
+
+(defcustom ellama-skills-global-path
+ (expand-file-name "ellama/skills" user-emacs-directory)
+ "Path to the global directory containing Agent Skills."
+ :type 'directory
+ :group 'ellama)
+
+(defcustom ellama-skills-local-path "skills"
+ "Project-relative path for local Agent Skills."
+ :type 'string
+ :group 'ellama)
+
+(cl-defstruct ellama-skill
+ id ; The folder name
+ name ; From frontmatter
+ description ; From frontmatter
+ path ; Absolute path to the skill directory
+ file-path) ; Absolute path to SKILL.md
+
+(defun ellama-skills--parse-frontmatter (file)
+ "Parse YAML frontmatter from FILE using yaml.el."
+ (with-temp-buffer
+ (insert-file-contents file)
+ (goto-char (point-min))
+ (if (and (looking-at "^---[ \t]*$")
+ (search-forward-regexp "^---[ \t]*$" nil t 2))
+ (let* ((end (match-beginning 0))
+ (start (save-excursion (goto-char (point-min)) (forward-line)
(point)))
+ (yaml-string (buffer-substring-no-properties start end)))
+ (condition-case nil
+ (yaml-parse-string yaml-string
+ :object-type 'alist
+ :object-key-type 'symbol)
+ (error nil)))
+ nil)))
+
+(defun ellama-skills--scan-directory (root-dir)
+ "Return list of `ellama-skill` structs found in ROOT-DIR."
+ (let (skills)
+ (when (and root-dir (file-exists-p root-dir))
+ (dolist (skill-dir (directory-files root-dir t "^[^.]"))
+ (when (file-directory-p skill-dir)
+ (let ((skill-file (expand-file-name "SKILL.md" skill-dir)))
+ (when (file-exists-p skill-file)
+ (let* ((meta (ellama-skills--parse-frontmatter skill-file))
+ (name (alist-get 'name meta))
+ (desc (alist-get 'description meta)))
+ (when (and name desc)
+ (push (make-ellama-skill
+ :id (file-name-nondirectory skill-dir)
+ :name name
+ :description desc
+ :path skill-dir
+ :file-path skill-file)
+ skills))))))))
+ skills))
+
+(defun ellama-skills-get-project-dir ()
+ "Get the absolute path to the project local skills directory."
+ (let ((root (ellama-tools-project-root-tool)))
+ (when root
+ (expand-file-name ellama-skills-local-path root))))
+
+(defun ellama-get-skills ()
+ "Scan and return all available skills (global and local)."
+ (append (ellama-skills--scan-directory ellama-skills-global-path)
+ (ellama-skills--scan-directory (ellama-skills-get-project-dir))))
+
+;;;###autoload
+(defun ellama-skills-generate-prompt ()
+ "Generate the <available_skills> XML block for the system prompt."
+ (let ((skills (ellama-get-skills)))
+ (if skills
+ (concat
+ "\n<available_skills>\n"
+ (mapconcat
+ (lambda (skill)
+ (format " <skill>\n <name>%s</name>\n
<description>%s</description>\n <location>%s</location>\n </skill>"
+ (ellama-skill-name skill)
+ (ellama-skill-description skill)
+ (ellama-skill-file-path skill)))
+ skills
+ "\n")
+ "\n</available_skills>\n"
+ "You have access to the skills listed above. To use a skill, use the
`read_file` tool on the file path specified in <location> to load its
instructions.")
+ "")))
+
+(provide 'ellama-skills)
+;;; ellama-skills.el ends here
diff --git a/ellama.el b/ellama.el
index 23f41ece93..df6b8f1e16 100644
--- a/ellama.el
+++ b/ellama.el
@@ -5,8 +5,8 @@
;; Author: Sergey Kostyaev <[email protected]>
;; 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.12
+;; Package-Requires: ((emacs "28.1") (llm "0.24.0") (plz "0.8") (transient
"0.7") (compat "29.1") (yaml "1.2.3"))
+;; Version: 1.11.0
;; SPDX-License-Identifier: GPL-3.0-or-later
;; Created: 8th Oct 2023
@@ -41,6 +41,7 @@
(require 'compat)
(eval-when-compile (require 'rx))
(require 'ellama-tools)
+(require 'ellama-skills)
(defgroup ellama nil
"Tool for interacting with LLMs."
@@ -1212,6 +1213,13 @@ Otherwire return current active session."
(defvar ellama-global-system nil)
+(defun ellama-get-system-message ()
+ "Return the effective system message, including dynamically scanned skills."
+ (let ((msg (concat (or ellama-global-system "")
+ (ellama-skills-generate-prompt))))
+ (when (not (string= msg ""))
+ msg)))
+
(defvar-local ellama--stop-scroll nil)
;;;###autoload
@@ -1510,7 +1518,7 @@ failure (with BUFFER current).
(donecb (or (plist-get args :on-done) #'ignore))
(prompt-with-ctx (ellama-context-prompt-with-context prompt))
(system (or (plist-get args :system)
- ellama-global-system))
+ (ellama-get-system-message)))
(llm-prompt (if session
(if (llm-chat-prompt-p (ellama-session-prompt session))
(progn
diff --git a/ellama.info b/ellama.info
index ec605322b7..17a2e7a7a0 100644
--- a/ellama.info
+++ b/ellama.info
@@ -66,6 +66,7 @@ Assistant". Previous sentence was written by Ellama itself.
* Minor modes::
* Using Blueprints::
* MCP Integration::
+* Agent Skills::
* Acknowledgments::
* Contributions::
* GNU Free Documentation License::
@@ -107,6 +108,12 @@ Using Blueprints
* Transient Menus::
* Running Blueprints programmatically::
+Agent Skills
+
+* Directory Structure::
+* Creating a Skill::
+* How it works::
+
File: ellama.info, Node: Installation, Next: Commands, Prev: Top, Up: Top
@@ -510,6 +517,10 @@ argument generated text string.
project-specific blueprints.
• ‘ellama-blueprint-file-extensions’: File extensions recognized as
blueprint files.
+ • ‘ellama-skills-global-path’: Path to the global directory
+ containing Agent Skills.
+ • ‘ellama-skills-local-path’: Project-relative path for local Agent
+ Skills. Default value is ‘"skills"’.
File: ellama.info, Node: Context Management, Next: Minor modes, Prev:
Configuration, Up: Top
@@ -944,7 +955,7 @@ arguments.
(global-set-key (kbd "C-c e M") #'my-chat-with-morpheus)
-File: ellama.info, Node: MCP Integration, Next: Acknowledgments, Prev:
Using Blueprints, Up: Top
+File: ellama.info, Node: MCP Integration, Next: Agent Skills, Prev: Using
Blueprints, Up: Top
8 MCP Integration
*****************
@@ -974,10 +985,79 @@ capability to ‘ellama’ you can add duckduckgo mcp server
tools)))))
-File: ellama.info, Node: Acknowledgments, Next: Contributions, Prev: MCP
Integration, Up: Top
+File: ellama.info, Node: Agent Skills, Next: Acknowledgments, Prev: MCP
Integration, Up: Top
-9 Acknowledgments
-*****************
+9 Agent Skills
+**************
+
+Ellama supports *Agent Skills*, a lightweight format for extending AI
+capabilities. Skills are loaded into context only when needed
+(Progressive Disclosure).
+
+* Menu:
+
+* Directory Structure::
+* Creating a Skill::
+* How it works::
+
+
+File: ellama.info, Node: Directory Structure, Next: Creating a Skill, Up:
Agent Skills
+
+9.1 Directory Structure
+=======================
+
+Ellama looks for skills in two locations:
+ 1. *Global*: ‘~/.emacs.d/ellama/skills/’ (Customizable via
+‘ellama-skills-global-path’)
+ 1. *Project-Local*: ‘skills/’ inside your project root (Customizable
+ via
+‘ellama-skills-local-path’)
+
+A skill is a directory containing a ‘SKILL.md’ file. This file includes
+metadata (‘name’ and ‘description’, at minimum) and instructions that
+tell an agent how to perform a specific task. Skills can also bundle
+scripts, templates, and reference materials.
+
+ my-project/
+ └──skills/
+ └── pdf-processing/
+ ├── SKILL.md # Required: instructions + metadata
+ ├── scripts/ # Optional: executable code
+ ├── references/ # Optional: documentation
+ └── assets/ # Optional: templates, resources
+
+
+File: ellama.info, Node: Creating a Skill, Next: How it works, Prev:
Directory Structure, Up: Agent Skills
+
+9.2 Creating a Skill
+====================
+
+SKILL.md must contain YAML frontmatter:
+
+ ---
+ name: pdf-processing
+ description: Extract text from PDFs and summarize them.
+ ---
+
+ # PDF Processing Instructions
+ To extract text from a PDF...
+
+
+File: ellama.info, Node: How it works, Prev: Creating a Skill, Up: Agent
Skills
+
+9.3 How it works
+================
+
+*Auto-Discovery*: Ellama scans skill directories automatically whenever
+a chat starts. *Context*: Skill metadata (name, description, location)
+is injected into the system prompt. *Activation*: The LLM uses the
+read_file tool to load the SKILL.md content when needed.
+
+
+File: ellama.info, Node: Acknowledgments, Next: Contributions, Prev: Agent
Skills, Up: Top
+
+10 Acknowledgments
+******************
Thanks Jeffrey Morgan (https://github.com/jmorganca) for excellent
project ollama (https://github.com/jmorganca/ollama). This project
@@ -996,7 +1076,7 @@ Without it only ‘ollama’ would be supported.
File: ellama.info, Node: Contributions, Next: GNU Free Documentation
License, Prev: Acknowledgments, Up: Top
-10 Contributions
+11 Contributions
****************
To contribute, submit a pull request or report a bug. This library is
@@ -1490,37 +1570,41 @@ their use in free software.
Tag Table:
Node: Top1379
-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
+Node: Installation3748
+Node: Commands8756
+Node: Keymap16195
+Node: Configuration19028
+Node: Context Management25551
+Node: Transient Menus for Context Management26459
+Node: Managing the Context28073
+Node: Considerations28848
+Node: Minor modes29441
+Node: ellama-context-header-line-mode31429
+Node: ellama-context-header-line-global-mode32254
+Node: ellama-context-mode-line-mode32974
+Node: ellama-context-mode-line-global-mode33822
+Node: Ellama Session Header Line Mode34526
+Node: Enabling and Disabling35095
+Node: Customization35542
+Node: Ellama Session Mode Line Mode35830
+Node: Enabling and Disabling (1)36415
+Node: Customization (1)36862
+Node: Using Blueprints37156
+Node: Key Components of Ellama Blueprints37796
+Node: Creating and Managing Blueprints38403
+Node: Blueprints files39381
+Node: Variable Management39802
+Node: Keymap and Mode40255
+Node: Transient Menus41191
+Node: Running Blueprints programmatically41737
+Node: MCP Integration42324
+Node: Agent Skills43346
+Node: Directory Structure43709
+Node: Creating a Skill44736
+Node: How it works45111
+Node: Acknowledgments45502
+Node: Contributions46213
+Node: GNU Free Documentation License46599
End Tag Table
diff --git a/skills/changelog/SKILL.md b/skills/changelog/SKILL.md
new file mode 100644
index 0000000000..96d4fd3528
--- /dev/null
+++ b/skills/changelog/SKILL.md
@@ -0,0 +1,35 @@
+---
+name: changelog
+description: Use this skill to generate changelog.
+---
+
+# Generating changelog
+
+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.
+
+Call shell_command tools with "git tag -l --points-at=main" argument to see
+previously released version. Based on this information and minority/majority of
+the changes you can fill version variable. If you are not sure, ask the user
+using ask_user tool with your variants of the version.
+
+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.
+```