@ketd/gemini-cli-sdk 0.3.3 → 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.js CHANGED
@@ -53,6 +53,101 @@ var JsonInputMessageType = /* @__PURE__ */ ((JsonInputMessageType2) => {
53
53
  return JsonInputMessageType2;
54
54
  })(JsonInputMessageType || {});
55
55
 
56
+ // src/logger.ts
57
+ var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
58
+ LogLevel2[LogLevel2["DEBUG"] = 0] = "DEBUG";
59
+ LogLevel2[LogLevel2["INFO"] = 1] = "INFO";
60
+ LogLevel2[LogLevel2["WARN"] = 2] = "WARN";
61
+ LogLevel2[LogLevel2["ERROR"] = 3] = "ERROR";
62
+ LogLevel2[LogLevel2["SILENT"] = 4] = "SILENT";
63
+ return LogLevel2;
64
+ })(LogLevel || {});
65
+ var consoleLogger = {
66
+ debug: (message, ...args) => console.log(message, ...args),
67
+ info: (message, ...args) => console.log(message, ...args),
68
+ warn: (message, ...args) => console.warn(message, ...args),
69
+ error: (message, ...args) => console.error(message, ...args)
70
+ };
71
+ var silentLogger = {
72
+ debug: () => {
73
+ },
74
+ info: () => {
75
+ },
76
+ warn: () => {
77
+ },
78
+ error: () => {
79
+ }
80
+ };
81
+ var SDKLogger = class {
82
+ logger;
83
+ level;
84
+ prefix;
85
+ constructor(options = {}) {
86
+ this.logger = options.logger || consoleLogger;
87
+ this.level = options.level ?? 1 /* INFO */;
88
+ this.prefix = options.prefix || "";
89
+ }
90
+ /**
91
+ * Update logger configuration
92
+ */
93
+ configure(options) {
94
+ if (options.logger !== void 0) {
95
+ this.logger = options.logger;
96
+ }
97
+ if (options.level !== void 0) {
98
+ this.level = options.level;
99
+ }
100
+ if (options.prefix !== void 0) {
101
+ this.prefix = options.prefix;
102
+ }
103
+ }
104
+ /**
105
+ * Set log level
106
+ */
107
+ setLevel(level) {
108
+ this.level = level;
109
+ }
110
+ /**
111
+ * Set custom logger implementation
112
+ */
113
+ setLogger(logger) {
114
+ this.logger = logger;
115
+ }
116
+ formatMessage(message) {
117
+ return this.prefix ? `${this.prefix} ${message}` : message;
118
+ }
119
+ debug(message, ...args) {
120
+ if (this.level <= 0 /* DEBUG */) {
121
+ this.logger.debug(this.formatMessage(message), ...args);
122
+ }
123
+ }
124
+ info(message, ...args) {
125
+ if (this.level <= 1 /* INFO */) {
126
+ this.logger.info(this.formatMessage(message), ...args);
127
+ }
128
+ }
129
+ warn(message, ...args) {
130
+ if (this.level <= 2 /* WARN */) {
131
+ this.logger.warn(this.formatMessage(message), ...args);
132
+ }
133
+ }
134
+ error(message, ...args) {
135
+ if (this.level <= 3 /* ERROR */) {
136
+ this.logger.error(this.formatMessage(message), ...args);
137
+ }
138
+ }
139
+ };
140
+ var sdkLogger = new SDKLogger({
141
+ prefix: "[GeminiSDK]",
142
+ level: 1 /* INFO */
143
+ });
144
+ function createLogger(component, options = {}) {
145
+ return new SDKLogger({
146
+ ...options,
147
+ prefix: options.prefix || `[${component}]`
148
+ });
149
+ }
150
+
56
151
  // src/query.ts
57
152
  function buildCliArgs(options, prompt) {
58
153
  const args = [];
@@ -84,7 +179,7 @@ function buildCliArgs(options, prompt) {
84
179
  args.push(prompt);
85
180
  return args;
86
181
  }
87
- function buildEnv(options) {
182
+ function buildEnv(options, logger) {
88
183
  const env = {
89
184
  ...process.env,
90
185
  ...options.env
@@ -95,25 +190,19 @@ function buildEnv(options) {
95
190
  if (useVertexAI) {
96
191
  env.GOOGLE_API_KEY = options.apiKey;
97
192
  env.GOOGLE_GENAI_USE_VERTEXAI = "true";
98
- if (options.debug) {
99
- console.log("[SDK] Vertex AI mode: Setting GOOGLE_API_KEY:", options.apiKey.substring(0, 10) + "...");
100
- }
193
+ logger.debug("Vertex AI mode: Setting GOOGLE_API_KEY:", options.apiKey.substring(0, 10) + "...");
101
194
  } else {
102
195
  env.GEMINI_API_KEY = options.apiKey;
103
- if (options.debug) {
104
- console.log("[SDK] Standard mode: Setting GEMINI_API_KEY:", options.apiKey.substring(0, 10) + "...");
105
- }
196
+ logger.debug("Standard mode: Setting GEMINI_API_KEY:", options.apiKey.substring(0, 10) + "...");
106
197
  }
107
198
  }
108
199
  if (!useVertexAI && env.GOOGLE_API_KEY) {
109
200
  delete env.GOOGLE_API_KEY;
110
- if (options.debug) {
111
- console.log("[SDK] Removed GOOGLE_API_KEY from environment (not using Vertex AI)");
112
- }
201
+ logger.debug("Removed GOOGLE_API_KEY from environment (not using Vertex AI)");
113
202
  }
114
203
  if (options.debug) {
115
204
  env.DEBUG = "1";
116
- console.log("[SDK] Environment variables set:", {
205
+ logger.debug("Environment variables set:", {
117
206
  GEMINI_API_KEY: env.GEMINI_API_KEY ? "***" : void 0,
118
207
  GOOGLE_API_KEY: env.GOOGLE_API_KEY ? "***" : void 0,
119
208
  GOOGLE_GENAI_USE_VERTEXAI: env.GOOGLE_GENAI_USE_VERTEXAI,
@@ -123,6 +212,10 @@ function buildEnv(options) {
123
212
  return env;
124
213
  }
125
214
  async function* query(prompt, options) {
215
+ const logger = createLogger("GeminiSDK", {
216
+ logger: options.logger,
217
+ level: options.debug ? 0 /* DEBUG */ : 1 /* INFO */
218
+ });
126
219
  if (!options.pathToGeminiCLI) {
127
220
  throw new GeminiSDKError("pathToGeminiCLI is required");
128
221
  }
@@ -132,7 +225,7 @@ async function* query(prompt, options) {
132
225
  );
133
226
  }
134
227
  const args = buildCliArgs(options, prompt);
135
- const env = buildEnv(options);
228
+ const env = buildEnv(options, logger);
136
229
  const cwd = options.cwd || process.cwd();
137
230
  const nodeExecutable = options.pathToNode || "node";
138
231
  let geminiProcess;
@@ -148,9 +241,7 @@ async function* query(prompt, options) {
148
241
  const stderrChunks = [];
149
242
  geminiProcess.stderr?.on("data", (data) => {
150
243
  stderrChunks.push(data);
151
- if (options.debug) {
152
- console.error("[Gemini CLI stderr]:", data.toString());
153
- }
244
+ logger.error("stderr:", data.toString());
154
245
  });
155
246
  let timeoutId;
156
247
  if (options.timeout) {
@@ -170,10 +261,8 @@ async function* query(prompt, options) {
170
261
  hasYieldedEvents = true;
171
262
  yield event;
172
263
  } catch (parseError) {
173
- if (options.debug) {
174
- console.error("[Gemini SDK] Failed to parse JSON line:", line);
175
- console.error("[Gemini SDK] Parse error:", parseError);
176
- }
264
+ logger.debug("Failed to parse JSON line:", line);
265
+ logger.debug("Parse error:", parseError);
177
266
  }
178
267
  }
179
268
  } catch (error) {
@@ -376,6 +465,10 @@ var GeminiStreamClient = class extends EventEmitter {
376
465
  constructor(options) {
377
466
  super();
378
467
  this.options = options;
468
+ this.logger = createLogger("GeminiStreamClient", {
469
+ logger: options.logger,
470
+ level: options.debug ? 0 /* DEBUG */ : 1 /* INFO */
471
+ });
379
472
  if (!options.pathToGeminiCLI) {
380
473
  throw new GeminiSDKError("pathToGeminiCLI is required");
381
474
  }
@@ -390,6 +483,7 @@ var GeminiStreamClient = class extends EventEmitter {
390
483
  initEvent = null;
391
484
  initTimeout = null;
392
485
  tempSettingsPath = null;
486
+ logger;
393
487
  /**
394
488
  * Start the Gemini CLI process
395
489
  */
@@ -433,9 +527,11 @@ var GeminiStreamClient = class extends EventEmitter {
433
527
  }
434
528
  if (this.process.stderr) {
435
529
  this.process.stderr.on("data", (chunk) => {
436
- if (this.options.debug) {
437
- console.error("[GeminiStreamClient] stderr:", chunk.toString());
530
+ const message = chunk.toString().trim();
531
+ if (!message || message.includes("Flushing log events")) {
532
+ return;
438
533
  }
534
+ this.logger.error("stderr:", message);
439
535
  });
440
536
  }
441
537
  this.emit("started");
@@ -502,6 +598,34 @@ var GeminiStreamClient = class extends EventEmitter {
502
598
  };
503
599
  this.writeMessage(message);
504
600
  }
601
+ /**
602
+ * Resume session from a session file
603
+ *
604
+ * This sends a control message to the CLI to:
605
+ * 1. Load history from the specified session file
606
+ * 2. Update the ChatRecordingService to use the session file
607
+ *
608
+ * Used when a warm pool adapter is assigned to a real session that has history.
609
+ *
610
+ * @param sessionFilePath - Path to the session file to resume from
611
+ */
612
+ async resumeSession(sessionFilePath) {
613
+ if (!this.isReady()) {
614
+ throw new GeminiSDKError("Client not ready. Call start() first.");
615
+ }
616
+ if (!sessionFilePath) {
617
+ throw new GeminiSDKError("sessionFilePath is required");
618
+ }
619
+ const message = {
620
+ type: "control" /* CONTROL */,
621
+ control: {
622
+ subtype: "resume_session",
623
+ sessionFilePath
624
+ },
625
+ session_id: this.options.sessionId
626
+ };
627
+ this.writeMessage(message);
628
+ }
505
629
  /**
506
630
  * Stop the CLI process
507
631
  */
@@ -543,11 +667,9 @@ var GeminiStreamClient = class extends EventEmitter {
543
667
  if (this.tempSettingsPath) {
544
668
  try {
545
669
  fs.unlinkSync(this.tempSettingsPath);
546
- if (this.options.debug) {
547
- console.log("[GeminiStreamClient] Cleaned up temp settings:", this.tempSettingsPath);
548
- }
670
+ this.logger.debug("Cleaned up temp settings:", this.tempSettingsPath);
549
671
  } catch (error) {
550
- console.error("[GeminiStreamClient] Failed to clean up temp settings:", error);
672
+ this.logger.error("Failed to clean up temp settings:", error);
551
673
  }
552
674
  this.tempSettingsPath = null;
553
675
  }
@@ -592,9 +714,7 @@ var GeminiStreamClient = class extends EventEmitter {
592
714
  }
593
715
  if (!fs.existsSync(geminiConfigDir)) {
594
716
  fs.mkdirSync(geminiConfigDir, { recursive: true });
595
- if (this.options.debug) {
596
- console.log("[GeminiStreamClient] Created config directory:", geminiConfigDir);
597
- }
717
+ this.logger.debug("Created config directory:", geminiConfigDir);
598
718
  }
599
719
  this.tempSettingsPath = path2.join(geminiConfigDir, "settings.json");
600
720
  const settings = {};
@@ -609,10 +729,8 @@ var GeminiStreamClient = class extends EventEmitter {
609
729
  }
610
730
  try {
611
731
  fs.writeFileSync(this.tempSettingsPath, JSON.stringify(settings, null, 2), "utf-8");
612
- if (this.options.debug) {
613
- console.log("[GeminiStreamClient] Wrote settings to:", this.tempSettingsPath);
614
- console.log("[GeminiStreamClient] Settings content:", JSON.stringify(settings, null, 2));
615
- }
732
+ this.logger.debug("Wrote settings to:", this.tempSettingsPath);
733
+ this.logger.debug("Settings content:", JSON.stringify(settings, null, 2));
616
734
  } catch (error) {
617
735
  throw new GeminiSDKError(`Failed to write settings file: ${error}`);
618
736
  }
@@ -630,9 +748,7 @@ var GeminiStreamClient = class extends EventEmitter {
630
748
  ];
631
749
  if (this.options.resumeSessionFilePath) {
632
750
  args.push("--resume-from-file", this.options.resumeSessionFilePath);
633
- if (this.options.debug) {
634
- console.log("[GeminiStreamClient] Resuming from session file:", this.options.resumeSessionFilePath);
635
- }
751
+ this.logger.debug("Resuming from session file:", this.options.resumeSessionFilePath);
636
752
  }
637
753
  if (this.options.model) {
638
754
  args.push("--model", this.options.model);
@@ -655,28 +771,20 @@ var GeminiStreamClient = class extends EventEmitter {
655
771
  };
656
772
  if (this.options.apiKey) {
657
773
  const useVertexAI = this.options.env?.GOOGLE_GENAI_USE_VERTEXAI === "true";
658
- if (this.options.debug) {
659
- console.log("[GeminiStreamClient] buildEnv() - API Key prefix:", this.options.apiKey.substring(0, 3));
660
- console.log("[GeminiStreamClient] buildEnv() - GOOGLE_GENAI_USE_VERTEXAI:", this.options.env?.GOOGLE_GENAI_USE_VERTEXAI);
661
- console.log("[GeminiStreamClient] buildEnv() - useVertexAI:", useVertexAI);
662
- }
774
+ this.logger.debug("buildEnv() - API Key prefix:", this.options.apiKey.substring(0, 3));
775
+ this.logger.debug("buildEnv() - GOOGLE_GENAI_USE_VERTEXAI:", this.options.env?.GOOGLE_GENAI_USE_VERTEXAI);
776
+ this.logger.debug("buildEnv() - useVertexAI:", useVertexAI);
663
777
  if (useVertexAI) {
664
778
  env.GOOGLE_API_KEY = this.options.apiKey;
665
- if (this.options.debug) {
666
- console.log("[GeminiStreamClient] buildEnv() - Setting GOOGLE_API_KEY for Vertex AI");
667
- }
779
+ this.logger.debug("buildEnv() - Setting GOOGLE_API_KEY for Vertex AI");
668
780
  } else {
669
781
  env.GEMINI_API_KEY = this.options.apiKey;
670
- if (this.options.debug) {
671
- console.log("[GeminiStreamClient] buildEnv() - Setting GEMINI_API_KEY for AI Studio");
672
- }
782
+ this.logger.debug("buildEnv() - Setting GEMINI_API_KEY for AI Studio");
673
783
  }
674
784
  }
675
- if (this.options.debug) {
676
- console.log("[GeminiStreamClient] buildEnv() - Final env has GOOGLE_API_KEY:", !!env.GOOGLE_API_KEY);
677
- console.log("[GeminiStreamClient] buildEnv() - Final env has GEMINI_API_KEY:", !!env.GEMINI_API_KEY);
678
- console.log("[GeminiStreamClient] buildEnv() - Final env GOOGLE_GENAI_USE_VERTEXAI:", env.GOOGLE_GENAI_USE_VERTEXAI);
679
- }
785
+ this.logger.debug("buildEnv() - Final env has GOOGLE_API_KEY:", !!env.GOOGLE_API_KEY);
786
+ this.logger.debug("buildEnv() - Final env has GEMINI_API_KEY:", !!env.GEMINI_API_KEY);
787
+ this.logger.debug("buildEnv() - Final env GOOGLE_GENAI_USE_VERTEXAI:", env.GOOGLE_GENAI_USE_VERTEXAI);
680
788
  return env;
681
789
  }
682
790
  /**
@@ -687,19 +795,15 @@ var GeminiStreamClient = class extends EventEmitter {
687
795
  throw new GeminiSDKError("stdin stream not available");
688
796
  }
689
797
  const json = JSON.stringify(message);
690
- if (this.options.debug) {
691
- console.log("[GeminiStreamClient] Writing message to stdin:", json.substring(0, 100));
692
- }
798
+ this.logger.debug("Writing message to stdin:", json.substring(0, 100));
693
799
  const success = this.stdinStream.write(json + "\n", (error) => {
694
800
  if (error) {
695
- console.error("[GeminiStreamClient] Write error:", error);
696
- } else if (this.options.debug) {
697
- console.log("[GeminiStreamClient] Write callback: message flushed to stdin");
801
+ this.logger.error("Write error:", error);
802
+ } else {
803
+ this.logger.debug("Write callback: message flushed to stdin");
698
804
  }
699
805
  });
700
- if (this.options.debug) {
701
- console.log("[GeminiStreamClient] Write success:", success, "Stream writable:", this.stdinStream.writable);
702
- }
806
+ this.logger.debug("Write success:", success, "Stream writable:", this.stdinStream.writable);
703
807
  }
704
808
  /**
705
809
  * Start reading JSONL events from stdout
@@ -714,23 +818,17 @@ var GeminiStreamClient = class extends EventEmitter {
714
818
  return;
715
819
  }
716
820
  if (trimmed.startsWith("[")) {
717
- if (this.options.debug) {
718
- console.log("[GeminiStreamClient] Skipping debug output:", trimmed.substring(0, 100));
719
- }
720
821
  return;
721
822
  }
722
823
  try {
723
824
  const event = JSON.parse(trimmed);
724
825
  this.handleEvent(event);
725
826
  } catch (error) {
726
- console.error("[GeminiStreamClient] Failed to parse JSON:", trimmed);
727
- console.error("[GeminiStreamClient] Error:", error);
827
+ this.logger.error("Failed to parse JSON:", trimmed);
828
+ this.logger.error("Error:", error);
728
829
  }
729
830
  });
730
831
  this.readlineInterface.on("close", () => {
731
- if (this.options.debug) {
732
- console.log("[GeminiStreamClient] readline interface closed");
733
- }
734
832
  });
735
833
  }
736
834
  /**
@@ -772,9 +870,7 @@ var GeminiStreamClient = class extends EventEmitter {
772
870
  * Handle process exit
773
871
  */
774
872
  handleProcessExit(code, signal) {
775
- if (this.options.debug) {
776
- console.log("[GeminiStreamClient] Process exited:", { code, signal });
777
- }
873
+ this.logger.debug("Process exited:", { code, signal });
778
874
  if (code !== 0 && code !== null) {
779
875
  this.status = "error" /* ERROR */;
780
876
  this.emit("error", new GeminiSDKError(`Process exited with code ${code}`, code));
@@ -793,7 +889,7 @@ var GeminiStreamClient = class extends EventEmitter {
793
889
  * Handle process error
794
890
  */
795
891
  handleProcessError(error) {
796
- console.error("[GeminiStreamClient] Process error:", error);
892
+ this.logger.error("Process error:", error);
797
893
  this.status = "error" /* ERROR */;
798
894
  this.emit("error", error);
799
895
  }
@@ -852,7 +948,7 @@ function validateModel(model) {
852
948
  return defaultModel;
853
949
  }
854
950
  if (!model.startsWith("gemini-")) {
855
- console.warn(`Warning: Model name "${model}" does not start with "gemini-"`);
951
+ sdkLogger.warn(`Warning: Model name "${model}" does not start with "gemini-"`);
856
952
  }
857
953
  return model;
858
954
  }
@@ -871,6 +967,6 @@ function formatTokens(tokens) {
871
967
  return tokens.toLocaleString();
872
968
  }
873
969
 
874
- export { ExitCode, GeminiClient, GeminiSDKError, GeminiStreamClient, JsonInputMessageType, JsonStreamEventType, ProcessStatus, findGeminiCLI, formatDuration, formatTokens, getApiKey, query, validateApiKey, validateModel };
970
+ export { ExitCode, GeminiClient, GeminiSDKError, GeminiStreamClient, JsonInputMessageType, JsonStreamEventType, LogLevel, ProcessStatus, SDKLogger, createLogger, findGeminiCLI, formatDuration, formatTokens, getApiKey, query, sdkLogger, silentLogger, validateApiKey, validateModel };
875
971
  //# sourceMappingURL=index.js.map
876
972
  //# sourceMappingURL=index.js.map