@browserbridge/bbx 1.6.2 → 1.6.4
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/package.json
CHANGED
|
@@ -973,15 +973,20 @@ function getProxyExampleHost(bindHost) {
|
|
|
973
973
|
return bindHost;
|
|
974
974
|
}
|
|
975
975
|
|
|
976
|
-
|
|
976
|
+
/** @type {string | null} */
|
|
977
|
+
let firstIpv4 = null;
|
|
978
|
+
for (const [name, entries] of Object.entries(os.networkInterfaces())) {
|
|
977
979
|
for (const entry of entries ?? []) {
|
|
978
980
|
if (!entry.internal && entry.family === 'IPv4') {
|
|
979
|
-
|
|
981
|
+
if (name.toLowerCase() === 'ethernet 0') {
|
|
982
|
+
return entry.address;
|
|
983
|
+
}
|
|
984
|
+
firstIpv4 ??= entry.address;
|
|
980
985
|
}
|
|
981
986
|
}
|
|
982
987
|
}
|
|
983
988
|
|
|
984
|
-
return '<host>';
|
|
989
|
+
return firstIpv4 ?? '<host>';
|
|
985
990
|
}
|
|
986
991
|
|
|
987
992
|
/**
|
|
@@ -132,6 +132,67 @@ export function summarizeToolError(error) {
|
|
|
132
132
|
);
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
+
/**
|
|
136
|
+
* @param {ToolResult} result
|
|
137
|
+
* @returns {boolean}
|
|
138
|
+
*/
|
|
139
|
+
function shouldTryRemoteFallback(result) {
|
|
140
|
+
if (!result.isError && result.structuredContent.ok !== false) {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
const text = result.content[0]?.text ?? '';
|
|
144
|
+
return /\b(ACCESS_DENIED|DAEMON_OFFLINE|EXTENSION_DISCONNECTED|NATIVE_HOST_UNAVAILABLE|CONNECTION_LOST)\b|\b(ENOENT|ECONNREFUSED|ETIMEDOUT)\b|ERROR: connect\b/u.test(
|
|
145
|
+
text
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* @param {ToolResult} result
|
|
151
|
+
* @param {string} destinationId
|
|
152
|
+
* @returns {ToolResult}
|
|
153
|
+
*/
|
|
154
|
+
function annotateAutoDestination(result, destinationId) {
|
|
155
|
+
return {
|
|
156
|
+
...result,
|
|
157
|
+
structuredContent: {
|
|
158
|
+
...result.structuredContent,
|
|
159
|
+
destinationId,
|
|
160
|
+
autoSelectedDestinationId: destinationId,
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* @param {(client: import('../../agent-client/src/client.js').BridgeClient) => Promise<ToolResult>} callback
|
|
167
|
+
* @param {ToolResult} localResult
|
|
168
|
+
* @returns {Promise<ToolResult>}
|
|
169
|
+
*/
|
|
170
|
+
async function tryRemoteFallback(callback, localResult) {
|
|
171
|
+
const remotes = (await listBridgeDestinations()).filter((destination) => !destination.local);
|
|
172
|
+
if (remotes.length === 0) {
|
|
173
|
+
return localResult;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
let lastFallbackResult = localResult;
|
|
177
|
+
for (const remote of remotes) {
|
|
178
|
+
const client = await createBridgeClientForDestination(remote.id);
|
|
179
|
+
try {
|
|
180
|
+
await client.connect();
|
|
181
|
+
const result = annotateAutoDestination(await callback(client), remote.id);
|
|
182
|
+
lastFallbackResult = result;
|
|
183
|
+
if (!shouldTryRemoteFallback(result)) {
|
|
184
|
+
return result;
|
|
185
|
+
}
|
|
186
|
+
} catch (error) {
|
|
187
|
+
lastFallbackResult = annotateAutoDestination(summarizeToolError(error), remote.id);
|
|
188
|
+
} finally {
|
|
189
|
+
await client.close();
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return lastFallbackResult;
|
|
194
|
+
}
|
|
195
|
+
|
|
135
196
|
/**
|
|
136
197
|
* @param {(client: import('../../agent-client/src/client.js').BridgeClient) => Promise<ToolResult>} callback
|
|
137
198
|
* @param {{ destinationId?: string | null }} [options]
|
|
@@ -140,7 +201,8 @@ export function summarizeToolError(error) {
|
|
|
140
201
|
export async function withToolClient(callback, options = {}) {
|
|
141
202
|
try {
|
|
142
203
|
if (!options.destinationId) {
|
|
143
|
-
|
|
204
|
+
const result = await withBridgeClient(callback);
|
|
205
|
+
return shouldTryRemoteFallback(result) ? await tryRemoteFallback(callback, result) : result;
|
|
144
206
|
}
|
|
145
207
|
const client = await createBridgeClientForDestination(options.destinationId);
|
|
146
208
|
await client.connect();
|
|
@@ -67,10 +67,31 @@ export {
|
|
|
67
67
|
const HOME_DIR = os.homedir();
|
|
68
68
|
|
|
69
69
|
/**
|
|
70
|
+
* @param {{ destinationId?: string }} [args]
|
|
70
71
|
* @returns {Promise<ToolResult>}
|
|
71
72
|
*/
|
|
72
|
-
export async function handleStatusTool() {
|
|
73
|
+
export async function handleStatusTool(args = {}) {
|
|
73
74
|
try {
|
|
75
|
+
const requestedDestinationId =
|
|
76
|
+
typeof args.destinationId === 'string' ? args.destinationId : null;
|
|
77
|
+
if (requestedDestinationId && requestedDestinationId !== 'local') {
|
|
78
|
+
const destination = (await getBridgeDestinations()).find(
|
|
79
|
+
(entry) => entry.id === requestedDestinationId
|
|
80
|
+
);
|
|
81
|
+
const result = await callRemoteHealth(requestedDestinationId);
|
|
82
|
+
return createToolResult(
|
|
83
|
+
result.reachable
|
|
84
|
+
? `Browser Bridge destination "${requestedDestinationId}" is reachable.`
|
|
85
|
+
: `Browser Bridge destination "${requestedDestinationId}" is not reachable.`,
|
|
86
|
+
{
|
|
87
|
+
ok: result.reachable === true,
|
|
88
|
+
destination: destination ?? { id: requestedDestinationId, local: false },
|
|
89
|
+
...result,
|
|
90
|
+
},
|
|
91
|
+
result.reachable !== true
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
74
95
|
const report = await getDoctorReport();
|
|
75
96
|
const destinations = await Promise.all(
|
|
76
97
|
(await getBridgeDestinations()).map(async (destination) => {
|
|
@@ -235,6 +235,9 @@ export function applyWindowsTcpTransportDefaults(env = process.env) {
|
|
|
235
235
|
if (env[BRIDGE_TCP_PORT_ENV] != null && env[BRIDGE_TCP_PORT_ENV] !== '') {
|
|
236
236
|
return false;
|
|
237
237
|
}
|
|
238
|
+
if (readProxyConfig(env)) {
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
238
241
|
if (env[BRIDGE_HOME_ENV]) {
|
|
239
242
|
return false;
|
|
240
243
|
}
|