{"version":3,"file":"vector.mjs","sources":["../../src/vector.ts"],"sourcesContent":["/**\n * Vector search API.\n *\n * This module can be used to interact with the vector database configured\n * in the Grafana LLM app plugin. That plugin must be installed, enabled and configured\n * in order for these functions to work.\n *\n * The {@link enabled} function can be used to check if the plugin is enabled and configured.\n */\n\nimport { getBackendSrv, logDebug } from \"@grafana/runtime\";\nimport { LLM_PLUGIN_ROUTE, setLLMPluginVersion } from \"./constants\";\nimport { HealthCheckResponse, VectorHealthDetails } from \"./types\";\n\ninterface SearchResultPayload extends Record<string, any> {}\n\n/**\n * A request to search for resources in the vector database.\n **/\nexport interface SearchRequest {\n  /**\n   * The name of the collection to search in.\n   **/\n  collection: string;\n\n  /** The query to search for. */\n  query: string;\n\n  /**\n   * Limit the number of results returned to the top `topK` results.\n   *\n   * Defaults to 10.\n   **/\n  topK?: number;\n\n  /** Metadata filters to apply to the vector search. */\n  /* example: filter: { metric_type: { $eq: 'histogram' } } */\n  filter?: Record<string, any>;\n}\n\n/**\n * The results of a vector search.\n *\n * Results will be ordered by score, descending.\n */\nexport interface SearchResult<T extends SearchResultPayload> {\n  /**\n   * The payload of the result.\n   *\n   * The type of this payload depends on the collection that was searched in.\n   * Grafana core types will be added to the same module as this type as they\n   * are implemented.\n   **/\n  payload: T;\n\n  /**\n   * The score of the result.\n   *\n   * This is a number between 0 and 1, where 1 is the best possible match.\n   */\n  score: number;\n}\n\ninterface SearchResultResponse<T extends SearchResultPayload> {\n  results: Array<SearchResult<T>>;\n}\n\n/**\n * Search for resources in the configured vector database.\n */\nexport async function search<T extends SearchResultPayload>(\n  request: SearchRequest,\n): Promise<Array<SearchResult<T>>> {\n  const response = await getBackendSrv().post<SearchResultResponse<T>>(\n    \"/api/plugins/grafana-llm-app/resources/vector/search\",\n    request,\n    {\n      headers: { \"Content-Type\": \"application/json\" },\n    },\n  );\n  return response.results;\n}\n\nlet loggedWarning = false;\n\n/** Check if the vector API is enabled and configured via the LLM plugin. */\nexport const health = async (): Promise<VectorHealthDetails> => {\n  // First check if the plugin is enabled.\n  try {\n    const settings = await getBackendSrv().get(\n      `${LLM_PLUGIN_ROUTE}/settings`,\n      undefined,\n      undefined,\n      {\n        showSuccessAlert: false,\n        showErrorAlert: false,\n      },\n    );\n    if (!settings.enabled) {\n      return {\n        enabled: false,\n        ok: false,\n        error: \"The Grafana LLM plugin is not enabled.\",\n      };\n    }\n  } catch (e) {\n    logDebug(String(e));\n    logDebug(\n      \"Failed to check if the vector service is enabled. This is expected if the Grafana LLM plugin is not installed, and the above error can be ignored.\",\n    );\n    loggedWarning = true;\n    return {\n      enabled: false,\n      ok: false,\n      error: \"The Grafana LLM plugin is not installed.\",\n    };\n  }\n\n  // Run a health check to see if the vector service is configured on the plugin.\n  let response: HealthCheckResponse;\n  try {\n    response = await getBackendSrv().get(\n      `${LLM_PLUGIN_ROUTE}/health`,\n      undefined,\n      undefined,\n      {\n        showSuccessAlert: false,\n        showErrorAlert: false,\n      },\n    );\n  } catch (e) {\n    // We shouldn't really get here if we managed to get the plugin's settings above,\n    // but catch this just in case.\n    if (!loggedWarning) {\n      logDebug(String(e));\n      logDebug(\n        \"Failed to check if vector service is enabled. This is expected if the Grafana LLM plugin is not installed, and the above error can be ignored.\",\n      );\n      loggedWarning = true;\n    }\n    return {\n      enabled: false,\n      ok: false,\n      error: \"The Grafana LLM plugin is not installed.\",\n    };\n  }\n\n  const { details } = response;\n  // Update the version if it's present on the response.\n  if (details?.version !== undefined) {\n    setLLMPluginVersion(details.version);\n  }\n  if (details?.vector === undefined) {\n    return {\n      enabled: false,\n      ok: false,\n      error: \"The Grafana LLM plugin is outdated; please update it.\",\n    };\n  }\n  return typeof details.vector === \"boolean\"\n    ? { enabled: details.vector, ok: details.vector }\n    : details.vector;\n};\n\nexport const enabled = async (): Promise<boolean> => {\n  const healthDetails = await health();\n  return healthDetails.enabled && healthDetails.ok;\n};\n"],"names":[],"mappings":";;;AAsEA,eAAsB,OACpB,OAAA,EACiC;AACjC,EAAA,MAAM,QAAA,GAAW,MAAM,aAAA,EAAc,CAAE,IAAA;AAAA,IACrC,sDAAA;AAAA,IACA,OAAA;AAAA,IACA;AAAA,MACE,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA;AAAmB;AAChD,GACF;AACA,EAAA,OAAO,QAAA,CAAS,OAAA;AAClB;AAEA,IAAI,aAAA,GAAgB,KAAA;AAGb,MAAM,SAAS,YAA0C;AAE9D,EAAA,IAAI;AACF,IAAA,MAAM,QAAA,GAAW,MAAM,aAAA,EAAc,CAAE,GAAA;AAAA,MACrC,GAAG,gBAAgB,CAAA,SAAA,CAAA;AAAA,MACnB,KAAA,CAAA;AAAA,MACA,KAAA,CAAA;AAAA,MACA;AAAA,QACE,gBAAA,EAAkB,KAAA;AAAA,QAClB,cAAA,EAAgB;AAAA;AAClB,KACF;AACA,IAAA,IAAI,CAAC,SAAS,OAAA,EAAS;AACrB,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,KAAA;AAAA,QACT,EAAA,EAAI,KAAA;AAAA,QACJ,KAAA,EAAO;AAAA,OACT;AAAA,IACF;AAAA,EACF,SAAS,CAAA,EAAG;AACV,IAAA,QAAA,CAAS,MAAA,CAAO,CAAC,CAAC,CAAA;AAClB,IAAA,QAAA;AAAA,MACE;AAAA,KACF;AACA,IAAA,aAAA,GAAgB,IAAA;AAChB,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,KAAA;AAAA,MACT,EAAA,EAAI,KAAA;AAAA,MACJ,KAAA,EAAO;AAAA,KACT;AAAA,EACF;AAGA,EAAA,IAAI,QAAA;AACJ,EAAA,IAAI;AACF,IAAA,QAAA,GAAW,MAAM,eAAc,CAAE,GAAA;AAAA,MAC/B,GAAG,gBAAgB,CAAA,OAAA,CAAA;AAAA,MACnB,KAAA,CAAA;AAAA,MACA,KAAA,CAAA;AAAA,MACA;AAAA,QACE,gBAAA,EAAkB,KAAA;AAAA,QAClB,cAAA,EAAgB;AAAA;AAClB,KACF;AAAA,EACF,SAAS,CAAA,EAAG;AAGV,IAAA,IAAI,CAAC,aAAA,EAAe;AAClB,MAAA,QAAA,CAAS,MAAA,CAAO,CAAC,CAAC,CAAA;AAClB,MAAA,QAAA;AAAA,QACE;AAAA,OACF;AACA,MAAA,aAAA,GAAgB,IAAA;AAAA,IAClB;AACA,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,KAAA;AAAA,MACT,EAAA,EAAI,KAAA;AAAA,MACJ,KAAA,EAAO;AAAA,KACT;AAAA,EACF;AAEA,EAAA,MAAM,EAAE,SAAQ,GAAI,QAAA;AAEpB,EAAA,IAAI,OAAA,EAAS,YAAY,MAAA,EAAW;AAClC,IAAA,mBAAA,CAAoB,QAAQ,OAAO,CAAA;AAAA,EACrC;AACA,EAAA,IAAI,OAAA,EAAS,WAAW,MAAA,EAAW;AACjC,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,KAAA;AAAA,MACT,EAAA,EAAI,KAAA;AAAA,MACJ,KAAA,EAAO;AAAA,KACT;AAAA,EACF;AACA,EAAA,OAAO,OAAO,OAAA,CAAQ,MAAA,KAAW,SAAA,GAC7B,EAAE,OAAA,EAAS,OAAA,CAAQ,MAAA,EAAQ,EAAA,EAAI,OAAA,CAAQ,MAAA,EAAO,GAC9C,OAAA,CAAQ,MAAA;AACd;AAEO,MAAM,UAAU,YAA8B;AACnD,EAAA,MAAM,aAAA,GAAgB,MAAM,MAAA,EAAO;AACnC,EAAA,OAAO,aAAA,CAAc,WAAW,aAAA,CAAc,EAAA;AAChD;;;;"}