@ketd/gemini-cli-sdk 0.3.4 → 0.3.5

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.
package/dist/index.cjs CHANGED
@@ -77,6 +77,101 @@ var JsonInputMessageType = /* @__PURE__ */ ((JsonInputMessageType2) => {
77
77
  return JsonInputMessageType2;
78
78
  })(JsonInputMessageType || {});
79
79
 
80
+ // src/logger.ts
81
+ var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
82
+ LogLevel2[LogLevel2["DEBUG"] = 0] = "DEBUG";
83
+ LogLevel2[LogLevel2["INFO"] = 1] = "INFO";
84
+ LogLevel2[LogLevel2["WARN"] = 2] = "WARN";
85
+ LogLevel2[LogLevel2["ERROR"] = 3] = "ERROR";
86
+ LogLevel2[LogLevel2["SILENT"] = 4] = "SILENT";
87
+ return LogLevel2;
88
+ })(LogLevel || {});
89
+ var consoleLogger = {
90
+ debug: (message, ...args) => console.log(message, ...args),
91
+ info: (message, ...args) => console.log(message, ...args),
92
+ warn: (message, ...args) => console.warn(message, ...args),
93
+ error: (message, ...args) => console.error(message, ...args)
94
+ };
95
+ var silentLogger = {
96
+ debug: () => {
97
+ },
98
+ info: () => {
99
+ },
100
+ warn: () => {
101
+ },
102
+ error: () => {
103
+ }
104
+ };
105
+ var SDKLogger = class {
106
+ logger;
107
+ level;
108
+ prefix;
109
+ constructor(options = {}) {
110
+ this.logger = options.logger || consoleLogger;
111
+ this.level = options.level ?? 1 /* INFO */;
112
+ this.prefix = options.prefix || "";
113
+ }
114
+ /**
115
+ * Update logger configuration
116
+ */
117
+ configure(options) {
118
+ if (options.logger !== void 0) {
119
+ this.logger = options.logger;
120
+ }
121
+ if (options.level !== void 0) {
122
+ this.level = options.level;
123
+ }
124
+ if (options.prefix !== void 0) {
125
+ this.prefix = options.prefix;
126
+ }
127
+ }
128
+ /**
129
+ * Set log level
130
+ */
131
+ setLevel(level) {
132
+ this.level = level;
133
+ }
134
+ /**
135
+ * Set custom logger implementation
136
+ */
137
+ setLogger(logger) {
138
+ this.logger = logger;
139
+ }
140
+ formatMessage(message) {
141
+ return this.prefix ? `${this.prefix} ${message}` : message;
142
+ }
143
+ debug(message, ...args) {
144
+ if (this.level <= 0 /* DEBUG */) {
145
+ this.logger.debug(this.formatMessage(message), ...args);
146
+ }
147
+ }
148
+ info(message, ...args) {
149
+ if (this.level <= 1 /* INFO */) {
150
+ this.logger.info(this.formatMessage(message), ...args);
151
+ }
152
+ }
153
+ warn(message, ...args) {
154
+ if (this.level <= 2 /* WARN */) {
155
+ this.logger.warn(this.formatMessage(message), ...args);
156
+ }
157
+ }
158
+ error(message, ...args) {
159
+ if (this.level <= 3 /* ERROR */) {
160
+ this.logger.error(this.formatMessage(message), ...args);
161
+ }
162
+ }
163
+ };
164
+ var sdkLogger = new SDKLogger({
165
+ prefix: "[GeminiSDK]",
166
+ level: 1 /* INFO */
167
+ });
168
+ function createLogger(component, options = {}) {
169
+ return new SDKLogger({
170
+ ...options,
171
+ prefix: options.prefix || `[${component}]`
172
+ });
173
+ }
174
+
80
175
  // src/query.ts
81
176
  function buildCliArgs(options, prompt) {
82
177
  const args = [];
@@ -108,7 +203,7 @@ function buildCliArgs(options, prompt) {
108
203
  args.push(prompt);
109
204
  return args;
110
205
  }
111
- function buildEnv(options) {
206
+ function buildEnv(options, logger) {
112
207
  const env = {
113
208
  ...process.env,
114
209
  ...options.env
@@ -119,25 +214,19 @@ function buildEnv(options) {
119
214
  if (useVertexAI) {
120
215
  env.GOOGLE_API_KEY = options.apiKey;
121
216
  env.GOOGLE_GENAI_USE_VERTEXAI = "true";
122
- if (options.debug) {
123
- console.log("[SDK] Vertex AI mode: Setting GOOGLE_API_KEY:", options.apiKey.substring(0, 10) + "...");
124
- }
217
+ logger.debug("Vertex AI mode: Setting GOOGLE_API_KEY:", options.apiKey.substring(0, 10) + "...");
125
218
  } else {
126
219
  env.GEMINI_API_KEY = options.apiKey;
127
- if (options.debug) {
128
- console.log("[SDK] Standard mode: Setting GEMINI_API_KEY:", options.apiKey.substring(0, 10) + "...");
129
- }
220
+ logger.debug("Standard mode: Setting GEMINI_API_KEY:", options.apiKey.substring(0, 10) + "...");
130
221
  }
131
222
  }
132
223
  if (!useVertexAI && env.GOOGLE_API_KEY) {
133
224
  delete env.GOOGLE_API_KEY;
134
- if (options.debug) {
135
- console.log("[SDK] Removed GOOGLE_API_KEY from environment (not using Vertex AI)");
136
- }
225
+ logger.debug("Removed GOOGLE_API_KEY from environment (not using Vertex AI)");
137
226
  }
138
227
  if (options.debug) {
139
228
  env.DEBUG = "1";
140
- console.log("[SDK] Environment variables set:", {
229
+ logger.debug("Environment variables set:", {
141
230
  GEMINI_API_KEY: env.GEMINI_API_KEY ? "***" : void 0,
142
231
  GOOGLE_API_KEY: env.GOOGLE_API_KEY ? "***" : void 0,
143
232
  GOOGLE_GENAI_USE_VERTEXAI: env.GOOGLE_GENAI_USE_VERTEXAI,
@@ -147,6 +236,10 @@ function buildEnv(options) {
147
236
  return env;
148
237
  }
149
238
  async function* query(prompt, options) {
239
+ const logger = createLogger("GeminiSDK", {
240
+ logger: options.logger,
241
+ level: options.debug ? 0 /* DEBUG */ : 1 /* INFO */
242
+ });
150
243
  if (!options.pathToGeminiCLI) {
151
244
  throw new GeminiSDKError("pathToGeminiCLI is required");
152
245
  }
@@ -156,7 +249,7 @@ async function* query(prompt, options) {
156
249
  );
157
250
  }
158
251
  const args = buildCliArgs(options, prompt);
159
- const env = buildEnv(options);
252
+ const env = buildEnv(options, logger);
160
253
  const cwd = options.cwd || process.cwd();
161
254
  const nodeExecutable = options.pathToNode || "node";
162
255
  let geminiProcess;
@@ -172,9 +265,7 @@ async function* query(prompt, options) {
172
265
  const stderrChunks = [];
173
266
  geminiProcess.stderr?.on("data", (data) => {
174
267
  stderrChunks.push(data);
175
- if (options.debug) {
176
- console.error("[Gemini CLI stderr]:", data.toString());
177
- }
268
+ logger.error("stderr:", data.toString());
178
269
  });
179
270
  let timeoutId;
180
271
  if (options.timeout) {
@@ -194,10 +285,8 @@ async function* query(prompt, options) {
194
285
  hasYieldedEvents = true;
195
286
  yield event;
196
287
  } catch (parseError) {
197
- if (options.debug) {
198
- console.error("[Gemini SDK] Failed to parse JSON line:", line);
199
- console.error("[Gemini SDK] Parse error:", parseError);
200
- }
288
+ logger.debug("Failed to parse JSON line:", line);
289
+ logger.debug("Parse error:", parseError);
201
290
  }
202
291
  }
203
292
  } catch (error) {
@@ -400,6 +489,10 @@ var GeminiStreamClient = class extends events.EventEmitter {
400
489
  constructor(options) {
401
490
  super();
402
491
  this.options = options;
492
+ this.logger = createLogger("GeminiStreamClient", {
493
+ logger: options.logger,
494
+ level: options.debug ? 0 /* DEBUG */ : 1 /* INFO */
495
+ });
403
496
  if (!options.pathToGeminiCLI) {
404
497
  throw new GeminiSDKError("pathToGeminiCLI is required");
405
498
  }
@@ -414,6 +507,7 @@ var GeminiStreamClient = class extends events.EventEmitter {
414
507
  initEvent = null;
415
508
  initTimeout = null;
416
509
  tempSettingsPath = null;
510
+ logger;
417
511
  /**
418
512
  * Start the Gemini CLI process
419
513
  */
@@ -457,9 +551,11 @@ var GeminiStreamClient = class extends events.EventEmitter {
457
551
  }
458
552
  if (this.process.stderr) {
459
553
  this.process.stderr.on("data", (chunk) => {
460
- if (this.options.debug) {
461
- console.error("[GeminiStreamClient] stderr:", chunk.toString());
554
+ const message = chunk.toString().trim();
555
+ if (!message || message.includes("Flushing log events")) {
556
+ return;
462
557
  }
558
+ this.logger.error("stderr:", message);
463
559
  });
464
560
  }
465
561
  this.emit("started");
@@ -595,11 +691,9 @@ var GeminiStreamClient = class extends events.EventEmitter {
595
691
  if (this.tempSettingsPath) {
596
692
  try {
597
693
  fs__namespace.unlinkSync(this.tempSettingsPath);
598
- if (this.options.debug) {
599
- console.log("[GeminiStreamClient] Cleaned up temp settings:", this.tempSettingsPath);
600
- }
694
+ this.logger.debug("Cleaned up temp settings:", this.tempSettingsPath);
601
695
  } catch (error) {
602
- console.error("[GeminiStreamClient] Failed to clean up temp settings:", error);
696
+ this.logger.error("Failed to clean up temp settings:", error);
603
697
  }
604
698
  this.tempSettingsPath = null;
605
699
  }
@@ -644,9 +738,7 @@ var GeminiStreamClient = class extends events.EventEmitter {
644
738
  }
645
739
  if (!fs__namespace.existsSync(geminiConfigDir)) {
646
740
  fs__namespace.mkdirSync(geminiConfigDir, { recursive: true });
647
- if (this.options.debug) {
648
- console.log("[GeminiStreamClient] Created config directory:", geminiConfigDir);
649
- }
741
+ this.logger.debug("Created config directory:", geminiConfigDir);
650
742
  }
651
743
  this.tempSettingsPath = path2__namespace.join(geminiConfigDir, "settings.json");
652
744
  const settings = {};
@@ -661,10 +753,8 @@ var GeminiStreamClient = class extends events.EventEmitter {
661
753
  }
662
754
  try {
663
755
  fs__namespace.writeFileSync(this.tempSettingsPath, JSON.stringify(settings, null, 2), "utf-8");
664
- if (this.options.debug) {
665
- console.log("[GeminiStreamClient] Wrote settings to:", this.tempSettingsPath);
666
- console.log("[GeminiStreamClient] Settings content:", JSON.stringify(settings, null, 2));
667
- }
756
+ this.logger.debug("Wrote settings to:", this.tempSettingsPath);
757
+ this.logger.debug("Settings content:", JSON.stringify(settings, null, 2));
668
758
  } catch (error) {
669
759
  throw new GeminiSDKError(`Failed to write settings file: ${error}`);
670
760
  }
@@ -682,9 +772,7 @@ var GeminiStreamClient = class extends events.EventEmitter {
682
772
  ];
683
773
  if (this.options.resumeSessionFilePath) {
684
774
  args.push("--resume-from-file", this.options.resumeSessionFilePath);
685
- if (this.options.debug) {
686
- console.log("[GeminiStreamClient] Resuming from session file:", this.options.resumeSessionFilePath);
687
- }
775
+ this.logger.debug("Resuming from session file:", this.options.resumeSessionFilePath);
688
776
  }
689
777
  if (this.options.model) {
690
778
  args.push("--model", this.options.model);
@@ -707,28 +795,20 @@ var GeminiStreamClient = class extends events.EventEmitter {
707
795
  };
708
796
  if (this.options.apiKey) {
709
797
  const useVertexAI = this.options.env?.GOOGLE_GENAI_USE_VERTEXAI === "true";
710
- if (this.options.debug) {
711
- console.log("[GeminiStreamClient] buildEnv() - API Key prefix:", this.options.apiKey.substring(0, 3));
712
- console.log("[GeminiStreamClient] buildEnv() - GOOGLE_GENAI_USE_VERTEXAI:", this.options.env?.GOOGLE_GENAI_USE_VERTEXAI);
713
- console.log("[GeminiStreamClient] buildEnv() - useVertexAI:", useVertexAI);
714
- }
798
+ this.logger.debug("buildEnv() - API Key prefix:", this.options.apiKey.substring(0, 3));
799
+ this.logger.debug("buildEnv() - GOOGLE_GENAI_USE_VERTEXAI:", this.options.env?.GOOGLE_GENAI_USE_VERTEXAI);
800
+ this.logger.debug("buildEnv() - useVertexAI:", useVertexAI);
715
801
  if (useVertexAI) {
716
802
  env.GOOGLE_API_KEY = this.options.apiKey;
717
- if (this.options.debug) {
718
- console.log("[GeminiStreamClient] buildEnv() - Setting GOOGLE_API_KEY for Vertex AI");
719
- }
803
+ this.logger.debug("buildEnv() - Setting GOOGLE_API_KEY for Vertex AI");
720
804
  } else {
721
805
  env.GEMINI_API_KEY = this.options.apiKey;
722
- if (this.options.debug) {
723
- console.log("[GeminiStreamClient] buildEnv() - Setting GEMINI_API_KEY for AI Studio");
724
- }
806
+ this.logger.debug("buildEnv() - Setting GEMINI_API_KEY for AI Studio");
725
807
  }
726
808
  }
727
- if (this.options.debug) {
728
- console.log("[GeminiStreamClient] buildEnv() - Final env has GOOGLE_API_KEY:", !!env.GOOGLE_API_KEY);
729
- console.log("[GeminiStreamClient] buildEnv() - Final env has GEMINI_API_KEY:", !!env.GEMINI_API_KEY);
730
- console.log("[GeminiStreamClient] buildEnv() - Final env GOOGLE_GENAI_USE_VERTEXAI:", env.GOOGLE_GENAI_USE_VERTEXAI);
731
- }
809
+ this.logger.debug("buildEnv() - Final env has GOOGLE_API_KEY:", !!env.GOOGLE_API_KEY);
810
+ this.logger.debug("buildEnv() - Final env has GEMINI_API_KEY:", !!env.GEMINI_API_KEY);
811
+ this.logger.debug("buildEnv() - Final env GOOGLE_GENAI_USE_VERTEXAI:", env.GOOGLE_GENAI_USE_VERTEXAI);
732
812
  return env;
733
813
  }
734
814
  /**
@@ -739,19 +819,15 @@ var GeminiStreamClient = class extends events.EventEmitter {
739
819
  throw new GeminiSDKError("stdin stream not available");
740
820
  }
741
821
  const json = JSON.stringify(message);
742
- if (this.options.debug) {
743
- console.log("[GeminiStreamClient] Writing message to stdin:", json.substring(0, 100));
744
- }
822
+ this.logger.debug("Writing message to stdin:", json.substring(0, 100));
745
823
  const success = this.stdinStream.write(json + "\n", (error) => {
746
824
  if (error) {
747
- console.error("[GeminiStreamClient] Write error:", error);
748
- } else if (this.options.debug) {
749
- console.log("[GeminiStreamClient] Write callback: message flushed to stdin");
825
+ this.logger.error("Write error:", error);
826
+ } else {
827
+ this.logger.debug("Write callback: message flushed to stdin");
750
828
  }
751
829
  });
752
- if (this.options.debug) {
753
- console.log("[GeminiStreamClient] Write success:", success, "Stream writable:", this.stdinStream.writable);
754
- }
830
+ this.logger.debug("Write success:", success, "Stream writable:", this.stdinStream.writable);
755
831
  }
756
832
  /**
757
833
  * Start reading JSONL events from stdout
@@ -766,23 +842,17 @@ var GeminiStreamClient = class extends events.EventEmitter {
766
842
  return;
767
843
  }
768
844
  if (trimmed.startsWith("[")) {
769
- if (this.options.debug) {
770
- console.log("[GeminiStreamClient] Skipping debug output:", trimmed.substring(0, 100));
771
- }
772
845
  return;
773
846
  }
774
847
  try {
775
848
  const event = JSON.parse(trimmed);
776
849
  this.handleEvent(event);
777
850
  } catch (error) {
778
- console.error("[GeminiStreamClient] Failed to parse JSON:", trimmed);
779
- console.error("[GeminiStreamClient] Error:", error);
851
+ this.logger.error("Failed to parse JSON:", trimmed);
852
+ this.logger.error("Error:", error);
780
853
  }
781
854
  });
782
855
  this.readlineInterface.on("close", () => {
783
- if (this.options.debug) {
784
- console.log("[GeminiStreamClient] readline interface closed");
785
- }
786
856
  });
787
857
  }
788
858
  /**
@@ -824,9 +894,7 @@ var GeminiStreamClient = class extends events.EventEmitter {
824
894
  * Handle process exit
825
895
  */
826
896
  handleProcessExit(code, signal) {
827
- if (this.options.debug) {
828
- console.log("[GeminiStreamClient] Process exited:", { code, signal });
829
- }
897
+ this.logger.debug("Process exited:", { code, signal });
830
898
  if (code !== 0 && code !== null) {
831
899
  this.status = "error" /* ERROR */;
832
900
  this.emit("error", new GeminiSDKError(`Process exited with code ${code}`, code));
@@ -845,7 +913,7 @@ var GeminiStreamClient = class extends events.EventEmitter {
845
913
  * Handle process error
846
914
  */
847
915
  handleProcessError(error) {
848
- console.error("[GeminiStreamClient] Process error:", error);
916
+ this.logger.error("Process error:", error);
849
917
  this.status = "error" /* ERROR */;
850
918
  this.emit("error", error);
851
919
  }
@@ -904,7 +972,7 @@ function validateModel(model) {
904
972
  return defaultModel;
905
973
  }
906
974
  if (!model.startsWith("gemini-")) {
907
- console.warn(`Warning: Model name "${model}" does not start with "gemini-"`);
975
+ sdkLogger.warn(`Warning: Model name "${model}" does not start with "gemini-"`);
908
976
  }
909
977
  return model;
910
978
  }
@@ -929,12 +997,17 @@ exports.GeminiSDKError = GeminiSDKError;
929
997
  exports.GeminiStreamClient = GeminiStreamClient;
930
998
  exports.JsonInputMessageType = JsonInputMessageType;
931
999
  exports.JsonStreamEventType = JsonStreamEventType;
1000
+ exports.LogLevel = LogLevel;
932
1001
  exports.ProcessStatus = ProcessStatus;
1002
+ exports.SDKLogger = SDKLogger;
1003
+ exports.createLogger = createLogger;
933
1004
  exports.findGeminiCLI = findGeminiCLI;
934
1005
  exports.formatDuration = formatDuration;
935
1006
  exports.formatTokens = formatTokens;
936
1007
  exports.getApiKey = getApiKey;
937
1008
  exports.query = query;
1009
+ exports.sdkLogger = sdkLogger;
1010
+ exports.silentLogger = silentLogger;
938
1011
  exports.validateApiKey = validateApiKey;
939
1012
  exports.validateModel = validateModel;
940
1013
  //# sourceMappingURL=index.cjs.map