@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.
- package/dist/index.js +67 -24
- 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
|
-
*
|
|
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
|
-
|
|
13582
|
-
|
|
13583
|
-
|
|
13584
|
-
|
|
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
|
-
|
|
13596
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
14128
|
-
"@bike4mind/mcp": "1.29.1-feat-cli-websocket-streaming.
|
|
14129
|
-
"@bike4mind/services": "2.48.1-feat-cli-websocket-streaming.
|
|
14130
|
-
"@bike4mind/utils": "2.5.1-feat-cli-websocket-streaming.
|
|
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: "
|
|
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(
|
|
16121
|
+
const serverConfig = await apiClient.get(
|
|
16122
|
+
"/api/settings/serverConfig"
|
|
16123
|
+
);
|
|
16083
16124
|
const wsUrl = serverConfig?.websocketUrl;
|
|
16084
|
-
|
|
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.
|
|
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.
|
|
114
|
-
"@bike4mind/mcp": "1.29.1-feat-cli-websocket-streaming.
|
|
115
|
-
"@bike4mind/services": "2.48.1-feat-cli-websocket-streaming.
|
|
116
|
-
"@bike4mind/utils": "2.5.1-feat-cli-websocket-streaming.
|
|
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": "
|
|
133
|
+
"gitHead": "855c924c80996fa2e1ed1f16b536416809a8b87c"
|
|
134
134
|
}
|