emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/gptel 84cd7bf5a4 144/273: gptel-gemini: Add Gemini support


From: ELPA Syncer
Subject: [nongnu] elpa/gptel 84cd7bf5a4 144/273: gptel-gemini: Add Gemini support
Date: Wed, 1 May 2024 10:02:16 -0400 (EDT)

branch: elpa/gptel
commit 84cd7bf5a467e279e676e2c71ae30b899fa20e60
Author: mrdylanyin <72154328+mrdylanyin@users.noreply.github.com>
Commit: Karthik Chikmagalur <karthikchikmagalur@gmail.com>

    gptel-gemini: Add Gemini support
    
    gptel-gemini.el (gptel--parse-response, gptel--request-data,
    gptel--parse-buffer, gptel-make-gemini): Add new file and support
    for the Google Gemini LLM API.  Streaming and setting model
    parameters (temperature, max tokesn) are not yet supported.
    
    README: Add instructions for Gemini.
---
 README.org      |  35 +++++++++++++++--
 gptel-gemini.el | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 145 insertions(+), 4 deletions(-)

diff --git a/README.org b/README.org
index 9fa9bf63ef..01e13ccd70 100644
--- a/README.org
+++ b/README.org
@@ -6,10 +6,11 @@ GPTel is a simple Large Language Model chat client for Emacs, 
with support for m
 
 | LLM Backend | Supports | Requires                |
 |-------------+----------+-------------------------|
-| ChatGPT     | ✓       | [[https://platform.openai.com/account/api-keys][API 
key]]                 |
-| Azure       | ✓       | Deployment and API key  |
-| Ollama      | ✓       | [[https://ollama.ai/][Ollama running locally]]  |
-| GPT4All     | ✓       | [[https://gpt4all.io/index.html][GPT4All running 
locally]] |
+| ChatGPT     | ✓        | [[https://platform.openai.com/account/api-keys][API 
key]]                 |
+| Azure       | ✓        | Deployment and API key  |
+| Ollama      | ✓        | [[https://ollama.ai/][Ollama running locally]]  |
+| GPT4All     | ✓        | [[https://gpt4all.io/index.html][GPT4All running 
locally]] |
+| Gemini      | ✓        | [[https://makersuite.google.com/app/apikey][API 
key]]                 |
 | PrivateGPT  | Planned  | -                       |
 | Llama.cpp   | Planned  | -                       |
 
@@ -45,6 +46,7 @@ GPTel uses Curl if available, but falls back to url-retrieve 
to work without ext
       - [[#azure][Azure]]
       - [[#gpt4all][GPT4All]]
       - [[#ollama][Ollama]]
+      - [[#gemini][Gemini]]
   - [[#usage][Usage]]
     - [[#in-any-buffer][In any buffer:]]
     - [[#in-a-dedicated-chat-buffer][In a dedicated chat buffer:]]
@@ -200,6 +202,31 @@ You can pick this backend from the transient menu when 
using gptel (see Usage),
 
 #+html: </details>
 
+**** Gemini
+#+html: </summary>
+
+Register a backend with
+#+begin_src emacs-lisp
+(gptel-make-gemini
+ "Gemini"
+ :key "YOUR_GEMINI_API_KEY"
+ :host "generativelanguage.googleapis.com"
+ :protocol "https"
+ :endpoint "/v1beta/models/gemini-pro:generateContent"
+ )
+#+end_src
+These are the required parameters, refer to the documentation of 
=gptel-make-gemini= for more. Currently stream is not functional.
+
+You can pick this backend from the transient menu when using gptel (see 
Usage), or set this as the default value of =gptel-backend=:
+
+#+begin_src emacs-lisp
+;; OPTIONAL configuration
+(setq-default gptel-model "Gemini-Pro" ;Pick your default model
+              gptel-backend (gptel-make-gemini "Gemini" :host ...))
+#+end_src
+
+#+html: </details>
+
 ** Usage
 
 
|-------------------+-------------------------------------------------------------------------|
diff --git a/gptel-gemini.el b/gptel-gemini.el
new file mode 100644
index 0000000000..9947d32a76
--- /dev/null
+++ b/gptel-gemini.el
@@ -0,0 +1,114 @@
+;;; gptel-gemini.el ---  Gemini suppport for gptel  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2023  Karthik Chikmagalur
+
+;; Author: Karthik Chikmagalur <karthikchikmagalur@gmail.com>
+;; Keywords:
+
+;; This program 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 of the License, or
+;; (at your option) any later version.
+
+;; This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This file adds support for the Gemini API to gptel
+
+;;; Code:
+(require 'gptel)
+(require 'cl-generic)
+
+;;; Gemini
+(cl-defstruct
+    (gptel-gemini (:constructor gptel--make-gemini)
+                  (:copier nil)
+                  (:include gptel-backend)))
+
+(cl-defmethod gptel--parse-response ((_backend gptel-gemini) response _info)
+  (map-nested-elt response '(:candidates 0 :content :parts 0 :text)))
+
+(cl-defmethod gptel--request-data ((_backend gptel-gemini) prompts)
+  "JSON encode PROMPTS for sending to Gemini."
+  (let ((prompts-plist
+         `(:contents [,@prompts]
+           )))
+    prompts-plist))
+
+(cl-defmethod gptel--parse-buffer ((_backend gptel-gemini) &optional 
max-entries)
+  (let ((prompts) (prop))
+    (while (and
+            (or (not max-entries) (>= max-entries 0))
+            (setq prop (text-property-search-backward
+                        'gptel 'response
+                        (when (get-char-property (max (point-min) (1- (point)))
+                                                 'gptel)
+                          t))))
+      (push (list :role (if (prop-match-value prop) "model" "user")
+                  :parts
+                  (list :text (string-trim
+                               (buffer-substring-no-properties 
(prop-match-beginning prop)
+                                                               (prop-match-end 
prop))
+                               (format "[\t\r\n ]*%s[\t\r\n ]*" (regexp-quote 
(gptel-prompt-prefix-string)))
+                               (format "[\t\r\n ]*%s[\t\r\n ]*" (regexp-quote 
(gptel-response-prefix-string)))))
+                  )
+            prompts)
+      (and max-entries (cl-decf max-entries)))
+    prompts))
+
+;;;###autoload
+(cl-defun gptel-make-gemini
+    (name &key header key
+          (host "generativelanguage.googleapis.com")
+          (protocol "https")
+          (models "gemini-pro")
+          (endpoint "/v1beta/models/gemini-pro:generateContent"))
+
+  "Register a Gemini backend for gptel with NAME.
+
+Keyword arguments:
+
+HOST (optional) is the API host, typically 
\"generativelanguage.googleapis.com\".
+
+MODELS is a list of available model names.
+
+STREAM is a boolean to toggle streaming responses, defaults to
+false.
+
+PROTOCOL (optional) specifies the protocol, https by default.
+
+ENDPOINT (optional) is the API endpoint for completions, defaults to
+\"/v1beta/models/gemini-pro:generateContent\".
+
+HEADER (optional) is for additional headers to send with each
+request. It should be an alist or a function that retuns an
+alist, like:
+((\"Content-Type\" . \"application/json\"))
+
+KEY (optional) is a variable whose value is the API key, or
+function that returns the key."
+  (let ((backend (gptel--make-gemini
+                  :name name
+                  :host host
+                  :header header
+                  :models models
+                  :protocol protocol
+                  :endpoint endpoint
+                  :stream nil
+                  :url (if protocol
+                           (concat protocol "://" host endpoint "?key=" key)
+                         (concat host endpoint "?key=" key)))))
+    (prog1 backend
+      (setf (alist-get name gptel--known-backends
+                       nil nil #'equal)
+            backend))))
+
+(provide 'gptel-gemini)
+;;; gptel-gemini.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]