Skip to content

lqdev/copilot-sdk-elisp

Repository files navigation

copilot-sdk-elisp — Emacs Lisp SDK for GitHub Copilot

Native Emacs Lisp client library for GitHub Copilot via the Agent Client Protocol (ACP).

This is the SDK — the protocol layer. For the full AI OS experience (chat UI, built-in tools, workflows, metaprogramming), see copilot-emacs.

This is NOT a completion plugin. For inline code completion, use copilot.el.

What This Provides

The Elisp equivalent of the official Copilot SDKs (Node.js, Python, .NET, Go, Java):

  • ACP transport — NDJSON (newline-delimited JSON-RPC 2.0) over stdio
  • Client lifecycleinitialize, capability negotiation, version checking
  • Session managementsession/new, session/prompt, session/cancel, session/load
  • Event streamingsession/update notifications (text chunks, tool calls, plans)
  • Permissionssession/request_permission handling
  • FS/Terminal handlersfs/read_text_file, fs/write_text_file, terminal/*
  • Tool framework — register, unregister, dispatch, JSON Schema helpers, usage stats
  • copilot-sdk-deftool macro — one-expression tool definition with auto-generated schema
  • Model intelligence — model selection, reasoning effort, reasoning summaries
  • Unix citizen tools — sandboxed shell pipelines and system tool discovery
  • Settings persistence — model/effort/summaries saved to ~/.copilot/emacs-settings.el
  • Session resume — list and resume previous CLI sessions
  • .plan file injection — Unix-tradition context bridge into every prompt
  • Per-project plan context — org-roam nodes as per-project plans, injected via <project_plan> tags
  • BYOK local providers — use Ollama, direct Anthropic/OpenAI, or any OpenAI-compatible endpoint

Looking for tool nursery, skills, and model routing? These application-level features live in copilot-emacs.

Requirements

  • Emacs 27.1+
  • Copilot CLI v1.0+ installed and authenticated

Installation

git clone https://github.com/lqdev/copilot-sdk-elisp.git
(add-to-list 'load-path "/path/to/copilot-sdk-elisp")
(require 'copilot-sdk)
(require 'copilot-sdk-tools)    ; tool framework + deftool macro

Quick Start

Programmatic Usage

;; Create a client and session
(copilot-sdk-ensure-client)
(let ((session (copilot-sdk-create-session nil)))
  ;; Send a message and wait for the response
  (copilot-sdk-send-and-wait session "What is Emacs?" 30))

;; Async with streaming callbacks
(copilot-sdk-send session "Explain this code"
  :on-text     (lambda (text) (princ text))
  :on-turn-end (lambda (reason) (message "Done: %s" reason)))

Define Custom Tools

Using the API directly

(copilot-sdk-tools-register
 "get-weather"
 "Get current weather for a city"
 (copilot-sdk-tools--make-schema
  `((city . ,(copilot-sdk-tools--string-prop "City name")))
  '("city"))
 (lambda (args)
   (format "Weather in %s: Sunny, 72°F" (alist-get 'city args))))

Using the copilot-sdk-deftool macro (recommended)

(copilot-sdk-deftool weather
  "Get weather for a city"
  ((city string "City name"))
  (format "Weather in %s: Sunny, 72°F" city))

One expression creates the function, JSON Schema, and registration.

Browse Tools

;; Browse ALL registered tools
M-x copilot-sdk-tools-list-ui

;; In the tools browser:
;;   RET — inspect tool details
;;   g — refresh

Session Resume

;; List available sessions
(copilot-sdk-list-sessions)
;; → (((id . "abc123") (title . "My Plan") (modified . "2025-01-15 10:30")) ...)

;; Resume a session programmatically
(copilot-sdk-load-session "session-id")

.plan File

The SDK reads ~/.plan (configurable) and injects its content into every prompt as <user_plan> context:

(setq copilot-sdk-plan-file "~/.plan")  ; default

Write your current goals, projects, or focus areas in this file and the agent will always know what you're working on.

Per-Project Plans

Projects can have their own plan context via org-roam nodes. Set the project name and the SDK will look up a matching org-roam node to inject as <project_plan> tags alongside the global .plan:

(setq copilot-sdk--project-name "my-project")

The function copilot-sdk--read-project-plan resolves the org-roam node by title (matching copilot-sdk--project-name) and returns its content. If no matching node is found, it falls back to ~/.plan.

copilot-sdk-send automatically wraps the project plan in <project_plan> tags when sending prompts to the agent, giving per-project context without manual copy-paste.

Configuration

(setq copilot-sdk-cli-path "/path/to/copilot")  ; Custom CLI path
(setq copilot-sdk-log-level "warning")            ; CLI log level
(setq copilot-sdk-auto-approve nil)               ; Auto-approve permissions (default: nil)

Model Intelligence

Select models, control reasoning effort, and enable reasoning summaries:

;; Set via customize or interactively
(setq copilot-sdk-default-model "claude-sonnet-4")      ; nil = agent default
(setq copilot-sdk-reasoning-effort "high")          ; nil, "low", "medium", "high", "xhigh"
(setq copilot-sdk-reasoning-summaries t)            ; For OpenAI models

;; Interactive commands
M-x copilot-sdk-select-model              ; completing-read with available models
M-x copilot-sdk-select-effort             ; set reasoning effort
M-x copilot-sdk-toggle-reasoning-summaries ; toggle summaries on/off

All three settings auto-persist to ~/.copilot/emacs-settings.el and are restored on startup via copilot-sdk-load-settings.

Unix Citizen Tools

Two built-in tools (registered via copilot-sdk-deftool) let the agent interact with the host system safely:

unix-pipe

Execute shell pipelines with guardrails:

;; The agent can run commands like:
;; ["rg" "pattern", "sort", "uniq -c", "head -20"]

;; Configuration
(setq copilot-sdk-unix-pipe-allowlist '("rg" "sort" "uniq" ...))  ; permitted commands
(setq copilot-sdk-unix-pipe-timeout 30)    ; max seconds per pipeline

Safety features:

  • Allowlist — only commands in copilot-sdk-unix-pipe-allowlist may execute
  • Dangerous pattern rejectionrm -rf /, fork bombs, dd, mkfs are blocked
  • Timeout — pipelines killed after copilot-sdk-unix-pipe-timeout seconds
  • Output truncation — capped at 100K characters

system-tools

Discovers available CLI tools on the host and returns JSON with tool names and versions. Checks for rg, fd, jq, curl, git, python3, node, gcc, docker, kubectl, and more.

Files

copilot-sdk.el            Core: ACP client, NDJSON transport, JSON-RPC, sessions,
                          permissions, FS/terminal handlers, event system, native tool
                          registration, model intelligence, settings persistence
copilot-sdk-tools.el      Tool framework: register, dispatch, schema helpers, deftool macro,
                          usage tracking, tools browser UI, unix-pipe, system-tools
copilot-sdk-local.el      BYOK local providers: Ollama, Anthropic, OpenAI, Azure, custom

Protocol: Agent Client Protocol (ACP)

Emacs ──── NDJSON JSON-RPC 2.0 ────▶ Copilot CLI (--acp --stdio) ──▶ GitHub Copilot
      ◀─── tool.call ──────────────┘

Tools are registered natively via the tools parameter in session.create. The CLI invokes them via tool.call JSON-RPC requests over the same connection.

Key methods: initialize, session/new, session/prompt, session/cancel, session/load

Agent→Client: session/update, session/request_permission, fs/*, terminal/*

Full spec: agentclientprotocol.com

Related Projects

Project Relationship
copilot-emacs AI OS app built ON this SDK (chat, tools, workflows)
copilot.el Inline completion (different protocol, complementary)
copilot-sdk Official SDKs (Node/Python/Go/.NET) — same scope, different language

Development

make compile   # Byte-compile
make test      # Run 132 ERT tests
make lint      # Checkdoc linting
make clean     # Remove .elc files

Local Model Providers (BYOK)

The SDK supports Bring Your Own Key — use local models (Ollama), direct API keys (Anthropic, OpenAI), or any OpenAI-compatible endpoint. The Copilot CLI handles all provider connections natively via the provider field in session.create.

Quick Start with Ollama

# Install and start Ollama
ollama serve
ollama pull qwen2.5-coder:7b
(require 'copilot-sdk-local)

;; Create a session with a local model
(let ((session (copilot-sdk-local-create-session
                :model "qwen2.5-coder:7b")))
  (copilot-sdk-local-send session "Write fizzbuzz in Elisp"
                          :on-text #'insert))

Provider Types

Provider Function Notes
Ollama (copilot-sdk-local-ollama-provider) Local, no API key needed
Anthropic (copilot-sdk-local-anthropic-provider KEY) Direct Claude access
OpenAI (copilot-sdk-local-openai-provider KEY) Direct GPT access
Azure (copilot-sdk-local-azure-provider URL KEY) Azure OpenAI
Foundry Local (copilot-sdk-local-foundry-provider) Microsoft Foundry
Custom (copilot-sdk-local-custom-provider URL) Any OpenAI-compatible

Interactive Commands

  • M-x copilot-sdk-local-status — check Ollama server status
  • M-x copilot-sdk-local-select-model — pick from available Ollama models

See samples/local-providers.el for more examples.

License

MIT — see LICENSE.

About

Emacs Lisp SDK for GitHub Copilot — ACP transport, tools, sessions, BYOK

Resources

License

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors