zmedelis / bosquet

Tooling to build LLM applications: prompt templating and composition, agents, LLM memory, and other instruments for builders of AI applications.
https://zmedelis.github.io/bosquet/
Eclipse Public License 1.0
280 stars 19 forks source link

empty string results in null pointer exception #54

Closed lidorcg closed 2 months ago

lidorcg commented 3 months ago

Working example:

(generate
   {:sys "You are the best LLM in the world"
    :examples "1"
    :prompt "In one word: How are you?"
    :template ["{{sys}}"
               "Examples:"
               "{{examples}}"
               "{{prompt}}"
               "{{res}}"]
    :res {:llm/service :ollama
          :llm/cache true
          :llm/model-params {:model :llama3:latest}}})
  =>
  #:bosquet{:completions
            {:sys "You are the best LLM in the world",
             :examples "1",
             :prompt "In one word: How are you?",
             :template "You are the best LLM in the world\nExamples:\n1\nIn one word: How are you?\nExcellent!",
             :res "Excellent!"},
            :usage {:res {:prompt 17, :completion 3, :total 20}, :bosquet/total {:prompt 17, :completion 3, :total 20}},
            :time 1874}

Empty string error:

(generate
   {:sys "You are the best LLM in the world"
    :examples ""
    :prompt "In one word: How are you?"
    :template ["{{sys}}"
               "Examples:"
               "{{examples}}"
               "{{prompt}}"
               "{{res}}"]
    :res {:llm/service :ollama
          :llm/cache true
          :llm/model-params {:model :llama3:latest}}})
=>
;INFO [bosquet.llm.generator:168] - resolver: (template) => :sys
; Execution error (NullPointerException) at java.io.StringReader/<init> (StringReader.java:51).
; Cannot invoke "String.length()" because "s" is null

This happens in:

(defn- prep-graph
  "Join strings if tempalte is provided as collection"
  [graph available-data]
  (->>
    graph
    (reduce-kv (fn [m k v] (assoc m k (if (vector? v) (u/join-coll v) v))) {})
    (reduce-kv
      (fn [m k v]
        (assoc
          m
          k
          (cond (string? v) (selmer/render v available-data) :else v)))
      {})))

Specifically:

(cond (string? v) (selmer/render v available-data) :else v)

selmer/render returns nil when recieving an empty string. and later bosquet throws exception.

Not sure if it's a bug or a feature but it was non-trivial to figure out :)

lidorcg commented 3 months ago

BTW, reference to non-existing keys doesn't throw...

zmedelis commented 2 months ago

@lidorcg thanks for debuging this. Fixed with https://github.com/zmedelis/bosquet/commit/7f69a61a8287b3bc113bd03c68a6314f7da28e7f