@blaxel/core 0.2.73-preview.111 → 0.2.73
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/cjs/.tsbuildinfo +1 -1
- package/dist/cjs/common/settings.js +2 -2
- package/dist/cjs/tools/index.js +1 -28
- package/dist/cjs/tools/mcpTool.js +48 -96
- package/dist/cjs/types/tools/index.d.ts +0 -2
- package/dist/cjs/types/tools/mcpTool.d.ts +5 -11
- package/dist/cjs-browser/.tsbuildinfo +1 -1
- package/dist/cjs-browser/common/settings.js +2 -2
- package/dist/cjs-browser/tools/index.js +1 -28
- package/dist/cjs-browser/tools/mcpTool.js +48 -96
- package/dist/cjs-browser/types/tools/index.d.ts +0 -2
- package/dist/cjs-browser/types/tools/mcpTool.d.ts +5 -11
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/common/settings.js +2 -2
- package/dist/esm/tools/index.js +0 -26
- package/dist/esm/tools/mcpTool.js +48 -96
- package/dist/esm-browser/.tsbuildinfo +1 -1
- package/dist/esm-browser/common/settings.js +2 -2
- package/dist/esm-browser/tools/index.js +0 -26
- package/dist/esm-browser/tools/mcpTool.js +48 -96
- package/package.json +1 -1
|
@@ -3,8 +3,8 @@ import { authentication } from "../authentication/index.js";
|
|
|
3
3
|
import { env } from "../common/env.js";
|
|
4
4
|
import { fs, os, path } from "../common/node.js";
|
|
5
5
|
// Build info - these placeholders are replaced at build time by build:replace-imports
|
|
6
|
-
const BUILD_VERSION = "0.2.73
|
|
7
|
-
const BUILD_COMMIT = "
|
|
6
|
+
const BUILD_VERSION = "0.2.73";
|
|
7
|
+
const BUILD_COMMIT = "ca69d9d46e02efafefc83f2fe96e377b857b493a";
|
|
8
8
|
const BUILD_SENTRY_DSN = "https://fd5e60e1c9820e1eef5ccebb84a07127@o4508714045276160.ingest.us.sentry.io/4510465864564736";
|
|
9
9
|
// Cache for config.yaml tracking value
|
|
10
10
|
let configTrackingValue = null;
|
package/dist/esm/tools/index.js
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import { findFromCache } from "../cache/index.js";
|
|
2
|
-
import { getFunction } from "../client/client.js";
|
|
3
|
-
import { getForcedUrl } from "../common/internal.js";
|
|
4
1
|
import { getMcpTool } from "./mcpTool.js";
|
|
5
2
|
export const getTool = async (name, options) => {
|
|
6
3
|
return await getMcpTool(name, options);
|
|
@@ -17,26 +14,3 @@ export const blTools = (names) => {
|
|
|
17
14
|
export const blTool = (name) => {
|
|
18
15
|
return new BLTools([name]);
|
|
19
16
|
};
|
|
20
|
-
export const getToolMetadata = async (tool) => {
|
|
21
|
-
const forcedUrl = getForcedUrl('function', tool);
|
|
22
|
-
if (forcedUrl) {
|
|
23
|
-
return {
|
|
24
|
-
metadata: {
|
|
25
|
-
name: tool,
|
|
26
|
-
},
|
|
27
|
-
spec: {
|
|
28
|
-
runtime: {},
|
|
29
|
-
},
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
const cacheData = await findFromCache("Function", tool);
|
|
33
|
-
if (cacheData) {
|
|
34
|
-
return cacheData;
|
|
35
|
-
}
|
|
36
|
-
const { data } = await getFunction({
|
|
37
|
-
path: {
|
|
38
|
-
functionName: tool,
|
|
39
|
-
},
|
|
40
|
-
});
|
|
41
|
-
return data || null;
|
|
42
|
-
};
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Client as ModelContextProtocolClient } from "@modelcontextprotocol/sdk/client/index.js";
|
|
2
2
|
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
3
|
+
import { getFunction, getSandbox } from "../client/index.js";
|
|
3
4
|
import { env } from "../common/env.js";
|
|
4
|
-
import { getForcedUrl
|
|
5
|
+
import { getForcedUrl } from "../common/internal.js";
|
|
5
6
|
import { logger } from "../common/logger.js";
|
|
6
7
|
import { settings } from "../common/settings.js";
|
|
7
|
-
import { authenticate
|
|
8
|
-
import { BlaxelMcpClientTransport } from "../mcp/client.js";
|
|
8
|
+
import { authenticate } from "../index.js";
|
|
9
9
|
import { startSpan } from "../telemetry/telemetry.js";
|
|
10
10
|
import { schemaToZodSchema } from "./zodSchema.js";
|
|
11
11
|
const McpToolCache = new Map();
|
|
@@ -14,12 +14,11 @@ export class McpTool {
|
|
|
14
14
|
type;
|
|
15
15
|
pluralType;
|
|
16
16
|
client;
|
|
17
|
-
transport;
|
|
18
17
|
timer;
|
|
19
18
|
ms;
|
|
20
|
-
transportName;
|
|
21
19
|
meta;
|
|
22
20
|
startPromise;
|
|
21
|
+
metadataUrl;
|
|
23
22
|
constructor(name, options = { ms: 5000 }) {
|
|
24
23
|
this.name = name;
|
|
25
24
|
this.type = "function";
|
|
@@ -41,27 +40,44 @@ export class McpTool {
|
|
|
41
40
|
version: "1.0.0",
|
|
42
41
|
});
|
|
43
42
|
}
|
|
44
|
-
get
|
|
45
|
-
|
|
46
|
-
return this.externalUrl;
|
|
47
|
-
}
|
|
48
|
-
return null;
|
|
43
|
+
get forcedUrl() {
|
|
44
|
+
return getForcedUrl(this.type, this.name);
|
|
49
45
|
}
|
|
50
46
|
get externalUrl() {
|
|
51
47
|
return new URL(`${settings.runUrl}/${settings.workspace}/${this.pluralType}/${this.name}`);
|
|
52
48
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
49
|
+
async fetchMetadataUrl() {
|
|
50
|
+
try {
|
|
51
|
+
if (this.type === "sandbox") {
|
|
52
|
+
const { data } = await getSandbox({ path: { sandboxName: this.name } });
|
|
53
|
+
if (data?.metadata?.url)
|
|
54
|
+
return data.metadata.url;
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
const { data } = await getFunction({ path: { functionName: this.name } });
|
|
58
|
+
if (data?.metadata?.url)
|
|
59
|
+
return data.metadata.url;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
64
|
+
logger.debug(`Failed to fetch metadata URL for ${this.name}: ${message}`);
|
|
65
|
+
}
|
|
66
|
+
return null;
|
|
59
67
|
}
|
|
60
|
-
|
|
61
|
-
if (this.forcedUrl)
|
|
68
|
+
async resolveUrl() {
|
|
69
|
+
if (this.forcedUrl) {
|
|
70
|
+
logger.debug(`MCP:${this.name}:ForcedURL:${this.forcedUrl.toString()}`);
|
|
62
71
|
return this.forcedUrl;
|
|
63
|
-
|
|
64
|
-
|
|
72
|
+
}
|
|
73
|
+
if (this.metadataUrl === undefined) {
|
|
74
|
+
this.metadataUrl = await this.fetchMetadataUrl();
|
|
75
|
+
}
|
|
76
|
+
if (this.metadataUrl) {
|
|
77
|
+
logger.debug(`MCP:${this.name}:MetadataURL:${this.metadataUrl}`);
|
|
78
|
+
return new URL(this.metadataUrl);
|
|
79
|
+
}
|
|
80
|
+
logger.debug(`MCP:${this.name}:FallingBackToExternalURL:${this.externalUrl.toString()}`);
|
|
65
81
|
return this.externalUrl;
|
|
66
82
|
}
|
|
67
83
|
async start() {
|
|
@@ -69,41 +85,15 @@ export class McpTool {
|
|
|
69
85
|
this.stopCloseTimer();
|
|
70
86
|
this.startPromise = this.startPromise || (async () => {
|
|
71
87
|
await authenticate();
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
try {
|
|
84
|
-
logger.debug(`MCP:${this.name}:Connecting::${this.url.toString()}`);
|
|
85
|
-
this.transport = await this.getTransport();
|
|
86
|
-
await this.client.connect(this.transport);
|
|
87
|
-
logger.debug(`MCP:${this.name}:Connected`);
|
|
88
|
-
}
|
|
89
|
-
catch (err) {
|
|
90
|
-
if (err instanceof Error) {
|
|
91
|
-
logger.error(`MCP ${this.name} connection failed: ${err.message}`, {
|
|
92
|
-
error: err.message,
|
|
93
|
-
stack: err.stack,
|
|
94
|
-
mcpName: this.name,
|
|
95
|
-
url: this.url
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
if (!this.fallbackUrl) {
|
|
99
|
-
throw err;
|
|
100
|
-
}
|
|
101
|
-
logger.debug(`MCP:${this.name}:Connecting to fallback`);
|
|
102
|
-
this.transportName = undefined;
|
|
103
|
-
this.transport = await this.getTransport(this.fallbackUrl);
|
|
104
|
-
await this.client.connect(this.transport);
|
|
105
|
-
logger.debug(`MCP:${this.name}:Connected to fallback`);
|
|
106
|
-
}
|
|
88
|
+
const url = await this.resolveUrl();
|
|
89
|
+
const mcpUrl = new URL(url.toString());
|
|
90
|
+
mcpUrl.pathname = mcpUrl.pathname.replace(/\/$/, "") + "/mcp";
|
|
91
|
+
logger.debug(`MCP:${this.name}:Connecting::${mcpUrl.toString()}`);
|
|
92
|
+
const transport = new StreamableHTTPClientTransport(mcpUrl, {
|
|
93
|
+
requestInit: { headers: settings.headers },
|
|
94
|
+
});
|
|
95
|
+
await this.client.connect(transport);
|
|
96
|
+
logger.debug(`MCP:${this.name}:Connected`);
|
|
107
97
|
})();
|
|
108
98
|
return await this.startPromise;
|
|
109
99
|
}
|
|
@@ -124,7 +114,7 @@ export class McpTool {
|
|
|
124
114
|
logger.error(`MCP ${this.name} close failed: ${err.message}`, {
|
|
125
115
|
error: err.message,
|
|
126
116
|
stack: err.stack,
|
|
127
|
-
mcpName: this.name
|
|
117
|
+
mcpName: this.name,
|
|
128
118
|
});
|
|
129
119
|
}
|
|
130
120
|
});
|
|
@@ -181,17 +171,13 @@ export class McpTool {
|
|
|
181
171
|
});
|
|
182
172
|
try {
|
|
183
173
|
logger.debug(`MCP:${this.name}:Tool calling`, toolName, JSON.stringify(args));
|
|
184
|
-
logger.debug(`MCP:${this.name}:Tool calling:start`);
|
|
185
174
|
await this.start();
|
|
186
|
-
logger.debug(`MCP:${this.name}:Tool calling:start2`);
|
|
187
175
|
const result = await this.client.callTool({
|
|
188
176
|
name: toolName,
|
|
189
177
|
arguments: args,
|
|
190
|
-
_meta: this.meta
|
|
178
|
+
_meta: this.meta,
|
|
191
179
|
});
|
|
192
|
-
logger.debug(`MCP:${this.name}:Tool calling:result`);
|
|
193
180
|
await this.close();
|
|
194
|
-
logger.debug(`MCP:${this.name}:Tool result`, toolName, JSON.stringify(args));
|
|
195
181
|
span.setAttribute("tool.call.result", JSON.stringify(result));
|
|
196
182
|
return result;
|
|
197
183
|
}
|
|
@@ -202,7 +188,7 @@ export class McpTool {
|
|
|
202
188
|
stack: err.stack,
|
|
203
189
|
mcpName: this.name,
|
|
204
190
|
toolName,
|
|
205
|
-
args: JSON.stringify(args)
|
|
191
|
+
args: JSON.stringify(args),
|
|
206
192
|
});
|
|
207
193
|
}
|
|
208
194
|
throw err;
|
|
@@ -211,40 +197,6 @@ export class McpTool {
|
|
|
211
197
|
span.end();
|
|
212
198
|
}
|
|
213
199
|
}
|
|
214
|
-
async getTransport(forcedUrl) {
|
|
215
|
-
if (!this.transportName) {
|
|
216
|
-
// Detect transport type dynamically by querying the function's endpoint
|
|
217
|
-
try {
|
|
218
|
-
const testUrl = (forcedUrl || this.url).toString();
|
|
219
|
-
const response = await fetch(testUrl + "/", {
|
|
220
|
-
method: "GET",
|
|
221
|
-
headers: settings.headers,
|
|
222
|
-
});
|
|
223
|
-
const responseText = await response.text();
|
|
224
|
-
if (responseText.toLowerCase().includes("websocket")) {
|
|
225
|
-
this.transportName = "websocket";
|
|
226
|
-
}
|
|
227
|
-
else {
|
|
228
|
-
this.transportName = "http-stream";
|
|
229
|
-
}
|
|
230
|
-
logger.debug(`Detected transport type for ${this.name}: ${this.transportName}`);
|
|
231
|
-
}
|
|
232
|
-
catch (error) {
|
|
233
|
-
// Default to websocket if we can't determine the transport type
|
|
234
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
235
|
-
logger.warn(`Failed to detect transport type for ${this.name}: ${message}. Defaulting to websocket.`);
|
|
236
|
-
this.transportName = "websocket";
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
const url = forcedUrl || this.url;
|
|
240
|
-
if (this.transportName === "http-stream") {
|
|
241
|
-
url.pathname = url.pathname + "/mcp";
|
|
242
|
-
return new StreamableHTTPClientTransport(url, { requestInit: { headers: settings.headers } });
|
|
243
|
-
}
|
|
244
|
-
else {
|
|
245
|
-
return new BlaxelMcpClientTransport(url.toString(), settings.headers, { retry: { max: 0 } });
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
200
|
}
|
|
249
201
|
export const getMcpTool = async (name, options) => {
|
|
250
202
|
let tool = McpToolCache.get(name);
|