1
0
Fork 0

Compare commits

...

5 commits

3 changed files with 80 additions and 23 deletions

View file

@ -42,7 +42,8 @@ The summarize commands accept a single universal prefix, which allows you to:
- insert the summary at point;
- choose a (different) target language;
- choose which summary engine to use;
- choose which summary format to use (prose or bullet list).
- choose which summary format to use (prose or bullet list);
- opt-out from caching at Kagi for confidential content.
Note that texts submitted to Kagi are subject to their [[https://kagi.com/privacy#Summarizer][Privacy Policy]].
@ -206,6 +207,14 @@ There's also a [[https://github.com/casey/just][justfile]] which allows you to e
* Changelog
** 0.5pre
*** New
- =kagi-summarize= has a =no-cache= parameter to opt out from caching at Kagi's side.
- =kagi-summarize-buffer= and =kagi-summarize-region= also have a =no-cache= parameter which can be toggled interactively when called with the universal prefix.
** 0.4
*** Breaking changes

View file

@ -324,7 +324,25 @@ https://www.example.com"
(it "uses the summary style when an invalid format is configured"
(setq kagi-summarizer-default-summary-format 'invalid)
(kagi-summarize just-enough-text-input)
(kagi-test--expect-object #'kagi--call-summarizer "summary_type" :to-equal 'summary)))
(kagi-test--expect-object #'kagi--call-summarizer "summary_type" :to-equal 'summary))
(it "lets Kagi cache by default"
(kagi-summarize just-enough-text-input)
(kagi-test--expect-object #'kagi--call-summarizer "cache" :to-equal t))
(it "does not let Kagi cache when no-cache is set"
(kagi-summarize just-enough-text-input nil nil nil t)
(kagi-test--expect-object #'kagi--call-summarizer "cache" :to-equal nil))
(it "lets the no-cache argument override the configured value"
(setq kagi-summarizer-cache t)
(kagi-summarize just-enough-text-input nil nil nil t)
(kagi-test--expect-object #'kagi--call-summarizer "cache" :to-equal nil))
(it "does not let Kagi cache if configured"
(setq kagi-summarizer-cache nil)
(kagi-summarize just-enough-text-input)
(kagi-test--expect-object #'kagi--call-summarizer "cache" :to-equal nil))
(it "caches by default for an invalid configuration value"
(setq kagi-summarizer-cache 'invalid)
(kagi-summarize just-enough-text-input)
(kagi-test--expect-object #'kagi--call-summarizer "cache" :to-equal t)))
(describe "kagi-summarize-buffer"
(before-each
(spy-on #'read-buffer)
@ -354,19 +372,20 @@ https://www.example.com"
(expect #'kagi--display-summary :not :to-have-been-called)
(expect #'kagi--insert-summary :to-have-been-called))
(it "passes arguments to kagi-summary"
(spy-on #'kagi--get-summarizer-parameters :and-return-value '(t lang bram random))
(spy-on #'kagi--get-summarizer-parameters :and-return-value '(t lang bram random maybe))
(call-interactively #'kagi-summarize-buffer)
(expect #'kagi-summarize :to-have-been-called)
(expect #'kagi--display-summary :not :to-have-been-called)
(expect #'kagi--insert-summary :to-have-been-called)
(kagi-test--expect-arg #'kagi-summarize 1 :to-equal 'lang)
(kagi-test--expect-arg #'kagi-summarize 2 :to-equal 'bram)
(kagi-test--expect-arg #'kagi-summarize 3 :to-equal 'random)))
(kagi-test--expect-arg #'kagi-summarize 3 :to-equal 'random)
(kagi-test--expect-arg #'kagi-summarize 4 :to-equal 'maybe)))
(describe "kagi-summarize-region"
(before-each
(spy-on #'region-beginning)
(spy-on #'region-end)
(spy-on #'kagi--get-summarizer-parameters :and-return-value '(lang bram random))
(spy-on #'kagi--get-summarizer-parameters :and-return-value '(lang bram random maybe))
(spy-on #'kagi-summarize :and-return-value dummy-output)
(spy-on #'buffer-name :and-return-value "buffer-name")
(spy-on #'buffer-substring-no-properties))
@ -376,7 +395,8 @@ https://www.example.com"
(expect #'kagi-summarize :to-have-been-called)
(kagi-test--expect-arg #'kagi-summarize 1 :to-equal 'lang)
(kagi-test--expect-arg #'kagi-summarize 2 :to-equal 'bram)
(kagi-test--expect-arg #'kagi-summarize 3 :to-equal 'random))
(kagi-test--expect-arg #'kagi-summarize 3 :to-equal 'random)
(kagi-test--expect-arg #'kagi-summarize 4 :to-equal 'maybe))
(it "opens a buffer with the summary"
(call-interactively #'kagi-summarize-region)
(expect #'kagi--display-summary :to-have-been-called)
@ -391,7 +411,8 @@ https://www.example.com"
(call-interactively #'kagi-summarize-url)
(kagi-test--expect-arg #'kagi-summarize 1 :to-equal 'lang)
(kagi-test--expect-arg #'kagi-summarize 2 :to-equal 'bram)
(kagi-test--expect-arg #'kagi-summarize 3 :to-equal 'random))
(kagi-test--expect-arg #'kagi-summarize 3 :to-equal 'random)
(kagi-test--expect-arg #'kagi-summarize 4 :to-equal nil))
(it "opens a buffer with the summary"
(call-interactively #'kagi-summarize-url)
(expect #'kagi--display-summary :to-have-been-called)

59
kagi.el
View file

@ -292,7 +292,7 @@ list of conses."
(append items
`(("engine" . ,kagi-summarizer-engine)
("summary_type" . ,kagi-summarizer-default-summary-format)
("cache" . ,kagi-summarizer-cache))
("cache" . ,(if kagi-summarizer-cache t nil)))
;; prevent a nil in the result list, causing (json-encode)
;; to generate a wrong request object.
@ -563,7 +563,7 @@ to `kagi-summarizer-default-language'."
kagi-summarizer-default-summary-format)
(t 'summary))))
(defun kagi-summarize (text-or-url &optional language engine format)
(defun kagi-summarize (text-or-url &optional language engine format no-cache)
"Return the summary of the given TEXT-OR-URL.
LANGUAGE is a supported two letter abbreviation of the language,
@ -574,13 +574,20 @@ ENGINE is the name of a supported summarizer engine, as
defined in `kagi--summarizer-engines'.
FORMAT is the summary format, where `summary' returns a paragraph
of text and `takeaway' returns a bullet list."
of text and `takeaway' returns a bullet list.
When NO-CACHE is t, inputs are not retained inside Kagi's
infrastructure. When nil, the default value for
`kagi-summarizer-cache' is used. Set to t for confidential
content."
(let ((kagi-summarizer-default-language
(kagi--summarizer-determine-language language))
(kagi-summarizer-engine
(kagi--summarizer-engine engine))
(kagi-summarizer-default-summary-format
(kagi--summarizer-format format)))
(kagi--summarizer-format format))
;; TODO break out logic in separate function
(kagi-summarizer-cache (if no-cache nil kagi-summarizer-cache)))
(if-let* ((response (if (kagi--url-p text-or-url)
(kagi--call-url-summarizer text-or-url)
(kagi--call-text-summarizer text-or-url)))
@ -593,13 +600,17 @@ of text and `takeaway' returns a bullet list."
(gethash "code" firsterror)))
(error "An error occurred while requesting a summary")))))
(defun kagi--get-summarizer-parameters (&optional prompt-insert-p)
(defun kagi--get-summarizer-parameters (&optional prompts)
"Return a list of interactively obtained summarizer parameters.
Not all commands need to insert a summary, so only prompt for
this when PROMPT-INSERT-P is non-nil."
Some parameters need to be called interactively, however, for
some clients that doesn't make sense. E.g. we don't want to ask
to insert when the region is highlighted. Therefore, PROMPTS is a
list of items that can be prompted interactively. It is
a (possibly empty) list with possible elements \\='prompt-for-insert
or \\='prompt-for-no-cache."
(append
(when prompt-insert-p
(when (seq-contains-p prompts 'prompt-for-insert)
(list
(and (equal current-prefix-arg '(4))
(not buffer-read-only)
@ -632,10 +643,14 @@ this when PROMPT-INSERT-P is non-nil."
summary-formats
kagi-summarizer-default-summary-format
nil
#'string=))))))
#'string=))))
(list
(and (seq-contains-p prompts 'prompt-for-no-cache)
(equal current-prefix-arg '(4))
(y-or-n-p "Cache the result?")))))
;;;###autoload
(defun kagi-summarize-buffer (buffer &optional insert language engine format interactive-p)
(defun kagi-summarize-buffer (buffer &optional insert language engine format no-cache interactive-p)
"Summarize the BUFFER's content and show it in a new window.
By default, the summary is shown in a new buffer.
@ -654,6 +669,11 @@ defined in `kagi--summarizer-engines'.
FORMAT is the summary format, where `summary' returns a paragraph
of text and `takeaway' returns a bullet list.
When NO-CACHE is t, inputs are not retained inside Kagi's
infrastructure. When nil, the default value for
`kagi-summarizer-cache' is used. Set to t for confidential
content.
With a single universal prefix argument (`C-u'), the user is
prompted whether the summary has to be inserted at point, which
target LANGUAGE to use, which summarizer ENGINE to use and which
@ -662,10 +682,11 @@ summary FORMAT to use.
INTERACTIVE-P is t when called interactively."
(interactive (append
(list (read-buffer (format-prompt "Buffer" "") nil t))
(kagi--get-summarizer-parameters t)
(kagi--get-summarizer-parameters '(prompt-for-insert
prompt-for-no-cache))
(list t)))
(let ((summary (with-current-buffer buffer
(kagi-summarize (buffer-string) language engine format)))
(kagi-summarize (buffer-string) language engine format no-cache)))
(summary-buffer-name (with-current-buffer buffer
(kagi--summary-buffer-name (buffer-name)))))
(cond ((and insert (not buffer-read-only)) (kagi--insert-summary summary))
@ -673,7 +694,7 @@ INTERACTIVE-P is t when called interactively."
(t summary))))
;;;###autoload
(defun kagi-summarize-region (begin end &optional language engine format)
(defun kagi-summarize-region (begin end &optional language engine format no-cache)
"Summarize the region's content marked by BEGIN and END positions.
The summary is always shown in a new buffer.
@ -688,17 +709,23 @@ defined in `kagi--summarizer-engines'.
FORMAT is the summary format, where `summary' returns a paragraph
of text and `takeaway' returns a bullet list.
When NO-CACHE is t, inputs are not retained inside Kagi's
infrastructure. When nil, the default value for
`kagi-summarizer-cache' is used. Set to t for confidential
content.
With a single universal prefix argument (`C-u'), the user is
prompted for which target LANGUAGE to use, which summarizer
ENGINE to use and which summary FORMAT to use."
(interactive (append
(list (region-beginning) (region-end))
(kagi--get-summarizer-parameters)))
(kagi--get-summarizer-parameters '(prompt-for-no-cache))))
(kagi--display-summary
(kagi-summarize (buffer-substring-no-properties begin end)
language
engine
format)
format
no-cache)
(kagi--summary-buffer-name (buffer-name))))
;;;###autoload
@ -739,7 +766,7 @@ types are supported:
(interactive
(cons
(read-string (format-prompt "URL" ""))
(kagi--get-summarizer-parameters t)))
(kagi--get-summarizer-parameters '(prompt-for-insert))))
(let ((summary (kagi-summarize url language engine format)))
(if (and insert (not buffer-read-only))
(kagi--insert-summary summary)