LLM task(s) for generating dashboard descriptions | (ns metabase-enterprise.llm.tasks.describe-dashboard (:require [clojure.set :refer [rename-keys]] [clojure.walk :as walk] [metabase-enterprise.llm.client :as llm-client] [metabase.util :as u] [metabase.util.json :as json] [toucan2.core :as t2])) |
Create a data-oriented summary of a dashboard as input to an LLM for summarization. | (defn- dashboard->prompt-data [dashboard-id] (let [{dashboard-name :name :keys [parameters dashcards]} (t2/hydrate (t2/select-one :model/Dashboard dashboard-id) [:dashcards :card :series :dashcard/action :dashcard/linkcard-info] :tabs :param_fields :param_values) param-id->param (zipmap (map :id parameters) (map (fn [param] (-> (select-keys param [:name :type]) (rename-keys {:name :parameter-name :type :filter-type}) (update :filter-type name))) parameters))] {:dashboard-name dashboard-name :charts (for [{:keys [card parameter_mappings]} dashcards :let [{card-name :name :keys [display description visualization_settings result_metadata]} card field-name->display-name (zipmap (map :name result_metadata) (mapv (some-fn :display_name :name) result_metadata)) visualization_settings (->> visualization_settings u/remove-nils (walk/prewalk (fn [v] (field-name->display-name v v))))]] (cond-> {:chart-name card-name :chart-description description :chart-type display :data-column-names (vals field-name->display-name) :chart-parameters (mapv (comp :parameter-name param-id->param :parameter_id) parameter_mappings)} (seq visualization_settings) (assoc :chart-settings visualization_settings))) :global-parameters (vals param-id->param)})) |
Create a human-friendly summary of a dashboard. Returns a map of the form: {:description "Some inferred description"} | (defn describe-dashboard [dashboard-id] (let [dashboard-summary (dashboard->prompt-data dashboard-id) summary-with-prompts (merge dashboard-summary {:description "%%FILL_THIS_DESCRIPTION_IN%%" :keywords "%%FILL_THESE_KEYWORDS_IN%%" :questions "%%FILL_THESE_QUESTIONS_IN%%"}) json-str (json/encode summary-with-prompts) client (-> (llm-client/create-chat-completion) (llm-client/wrap-parse-json (fn [{:keys [description keywords questions]}] {:description (format "Keywords: %s\n\nDescription: %s\n\nQuestions:\n%s" keywords description questions)})))] (client {:messages [{:role "system" :content "You are a helpful assistant that summarizes dashboards I am generating for my customers by filling in the missing \"description\", \"keywords\", and \"questions\" keys in a json fragment."} {:role "assistant" :content "The \"description\" key is a user friendly description of the dashboard containing up to two sentences. This description may not be more than 256 characters."} {:role "assistant" :content "The \"keywords\" key is 3-5 single-quoted, comma-separated key words describing the dashboard (e.g. 'keyword1', 'key word'). Keywords might be used to categorize, concisely describe, or label the entire dashboard."} {:role "assistant" :content "The \"questions\" key contains a markdown-formatted hyphenated list of up to 5 questions this dashboard might help a user answer. Each question should be on its own line."} {:role "assistant" :content "The parts you replace are \"%%FILL_THIS_DESCRIPTION_IN%%\", \"%%FILL_THESE_KEYWORDS_IN%%\", and \"%%FILL_THESE_QUESTIONS_IN%%\"."} {:role "assistant" :content "Return only a json object with the \"description\", \"keywords\", and \"questions\" fields and nothing else."} {:role "user" :content json-str}]}))) |