@probelabs/probe 0.6.0-rc101 → 0.6.0-rc103
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/build/agent/ProbeAgent.js +254 -4
- package/build/agent/index.js +257 -41
- package/build/mcp/index.js +24 -145
- package/build/mcp/index.ts +23 -162
- package/build/tools/system-message.js +7 -1
- package/cjs/agent/ProbeAgent.cjs +202 -11
- package/cjs/index.cjs +214 -23
- package/package.json +1 -1
- package/src/agent/ProbeAgent.js +254 -4
- package/src/agent/index.js +50 -18
- package/src/mcp/index.ts +23 -162
- package/src/tools/system-message.js +7 -1
package/cjs/index.cjs
CHANGED
|
@@ -1543,7 +1543,7 @@ async function delegate({ task, timeout = 300, debug = false, currentIteration =
|
|
|
1543
1543
|
console.error(`[DELEGATE] Using binary at: ${binaryPath}`);
|
|
1544
1544
|
console.error(`[DELEGATE] Command args: ${args.join(" ")}`);
|
|
1545
1545
|
}
|
|
1546
|
-
return new Promise((
|
|
1546
|
+
return new Promise((resolve2, reject) => {
|
|
1547
1547
|
const delegationSpan = tracer ? tracer.createDelegationSpan(sessionId, task) : null;
|
|
1548
1548
|
const process2 = (0, import_child_process5.spawn)(binaryPath, args, {
|
|
1549
1549
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -1608,7 +1608,7 @@ async function delegate({ task, timeout = 300, debug = false, currentIteration =
|
|
|
1608
1608
|
delegationSpan.end();
|
|
1609
1609
|
}
|
|
1610
1610
|
}
|
|
1611
|
-
|
|
1611
|
+
resolve2(response);
|
|
1612
1612
|
} else {
|
|
1613
1613
|
const errorMessage = stderr.trim() || `Delegate process failed with exit code ${code}`;
|
|
1614
1614
|
if (debug) {
|
|
@@ -2040,13 +2040,19 @@ For GitHub-compatible mermaid diagrams, avoid single quotes and parentheses in n
|
|
|
2040
2040
|
|
|
2041
2041
|
**Rules:**
|
|
2042
2042
|
- NO single quotes in any node labels: 'text' \u2192 "text" or text
|
|
2043
|
-
- NO parentheses in square brackets: [Text (detail)] \u2192 [Text - detail]
|
|
2043
|
+
- NO parentheses in square brackets: [Text (detail)] \u2192 [Text - detail]
|
|
2044
2044
|
- NO complex expressions in diamonds: {a && b} \u2192 {condition}
|
|
2045
|
+
- NO HTML tags in node labels: [<pre>code</pre>] \u2192 ["code block"] or [Code Block]
|
|
2045
2046
|
- USE single quotes for styles and classes: classDef highlight fill:'#ff9999'
|
|
2047
|
+
- CRITICAL: When using quotes in node labels, place them INSIDE the brackets: ["quoted text"], NOT [quoted text"]
|
|
2046
2048
|
|
|
2047
2049
|
**Examples:**
|
|
2048
2050
|
- \u2705 [Load Config] ["Run command"] {Valid?}
|
|
2051
|
+
- \u2705 ["depends_on: [generate-items]"] (correct quote placement)
|
|
2052
|
+
- \u2705 ["Code Block"] (clean text instead of HTML)
|
|
2049
2053
|
- \u274C [Load (config)] [Run 'command'] {isValid('x')}
|
|
2054
|
+
- \u274C [depends_on: [generate-items"] (incorrect quote placement - quote ends inside bracket)
|
|
2055
|
+
- \u274C [<pre>depends_on: [generate-items]</pre>] (HTML tags in node labels)
|
|
2050
2056
|
|
|
2051
2057
|
**Diagram Type Selection:**
|
|
2052
2058
|
|
|
@@ -2862,7 +2868,7 @@ function createMockProvider() {
|
|
|
2862
2868
|
provider: "mock",
|
|
2863
2869
|
// Mock the doGenerate method used by Vercel AI SDK
|
|
2864
2870
|
doGenerate: async ({ messages, tools: tools2 }) => {
|
|
2865
|
-
await new Promise((
|
|
2871
|
+
await new Promise((resolve2) => setTimeout(resolve2, 10));
|
|
2866
2872
|
return {
|
|
2867
2873
|
text: "This is a mock response for testing",
|
|
2868
2874
|
toolCalls: [],
|
|
@@ -4687,7 +4693,7 @@ var ProbeAgent_exports = {};
|
|
|
4687
4693
|
__export(ProbeAgent_exports, {
|
|
4688
4694
|
ProbeAgent: () => ProbeAgent
|
|
4689
4695
|
});
|
|
4690
|
-
var import_anthropic, import_openai, import_google, import_ai2, import_crypto5, import_events2, MAX_TOOL_ITERATIONS, MAX_HISTORY_MESSAGES, ProbeAgent;
|
|
4696
|
+
var import_anthropic, import_openai, import_google, import_ai2, import_crypto5, import_events2, import_fs5, import_promises, import_path7, MAX_TOOL_ITERATIONS, MAX_HISTORY_MESSAGES, SUPPORTED_IMAGE_EXTENSIONS, MAX_IMAGE_FILE_SIZE, ProbeAgent;
|
|
4691
4697
|
var init_ProbeAgent = __esm({
|
|
4692
4698
|
"src/agent/ProbeAgent.js"() {
|
|
4693
4699
|
"use strict";
|
|
@@ -4697,6 +4703,9 @@ var init_ProbeAgent = __esm({
|
|
|
4697
4703
|
import_ai2 = require("ai");
|
|
4698
4704
|
import_crypto5 = require("crypto");
|
|
4699
4705
|
import_events2 = require("events");
|
|
4706
|
+
import_fs5 = require("fs");
|
|
4707
|
+
import_promises = require("fs/promises");
|
|
4708
|
+
import_path7 = require("path");
|
|
4700
4709
|
init_tokenCounter();
|
|
4701
4710
|
init_tools2();
|
|
4702
4711
|
init_common();
|
|
@@ -4707,6 +4716,8 @@ var init_ProbeAgent = __esm({
|
|
|
4707
4716
|
init_mcp();
|
|
4708
4717
|
MAX_TOOL_ITERATIONS = parseInt(process.env.MAX_TOOL_ITERATIONS || "30", 10);
|
|
4709
4718
|
MAX_HISTORY_MESSAGES = 100;
|
|
4719
|
+
SUPPORTED_IMAGE_EXTENSIONS = ["png", "jpg", "jpeg", "webp", "gif", "bmp", "svg"];
|
|
4720
|
+
MAX_IMAGE_FILE_SIZE = 20 * 1024 * 1024;
|
|
4710
4721
|
ProbeAgent = class {
|
|
4711
4722
|
/**
|
|
4712
4723
|
* Create a new ProbeAgent instance
|
|
@@ -4750,6 +4761,8 @@ var init_ProbeAgent = __esm({
|
|
|
4750
4761
|
}
|
|
4751
4762
|
this.initializeTools();
|
|
4752
4763
|
this.history = [];
|
|
4764
|
+
this.pendingImages = /* @__PURE__ */ new Map();
|
|
4765
|
+
this.currentImages = [];
|
|
4753
4766
|
this.events = new import_events2.EventEmitter();
|
|
4754
4767
|
this.enableMcp = !!options.enableMcp || process.env.ENABLE_MCP === "1";
|
|
4755
4768
|
this.mcpConfigPath = options.mcpConfigPath || null;
|
|
@@ -4875,6 +4888,175 @@ var init_ProbeAgent = __esm({
|
|
|
4875
4888
|
console.log(`Using Google API with model: ${this.model}${apiUrl ? ` (URL: ${apiUrl})` : ""}`);
|
|
4876
4889
|
}
|
|
4877
4890
|
}
|
|
4891
|
+
/**
|
|
4892
|
+
* Process assistant response content and detect/load image references
|
|
4893
|
+
* @param {string} content - The assistant's response content
|
|
4894
|
+
* @returns {Promise<void>}
|
|
4895
|
+
*/
|
|
4896
|
+
async processImageReferences(content) {
|
|
4897
|
+
if (!content) return;
|
|
4898
|
+
const extensionsPattern = `(?:${SUPPORTED_IMAGE_EXTENSIONS.join("|")})`;
|
|
4899
|
+
const imagePatterns = [
|
|
4900
|
+
// Direct file path mentions: "./screenshot.png", "/path/to/image.jpg", etc.
|
|
4901
|
+
new RegExp(`(?:\\.?\\.\\/)?[^\\s"'<>\\[\\]]+\\.${extensionsPattern}(?!\\w)`, "gi"),
|
|
4902
|
+
// Contextual mentions: "look at image.png", "the file screenshot.jpg shows"
|
|
4903
|
+
new RegExp(`(?:image|file|screenshot|diagram|photo|picture|graphic)\\s*:?\\s*([^\\s"'<>\\[\\]]+\\.${extensionsPattern})(?!\\w)`, "gi"),
|
|
4904
|
+
// Tool result mentions: often contain file paths
|
|
4905
|
+
new RegExp(`(?:found|saved|created|generated).*?([^\\s"'<>\\[\\]]+\\.${extensionsPattern})(?!\\w)`, "gi")
|
|
4906
|
+
];
|
|
4907
|
+
const foundPaths = /* @__PURE__ */ new Set();
|
|
4908
|
+
for (const pattern of imagePatterns) {
|
|
4909
|
+
let match;
|
|
4910
|
+
while ((match = pattern.exec(content)) !== null) {
|
|
4911
|
+
const imagePath = match[1] || match[0];
|
|
4912
|
+
if (imagePath && imagePath.length > 0) {
|
|
4913
|
+
foundPaths.add(imagePath.trim());
|
|
4914
|
+
}
|
|
4915
|
+
}
|
|
4916
|
+
}
|
|
4917
|
+
if (foundPaths.size === 0) return;
|
|
4918
|
+
if (this.debug) {
|
|
4919
|
+
console.log(`[DEBUG] Found ${foundPaths.size} potential image references:`, Array.from(foundPaths));
|
|
4920
|
+
}
|
|
4921
|
+
for (const imagePath of foundPaths) {
|
|
4922
|
+
await this.loadImageIfValid(imagePath);
|
|
4923
|
+
}
|
|
4924
|
+
}
|
|
4925
|
+
/**
|
|
4926
|
+
* Load and cache an image if it's valid and accessible
|
|
4927
|
+
* @param {string} imagePath - Path to the image file
|
|
4928
|
+
* @returns {Promise<boolean>} - True if image was loaded successfully
|
|
4929
|
+
*/
|
|
4930
|
+
async loadImageIfValid(imagePath) {
|
|
4931
|
+
try {
|
|
4932
|
+
if (this.pendingImages.has(imagePath)) {
|
|
4933
|
+
if (this.debug) {
|
|
4934
|
+
console.log(`[DEBUG] Image already loaded: ${imagePath}`);
|
|
4935
|
+
}
|
|
4936
|
+
return true;
|
|
4937
|
+
}
|
|
4938
|
+
const allowedDirs = this.allowedFolders && this.allowedFolders.length > 0 ? this.allowedFolders : [process.cwd()];
|
|
4939
|
+
let absolutePath;
|
|
4940
|
+
let isPathAllowed = false;
|
|
4941
|
+
if ((0, import_path7.isAbsolute)(imagePath)) {
|
|
4942
|
+
absolutePath = imagePath;
|
|
4943
|
+
isPathAllowed = allowedDirs.some((dir) => absolutePath.startsWith((0, import_path7.resolve)(dir)));
|
|
4944
|
+
} else {
|
|
4945
|
+
for (const dir of allowedDirs) {
|
|
4946
|
+
const resolvedPath = (0, import_path7.resolve)(dir, imagePath);
|
|
4947
|
+
if (resolvedPath.startsWith((0, import_path7.resolve)(dir))) {
|
|
4948
|
+
absolutePath = resolvedPath;
|
|
4949
|
+
isPathAllowed = true;
|
|
4950
|
+
break;
|
|
4951
|
+
}
|
|
4952
|
+
}
|
|
4953
|
+
}
|
|
4954
|
+
if (!isPathAllowed) {
|
|
4955
|
+
if (this.debug) {
|
|
4956
|
+
console.log(`[DEBUG] Image path outside allowed directories: ${imagePath}`);
|
|
4957
|
+
}
|
|
4958
|
+
return false;
|
|
4959
|
+
}
|
|
4960
|
+
let fileStats;
|
|
4961
|
+
try {
|
|
4962
|
+
fileStats = await (0, import_promises.stat)(absolutePath);
|
|
4963
|
+
} catch (error) {
|
|
4964
|
+
if (this.debug) {
|
|
4965
|
+
console.log(`[DEBUG] Image file not found: ${absolutePath}`);
|
|
4966
|
+
}
|
|
4967
|
+
return false;
|
|
4968
|
+
}
|
|
4969
|
+
if (fileStats.size > MAX_IMAGE_FILE_SIZE) {
|
|
4970
|
+
if (this.debug) {
|
|
4971
|
+
console.log(`[DEBUG] Image file too large: ${absolutePath} (${fileStats.size} bytes, max: ${MAX_IMAGE_FILE_SIZE})`);
|
|
4972
|
+
}
|
|
4973
|
+
return false;
|
|
4974
|
+
}
|
|
4975
|
+
const extension = absolutePath.toLowerCase().split(".").pop();
|
|
4976
|
+
if (!SUPPORTED_IMAGE_EXTENSIONS.includes(extension)) {
|
|
4977
|
+
if (this.debug) {
|
|
4978
|
+
console.log(`[DEBUG] Unsupported image format: ${extension}`);
|
|
4979
|
+
}
|
|
4980
|
+
return false;
|
|
4981
|
+
}
|
|
4982
|
+
const mimeTypes = {
|
|
4983
|
+
"png": "image/png",
|
|
4984
|
+
"jpg": "image/jpeg",
|
|
4985
|
+
"jpeg": "image/jpeg",
|
|
4986
|
+
"webp": "image/webp",
|
|
4987
|
+
"gif": "image/gif",
|
|
4988
|
+
"bmp": "image/bmp",
|
|
4989
|
+
"svg": "image/svg+xml"
|
|
4990
|
+
};
|
|
4991
|
+
const mimeType = mimeTypes[extension];
|
|
4992
|
+
const fileBuffer = await (0, import_promises.readFile)(absolutePath);
|
|
4993
|
+
const base64Data = fileBuffer.toString("base64");
|
|
4994
|
+
const dataUrl = `data:${mimeType};base64,${base64Data}`;
|
|
4995
|
+
this.pendingImages.set(imagePath, dataUrl);
|
|
4996
|
+
if (this.debug) {
|
|
4997
|
+
console.log(`[DEBUG] Successfully loaded image: ${imagePath} (${fileBuffer.length} bytes)`);
|
|
4998
|
+
}
|
|
4999
|
+
return true;
|
|
5000
|
+
} catch (error) {
|
|
5001
|
+
if (this.debug) {
|
|
5002
|
+
console.log(`[DEBUG] Failed to load image ${imagePath}: ${error.message}`);
|
|
5003
|
+
}
|
|
5004
|
+
return false;
|
|
5005
|
+
}
|
|
5006
|
+
}
|
|
5007
|
+
/**
|
|
5008
|
+
* Get all currently loaded images as an array for AI model consumption
|
|
5009
|
+
* @returns {Array<string>} - Array of base64 data URLs
|
|
5010
|
+
*/
|
|
5011
|
+
getCurrentImages() {
|
|
5012
|
+
return Array.from(this.pendingImages.values());
|
|
5013
|
+
}
|
|
5014
|
+
/**
|
|
5015
|
+
* Clear loaded images (useful for new conversations)
|
|
5016
|
+
*/
|
|
5017
|
+
clearLoadedImages() {
|
|
5018
|
+
this.pendingImages.clear();
|
|
5019
|
+
this.currentImages = [];
|
|
5020
|
+
if (this.debug) {
|
|
5021
|
+
console.log("[DEBUG] Cleared all loaded images");
|
|
5022
|
+
}
|
|
5023
|
+
}
|
|
5024
|
+
/**
|
|
5025
|
+
* Prepare messages for AI consumption, adding images to the latest user message if available
|
|
5026
|
+
* @param {Array} messages - Current conversation messages
|
|
5027
|
+
* @returns {Array} - Messages formatted for AI SDK with potential image content
|
|
5028
|
+
*/
|
|
5029
|
+
prepareMessagesWithImages(messages) {
|
|
5030
|
+
const loadedImages = this.getCurrentImages();
|
|
5031
|
+
if (loadedImages.length === 0) {
|
|
5032
|
+
return messages;
|
|
5033
|
+
}
|
|
5034
|
+
const messagesWithImages = [...messages];
|
|
5035
|
+
const lastUserMessageIndex = messagesWithImages.map((m) => m.role).lastIndexOf("user");
|
|
5036
|
+
if (lastUserMessageIndex === -1) {
|
|
5037
|
+
if (this.debug) {
|
|
5038
|
+
console.log("[DEBUG] No user messages found to attach images to");
|
|
5039
|
+
}
|
|
5040
|
+
return messages;
|
|
5041
|
+
}
|
|
5042
|
+
const lastUserMessage = messagesWithImages[lastUserMessageIndex];
|
|
5043
|
+
if (typeof lastUserMessage.content === "string") {
|
|
5044
|
+
messagesWithImages[lastUserMessageIndex] = {
|
|
5045
|
+
...lastUserMessage,
|
|
5046
|
+
content: [
|
|
5047
|
+
{ type: "text", text: lastUserMessage.content },
|
|
5048
|
+
...loadedImages.map((imageData) => ({
|
|
5049
|
+
type: "image",
|
|
5050
|
+
image: imageData
|
|
5051
|
+
}))
|
|
5052
|
+
]
|
|
5053
|
+
};
|
|
5054
|
+
if (this.debug) {
|
|
5055
|
+
console.log(`[DEBUG] Added ${loadedImages.length} images to the latest user message`);
|
|
5056
|
+
}
|
|
5057
|
+
}
|
|
5058
|
+
return messagesWithImages;
|
|
5059
|
+
}
|
|
4878
5060
|
/**
|
|
4879
5061
|
* Initialize mock model for testing
|
|
4880
5062
|
*/
|
|
@@ -4974,7 +5156,7 @@ Examples:
|
|
|
4974
5156
|
</extract>
|
|
4975
5157
|
|
|
4976
5158
|
<attempt_completion>
|
|
4977
|
-
|
|
5159
|
+
The configuration is loaded from src/config.js lines 15-25 which contains the database settings.
|
|
4978
5160
|
</attempt_completion>
|
|
4979
5161
|
|
|
4980
5162
|
# Special Case: Quick Completion
|
|
@@ -5001,7 +5183,7 @@ I need to find code related to error handling in the search module. The most app
|
|
|
5001
5183
|
6. Wait for the tool execution result, which will be provided in the next message (within a <tool_result> block).
|
|
5002
5184
|
7. Analyze the tool result and decide the next step. If more tool calls are needed, repeat steps 2-6.
|
|
5003
5185
|
8. If the task is fully complete and all previous steps were successful, use the \`<attempt_completion>\` tool to provide the final answer. This is the ONLY way to finish the task.
|
|
5004
|
-
9. If you cannot proceed (e.g., missing information, invalid request), explain the issue clearly
|
|
5186
|
+
9. If you cannot proceed (e.g., missing information, invalid request), use \`<attempt_completion>\` to explain the issue clearly with an appropriate message directly inside the tags.
|
|
5005
5187
|
10. If your previous response was already correct and complete, you may use \`<attempt_complete>\` as a shorthand.
|
|
5006
5188
|
|
|
5007
5189
|
Available Tools:
|
|
@@ -5256,9 +5438,10 @@ You are working with a repository located at: ${searchDirectory}
|
|
|
5256
5438
|
let assistantResponseContent = "";
|
|
5257
5439
|
try {
|
|
5258
5440
|
const executeAIRequest = async () => {
|
|
5441
|
+
const messagesForAI = this.prepareMessagesWithImages(currentMessages);
|
|
5259
5442
|
const result = await (0, import_ai2.streamText)({
|
|
5260
5443
|
model: this.provider(this.model),
|
|
5261
|
-
messages:
|
|
5444
|
+
messages: messagesForAI,
|
|
5262
5445
|
maxTokens: maxResponseTokens,
|
|
5263
5446
|
temperature: 0.3
|
|
5264
5447
|
});
|
|
@@ -5292,6 +5475,9 @@ You are working with a repository located at: ${searchDirectory}
|
|
|
5292
5475
|
const assistantPreview = createMessagePreview(assistantResponseContent);
|
|
5293
5476
|
console.log(`[DEBUG] Assistant response (${assistantResponseContent.length} chars): ${assistantPreview}`);
|
|
5294
5477
|
}
|
|
5478
|
+
if (assistantResponseContent) {
|
|
5479
|
+
await this.processImageReferences(assistantResponseContent);
|
|
5480
|
+
}
|
|
5295
5481
|
const validTools = [
|
|
5296
5482
|
"search",
|
|
5297
5483
|
"query",
|
|
@@ -5416,12 +5602,17 @@ ${toolResultContent}
|
|
|
5416
5602
|
throw toolError;
|
|
5417
5603
|
}
|
|
5418
5604
|
currentMessages.push({ role: "assistant", content: assistantResponseContent });
|
|
5605
|
+
const toolResultContent = typeof toolResult === "string" ? toolResult : JSON.stringify(toolResult, null, 2);
|
|
5606
|
+
const toolResultMessage = `<tool_result>
|
|
5607
|
+
${toolResultContent}
|
|
5608
|
+
</tool_result>`;
|
|
5419
5609
|
currentMessages.push({
|
|
5420
5610
|
role: "user",
|
|
5421
|
-
content:
|
|
5422
|
-
${typeof toolResult === "string" ? toolResult : JSON.stringify(toolResult, null, 2)}
|
|
5423
|
-
</tool_result>`
|
|
5611
|
+
content: toolResultMessage
|
|
5424
5612
|
});
|
|
5613
|
+
if (toolResultContent) {
|
|
5614
|
+
await this.processImageReferences(toolResultContent);
|
|
5615
|
+
}
|
|
5425
5616
|
if (this.debug) {
|
|
5426
5617
|
console.log(`[DEBUG] Tool ${toolName} executed successfully. Result length: ${typeof toolResult === "string" ? toolResult.length : JSON.stringify(toolResult).length}`);
|
|
5427
5618
|
}
|
|
@@ -5919,12 +6110,12 @@ function initializeSimpleTelemetryFromOptions(options) {
|
|
|
5919
6110
|
});
|
|
5920
6111
|
return telemetry;
|
|
5921
6112
|
}
|
|
5922
|
-
var
|
|
6113
|
+
var import_fs6, import_path8, SimpleTelemetry, SimpleAppTracer;
|
|
5923
6114
|
var init_simpleTelemetry = __esm({
|
|
5924
6115
|
"src/agent/simpleTelemetry.js"() {
|
|
5925
6116
|
"use strict";
|
|
5926
|
-
|
|
5927
|
-
|
|
6117
|
+
import_fs6 = require("fs");
|
|
6118
|
+
import_path8 = require("path");
|
|
5928
6119
|
SimpleTelemetry = class {
|
|
5929
6120
|
constructor(options = {}) {
|
|
5930
6121
|
this.serviceName = options.serviceName || "probe-agent";
|
|
@@ -5938,11 +6129,11 @@ var init_simpleTelemetry = __esm({
|
|
|
5938
6129
|
}
|
|
5939
6130
|
initializeFileExporter() {
|
|
5940
6131
|
try {
|
|
5941
|
-
const dir = (0,
|
|
5942
|
-
if (!(0,
|
|
5943
|
-
(0,
|
|
6132
|
+
const dir = (0, import_path8.dirname)(this.filePath);
|
|
6133
|
+
if (!(0, import_fs6.existsSync)(dir)) {
|
|
6134
|
+
(0, import_fs6.mkdirSync)(dir, { recursive: true });
|
|
5944
6135
|
}
|
|
5945
|
-
this.stream = (0,
|
|
6136
|
+
this.stream = (0, import_fs6.createWriteStream)(this.filePath, { flags: "a" });
|
|
5946
6137
|
this.stream.on("error", (error) => {
|
|
5947
6138
|
console.error(`[SimpleTelemetry] Stream error: ${error.message}`);
|
|
5948
6139
|
});
|
|
@@ -6003,20 +6194,20 @@ var init_simpleTelemetry = __esm({
|
|
|
6003
6194
|
}
|
|
6004
6195
|
async flush() {
|
|
6005
6196
|
if (this.stream) {
|
|
6006
|
-
return new Promise((
|
|
6007
|
-
this.stream.once("drain",
|
|
6197
|
+
return new Promise((resolve2) => {
|
|
6198
|
+
this.stream.once("drain", resolve2);
|
|
6008
6199
|
if (!this.stream.writableNeedDrain) {
|
|
6009
|
-
|
|
6200
|
+
resolve2();
|
|
6010
6201
|
}
|
|
6011
6202
|
});
|
|
6012
6203
|
}
|
|
6013
6204
|
}
|
|
6014
6205
|
async shutdown() {
|
|
6015
6206
|
if (this.stream) {
|
|
6016
|
-
return new Promise((
|
|
6207
|
+
return new Promise((resolve2) => {
|
|
6017
6208
|
this.stream.end(() => {
|
|
6018
6209
|
console.log(`[SimpleTelemetry] File stream closed: ${this.filePath}`);
|
|
6019
|
-
|
|
6210
|
+
resolve2();
|
|
6020
6211
|
});
|
|
6021
6212
|
});
|
|
6022
6213
|
}
|