@karmaniverous/jeeves-watcher 0.9.2 → 0.9.3

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.
@@ -25,7 +25,6 @@ import { JSONPath } from 'jsonpath-plus';
25
25
  import { createHash } from 'node:crypto';
26
26
  import crypto from 'crypto';
27
27
  import { cosmiconfig } from 'cosmiconfig';
28
- import { GoogleGenerativeAIEmbeddings } from '@langchain/google-genai';
29
28
  import pino from 'pino';
30
29
  import { v5 } from 'uuid';
31
30
  import * as cheerio from 'cheerio';
@@ -3897,10 +3896,11 @@ function getLogger(logger) {
3897
3896
 
3898
3897
  /**
3899
3898
  * @module embedding/geminiProvider
3900
- * Gemini embedding provider using Google Generative AI.
3899
+ * Gemini embedding provider using the Google Generative AI REST API directly.
3901
3900
  */
3901
+ const GEMINI_API_BASE = 'https://generativelanguage.googleapis.com/v1beta';
3902
3902
  /**
3903
- * Create a Gemini embedding provider using the Google Generative AI SDK.
3903
+ * Create a Gemini embedding provider using the Google Generative AI REST API.
3904
3904
  *
3905
3905
  * @param config - The embedding configuration.
3906
3906
  * @param logger - Optional pino logger for retry warnings.
@@ -3912,20 +3912,32 @@ function createGeminiProvider(config, logger) {
3912
3912
  throw new Error('Gemini embedding provider requires config.embedding.apiKey');
3913
3913
  }
3914
3914
  const dimensions = config.dimensions ?? 3072;
3915
+ const model = config.model;
3916
+ const apiKey = config.apiKey;
3915
3917
  const log = getLogger(logger);
3916
- const embedder = new GoogleGenerativeAIEmbeddings({
3917
- apiKey: config.apiKey,
3918
- model: config.model,
3919
- });
3918
+ const url = `${GEMINI_API_BASE}/models/${model}:batchEmbedContents?key=${apiKey}`;
3920
3919
  return {
3921
3920
  dimensions,
3922
3921
  async embed(texts) {
3923
3922
  const vectors = await retry(async (attempt) => {
3924
3923
  if (attempt > 1) {
3925
- log.warn({ attempt, provider: 'gemini', model: config.model }, 'Retrying embedding request');
3924
+ log.warn({ attempt, provider: 'gemini', model }, 'Retrying embedding request');
3925
+ }
3926
+ const requests = texts.map((text) => ({
3927
+ model: `models/${model}`,
3928
+ content: { parts: [{ text }] },
3929
+ }));
3930
+ const response = await fetch(url, {
3931
+ method: 'POST',
3932
+ headers: { 'Content-Type': 'application/json' },
3933
+ body: JSON.stringify({ requests }),
3934
+ });
3935
+ if (!response.ok) {
3936
+ const body = await response.text();
3937
+ throw new Error(`Gemini API error ${String(response.status)}: ${body}`);
3926
3938
  }
3927
- // embedDocuments returns vectors for multiple texts
3928
- return embedder.embedDocuments(texts);
3939
+ const data = (await response.json());
3940
+ return data.embeddings.map((e) => e.values);
3929
3941
  }, {
3930
3942
  attempts: 5,
3931
3943
  baseDelayMs: 500,
@@ -3936,7 +3948,7 @@ function createGeminiProvider(config, logger) {
3936
3948
  attempt,
3937
3949
  delayMs,
3938
3950
  provider: 'gemini',
3939
- model: config.model,
3951
+ model,
3940
3952
  err: normalizeError(error),
3941
3953
  }, 'Embedding call failed; will retry');
3942
3954
  },
package/dist/index.js CHANGED
@@ -22,7 +22,6 @@ import { createHash } from 'node:crypto';
22
22
  import crypto from 'crypto';
23
23
  import chokidar from 'chokidar';
24
24
  import { cosmiconfig } from 'cosmiconfig';
25
- import { GoogleGenerativeAIEmbeddings } from '@langchain/google-genai';
26
25
  import pino from 'pino';
27
26
  import { v5 } from 'uuid';
28
27
  import * as cheerio from 'cheerio';
@@ -3873,10 +3872,11 @@ function getLogger(logger) {
3873
3872
 
3874
3873
  /**
3875
3874
  * @module embedding/geminiProvider
3876
- * Gemini embedding provider using Google Generative AI.
3875
+ * Gemini embedding provider using the Google Generative AI REST API directly.
3877
3876
  */
3877
+ const GEMINI_API_BASE = 'https://generativelanguage.googleapis.com/v1beta';
3878
3878
  /**
3879
- * Create a Gemini embedding provider using the Google Generative AI SDK.
3879
+ * Create a Gemini embedding provider using the Google Generative AI REST API.
3880
3880
  *
3881
3881
  * @param config - The embedding configuration.
3882
3882
  * @param logger - Optional pino logger for retry warnings.
@@ -3888,20 +3888,32 @@ function createGeminiProvider(config, logger) {
3888
3888
  throw new Error('Gemini embedding provider requires config.embedding.apiKey');
3889
3889
  }
3890
3890
  const dimensions = config.dimensions ?? 3072;
3891
+ const model = config.model;
3892
+ const apiKey = config.apiKey;
3891
3893
  const log = getLogger(logger);
3892
- const embedder = new GoogleGenerativeAIEmbeddings({
3893
- apiKey: config.apiKey,
3894
- model: config.model,
3895
- });
3894
+ const url = `${GEMINI_API_BASE}/models/${model}:batchEmbedContents?key=${apiKey}`;
3896
3895
  return {
3897
3896
  dimensions,
3898
3897
  async embed(texts) {
3899
3898
  const vectors = await retry(async (attempt) => {
3900
3899
  if (attempt > 1) {
3901
- log.warn({ attempt, provider: 'gemini', model: config.model }, 'Retrying embedding request');
3900
+ log.warn({ attempt, provider: 'gemini', model }, 'Retrying embedding request');
3901
+ }
3902
+ const requests = texts.map((text) => ({
3903
+ model: `models/${model}`,
3904
+ content: { parts: [{ text }] },
3905
+ }));
3906
+ const response = await fetch(url, {
3907
+ method: 'POST',
3908
+ headers: { 'Content-Type': 'application/json' },
3909
+ body: JSON.stringify({ requests }),
3910
+ });
3911
+ if (!response.ok) {
3912
+ const body = await response.text();
3913
+ throw new Error(`Gemini API error ${String(response.status)}: ${body}`);
3902
3914
  }
3903
- // embedDocuments returns vectors for multiple texts
3904
- return embedder.embedDocuments(texts);
3915
+ const data = (await response.json());
3916
+ return data.embeddings.map((e) => e.values);
3905
3917
  }, {
3906
3918
  attempts: 5,
3907
3919
  baseDelayMs: 500,
@@ -3912,7 +3924,7 @@ function createGeminiProvider(config, logger) {
3912
3924
  attempt,
3913
3925
  delayMs,
3914
3926
  provider: 'gemini',
3915
- model: config.model,
3927
+ model,
3916
3928
  err: normalizeError(error),
3917
3929
  }, 'Embedding call failed; will retry');
3918
3930
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@karmaniverous/jeeves-watcher",
3
- "version": "0.9.2",
3
+ "version": "0.9.3",
4
4
  "author": "Jason Williscroft",
5
5
  "description": "Filesystem watcher that keeps a Qdrant vector store in sync with document changes",
6
6
  "license": "BSD-3-Clause",
@@ -52,8 +52,6 @@
52
52
  "dependencies": {
53
53
  "@commander-js/extra-typings": "^14.0.0",
54
54
  "@karmaniverous/jsonmap": "^2.1.1",
55
- "@langchain/google-genai": "*",
56
- "@langchain/qdrant": "*",
57
55
  "@langchain/textsplitters": "*",
58
56
  "@qdrant/js-client-rest": "*",
59
57
  "ajv": "^8.18.0",