@bike4mind/cli 0.2.29-feat-cli-websocket-streaming.18878 → 0.2.29-feat-cli-websocket-streaming.18880

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.
Files changed (2) hide show
  1. package/dist/index.js +67 -24
  2. package/package.json +6 -6
package/dist/index.js CHANGED
@@ -13484,9 +13484,10 @@ var WebSocketLlmBackend = class {
13484
13484
  this.apiClient = options.apiClient;
13485
13485
  this.currentModel = options.model;
13486
13486
  this.tokenGetter = options.tokenGetter;
13487
+ this.wsCompletionUrl = options.wsCompletionUrl;
13487
13488
  }
13488
13489
  /**
13489
- * Make LLM completion request via WebSocket.
13490
+ * Send completion request via HTTP POST, receive streaming response via WebSocket.
13490
13491
  * Collects all streamed chunks, then calls callback once at completion
13491
13492
  * with the full accumulated content.
13492
13493
  */
@@ -13500,10 +13501,6 @@ var WebSocketLlmBackend = class {
13500
13501
  throw new Error("WebSocket is not connected");
13501
13502
  }
13502
13503
  const requestId = uuidv411();
13503
- const token = await this.tokenGetter();
13504
- if (!token) {
13505
- throw new Error("No access token available");
13506
- }
13507
13504
  return new Promise((resolve3, reject) => {
13508
13505
  const isVerbose = process.env.B4M_VERBOSE === "1";
13509
13506
  const isUltraVerbose = process.env.B4M_DEBUG_STREAM === "1";
@@ -13519,10 +13516,16 @@ var WebSocketLlmBackend = class {
13519
13516
  if (settled) return;
13520
13517
  settled = true;
13521
13518
  this.wsManager.offRequest(requestId);
13519
+ this.wsManager.offDisconnect(onDisconnect);
13522
13520
  action();
13523
13521
  };
13524
13522
  const settleResolve = () => settle(() => resolve3());
13525
13523
  const settleReject = (err) => settle(() => reject(err));
13524
+ const onDisconnect = () => {
13525
+ logger.debug("[WebSocketLlmBackend] Connection dropped during completion");
13526
+ settleReject(new Error("WebSocket connection lost during completion"));
13527
+ };
13528
+ this.wsManager.onDisconnect(onDisconnect);
13526
13529
  if (options.abortSignal) {
13527
13530
  if (options.abortSignal.aborted) {
13528
13531
  settleResolve();
@@ -13578,10 +13581,10 @@ var WebSocketLlmBackend = class {
13578
13581
  settleReject(new Error(errorMsg));
13579
13582
  }
13580
13583
  });
13581
- try {
13582
- this.wsManager.send({
13583
- action: "cli_completion_request",
13584
- accessToken: token,
13584
+ const axiosInstance = this.apiClient.getAxiosInstance();
13585
+ axiosInstance.post(
13586
+ this.wsCompletionUrl,
13587
+ {
13585
13588
  requestId,
13586
13589
  model,
13587
13590
  messages,
@@ -13591,10 +13594,12 @@ var WebSocketLlmBackend = class {
13591
13594
  stream: true,
13592
13595
  tools: options.tools || []
13593
13596
  }
13594
- });
13595
- } catch (err) {
13596
- settleReject(err instanceof Error ? err : new Error(String(err)));
13597
- }
13597
+ },
13598
+ { signal: options.abortSignal }
13599
+ ).catch((err) => {
13600
+ const msg = err instanceof Error ? err.message : String(err);
13601
+ settleReject(new Error(`HTTP request failed: ${msg}`));
13602
+ });
13598
13603
  });
13599
13604
  }
13600
13605
  /**
@@ -13677,6 +13682,7 @@ var WebSocketConnectionManager = class {
13677
13682
  this.reconnectAttempts = 0;
13678
13683
  this.maxReconnectDelay = 3e4;
13679
13684
  this.handlers = /* @__PURE__ */ new Map();
13685
+ this.disconnectHandlers = /* @__PURE__ */ new Set();
13680
13686
  this.connected = false;
13681
13687
  this.connecting = false;
13682
13688
  this.closed = false;
@@ -13724,6 +13730,7 @@ var WebSocketConnectionManager = class {
13724
13730
  this.ws.onclose = () => {
13725
13731
  logger.debug("[WS] Connection closed");
13726
13732
  this.cleanup();
13733
+ this.notifyDisconnect();
13727
13734
  if (!this.closed) {
13728
13735
  this.scheduleReconnect();
13729
13736
  }
@@ -13749,7 +13756,13 @@ var WebSocketConnectionManager = class {
13749
13756
  if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
13750
13757
  throw new Error("WebSocket is not connected");
13751
13758
  }
13752
- this.ws.send(JSON.stringify(data));
13759
+ const payload = JSON.stringify(data);
13760
+ const sizeKB = (payload.length / 1024).toFixed(1);
13761
+ logger.debug(`[WS] Sending ${sizeKB} KB (action: ${data.action})`);
13762
+ if (payload.length > 32e3) {
13763
+ logger.warn(`[WS] Payload ${sizeKB} KB exceeds API Gateway 32 KB frame limit \u2014 connection will be closed`);
13764
+ }
13765
+ this.ws.send(payload);
13753
13766
  }
13754
13767
  /**
13755
13768
  * Register a handler for messages matching a specific requestId.
@@ -13763,6 +13776,18 @@ var WebSocketConnectionManager = class {
13763
13776
  offRequest(requestId) {
13764
13777
  this.handlers.delete(requestId);
13765
13778
  }
13779
+ /**
13780
+ * Register a handler that fires when the connection drops.
13781
+ */
13782
+ onDisconnect(handler) {
13783
+ this.disconnectHandlers.add(handler);
13784
+ }
13785
+ /**
13786
+ * Remove a disconnect handler.
13787
+ */
13788
+ offDisconnect(handler) {
13789
+ this.disconnectHandlers.delete(handler);
13790
+ }
13766
13791
  /**
13767
13792
  * Close the connection and stop all heartbeat/reconnect logic.
13768
13793
  */
@@ -13774,6 +13799,7 @@ var WebSocketConnectionManager = class {
13774
13799
  this.ws = null;
13775
13800
  }
13776
13801
  this.handlers.clear();
13802
+ this.disconnectHandlers.clear();
13777
13803
  }
13778
13804
  startHeartbeat() {
13779
13805
  this.stopHeartbeat();
@@ -13798,6 +13824,14 @@ var WebSocketConnectionManager = class {
13798
13824
  this.connecting = false;
13799
13825
  this.stopHeartbeat();
13800
13826
  }
13827
+ notifyDisconnect() {
13828
+ for (const handler of this.disconnectHandlers) {
13829
+ try {
13830
+ handler();
13831
+ } catch {
13832
+ }
13833
+ }
13834
+ }
13801
13835
  scheduleReconnect() {
13802
13836
  if (this.closed) return;
13803
13837
  this.reconnectAttempts++;
@@ -13840,10 +13874,15 @@ var WebSocketToolExecutor = class {
13840
13874
  if (settled) return;
13841
13875
  settled = true;
13842
13876
  this.wsManager.offRequest(requestId);
13877
+ this.wsManager.offDisconnect(onDisconnect);
13843
13878
  action();
13844
13879
  };
13845
13880
  const settleResolve = (result) => settle(() => resolve3(result));
13846
13881
  const settleReject = (err) => settle(() => reject(err));
13882
+ const onDisconnect = () => {
13883
+ settleReject(new Error("WebSocket connection lost during tool execution"));
13884
+ };
13885
+ this.wsManager.onDisconnect(onDisconnect);
13847
13886
  if (abortSignal) {
13848
13887
  if (abortSignal.aborted) {
13849
13888
  settleReject(new Error("Tool execution aborted"));
@@ -14014,7 +14053,7 @@ import { isAxiosError as isAxiosError2 } from "axios";
14014
14053
  // package.json
14015
14054
  var package_default = {
14016
14055
  name: "@bike4mind/cli",
14017
- version: "0.2.29-feat-cli-websocket-streaming.18878+661239950",
14056
+ version: "0.2.29-feat-cli-websocket-streaming.18880+855c924c8",
14018
14057
  type: "module",
14019
14058
  description: "Interactive CLI tool for Bike4Mind with ReAct agents",
14020
14059
  license: "UNLICENSED",
@@ -14124,10 +14163,10 @@ var package_default = {
14124
14163
  },
14125
14164
  devDependencies: {
14126
14165
  "@bike4mind/agents": "0.1.0",
14127
- "@bike4mind/common": "2.50.1-feat-cli-websocket-streaming.18878+661239950",
14128
- "@bike4mind/mcp": "1.29.1-feat-cli-websocket-streaming.18878+661239950",
14129
- "@bike4mind/services": "2.48.1-feat-cli-websocket-streaming.18878+661239950",
14130
- "@bike4mind/utils": "2.5.1-feat-cli-websocket-streaming.18878+661239950",
14166
+ "@bike4mind/common": "2.50.1-feat-cli-websocket-streaming.18880+855c924c8",
14167
+ "@bike4mind/mcp": "1.29.1-feat-cli-websocket-streaming.18880+855c924c8",
14168
+ "@bike4mind/services": "2.48.1-feat-cli-websocket-streaming.18880+855c924c8",
14169
+ "@bike4mind/utils": "2.5.1-feat-cli-websocket-streaming.18880+855c924c8",
14131
14170
  "@types/better-sqlite3": "^7.6.13",
14132
14171
  "@types/diff": "^5.0.9",
14133
14172
  "@types/jsonwebtoken": "^9.0.4",
@@ -14144,7 +14183,7 @@ var package_default = {
14144
14183
  optionalDependencies: {
14145
14184
  "@vscode/ripgrep": "^1.17.0"
14146
14185
  },
14147
- gitHead: "661239950fcb26f7027596b319567a19d56fb1a7"
14186
+ gitHead: "855c924c80996fa2e1ed1f16b536416809a8b87c"
14148
14187
  };
14149
14188
 
14150
14189
  // src/config/constants.ts
@@ -16079,9 +16118,12 @@ function CliApp() {
16079
16118
  let wsManager = null;
16080
16119
  let llm;
16081
16120
  try {
16082
- const serverConfig = await apiClient.get("/api/settings/serverConfig");
16121
+ const serverConfig = await apiClient.get(
16122
+ "/api/settings/serverConfig"
16123
+ );
16083
16124
  const wsUrl = serverConfig?.websocketUrl;
16084
- if (wsUrl) {
16125
+ const wsCompletionUrl = serverConfig?.wsCompletionUrl;
16126
+ if (wsUrl && wsCompletionUrl) {
16085
16127
  wsManager = new WebSocketConnectionManager(wsUrl, tokenGetter);
16086
16128
  await wsManager.connect();
16087
16129
  const wsToolExecutor2 = new WebSocketToolExecutor(wsManager, tokenGetter);
@@ -16090,11 +16132,12 @@ function CliApp() {
16090
16132
  wsManager,
16091
16133
  apiClient,
16092
16134
  model: config.defaultModel,
16093
- tokenGetter
16135
+ tokenGetter,
16136
+ wsCompletionUrl
16094
16137
  });
16095
16138
  logger.debug("\u{1F50C} Using WebSocket transport (bypasses CloudFront timeout)");
16096
16139
  } else {
16097
- throw new Error("No websocketUrl in server config");
16140
+ throw new Error("No websocketUrl or wsCompletionUrl in server config");
16098
16141
  }
16099
16142
  } catch (wsError) {
16100
16143
  logger.debug(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bike4mind/cli",
3
- "version": "0.2.29-feat-cli-websocket-streaming.18878+661239950",
3
+ "version": "0.2.29-feat-cli-websocket-streaming.18880+855c924c8",
4
4
  "type": "module",
5
5
  "description": "Interactive CLI tool for Bike4Mind with ReAct agents",
6
6
  "license": "UNLICENSED",
@@ -110,10 +110,10 @@
110
110
  },
111
111
  "devDependencies": {
112
112
  "@bike4mind/agents": "0.1.0",
113
- "@bike4mind/common": "2.50.1-feat-cli-websocket-streaming.18878+661239950",
114
- "@bike4mind/mcp": "1.29.1-feat-cli-websocket-streaming.18878+661239950",
115
- "@bike4mind/services": "2.48.1-feat-cli-websocket-streaming.18878+661239950",
116
- "@bike4mind/utils": "2.5.1-feat-cli-websocket-streaming.18878+661239950",
113
+ "@bike4mind/common": "2.50.1-feat-cli-websocket-streaming.18880+855c924c8",
114
+ "@bike4mind/mcp": "1.29.1-feat-cli-websocket-streaming.18880+855c924c8",
115
+ "@bike4mind/services": "2.48.1-feat-cli-websocket-streaming.18880+855c924c8",
116
+ "@bike4mind/utils": "2.5.1-feat-cli-websocket-streaming.18880+855c924c8",
117
117
  "@types/better-sqlite3": "^7.6.13",
118
118
  "@types/diff": "^5.0.9",
119
119
  "@types/jsonwebtoken": "^9.0.4",
@@ -130,5 +130,5 @@
130
130
  "optionalDependencies": {
131
131
  "@vscode/ripgrep": "^1.17.0"
132
132
  },
133
- "gitHead": "661239950fcb26f7027596b319567a19d56fb1a7"
133
+ "gitHead": "855c924c80996fa2e1ed1f16b536416809a8b87c"
134
134
  }