@bike4mind/cli 0.15.2 → 0.16.0
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/README.md +49 -0
- package/bin/bike4mind-cli.mjs +66 -0
- package/dist/{ConfigStore-w0o_0xs0.mjs → ConfigStore-CtGc4fF2.mjs} +136 -9
- package/dist/commands/apiCommand.mjs +1 -1
- package/dist/commands/doctorCommand.mjs +1 -1
- package/dist/commands/envCommand.mjs +1 -1
- package/dist/commands/headlessCommand.mjs +2 -2
- package/dist/commands/mcpCommand.mjs +1 -1
- package/dist/commands/updateCommand.mjs +1 -1
- package/dist/index.mjs +36 -10
- package/dist/{package-C9MYdYCP.mjs → package-3pouvthv.mjs} +1 -1
- package/dist/{tools-j5oGazTr.mjs → tools-D9eSRR7Q.mjs} +345 -152
- package/package.json +21 -21
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { $ as ProjectEvents, A as GenerateImageToolCallSchema, At as dayjsConfig_default, B as InviteEvents, Bt as resolveNavigationIntents, C as ElabsEvents, Ct as UnauthorizedError, D as ForbiddenError, Dt as VideoModels, E as FileEvents, Et as VideoGenerationUsageTransaction, F as ImageEditUsageTransaction, Ft as isGPTImage2Model, G as ModalEvents, H as KnowledgeType, Ht as secureParameters, I as ImageGenerationUsageTransaction, It as isGPTImageModel, J as OpenAIEmbeddingModel, Jt as isNearLimit, K as ModelBackend, Kt as buildRateLimitLogEntry, L as ImageModels, Lt as isSupportedEmbeddingModel, M as GenericCreditDeductTransaction, Mt as getDataLakeTags, N as HTTPError, Nt as getMcpProviderMetadata, O as FriendshipEvents, Ot as XAI_IMAGE_MODELS, P as HttpStatus, Pt as getViewById, Q as ProfileEvents, R as InboxEvents, Rt as isZodError, S as DashboardParamsSchema, St as UiNavigationEvents, T as FeedbackEvents, Tt as VIDEO_SIZE_CONSTRAINTS, U as LLMEvents, Ut as settingsMap, V as InviteType, Vt as sanitizeTelemetryError, W as MiscEvents, X as Permission, Xt as CollectionType, Y as OpenAIImageGenerationInput, Yt as parseRateLimitHeaders, Z as PermissionDeniedError, _ as ChatCompletionCreateInputSchema, _t as TaskScheduleHandler, a as ALERT_THRESHOLDS, at as ReceivedCreditTransaction, b as CompletionApiUsageTransaction, bt as ToolUsageTransaction, c as ApiKeyScope, ct as ResearchModeParamsSchema, d as ArtifactTypeSchema, dt as ResearchTaskType, et as PromptIntentSchema, f as AuthEvents, ft as SessionEvents, gt as TagType, h as BadRequestError, ht as SupportedFabFileMimeTypes, it as RealtimeVoiceUsageTransaction, j as GenericCreditAddTransaction, jt as getAccessibleDataLakes, k as GEMINI_IMAGE_MODELS, kt as b4mLLMTools, l as ApiKeyType, lt as ResearchTaskExecutionType, m as BFL_SAFETY_TOLERANCE, mt as SubscriptionCreditTransaction, n as logger, nt as PurchaseTransaction, o as AiEvents, ot as RechartsChartTypeList, p as BFL_IMAGE_MODELS, pt as SpeechToTextUsageTransaction, q as NotFoundError, qt as extractSnippetMeta, rt as QuestMasterParamsSchema, s as ApiKeyEvents, st as RegInviteEvents, t as ConfigStore, tt as PromptMetaZodSchema, u as AppFileEvents, ut as ResearchTaskPeriodicFrequencyType, v as ChatModels, vt as TextGenerationUsageTransaction, w as FavoriteDocumentType, wt as UnprocessableEntityError, x as CorruptedFileError, xt as TransferCreditTransaction, y as ClaudeArtifactMimeTypes, yt as TooManyRequestsError, z as InternalServerError, zt as obfuscateApiKey } from "./ConfigStore-
|
|
2
|
+
import { $ as ProjectEvents, A as GenerateImageToolCallSchema, At as dayjsConfig_default, B as InviteEvents, Bt as resolveNavigationIntents, C as ElabsEvents, Ct as UnauthorizedError, D as ForbiddenError, Dt as VideoModels, E as FileEvents, Et as VideoGenerationUsageTransaction, F as ImageEditUsageTransaction, Ft as isGPTImage2Model, G as ModalEvents, H as KnowledgeType, Ht as secureParameters, I as ImageGenerationUsageTransaction, It as isGPTImageModel, J as OpenAIEmbeddingModel, Jt as isNearLimit, K as ModelBackend, Kt as buildRateLimitLogEntry, L as ImageModels, Lt as isSupportedEmbeddingModel, M as GenericCreditDeductTransaction, Mt as getDataLakeTags, N as HTTPError, Nt as getMcpProviderMetadata, O as FriendshipEvents, Ot as XAI_IMAGE_MODELS, P as HttpStatus, Pt as getViewById, Q as ProfileEvents, R as InboxEvents, Rt as isZodError, S as DashboardParamsSchema, St as UiNavigationEvents, T as FeedbackEvents, Tt as VIDEO_SIZE_CONSTRAINTS, U as LLMEvents, Ut as settingsMap, V as InviteType, Vt as sanitizeTelemetryError, W as MiscEvents, X as Permission, Xt as CollectionType, Y as OpenAIImageGenerationInput, Yt as parseRateLimitHeaders, Z as PermissionDeniedError, _ as ChatCompletionCreateInputSchema, _t as TaskScheduleHandler, a as ALERT_THRESHOLDS, at as ReceivedCreditTransaction, b as CompletionApiUsageTransaction, bt as ToolUsageTransaction, c as ApiKeyScope, ct as ResearchModeParamsSchema, d as ArtifactTypeSchema, dt as ResearchTaskType, et as PromptIntentSchema, f as AuthEvents, ft as SessionEvents, gt as TagType, h as BadRequestError, ht as SupportedFabFileMimeTypes, it as RealtimeVoiceUsageTransaction, j as GenericCreditAddTransaction, jt as getAccessibleDataLakes, k as GEMINI_IMAGE_MODELS, kt as b4mLLMTools, l as ApiKeyType, lt as ResearchTaskExecutionType, m as BFL_SAFETY_TOLERANCE, mt as SubscriptionCreditTransaction, n as logger, nt as PurchaseTransaction, o as AiEvents, ot as RechartsChartTypeList, p as BFL_IMAGE_MODELS, pt as SpeechToTextUsageTransaction, q as NotFoundError, qt as extractSnippetMeta, rt as QuestMasterParamsSchema, s as ApiKeyEvents, st as RegInviteEvents, t as ConfigStore, tt as PromptMetaZodSchema, u as AppFileEvents, ut as ResearchTaskPeriodicFrequencyType, v as ChatModels, vt as TextGenerationUsageTransaction, w as FavoriteDocumentType, wt as UnprocessableEntityError, x as CorruptedFileError, xt as TransferCreditTransaction, y as ClaudeArtifactMimeTypes, yt as TooManyRequestsError, z as InternalServerError, zt as obfuscateApiKey } from "./ConfigStore-CtGc4fF2.mjs";
|
|
3
3
|
import { a as isUserLockedOut, c as userCanDisableMFA, d as userRequiresMFA, f as verifyBackupCode, i as getLockoutTimeRemaining, l as userEligibleForMFA, n as generateBackupCodes, o as recordFailedAttempt, p as verifyTOTPToken, r as generateTOTPSetup, s as shouldResetFailedAttempts, t as clearFailedAttempts, u as userHasMFAConfigured } from "./utils-PpNti-tY.mjs";
|
|
4
4
|
import { n as isPathAllowed, t as assertPathAllowed } from "./pathValidation-D8tjkQXE-1HwvsuYT.mjs";
|
|
5
|
-
import { t as version } from "./package-
|
|
5
|
+
import { t as version } from "./package-3pouvthv.mjs";
|
|
6
6
|
import { execFile, execFileSync, spawn } from "child_process";
|
|
7
7
|
import crypto, { createHash, randomBytes, randomUUID } from "crypto";
|
|
8
8
|
import { existsSync, promises, readFileSync, readdirSync, rmSync, statSync, unlinkSync, writeFileSync } from "fs";
|
|
@@ -70,6 +70,7 @@ import { Mutex } from "async-mutex";
|
|
|
70
70
|
import "zod-validation-error";
|
|
71
71
|
import { homedir as homedir$1 } from "node:os";
|
|
72
72
|
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
73
|
+
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
73
74
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
74
75
|
import { fileURLToPath } from "url";
|
|
75
76
|
import WsWebSocket from "ws";
|
|
@@ -1902,6 +1903,18 @@ function shouldUseParallelExecution(toolsUsed, isReadOnly = defaultIsReadOnlyToo
|
|
|
1902
1903
|
return toolsUsed.filter((tool) => isReadOnly(tool.name)).length >= 2;
|
|
1903
1904
|
}
|
|
1904
1905
|
/**
|
|
1906
|
+
* True when an error is an abort/cancellation (user stop or execution timeout)
|
|
1907
|
+
* rather than a real failure. Aborts are benign and must NOT be logged at error
|
|
1908
|
+
* severity — error logs trip the CloudWatch ERROR→LiveOps/Slack alert path and
|
|
1909
|
+
* page on routine cancellations (#8947, #8669).
|
|
1910
|
+
*/
|
|
1911
|
+
function isAbortError(error, signal) {
|
|
1912
|
+
if (signal?.aborted) return true;
|
|
1913
|
+
if (!(error instanceof Error)) return false;
|
|
1914
|
+
if (error.name === "AbortError") return true;
|
|
1915
|
+
return error.message.toLowerCase().includes("aborted");
|
|
1916
|
+
}
|
|
1917
|
+
/**
|
|
1905
1918
|
* ReAct (Reasoning and Acting) Agent
|
|
1906
1919
|
*
|
|
1907
1920
|
* This agent uses the ReAct pattern to solve problems by:
|
|
@@ -2051,6 +2064,9 @@ var ReActAgent = class extends EventEmitter {
|
|
|
2051
2064
|
let currentText = "";
|
|
2052
2065
|
const processedToolIds = /* @__PURE__ */ new Set();
|
|
2053
2066
|
let hadToolCalls = false;
|
|
2067
|
+
let thoughtEmitted = false;
|
|
2068
|
+
const iterStartInputTokens = this.totalInputTokens;
|
|
2069
|
+
const iterStartOutputTokens = this.totalOutputTokens;
|
|
2054
2070
|
if (maxHistoryIterations > 0 && iterations > 1) {
|
|
2055
2071
|
trimConversationHistory(messages, maxHistoryIterations, this.initialMessageCount);
|
|
2056
2072
|
trimSteps(this.steps, maxHistoryIterations);
|
|
@@ -2092,35 +2108,18 @@ var ReActAgent = class extends EventEmitter {
|
|
|
2092
2108
|
this.totalCacheWriteTokens += completionInfo.cacheStats.cacheWriteTokens || 0;
|
|
2093
2109
|
}
|
|
2094
2110
|
if (completionInfo.creditsUsed) this.totalCredits += completionInfo.creditsUsed;
|
|
2095
|
-
if (currentText.trim() && completionInfo.toolsUsed?.length) {
|
|
2096
|
-
const thoughtStep = {
|
|
2097
|
-
type: "thought",
|
|
2098
|
-
content: currentText.trim(),
|
|
2099
|
-
metadata: { timestamp: Date.now() }
|
|
2100
|
-
};
|
|
2101
|
-
this.steps.push(thoughtStep);
|
|
2102
|
-
this.emit("thought", thoughtStep);
|
|
2103
|
-
}
|
|
2104
|
-
if (!completionInfo.toolsUsed?.length && currentText.trim()) {
|
|
2105
|
-
finalAnswer = currentText.trim();
|
|
2106
|
-
const finalStep = {
|
|
2107
|
-
type: "final_answer",
|
|
2108
|
-
content: finalAnswer,
|
|
2109
|
-
metadata: {
|
|
2110
|
-
timestamp: Date.now(),
|
|
2111
|
-
tokenUsage: {
|
|
2112
|
-
prompt: inputTokens,
|
|
2113
|
-
completion: outputTokens,
|
|
2114
|
-
total: inputTokens + outputTokens
|
|
2115
|
-
}
|
|
2116
|
-
}
|
|
2117
|
-
};
|
|
2118
|
-
this.steps.push(finalStep);
|
|
2119
|
-
this.emit("final_answer", finalStep);
|
|
2120
|
-
iterationComplete = true;
|
|
2121
|
-
}
|
|
2122
2111
|
if (completionInfo.toolsUsed && completionInfo.toolsUsed.length > 0) {
|
|
2123
2112
|
hadToolCalls = true;
|
|
2113
|
+
if (!thoughtEmitted && currentText.trim()) {
|
|
2114
|
+
const thoughtStep = {
|
|
2115
|
+
type: "thought",
|
|
2116
|
+
content: currentText.trim(),
|
|
2117
|
+
metadata: { timestamp: Date.now() }
|
|
2118
|
+
};
|
|
2119
|
+
this.steps.push(thoughtStep);
|
|
2120
|
+
this.emit("thought", thoughtStep);
|
|
2121
|
+
thoughtEmitted = true;
|
|
2122
|
+
}
|
|
2124
2123
|
const thinkingBlocks = completionInfo.thinking || [];
|
|
2125
2124
|
const unprocessedTools = [];
|
|
2126
2125
|
for (const toolUse of completionInfo.toolsUsed) {
|
|
@@ -2159,6 +2158,26 @@ var ReActAgent = class extends EventEmitter {
|
|
|
2159
2158
|
}
|
|
2160
2159
|
}
|
|
2161
2160
|
});
|
|
2161
|
+
if (!hadToolCalls && currentText.trim()) {
|
|
2162
|
+
finalAnswer = currentText.trim();
|
|
2163
|
+
const iterInputTokens = this.totalInputTokens - iterStartInputTokens;
|
|
2164
|
+
const iterOutputTokens = this.totalOutputTokens - iterStartOutputTokens;
|
|
2165
|
+
const finalStep = {
|
|
2166
|
+
type: "final_answer",
|
|
2167
|
+
content: finalAnswer,
|
|
2168
|
+
metadata: {
|
|
2169
|
+
timestamp: Date.now(),
|
|
2170
|
+
tokenUsage: {
|
|
2171
|
+
prompt: iterInputTokens,
|
|
2172
|
+
completion: iterOutputTokens,
|
|
2173
|
+
total: iterInputTokens + iterOutputTokens
|
|
2174
|
+
}
|
|
2175
|
+
}
|
|
2176
|
+
};
|
|
2177
|
+
this.steps.push(finalStep);
|
|
2178
|
+
this.emit("final_answer", finalStep);
|
|
2179
|
+
iterationComplete = true;
|
|
2180
|
+
}
|
|
2162
2181
|
if (iterationComplete && finalAnswer) break;
|
|
2163
2182
|
if (hadToolCalls && options.confidenceGate && this.iterationConfidences.length > 0) {
|
|
2164
2183
|
const iterAvg = this.iterationConfidences.reduce((a, b) => a + b, 0) / this.iterationConfidences.length;
|
|
@@ -2258,7 +2277,8 @@ var ReActAgent = class extends EventEmitter {
|
|
|
2258
2277
|
this.emit("complete", result);
|
|
2259
2278
|
return result;
|
|
2260
2279
|
}
|
|
2261
|
-
this.context.logger.
|
|
2280
|
+
if (isAbortError(error, options.signal)) this.context.logger.warn("[ReActAgent] Execution aborted (user cancel or timeout):", error);
|
|
2281
|
+
else this.context.logger.error("[ReActAgent] Error during execution:", error);
|
|
2262
2282
|
this.emit("error", error);
|
|
2263
2283
|
throw error;
|
|
2264
2284
|
}
|
|
@@ -2530,6 +2550,9 @@ Remember: You are an autonomous AGENT. Act independently and solve problems proa
|
|
|
2530
2550
|
let finalAnswer = "";
|
|
2531
2551
|
const processedToolIds = /* @__PURE__ */ new Set();
|
|
2532
2552
|
let hadToolCalls = false;
|
|
2553
|
+
let thoughtEmitted = false;
|
|
2554
|
+
const iterStartInputTokens = this.totalInputTokens;
|
|
2555
|
+
const iterStartOutputTokens = this.totalOutputTokens;
|
|
2533
2556
|
const cacheStrategy = options.enableCaching ? {
|
|
2534
2557
|
enableCaching: true,
|
|
2535
2558
|
cacheSystemPrompt: true,
|
|
@@ -2567,41 +2590,22 @@ Remember: You are an autonomous AGENT. Act independently and solve problems proa
|
|
|
2567
2590
|
this.totalCacheWriteTokens += completionInfo.cacheStats.cacheWriteTokens || 0;
|
|
2568
2591
|
}
|
|
2569
2592
|
if (completionInfo.creditsUsed) this.totalCredits += completionInfo.creditsUsed;
|
|
2570
|
-
if (currentText.trim() && completionInfo.toolsUsed?.length) {
|
|
2571
|
-
const thoughtStep = {
|
|
2572
|
-
type: "thought",
|
|
2573
|
-
content: currentText.trim(),
|
|
2574
|
-
metadata: {
|
|
2575
|
-
timestamp: Date.now(),
|
|
2576
|
-
iteration: this.iterations - 1
|
|
2577
|
-
}
|
|
2578
|
-
};
|
|
2579
|
-
this.steps.push(thoughtStep);
|
|
2580
|
-
iterationSteps.push(thoughtStep);
|
|
2581
|
-
this.emit("thought", thoughtStep);
|
|
2582
|
-
}
|
|
2583
|
-
if (!completionInfo.toolsUsed?.length && currentText.trim()) {
|
|
2584
|
-
finalAnswer = currentText.trim();
|
|
2585
|
-
const finalStep = {
|
|
2586
|
-
type: "final_answer",
|
|
2587
|
-
content: finalAnswer,
|
|
2588
|
-
metadata: {
|
|
2589
|
-
timestamp: Date.now(),
|
|
2590
|
-
iteration: this.iterations - 1,
|
|
2591
|
-
tokenUsage: {
|
|
2592
|
-
prompt: inputTokens,
|
|
2593
|
-
completion: outputTokens,
|
|
2594
|
-
total: inputTokens + outputTokens
|
|
2595
|
-
}
|
|
2596
|
-
}
|
|
2597
|
-
};
|
|
2598
|
-
this.steps.push(finalStep);
|
|
2599
|
-
iterationSteps.push(finalStep);
|
|
2600
|
-
this.emit("final_answer", finalStep);
|
|
2601
|
-
iterationComplete = true;
|
|
2602
|
-
}
|
|
2603
2593
|
if (completionInfo.toolsUsed && completionInfo.toolsUsed.length > 0) {
|
|
2604
2594
|
hadToolCalls = true;
|
|
2595
|
+
if (!thoughtEmitted && currentText.trim()) {
|
|
2596
|
+
const thoughtStep = {
|
|
2597
|
+
type: "thought",
|
|
2598
|
+
content: currentText.trim(),
|
|
2599
|
+
metadata: {
|
|
2600
|
+
timestamp: Date.now(),
|
|
2601
|
+
iteration: this.iterations - 1
|
|
2602
|
+
}
|
|
2603
|
+
};
|
|
2604
|
+
this.steps.push(thoughtStep);
|
|
2605
|
+
iterationSteps.push(thoughtStep);
|
|
2606
|
+
this.emit("thought", thoughtStep);
|
|
2607
|
+
thoughtEmitted = true;
|
|
2608
|
+
}
|
|
2605
2609
|
const thinkingBlocks = completionInfo.thinking || [];
|
|
2606
2610
|
const unprocessedTools = [];
|
|
2607
2611
|
for (const toolUse of completionInfo.toolsUsed) {
|
|
@@ -2645,6 +2649,28 @@ Remember: You are an autonomous AGENT. Act independently and solve problems proa
|
|
|
2645
2649
|
}
|
|
2646
2650
|
}
|
|
2647
2651
|
});
|
|
2652
|
+
if (!hadToolCalls && currentText.trim()) {
|
|
2653
|
+
finalAnswer = currentText.trim();
|
|
2654
|
+
const iterInputTokens = this.totalInputTokens - iterStartInputTokens;
|
|
2655
|
+
const iterOutputTokens = this.totalOutputTokens - iterStartOutputTokens;
|
|
2656
|
+
const finalStep = {
|
|
2657
|
+
type: "final_answer",
|
|
2658
|
+
content: finalAnswer,
|
|
2659
|
+
metadata: {
|
|
2660
|
+
timestamp: Date.now(),
|
|
2661
|
+
iteration: this.iterations - 1,
|
|
2662
|
+
tokenUsage: {
|
|
2663
|
+
prompt: iterInputTokens,
|
|
2664
|
+
completion: iterOutputTokens,
|
|
2665
|
+
total: iterInputTokens + iterOutputTokens
|
|
2666
|
+
}
|
|
2667
|
+
}
|
|
2668
|
+
};
|
|
2669
|
+
this.steps.push(finalStep);
|
|
2670
|
+
iterationSteps.push(finalStep);
|
|
2671
|
+
this.emit("final_answer", finalStep);
|
|
2672
|
+
iterationComplete = true;
|
|
2673
|
+
}
|
|
2648
2674
|
if (hadToolCalls && options.confidenceGate && this.iterationConfidences.length > 0) {
|
|
2649
2675
|
const iterAvg = this.iterationConfidences.reduce((a, b) => a + b, 0) / this.iterationConfidences.length;
|
|
2650
2676
|
const decision = options.confidenceGate(iterAvg, this.iterations);
|
|
@@ -2727,7 +2753,7 @@ Remember: You are an autonomous AGENT. Act independently and solve problems proa
|
|
|
2727
2753
|
};
|
|
2728
2754
|
}
|
|
2729
2755
|
return {
|
|
2730
|
-
step: iterationSteps.
|
|
2756
|
+
step: iterationSteps.findLast((s) => s.type === "final_answer") || iterationSteps[iterationSteps.length - 1] || {
|
|
2731
2757
|
type: "thought",
|
|
2732
2758
|
content: currentText.trim() || "No output from this iteration",
|
|
2733
2759
|
metadata: { timestamp: Date.now() }
|
|
@@ -2761,7 +2787,8 @@ Remember: You are an autonomous AGENT. Act independently and solve problems proa
|
|
|
2761
2787
|
checkpoint: this.toCheckpoint()
|
|
2762
2788
|
};
|
|
2763
2789
|
}
|
|
2764
|
-
this.context.logger.
|
|
2790
|
+
if (isAbortError(error, options.signal)) this.context.logger.warn("[ReActAgent] Iteration aborted (user cancel or timeout):", error);
|
|
2791
|
+
else this.context.logger.error("[ReActAgent] Error during runIteration:", error);
|
|
2765
2792
|
this.emit("error", error);
|
|
2766
2793
|
throw error;
|
|
2767
2794
|
}
|
|
@@ -4117,7 +4144,7 @@ These tools are lightweight — use them naturally as part of your work, not as
|
|
|
4117
4144
|
|
|
4118
4145
|
## Working Directory
|
|
4119
4146
|
|
|
4120
|
-
The current working directory is \`${process.cwd()}\`. All relative paths in tool calls resolve from here. When using \`${TOOL_GLOB_FILES}\` or \`${TOOL_GREP_SEARCH}\` without an explicit \`dir_path\`, they search from this directory.${directoriesSection}${projectContextSection}${skillsSection}${featureModulesSection}${planModeSection}${deferredToolSection}`;
|
|
4147
|
+
The current working directory is \`${process.cwd()}\`. All relative paths in tool calls resolve from here. When using \`${TOOL_GLOB_FILES}\` or \`${TOOL_GREP_SEARCH}\` without an explicit \`dir_path\`, they search from this directory.${directoriesSection}${projectContextSection}${skillsSection}${featureModulesSection}${planModeSection}${deferredToolSection}${config?.appendSystemPrompt ? `\n\n${config.appendSystemPrompt}` : ""}`;
|
|
4121
4148
|
}
|
|
4122
4149
|
/**
|
|
4123
4150
|
* Build the minimal-variant system prompt. Reuses the project context,
|
|
@@ -4147,7 +4174,7 @@ Guidelines:
|
|
|
4147
4174
|
|
|
4148
4175
|
## Working Directory
|
|
4149
4176
|
|
|
4150
|
-
The current working directory is \`${process.cwd()}\`. All relative paths in tool calls resolve from here. When using \`${TOOL_GLOB_FILES}\` or \`${TOOL_GREP_SEARCH}\` without an explicit \`dir_path\`, they search from this directory.${directoriesSection}${projectContextSection}${skillsSection}${featureModulesSection}${planModeSection}${deferredToolSection}`;
|
|
4177
|
+
The current working directory is \`${process.cwd()}\`. All relative paths in tool calls resolve from here. When using \`${TOOL_GLOB_FILES}\` or \`${TOOL_GREP_SEARCH}\` without an explicit \`dir_path\`, they search from this directory.${directoriesSection}${projectContextSection}${skillsSection}${featureModulesSection}${planModeSection}${deferredToolSection}${config?.appendSystemPrompt ? `\n\n${config.appendSystemPrompt}` : ""}`;
|
|
4151
4178
|
}
|
|
4152
4179
|
/**
|
|
4153
4180
|
* Pick a system prompt by variant. The dispatch point for the
|
|
@@ -4242,7 +4269,7 @@ function isWriteTargetingPlanFile(toolName, args, cwd = process.cwd()) {
|
|
|
4242
4269
|
return rel === "" || !rel.startsWith("..") && !path.isAbsolute(rel);
|
|
4243
4270
|
}
|
|
4244
4271
|
//#endregion
|
|
4245
|
-
//#region ../../b4m-core/services/dist/
|
|
4272
|
+
//#region ../../b4m-core/services/dist/rolldown-runtime-BBjsoOtd.mjs
|
|
4246
4273
|
var __defProp$2 = Object.defineProperty;
|
|
4247
4274
|
var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
|
|
4248
4275
|
var __getOwnPropNames$1 = Object.getOwnPropertyNames;
|
|
@@ -4268,7 +4295,7 @@ var __copyProps$1 = (to, from, except, desc) => {
|
|
|
4268
4295
|
};
|
|
4269
4296
|
var __reExport$1 = (target, mod, secondTarget) => (__copyProps$1(target, mod, "default"), secondTarget && __copyProps$1(secondTarget, mod, "default"));
|
|
4270
4297
|
//#endregion
|
|
4271
|
-
//#region ../../b4m-core/utils/dist/
|
|
4298
|
+
//#region ../../b4m-core/utils/dist/rolldown-runtime-BBjsoOtd.mjs
|
|
4272
4299
|
var __defProp$1 = Object.defineProperty;
|
|
4273
4300
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4274
4301
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
@@ -8477,7 +8504,8 @@ var GeminiImageService = class extends AIImageService {
|
|
|
8477
8504
|
async generateImageViaContent(prompt, model = ImageModels.GEMINI_2_5_FLASH_IMAGE) {
|
|
8478
8505
|
const response = await this.genAI.models.generateContent({
|
|
8479
8506
|
model,
|
|
8480
|
-
contents: [{ text: prompt }]
|
|
8507
|
+
contents: [{ text: prompt }],
|
|
8508
|
+
config: { responseModalities: ["IMAGE", "TEXT"] }
|
|
8481
8509
|
});
|
|
8482
8510
|
if (!response.candidates || response.candidates.length === 0) throw new Error("No candidates returned from Gemini");
|
|
8483
8511
|
const candidate = response.candidates[0];
|
|
@@ -8568,7 +8596,8 @@ var GeminiImageService = class extends AIImageService {
|
|
|
8568
8596
|
});
|
|
8569
8597
|
const response = await this.genAI.models.generateContent({
|
|
8570
8598
|
model,
|
|
8571
|
-
contents
|
|
8599
|
+
contents,
|
|
8600
|
+
config: { responseModalities: ["IMAGE", "TEXT"] }
|
|
8572
8601
|
});
|
|
8573
8602
|
if (!response.candidates || response.candidates.length === 0) throw new Error("No candidates returned from Gemini");
|
|
8574
8603
|
const candidate = response.candidates[0];
|
|
@@ -9769,8 +9798,9 @@ function registerLambdaErrorHandlers(logger) {
|
|
|
9769
9798
|
} else log.error("[Lambda] Unhandled promise rejection", logEntry);
|
|
9770
9799
|
});
|
|
9771
9800
|
process.on("uncaughtException", (error) => {
|
|
9772
|
-
const
|
|
9773
|
-
log.
|
|
9801
|
+
const category = classifyError(error);
|
|
9802
|
+
if (category.startsWith("network_")) log.warn("[Lambda] Network error (uncaught exception)", buildLogEntry(error, category));
|
|
9803
|
+
else log.error("[Lambda] Uncaught exception", buildLogEntry(error, "uncaught_exception"));
|
|
9774
9804
|
});
|
|
9775
9805
|
}
|
|
9776
9806
|
/**
|
|
@@ -10040,7 +10070,7 @@ z.object({
|
|
|
10040
10070
|
userId: z.string()
|
|
10041
10071
|
});
|
|
10042
10072
|
//#endregion
|
|
10043
|
-
//#region ../../b4m-core/auth/dist/
|
|
10073
|
+
//#region ../../b4m-core/auth/dist/rolldown-runtime-D7D4PA-g.mjs
|
|
10044
10074
|
var __defProp = Object.defineProperty;
|
|
10045
10075
|
var __exportAll = (all, no_symbols) => {
|
|
10046
10076
|
let target = {};
|
|
@@ -10251,6 +10281,13 @@ var apiKeyService_exports = /* @__PURE__ */ __exportAll$2({});
|
|
|
10251
10281
|
__reExport$1(apiKeyService_exports, apiKeyService_exports$1);
|
|
10252
10282
|
//#endregion
|
|
10253
10283
|
//#region ../../b4m-core/services/dist/llm/tools/implementation/websearch/index.mjs
|
|
10284
|
+
function safeHostname(url) {
|
|
10285
|
+
try {
|
|
10286
|
+
return new URL(url).hostname;
|
|
10287
|
+
} catch {
|
|
10288
|
+
return url;
|
|
10289
|
+
}
|
|
10290
|
+
}
|
|
10254
10291
|
async function serpApiSearch(adapters, query, num_results) {
|
|
10255
10292
|
const apiKey = await (0, apiKeyService_exports.getSerperKey)(adapters);
|
|
10256
10293
|
const url = new URL("https://serpapi.com/search");
|
|
@@ -10317,7 +10354,7 @@ async function performWebSearch(adapters, params) {
|
|
|
10317
10354
|
fullContext: result.snippet
|
|
10318
10355
|
}
|
|
10319
10356
|
}));
|
|
10320
|
-
const formattedResults = results.map((result, index) => `${index + 1}. **${result.title}**\n${result.snippet}\nSource: [${
|
|
10357
|
+
const formattedResults = results.map((result, index) => `${index + 1}. **${result.title}**\n${result.snippet}\nSource: [${safeHostname(result.link)}](${result.link})\n`).join("\n");
|
|
10321
10358
|
return {
|
|
10322
10359
|
formattedResults: formattedResults ? `Here's what I found from searching the web:\n\n${formattedResults}` : "No results found from web search.",
|
|
10323
10360
|
citables
|
|
@@ -19738,13 +19775,19 @@ const updateUserSchema = z.object({
|
|
|
19738
19775
|
scrollbarWidth: z.number().optional(),
|
|
19739
19776
|
experimentalFeatures: z.record(z.string(), z.boolean()).optional(),
|
|
19740
19777
|
rechartsDisplayMode: z.enum(["inline", "artifact"]).optional(),
|
|
19778
|
+
toolsCatalogCollapsed: z.boolean().optional(),
|
|
19741
19779
|
docxTemplateFileId: z.string().nullable().optional(),
|
|
19742
19780
|
contextTelemetryLevel: z.enum([
|
|
19743
19781
|
"none",
|
|
19744
19782
|
"basic",
|
|
19745
19783
|
"enhanced"
|
|
19746
19784
|
]).optional(),
|
|
19747
|
-
contextTelemetryConsentedAt: z.date().optional()
|
|
19785
|
+
contextTelemetryConsentedAt: z.date().optional(),
|
|
19786
|
+
agentModeDefault: z.enum([
|
|
19787
|
+
"off",
|
|
19788
|
+
"auto",
|
|
19789
|
+
"on"
|
|
19790
|
+
]).optional()
|
|
19748
19791
|
}).nullable().optional()
|
|
19749
19792
|
});
|
|
19750
19793
|
z.object({
|
|
@@ -19787,7 +19830,7 @@ z.object({
|
|
|
19787
19830
|
username: z.string(),
|
|
19788
19831
|
email: z.string(),
|
|
19789
19832
|
name: z.string(),
|
|
19790
|
-
inviteCode: z.string(),
|
|
19833
|
+
inviteCode: z.string().optional(),
|
|
19791
19834
|
password: z.string(),
|
|
19792
19835
|
metadata: z.object({
|
|
19793
19836
|
loginTime: z.date(),
|
|
@@ -19940,6 +19983,7 @@ z.object({
|
|
|
19940
19983
|
disabledTools: z.array(z.string()).optional(),
|
|
19941
19984
|
forceKnowledgeRetrieval: z.boolean().optional(),
|
|
19942
19985
|
retrievalTags: z.array(z.string()).optional(),
|
|
19986
|
+
citationStyle: z.enum(["named", "indexed"]).optional(),
|
|
19943
19987
|
temperature: z.number().optional(),
|
|
19944
19988
|
tags: z.array(z.object({
|
|
19945
19989
|
name: z.string(),
|
|
@@ -21574,6 +21618,30 @@ z.object({
|
|
|
21574
21618
|
text: z.string(),
|
|
21575
21619
|
context: z.string().optional()
|
|
21576
21620
|
});
|
|
21621
|
+
`${[
|
|
21622
|
+
"needs_web_search",
|
|
21623
|
+
"needs_current_data",
|
|
21624
|
+
"needs_file_lookup",
|
|
21625
|
+
"needs_calculation",
|
|
21626
|
+
"multi_step_reasoning",
|
|
21627
|
+
"requires_retrieval",
|
|
21628
|
+
"compare_sources",
|
|
21629
|
+
"verify_facts"
|
|
21630
|
+
].join(", ")}${[
|
|
21631
|
+
"personal_opinion",
|
|
21632
|
+
"creative_writing",
|
|
21633
|
+
"casual_chat",
|
|
21634
|
+
"self_contained",
|
|
21635
|
+
"definition_only",
|
|
21636
|
+
"follow_up_clarification",
|
|
21637
|
+
"roleplay"
|
|
21638
|
+
].join(", ")}`;
|
|
21639
|
+
z.object({
|
|
21640
|
+
useAgent: z.boolean(),
|
|
21641
|
+
confidence: z.number().min(0).max(1),
|
|
21642
|
+
reason: z.string(),
|
|
21643
|
+
signals: z.array(z.string())
|
|
21644
|
+
});
|
|
21577
21645
|
const SingleMementoEvalSchema = z.object({
|
|
21578
21646
|
importance: z.number().min(1).max(10),
|
|
21579
21647
|
summary: z.string(),
|
|
@@ -23491,8 +23559,175 @@ const DEFAULT_AGENT_MODEL = ChatModels.CLAUDE_4_5_HAIKU;
|
|
|
23491
23559
|
*/
|
|
23492
23560
|
const DEFAULT_THOROUGHNESS = "medium";
|
|
23493
23561
|
//#endregion
|
|
23562
|
+
//#region src/agents/toolFilter.ts
|
|
23563
|
+
/**
|
|
23564
|
+
* Check if a tool name matches a pattern
|
|
23565
|
+
*
|
|
23566
|
+
* Supports wildcards (*) that match any sequence of characters.
|
|
23567
|
+
*
|
|
23568
|
+
* @param toolName - The actual tool name to check
|
|
23569
|
+
* @param pattern - The pattern to match against (may include * wildcards)
|
|
23570
|
+
* @returns true if the tool name matches the pattern
|
|
23571
|
+
*
|
|
23572
|
+
* @example
|
|
23573
|
+
* matchesToolPattern('mcp__github__create_issue', 'mcp__github__*') // true
|
|
23574
|
+
* matchesToolPattern('mcp__github__delete_repo', 'mcp__*__delete_*') // true
|
|
23575
|
+
* matchesToolPattern('file_read', 'file_read') // true
|
|
23576
|
+
* matchesToolPattern('file_read', 'file_*') // true
|
|
23577
|
+
* matchesToolPattern('file_read', '*_read') // true
|
|
23578
|
+
* matchesToolPattern('bash_execute', 'file_*') // false
|
|
23579
|
+
*/
|
|
23580
|
+
function matchesToolPattern(toolName, pattern) {
|
|
23581
|
+
const regexPattern = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
|
|
23582
|
+
return new RegExp(`^${regexPattern}$`).test(toolName);
|
|
23583
|
+
}
|
|
23584
|
+
/**
|
|
23585
|
+
* Check if a tool name matches any pattern in a list
|
|
23586
|
+
*
|
|
23587
|
+
* @param toolName - The tool name to check
|
|
23588
|
+
* @param patterns - Array of patterns to match against
|
|
23589
|
+
* @returns true if the tool matches any pattern
|
|
23590
|
+
*/
|
|
23591
|
+
function matchesAnyPattern(toolName, patterns) {
|
|
23592
|
+
return patterns.some((pattern) => matchesToolPattern(toolName, pattern));
|
|
23593
|
+
}
|
|
23594
|
+
/**
|
|
23595
|
+
* Filter tools based on allowed and denied patterns
|
|
23596
|
+
*
|
|
23597
|
+
* Rules:
|
|
23598
|
+
* 1. Denied patterns take precedence over allowed patterns
|
|
23599
|
+
* 2. If no allowed patterns specified, all tools are allowed (minus denied)
|
|
23600
|
+
* 3. If allowed patterns specified, only matching tools are allowed
|
|
23601
|
+
* 4. Supports wildcards in both allowed and denied patterns
|
|
23602
|
+
*
|
|
23603
|
+
* @param allTools - Complete list of available tools
|
|
23604
|
+
* @param allowedPatterns - Whitelist patterns (optional)
|
|
23605
|
+
* @param deniedPatterns - Blacklist patterns (optional)
|
|
23606
|
+
* @returns Filtered list of tools
|
|
23607
|
+
*
|
|
23608
|
+
* @example
|
|
23609
|
+
* // Allow only specific tools
|
|
23610
|
+
* filterToolsByPatterns(tools, ['file_read', 'grep_search'])
|
|
23611
|
+
*
|
|
23612
|
+
* // Allow all GitHub MCP tools except delete operations
|
|
23613
|
+
* filterToolsByPatterns(tools, ['mcp__github__*'], ['mcp__github__delete_*'])
|
|
23614
|
+
*
|
|
23615
|
+
* // Deny specific tools, allow everything else
|
|
23616
|
+
* filterToolsByPatterns(tools, undefined, ['create_file', 'edit_file'])
|
|
23617
|
+
*/
|
|
23618
|
+
function filterToolsByPatterns(allTools, allowedPatterns, deniedPatterns) {
|
|
23619
|
+
return allTools.filter((tool) => {
|
|
23620
|
+
const toolName = tool.toolSchema.name;
|
|
23621
|
+
if (deniedPatterns && deniedPatterns.length > 0) {
|
|
23622
|
+
if (matchesAnyPattern(toolName, deniedPatterns)) return false;
|
|
23623
|
+
}
|
|
23624
|
+
if (!allowedPatterns || allowedPatterns.length === 0) return true;
|
|
23625
|
+
return matchesAnyPattern(toolName, allowedPatterns);
|
|
23626
|
+
});
|
|
23627
|
+
}
|
|
23628
|
+
//#endregion
|
|
23629
|
+
//#region src/utils/processHooks.ts
|
|
23630
|
+
const HOOK_TIMEOUT_MS = 5e3;
|
|
23631
|
+
/** Does a group's matcher match the event's matcher value? `*`/empty/undefined match anything. */
|
|
23632
|
+
function matcherMatches(groupMatcher, eventMatcher) {
|
|
23633
|
+
if (groupMatcher === void 0 || groupMatcher === "" || groupMatcher === "*") return true;
|
|
23634
|
+
return groupMatcher === eventMatcher;
|
|
23635
|
+
}
|
|
23636
|
+
var ProcessHooks = class {
|
|
23637
|
+
constructor(hooks) {
|
|
23638
|
+
this.hooks = hooks;
|
|
23639
|
+
}
|
|
23640
|
+
/**
|
|
23641
|
+
* Run every command registered for `event` whose matcher matches `eventMatcher`.
|
|
23642
|
+
* `payload` is written to each command's stdin (then EOF). Best-effort: a failing
|
|
23643
|
+
* command never throws or blocks the caller's lifecycle.
|
|
23644
|
+
*/
|
|
23645
|
+
async fire(event, eventMatcher, payload) {
|
|
23646
|
+
const groups = this.hooks[event];
|
|
23647
|
+
if (!groups || groups.length === 0) return;
|
|
23648
|
+
const stdin = JSON.stringify({
|
|
23649
|
+
hook_event_name: event,
|
|
23650
|
+
...eventMatcher ? { matcher: eventMatcher } : {},
|
|
23651
|
+
...payload
|
|
23652
|
+
});
|
|
23653
|
+
const runs = [];
|
|
23654
|
+
for (const group of groups) {
|
|
23655
|
+
if (!matcherMatches(group.matcher, eventMatcher)) continue;
|
|
23656
|
+
for (const hook of group.hooks ?? []) {
|
|
23657
|
+
if (hook.type !== "command" || !hook.command) continue;
|
|
23658
|
+
runs.push(runShellCommand({
|
|
23659
|
+
command: hook.command,
|
|
23660
|
+
cwd: process.cwd(),
|
|
23661
|
+
timeoutMs: HOOK_TIMEOUT_MS,
|
|
23662
|
+
stdin
|
|
23663
|
+
}).catch(() => void 0));
|
|
23664
|
+
}
|
|
23665
|
+
}
|
|
23666
|
+
await Promise.all(runs);
|
|
23667
|
+
}
|
|
23668
|
+
/** Fired when an interactive permission prompt begins blocking. */
|
|
23669
|
+
fireNotificationPermissionPrompt(toolName) {
|
|
23670
|
+
return this.fire("Notification", "permission_prompt", { tool_name: toolName });
|
|
23671
|
+
}
|
|
23672
|
+
/** Fired after any tool completes. */
|
|
23673
|
+
firePostToolUse(toolName) {
|
|
23674
|
+
return this.fire("PostToolUse", void 0, { tool_name: toolName });
|
|
23675
|
+
}
|
|
23676
|
+
/** Fired at the end of every agent turn. */
|
|
23677
|
+
fireStop() {
|
|
23678
|
+
return this.fire("Stop");
|
|
23679
|
+
}
|
|
23680
|
+
/** Fired when the user submits a new prompt. */
|
|
23681
|
+
fireUserPromptSubmit() {
|
|
23682
|
+
return this.fire("UserPromptSubmit");
|
|
23683
|
+
}
|
|
23684
|
+
};
|
|
23685
|
+
/**
|
|
23686
|
+
* Parse a `--settings` JSON string into a {@link SettingsHooks}. Defensive:
|
|
23687
|
+
* malformed JSON or a missing/!-object `hooks` field yields `null` (no hooks),
|
|
23688
|
+
* never throws — a bad `--settings` must not brick the launch.
|
|
23689
|
+
*/
|
|
23690
|
+
function parseSettingsHooks(settingsJson) {
|
|
23691
|
+
if (!settingsJson) return null;
|
|
23692
|
+
try {
|
|
23693
|
+
const parsed = JSON.parse(settingsJson);
|
|
23694
|
+
if (!parsed || typeof parsed !== "object") return null;
|
|
23695
|
+
const hooks = parsed.hooks;
|
|
23696
|
+
if (!hooks || typeof hooks !== "object") return null;
|
|
23697
|
+
return hooks;
|
|
23698
|
+
} catch {
|
|
23699
|
+
return null;
|
|
23700
|
+
}
|
|
23701
|
+
}
|
|
23702
|
+
let cached;
|
|
23703
|
+
/**
|
|
23704
|
+
* Lazily-built process-hook singleton from `B4M_SETTINGS_JSON`. Returns null when
|
|
23705
|
+
* no hooks are configured, so call sites can `void getProcessHooks()?.fireStop()`.
|
|
23706
|
+
*/
|
|
23707
|
+
function getProcessHooks() {
|
|
23708
|
+
if (cached !== void 0) return cached;
|
|
23709
|
+
const hooks = parseSettingsHooks(process.env.B4M_SETTINGS_JSON);
|
|
23710
|
+
cached = hooks ? new ProcessHooks(hooks) : null;
|
|
23711
|
+
return cached;
|
|
23712
|
+
}
|
|
23713
|
+
//#endregion
|
|
23494
23714
|
//#region src/utils/toolsAdapter.ts
|
|
23495
23715
|
/**
|
|
23716
|
+
* Tool-name patterns auto-approved without a permission prompt, from `--allowedTools`
|
|
23717
|
+
* (claude-compat; e.g. `mcp__manifold__*`). Parsed once from B4M_ALLOWED_TOOLS — set by
|
|
23718
|
+
* bin/bike4mind-cli.mjs. Returns [] when unset so behaviour is unchanged off-host.
|
|
23719
|
+
*/
|
|
23720
|
+
let cachedAllowedTools;
|
|
23721
|
+
function getAllowedToolPatterns() {
|
|
23722
|
+
if (cachedAllowedTools === void 0) try {
|
|
23723
|
+
const raw = process.env.B4M_ALLOWED_TOOLS;
|
|
23724
|
+
cachedAllowedTools = raw ? JSON.parse(raw) : [];
|
|
23725
|
+
} catch {
|
|
23726
|
+
cachedAllowedTools = [];
|
|
23727
|
+
}
|
|
23728
|
+
return cachedAllowedTools;
|
|
23729
|
+
}
|
|
23730
|
+
/**
|
|
23496
23731
|
* Simple CLI-friendly storage adapter
|
|
23497
23732
|
* Most methods won't be called for CLI-only tools
|
|
23498
23733
|
* Silent to avoid interfering with Ink rendering
|
|
@@ -23601,6 +23836,7 @@ function wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, a
|
|
|
23601
23836
|
toolName,
|
|
23602
23837
|
result
|
|
23603
23838
|
});
|
|
23839
|
+
getProcessHooks()?.firePostToolUse(toolName);
|
|
23604
23840
|
return result;
|
|
23605
23841
|
}
|
|
23606
23842
|
const { useCliStore } = await import("./store-DgzCTRkN.mjs");
|
|
@@ -23613,6 +23849,8 @@ function wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, a
|
|
|
23613
23849
|
});
|
|
23614
23850
|
return result;
|
|
23615
23851
|
}
|
|
23852
|
+
const allowedPatterns = getAllowedToolPatterns();
|
|
23853
|
+
if (allowedPatterns.length > 0 && matchesAnyPattern(toolName, allowedPatterns)) return executeAndRecord();
|
|
23616
23854
|
if (!permissionManager.needsPermission(toolName, { isSandboxed })) return executeAndRecord();
|
|
23617
23855
|
if (interactionMode === "auto-accept") return executeAndRecord();
|
|
23618
23856
|
const response = await showPermissionPrompt(toolName, effectiveArgs, await generateToolPreview(toolName, args, isSandboxed));
|
|
@@ -24338,9 +24576,11 @@ var MCPClient = class {
|
|
|
24338
24576
|
customArgs;
|
|
24339
24577
|
suppressStderr;
|
|
24340
24578
|
onStderrLine;
|
|
24579
|
+
url;
|
|
24580
|
+
headers;
|
|
24341
24581
|
tools = [];
|
|
24342
24582
|
serverName;
|
|
24343
|
-
constructor({ envVariables, name, command, args, suppressStderr = false, onStderrLine }) {
|
|
24583
|
+
constructor({ envVariables, name, command, args, suppressStderr = false, onStderrLine, url, headers }) {
|
|
24344
24584
|
this.mcp = new Client({
|
|
24345
24585
|
name: "mcp-client-cli",
|
|
24346
24586
|
version: "1.0.0"
|
|
@@ -24351,9 +24591,26 @@ var MCPClient = class {
|
|
|
24351
24591
|
this.customArgs = args;
|
|
24352
24592
|
this.suppressStderr = suppressStderr;
|
|
24353
24593
|
this.onStderrLine = onStderrLine;
|
|
24594
|
+
this.url = url;
|
|
24595
|
+
this.headers = headers;
|
|
24354
24596
|
}
|
|
24355
24597
|
async connectToServer() {
|
|
24356
24598
|
try {
|
|
24599
|
+
if (this.url) {
|
|
24600
|
+
const transport = new StreamableHTTPClientTransport(new URL(this.url), { requestInit: this.headers ? { headers: this.headers } : void 0 });
|
|
24601
|
+
transport.onerror = (error) => {
|
|
24602
|
+
console.error(`[MCP] Transport error for ${this.serverName}:`, error);
|
|
24603
|
+
};
|
|
24604
|
+
this.transport = transport;
|
|
24605
|
+
await this.mcp.connect(transport);
|
|
24606
|
+
const toolsResult = await this.mcp.listTools();
|
|
24607
|
+
this.tools = toolsResult.tools.map((tool) => ({
|
|
24608
|
+
name: tool.name,
|
|
24609
|
+
description: tool.description,
|
|
24610
|
+
input_schema: tool.inputSchema
|
|
24611
|
+
}));
|
|
24612
|
+
return;
|
|
24613
|
+
}
|
|
24357
24614
|
const envVarsObject = this.envVariables.reduce((acc, env) => ({
|
|
24358
24615
|
...acc,
|
|
24359
24616
|
[env.key]: env.value
|
|
@@ -24378,7 +24635,7 @@ var MCPClient = class {
|
|
|
24378
24635
|
console.log(`[MCP] Using server: ${this.serverName} at ${serverScriptPath}`);
|
|
24379
24636
|
}
|
|
24380
24637
|
const stderrMode = this.suppressStderr ? "ignore" : this.onStderrLine ? "pipe" : void 0;
|
|
24381
|
-
const
|
|
24638
|
+
const stdioTransport = new StdioClientTransport({
|
|
24382
24639
|
command,
|
|
24383
24640
|
args,
|
|
24384
24641
|
env: {
|
|
@@ -24386,13 +24643,13 @@ var MCPClient = class {
|
|
|
24386
24643
|
...envVarsObject
|
|
24387
24644
|
},
|
|
24388
24645
|
...stderrMode && { stderr: stderrMode }
|
|
24389
|
-
};
|
|
24390
|
-
this.transport =
|
|
24391
|
-
|
|
24646
|
+
});
|
|
24647
|
+
this.transport = stdioTransport;
|
|
24648
|
+
stdioTransport.onerror = (error) => {
|
|
24392
24649
|
console.error(`[MCP] Transport error for ${this.serverName}:`, error);
|
|
24393
24650
|
};
|
|
24394
|
-
await this.mcp.connect(
|
|
24395
|
-
if (this.onStderrLine &&
|
|
24651
|
+
await this.mcp.connect(stdioTransport);
|
|
24652
|
+
if (this.onStderrLine && stdioTransport.stderr) this.readStderr(stdioTransport.stderr);
|
|
24396
24653
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
24397
24654
|
const toolsResult = await this.mcp.listTools();
|
|
24398
24655
|
this.tools = toolsResult.tools.map((tool) => {
|
|
@@ -24614,6 +24871,8 @@ var McpManager = class {
|
|
|
24614
24871
|
name: serverConfig.name,
|
|
24615
24872
|
command: serverConfig.command,
|
|
24616
24873
|
args: serverConfig.args,
|
|
24874
|
+
url: serverConfig.url,
|
|
24875
|
+
headers: serverConfig.headers,
|
|
24617
24876
|
suppressStderr: true
|
|
24618
24877
|
});
|
|
24619
24878
|
await client.connectToServer();
|
|
@@ -24671,6 +24930,7 @@ var McpManager = class {
|
|
|
24671
24930
|
const key = JSON.stringify({
|
|
24672
24931
|
command: serverConfig.command,
|
|
24673
24932
|
args: serverConfig.args,
|
|
24933
|
+
url: serverConfig.url,
|
|
24674
24934
|
env: serverConfig.env
|
|
24675
24935
|
});
|
|
24676
24936
|
return createHash("sha256").update(key).digest("hex").slice(0, 16);
|
|
@@ -25913,73 +26173,6 @@ var ApiClient = class {
|
|
|
25913
26173
|
}
|
|
25914
26174
|
};
|
|
25915
26175
|
//#endregion
|
|
25916
|
-
//#region src/agents/toolFilter.ts
|
|
25917
|
-
/**
|
|
25918
|
-
* Check if a tool name matches a pattern
|
|
25919
|
-
*
|
|
25920
|
-
* Supports wildcards (*) that match any sequence of characters.
|
|
25921
|
-
*
|
|
25922
|
-
* @param toolName - The actual tool name to check
|
|
25923
|
-
* @param pattern - The pattern to match against (may include * wildcards)
|
|
25924
|
-
* @returns true if the tool name matches the pattern
|
|
25925
|
-
*
|
|
25926
|
-
* @example
|
|
25927
|
-
* matchesToolPattern('mcp__github__create_issue', 'mcp__github__*') // true
|
|
25928
|
-
* matchesToolPattern('mcp__github__delete_repo', 'mcp__*__delete_*') // true
|
|
25929
|
-
* matchesToolPattern('file_read', 'file_read') // true
|
|
25930
|
-
* matchesToolPattern('file_read', 'file_*') // true
|
|
25931
|
-
* matchesToolPattern('file_read', '*_read') // true
|
|
25932
|
-
* matchesToolPattern('bash_execute', 'file_*') // false
|
|
25933
|
-
*/
|
|
25934
|
-
function matchesToolPattern(toolName, pattern) {
|
|
25935
|
-
const regexPattern = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
|
|
25936
|
-
return new RegExp(`^${regexPattern}$`).test(toolName);
|
|
25937
|
-
}
|
|
25938
|
-
/**
|
|
25939
|
-
* Check if a tool name matches any pattern in a list
|
|
25940
|
-
*
|
|
25941
|
-
* @param toolName - The tool name to check
|
|
25942
|
-
* @param patterns - Array of patterns to match against
|
|
25943
|
-
* @returns true if the tool matches any pattern
|
|
25944
|
-
*/
|
|
25945
|
-
function matchesAnyPattern(toolName, patterns) {
|
|
25946
|
-
return patterns.some((pattern) => matchesToolPattern(toolName, pattern));
|
|
25947
|
-
}
|
|
25948
|
-
/**
|
|
25949
|
-
* Filter tools based on allowed and denied patterns
|
|
25950
|
-
*
|
|
25951
|
-
* Rules:
|
|
25952
|
-
* 1. Denied patterns take precedence over allowed patterns
|
|
25953
|
-
* 2. If no allowed patterns specified, all tools are allowed (minus denied)
|
|
25954
|
-
* 3. If allowed patterns specified, only matching tools are allowed
|
|
25955
|
-
* 4. Supports wildcards in both allowed and denied patterns
|
|
25956
|
-
*
|
|
25957
|
-
* @param allTools - Complete list of available tools
|
|
25958
|
-
* @param allowedPatterns - Whitelist patterns (optional)
|
|
25959
|
-
* @param deniedPatterns - Blacklist patterns (optional)
|
|
25960
|
-
* @returns Filtered list of tools
|
|
25961
|
-
*
|
|
25962
|
-
* @example
|
|
25963
|
-
* // Allow only specific tools
|
|
25964
|
-
* filterToolsByPatterns(tools, ['file_read', 'grep_search'])
|
|
25965
|
-
*
|
|
25966
|
-
* // Allow all GitHub MCP tools except delete operations
|
|
25967
|
-
* filterToolsByPatterns(tools, ['mcp__github__*'], ['mcp__github__delete_*'])
|
|
25968
|
-
*
|
|
25969
|
-
* // Deny specific tools, allow everything else
|
|
25970
|
-
* filterToolsByPatterns(tools, undefined, ['create_file', 'edit_file'])
|
|
25971
|
-
*/
|
|
25972
|
-
function filterToolsByPatterns(allTools, allowedPatterns, deniedPatterns) {
|
|
25973
|
-
return allTools.filter((tool) => {
|
|
25974
|
-
const toolName = tool.toolSchema.name;
|
|
25975
|
-
if (deniedPatterns && deniedPatterns.length > 0) {
|
|
25976
|
-
if (matchesAnyPattern(toolName, deniedPatterns)) return false;
|
|
25977
|
-
}
|
|
25978
|
-
if (!allowedPatterns || allowedPatterns.length === 0) return true;
|
|
25979
|
-
return matchesAnyPattern(toolName, allowedPatterns);
|
|
25980
|
-
});
|
|
25981
|
-
}
|
|
25982
|
-
//#endregion
|
|
25983
26176
|
//#region src/tools/skillTool.ts
|
|
25984
26177
|
/**
|
|
25985
26178
|
* Execute a lifecycle hook script
|
|
@@ -28719,4 +28912,4 @@ function createReviewGateStore(onUpdate) {
|
|
|
28719
28912
|
};
|
|
28720
28913
|
}
|
|
28721
28914
|
//#endregion
|
|
28722
|
-
export {
|
|
28915
|
+
export { SessionStore as $, substituteArguments as A, DEFAULT_RETRY_CONFIG as B, WebSocketToolExecutor as C, ServerLlmBackend as D, WebSocketLlmBackend as E, generateCliTools as F, getPlanModeFilePath as G, clearFeatureModuleTools as H, getProcessHooks as I, isReadOnlyTool as J, buildSystemPrompt as K, ALWAYS_DENIED_FOR_AGENTS as L, extractCompactInstructions as M, loadContextFiles as N, isTransientNetworkError as O, PermissionManager as P, CommandHistoryStore as Q, DEFAULT_AGENT_MODEL as R, ApiClient as S, FallbackLlmBackend as T, registerFeatureModuleTools as U, DEFAULT_THOROUGHNESS as V, setWebSocketToolExecutor as W, CustomCommandStore as X, ReActAgent as Y, CheckpointStore as Z, createAgentDelegateTool as _, createBlockerTools as a, formatFileSize$1 as at, createSkillTool as b, createDecisionStore as c, createFindDefinitionTool as d, OAuthClient as et, createTodoStore as f, BackgroundAgentManager as g, createBackgroundAgentTools as h, createBlockerStore as i, mergeCommands as it, formatStep as j, McpManager as k, formatDecisionsOutput as l, createCoordinateTaskTool as m, createReviewGateTool as n, processFileReferences as nt, formatBlockersOutput as o, searchFiles as ot, createWriteTodosTool as p, buildSkillsPromptSection as q, formatReviewGatesOutput as r, searchCommands as rt, createDecisionLogTool as s, warmFileCache as st, createReviewGateStore as t, hasFileReferences as tt, createGetFileStructureTool as u, AgentStore as v, WebSocketConnectionManager as w, parseAgentConfig as x, SubagentOrchestrator as y, DEFAULT_MAX_ITERATIONS as z };
|