@smyslenny/agent-memory 4.2.0 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -690,6 +690,44 @@ function createLocalHttpEmbeddingProvider(opts) {
690
690
  }
691
691
  };
692
692
  }
693
+ function createGeminiEmbeddingProvider(opts) {
694
+ const id = stableProviderId(`gemini:${opts.model}`, `${opts.model}|${opts.dimension}`);
695
+ return {
696
+ id,
697
+ model: opts.model,
698
+ dimension: opts.dimension,
699
+ async embed(texts) {
700
+ if (texts.length === 0) return [];
701
+ const fetchFn = getFetch(opts.fetchImpl);
702
+ const url2 = `https://generativelanguage.googleapis.com/v1beta/models/${opts.model}:batchEmbedContents?key=${opts.apiKey}`;
703
+ const requests = texts.map((text) => ({
704
+ model: `models/${opts.model}`,
705
+ content: { parts: [{ text }] },
706
+ outputDimensionality: opts.dimension
707
+ }));
708
+ const response = await fetchFn(url2, {
709
+ method: "POST",
710
+ headers: { "content-type": "application/json" },
711
+ body: JSON.stringify({ requests })
712
+ });
713
+ if (!response.ok) {
714
+ const detail = await response.text().catch(() => "");
715
+ throw new Error(`Gemini embedding request failed: ${response.status} ${response.statusText}${detail ? ` \u2014 ${detail}` : ""}`);
716
+ }
717
+ const json2 = await response.json();
718
+ const embeddings = json2?.embeddings;
719
+ if (!Array.isArray(embeddings)) {
720
+ throw new Error("Gemini embedding response missing embeddings array");
721
+ }
722
+ return embeddings.map(
723
+ (entry, index) => assertEmbeddingVector(entry?.values, opts.dimension, `Gemini embedding item ${index}`)
724
+ );
725
+ },
726
+ async healthcheck() {
727
+ await this.embed(["healthcheck"]);
728
+ }
729
+ };
730
+ }
693
731
  function normalizeEmbeddingBaseUrl(baseUrl) {
694
732
  return trimTrailingSlashes(baseUrl);
695
733
  }
@@ -707,7 +745,7 @@ function parseDimension(raw) {
707
745
  }
708
746
  function parseProvider(raw) {
709
747
  if (!raw) return null;
710
- if (raw === "openai-compatible" || raw === "local-http") {
748
+ if (raw === "openai-compatible" || raw === "local-http" || raw === "gemini") {
711
749
  return raw;
712
750
  }
713
751
  throw new Error(`Unsupported embedding provider: ${raw}`);
@@ -718,8 +756,8 @@ function getEmbeddingProviderConfigFromEnv(env = process.env) {
718
756
  const baseUrl = env.AGENT_MEMORY_EMBEDDING_BASE_URL;
719
757
  const model = env.AGENT_MEMORY_EMBEDDING_MODEL;
720
758
  const dimension = parseDimension(env.AGENT_MEMORY_EMBEDDING_DIMENSION);
721
- if (!baseUrl) {
722
- throw new Error("AGENT_MEMORY_EMBEDDING_BASE_URL is required when embeddings are enabled");
759
+ if (!baseUrl && provider !== "gemini") {
760
+ throw new Error("AGENT_MEMORY_EMBEDDING_BASE_URL is required when embeddings are enabled (not needed for gemini provider)");
723
761
  }
724
762
  if (!model) {
725
763
  throw new Error("AGENT_MEMORY_EMBEDDING_MODEL is required when embeddings are enabled");
@@ -730,9 +768,12 @@ function getEmbeddingProviderConfigFromEnv(env = process.env) {
730
768
  if (provider === "openai-compatible" && !env.AGENT_MEMORY_EMBEDDING_API_KEY) {
731
769
  throw new Error("AGENT_MEMORY_EMBEDDING_API_KEY is required for openai-compatible providers");
732
770
  }
771
+ if (provider === "gemini" && !env.AGENT_MEMORY_EMBEDDING_API_KEY) {
772
+ throw new Error("AGENT_MEMORY_EMBEDDING_API_KEY is required for gemini provider (Google AI API key)");
773
+ }
733
774
  return {
734
775
  provider,
735
- baseUrl,
776
+ baseUrl: baseUrl ?? "",
736
777
  model,
737
778
  dimension,
738
779
  apiKey: env.AGENT_MEMORY_EMBEDDING_API_KEY
@@ -741,8 +782,16 @@ function getEmbeddingProviderConfigFromEnv(env = process.env) {
741
782
  function createEmbeddingProvider(input, opts) {
742
783
  const normalized = {
743
784
  ...input,
744
- baseUrl: normalizeEmbeddingBaseUrl(input.baseUrl)
785
+ baseUrl: input.baseUrl ? normalizeEmbeddingBaseUrl(input.baseUrl) : ""
745
786
  };
787
+ if (normalized.provider === "gemini") {
788
+ return createGeminiEmbeddingProvider({
789
+ model: normalized.model,
790
+ dimension: normalized.dimension,
791
+ apiKey: normalized.apiKey,
792
+ fetchImpl: opts?.fetchImpl
793
+ });
794
+ }
746
795
  if (normalized.provider === "openai-compatible") {
747
796
  return createOpenAICompatibleEmbeddingProvider({
748
797
  baseUrl: normalized.baseUrl,
@@ -769,13 +818,16 @@ function resolveEmbeddingProviderConfig(opts) {
769
818
  const model = opts?.config?.model ?? envConfig?.model;
770
819
  const dimension = opts?.config?.dimension ?? envConfig?.dimension;
771
820
  const apiKey = opts?.config?.apiKey ?? envConfig?.apiKey;
772
- if (!provider || !baseUrl || !model || !dimension) {
821
+ if (!provider || !model || !dimension) {
773
822
  throw new Error("Incomplete embedding provider configuration");
774
823
  }
775
- if (provider === "openai-compatible" && !apiKey) {
776
- throw new Error("OpenAI-compatible embedding providers require an API key");
824
+ if (provider !== "gemini" && !baseUrl) {
825
+ throw new Error("baseUrl is required for non-gemini embedding providers");
826
+ }
827
+ if ((provider === "openai-compatible" || provider === "gemini") && !apiKey) {
828
+ throw new Error(`${provider} embedding provider requires an API key`);
777
829
  }
778
- return { provider, baseUrl, model, dimension, apiKey };
830
+ return { provider, baseUrl: baseUrl ?? "", model, dimension, apiKey };
779
831
  }
780
832
  function getEmbeddingProvider(opts) {
781
833
  const config2 = resolveEmbeddingProviderConfig({ config: opts?.config, env: opts?.env });