{"id":28553922,"url":"https://github.com/sunflowerseastar/ob-llm","last_synced_at":"2026-05-19T07:34:56.727Z","repository":{"id":296815480,"uuid":"994513828","full_name":"sunflowerseastar/ob-llm","owner":"sunflowerseastar","description":"LLM Babel babble","archived":false,"fork":false,"pushed_at":"2025-12-12T14:26:58.000Z","size":94,"stargazers_count":6,"open_issues_count":1,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-14T02:12:28.994Z","etag":null,"topics":["ai","babel","emacs","llm","llms","org-mode"],"latest_commit_sha":null,"homepage":"","language":"Emacs Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sunflowerseastar.png","metadata":{"files":{"readme":"README.org","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-06-02T04:00:00.000Z","updated_at":"2026-02-14T11:32:24.000Z","dependencies_parsed_at":"2025-06-04T13:10:58.042Z","dependency_job_id":"e5b911d3-530e-4a50-9f2e-28e5983a4529","html_url":"https://github.com/sunflowerseastar/ob-llm","commit_stats":null,"previous_names":["sunflowerseastar/org-llm","sunflowerseastar/ob-llm"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/sunflowerseastar/ob-llm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunflowerseastar%2Fob-llm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunflowerseastar%2Fob-llm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunflowerseastar%2Fob-llm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunflowerseastar%2Fob-llm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sunflowerseastar","download_url":"https://codeload.github.com/sunflowerseastar/ob-llm/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunflowerseastar%2Fob-llm/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33206320,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-19T07:16:55.748Z","status":"ssl_error","status_checked_at":"2026-05-19T07:16:54.366Z","response_time":58,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","babel","emacs","llm","llms","org-mode"],"created_at":"2025-06-10T05:00:50.710Z","updated_at":"2026-05-19T07:34:56.701Z","avatar_url":"https://github.com/sunflowerseastar.png","language":"Emacs Lisp","funding_links":[],"categories":[],"sub_categories":[],"readme":"* ob-llm\n\n[[https://melpa.org/#/ob-llm][file:https://melpa.org/packages/ob-llm-badge.svg]]\n\nTalk to LLMs from within Org mode by using Babel code blocks.\n\n#+begin_quote\nNOTE: ob-llm requires the [[https://github.com/simonw/llm][llm]] CLI tool\n#+end_quote\n\nob-llm interfaces with LLMs by wrapping ~llm~, a specific command line tool created by Simon Willison. Setting up ~llm~, configuring it, and understanding its interface are required. Please visit the documentation for ~llm~ [[https://llm.datasette.io/en/stable/setup.html][here]]. Also, capability with [[https://www.gnu.org/software/emacs/][GNU Emacs]], [[https://orgmode.org/][Org mode]], and [[https://orgmode.org/worg/org-contrib/babel/intro.html][Babel]] is assumed.\n\n** Example\n\nUsing ~llm~ from the command line:\n\n#+begin_src sh\nllm -m 4o \"Explain 'a person needs an LLM like a pelican needs a bicycle'\"\n#+end_src\n\nUsing ob-llm from inside an Org mode buffer:\n\n#+begin_src org\n,#+begin_src llm :m 4o\nExplain 'a person needs an LLM like a pelican needs a bicycle'\n,#+end_src\n#+end_src\n\nExecute the llm Babel code block by calling ~org-ctrl-c-ctrl-c~ with the binding ~C-c C-c~.\n\n* Features\n\nSince this package is a wrapper of the ~llm~ CLI tool, the feature set is mostly ~llm~'s feature set.\n\nFeatures provided by ~llm~ (found [[https://github.com/simonw/llm][here]]):\n\n- [[https://llm.datasette.io/en/stable/openai-models.html][model selection]] (including [[https://llm.datasette.io/en/stable/other-models.html][local models]]) and configuration\n- local [[https://llm.datasette.io/en/stable/logging.html][sqlite storage]], easily navigable by [[https://github.com/simonw/datasette][datasette]], [[https://github.com/saulpw/visidata][visidata]], etc.\n  - use arbitrary databases (ex. different DB per work project), or \"no-log\"\n  - [[https://llm.datasette.io/en/stable/logging.html#searching-the-logs][search history]], [[https://llm.datasette.io/en/stable/usage.html#continuing-a-conversation][continue any conversation]]\n- [[https://llm.datasette.io/en/stable/usage.html#executing-a-prompt][streaming]], [[https://llm.datasette.io/en/stable/usage.html#system-prompts][system prompts]], [[https://llm.datasette.io/en/stable/fragments.html][fragments]] (including files, URLs), [[https://llm.datasette.io/en/stable/usage.html#attachments][attachments]] (multi-modal)\n- [[https://llm.datasette.io/en/stable/plugins/index.html][plugins]], [[https://llm.datasette.io/en/stable/schemas.html][schemas]], [[https://llm.datasette.io/en/stable/templates.html][templates]]\n\nFeatures provided by ob-llm:\n\n- interface with ~llm~ from inside Org mode buffers, passing Babel code block header arguments as flags\n- supports async, streaming, and concurrent processes across multiple buffers\n- finished responses are automatically converted to prettified JSON or Org mode:\n  - ~schema~ and ~schema-multi~ responses are pretty-printed as JSON\n  - other, general responses are converted from markdown to Org mode\n    - the converted Org will \"shift\" its headings to match the current Org doc's heading level\n  - NOTE: JSON pretty-printing requires [[https://jqlang.org/][jq]]; Org mode conversion requires [[https://pandoc.org/][Pandoc]]\n  - NOTE: disable auto-conversion per prompt with a ~:no-conversion~ Babel code block header argument, or disable auto-conversion via a customization setting with ~(setq ob-llm-post-process-auto-convert-p nil)~\n- refresh ~llm~-ready models with ~ob-llm-refresh-models~\n- model helpers: copy (kill), paste (yank), see/set default model\n- interactively search the ~llm~ logs database with ~ob-llm-query-logs~\n- mode-line indicator for when ob-llm is in use\n- immediate process termination with ~ob-llm-kill-all-processes~\n\n* General Usage\n\n1. Enable with ~(ob-llm-mode 1)~\n2. Write a code block: ~#+begin_src llm...\u003cprompt as body\u003e...#+end_src~\n3. Execute with ~C-c C-c~\n\n** Code Block Header Arguments (\"Params\") Handling\n\nThe header arguments ([[https://orgmode.org/manual/Using-Header-Arguments.html][docs]], [[https://org-babel.readthedocs.io/en/latest/header-args/][reference card]]) for the Babel code blocks are a bit overloaded in that they might be used (1) to control Org mode Babel code block evaluation behavior, (2) to control ob-llm application behavior/settings, or otherwise (3) to be passed along as flags to the ~llm~ command.\n\n1. *Org babel parameters* are consumed by Org mode, and thus not passed to LLM command: ~:results~, ~:exports~, ~:cache~, ~:noweb~, ~:session~, ~:tangle~, ~:hlines~, etc.\n  - ~:results silent~ will emit to the output buffer, but the results will not be streamed or copied in to the org buffer (or post-processed).\n\n2. *Custom ob-llm parameters* are used for special handling: ~:no-conversion~ leaves the completed response unprocessed, and ~:user-path~ will set the ~LLM_USER_PATH~ environment variable for that command.\n\n3. *All other parameters* are passed to the ~llm~ command as flags.\n\n** Model Management\n\n| ~ob-llm-yank-a-model-name~    | Select a model from ~ob-llm-models~ to paste              |\n| ~ob-llm-kill-a-model-name~    | Select a model from ~ob-llm-models~ to kill               |\n| ~ob-llm-echo-default-model~   | Show the current default model in the echo area           |\n| ~ob-llm-change-default-model~ | Pick which model from ~ob-llm-models~ to set as default   |\n| ~ob-llm-refresh-models~       | Update ~ob-llm-models~ with the models available to ~llm~ |\n\n** Conversation History\n\nSearch logs from the ~llm~ logs database with ~ob-llm-query-logs~. Selecting one will copy (kill) the conversation ID, which can be used to then resume that conversation from any code block.\n\n#+begin_src org\n,#+begin_src llm :system \"single word response\"\nwhat is the longest word in the English language that is all vowels?\n,#+end_src\n\n,#+RESULTS:\nEuouae\n\n\n,#+begin_src llm :s \"single word response\"\nwho is halfway between Rameau and Bach?\n,#+end_src\n\n,#+RESULTS:\nHandel\n\nUse ~:continue~ to keep going with the most recent conversation.\n\n,#+begin_src llm :continue :s \"terse\"\nwho would come before Rameau in this same line\n,#+end_src\n\n,#+RESULTS:\nCouperin\n\n\nNow call ~ob-llm-query-logs~, search for \"vowels\", then select the original\nconversation. Pass its ID with the header argument ~:cid~ or ~:conversation~.\n\n,#+begin_src llm :cid 01jwrgrwaj73adxm7prx46gpxj :s \"terse\"\ndefinition?\n,#+end_src\n\n,#+RESULTS:\nA medieval musical notation representing the vowel sounds of \"seculorum Amen\"\nsung at the end of psalms.\n#+end_src\n\n** Customization\n\n| ~ob-llm-line-indicator~                              | What to show in the mode line while a process is active. Default is \"★\"                                  |\n| ~ob-llm-post-process-auto-convert-p~                 | Whether to convert completed responses to prettified JSON (schema) or Org mode (regular). Default is ~t~ |\n| ~ob-llm-models~                                      | Models available to yank, kill, and set as default. Update this by calling ~ob-llm-refresh-models~       |\n| ~ob-llm-pandoc-additional-org-mode-conversion-flags~ | Additional flags to pass to Pandoc when converting general responses to Org mode                         |\n\n*** Converting Markdown to Org Syntax with Pandoc\n\nWhen a general response is finished (as opposed to a code block with header arguments of ~:schema~ or ~:schema-multi~ ([[https://llm.datasette.io/en/stable/schemas.html][docs]])), it is automatically converted to Org mode using [[https://pandoc.org/][Pandoc]]. This can be turned off for a single code block with a header argument of ~:no-conversion~, or as a customization by setting ~ob-llm-post-process-auto-convert-p~ to ~nil~.\n\nAdditional flags can be passed to Pandoc during the \"convert the completed markdown response to org mode\" step using ~ob-llm-pandoc-additional-org-mode-conversion-flags~. For instance, to exclude the PROPERTY drawers from Org headings:\n\n#+begin_src emacs-lisp\n(setq ob-llm-pandoc-additional-org-mode-conversion-flags\n      '(\"--lua-filter=/Users/myuser/.local/share/remove-header-attr.lua\"))\n#+end_src\n\nAnd then these contents for the ~remove-header-attr.lua~ file are at that location:\n\n#+begin_src lua\nfunction Header (header)\n  return pandoc.Header(header.level, header.content, pandoc.Attr())\nend\n#+end_src\n\n*** Adjusting the Converted Org Syntax's Heading Level\n\nAfter a general response is converted to Org, and before it's inserted back into the source Org buffer, the newly converted Org syntax's headings are all \"shifted\" over to nest into the source Org buffer's appropriate heading level. This is done with sed. This can be turned off per code block with ~:no-shift~, or as a customization with ~(setq ob-llm-post-process-auto-shift-p nil)~.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsunflowerseastar%2Fob-llm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsunflowerseastar%2Fob-llm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsunflowerseastar%2Fob-llm/lists"}