@bike4mind/cli 0.2.40-refactor-slack-remove-next-dependency.20305 → 0.2.40

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.
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  CurationArtifactType
4
- } from "./chunk-QI3M7KVC.js";
4
+ } from "./chunk-MRKLVT3J.js";
5
5
 
6
6
  // ../../b4m-core/packages/services/dist/src/notebookCurationService/artifactExtractor.js
7
7
  var ARTIFACT_TAG_REGEX = /<artifact\s+(.*?)>([\s\S]*?)<\/artifact>/gi;
@@ -19,7 +19,7 @@ import {
19
19
  dayjsConfig_default,
20
20
  extractSnippetMeta,
21
21
  settingsMap
22
- } from "./chunk-QI3M7KVC.js";
22
+ } from "./chunk-MRKLVT3J.js";
23
23
 
24
24
  // ../../b4m-core/packages/utils/dist/src/storage/S3Storage.js
25
25
  import { S3Client, PutObjectCommand, DeleteObjectCommand, GetObjectCommand, HeadObjectCommand } from "@aws-sdk/client-s3";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  BadRequestError,
4
4
  secureParameters
5
- } from "./chunk-GONER47A.js";
5
+ } from "./chunk-C76VBMTC.js";
6
6
  import {
7
7
  CompletionApiUsageTransaction,
8
8
  GenericCreditDeductTransaction,
@@ -13,7 +13,7 @@ import {
13
13
  ToolUsageTransaction,
14
14
  TransferCreditTransaction,
15
15
  VideoGenerationUsageTransaction
16
- } from "./chunk-QI3M7KVC.js";
16
+ } from "./chunk-MRKLVT3J.js";
17
17
 
18
18
  // ../../b4m-core/packages/services/dist/src/creditService/subtractCredits.js
19
19
  import { z } from "zod";
@@ -4,7 +4,7 @@ import {
4
4
  getOpenWeatherKey,
5
5
  getSerperKey,
6
6
  getWolframAlphaKey
7
- } from "./chunk-ACVKD3F5.js";
7
+ } from "./chunk-MOJK3K6H.js";
8
8
  import {
9
9
  BFLImageService,
10
10
  BaseStorage,
@@ -16,15 +16,16 @@ import {
16
16
  OpenAIBackend,
17
17
  OpenAIImageService,
18
18
  XAIImageService
19
- } from "./chunk-GONER47A.js";
19
+ } from "./chunk-C76VBMTC.js";
20
20
  import {
21
21
  Logger
22
22
  } from "./chunk-PFBYGCOW.js";
23
23
  import {
24
24
  ConfigStore,
25
25
  logger
26
- } from "./chunk-WBURRFA6.js";
26
+ } from "./chunk-IK5H63CY.js";
27
27
  import {
28
+ ALERT_THRESHOLDS,
28
29
  AiEvents,
29
30
  ApiKeyEvents,
30
31
  ApiKeyScope,
@@ -80,8 +81,9 @@ import {
80
81
  getDataLakeTags,
81
82
  getMcpProviderMetadata,
82
83
  getViewById,
83
- resolveNavigationIntents
84
- } from "./chunk-QI3M7KVC.js";
84
+ resolveNavigationIntents,
85
+ sanitizeTelemetryError
86
+ } from "./chunk-MRKLVT3J.js";
85
87
 
86
88
  // src/utils/fileSearch.ts
87
89
  import * as fs from "fs";
@@ -13894,6 +13896,354 @@ var CombinedExtractor = class {
13894
13896
  };
13895
13897
  var combinedExtractor = new CombinedExtractor();
13896
13898
 
13899
+ // ../../b4m-core/packages/services/dist/src/telemetry/AnomalyAlertService.js
13900
+ var AnomalyAlertService = class _AnomalyAlertService {
13901
+ constructor(loggerOrConfig, alertConfig) {
13902
+ this.dedupCache = /* @__PURE__ */ new Map();
13903
+ if (typeof loggerOrConfig.logger !== "undefined") {
13904
+ const config = loggerOrConfig;
13905
+ this.logger = config.logger;
13906
+ this.config = config.alertConfig;
13907
+ this.cacheRepository = config.cacheRepository;
13908
+ this.slackSender = config.slackSender;
13909
+ } else {
13910
+ this.logger = loggerOrConfig;
13911
+ this.config = alertConfig;
13912
+ }
13913
+ }
13914
+ /**
13915
+ * Check if Slack alerting is properly configured
13916
+ */
13917
+ isSlackConfigured() {
13918
+ return !!(this.config.slackWorkspaceId && this.config.slackChannelId && this.slackSender);
13919
+ }
13920
+ /**
13921
+ * Check if an alert should be sent and send it if appropriate
13922
+ */
13923
+ async checkAndAlert(telemetry) {
13924
+ if (!this.config.enabled || !this.isSlackConfigured()) {
13925
+ return false;
13926
+ }
13927
+ const { anomalies } = telemetry;
13928
+ const threshold = this.config.alertThreshold ?? ALERT_THRESHOLDS.warning;
13929
+ if (anomalies.anomalyScore < threshold) {
13930
+ return false;
13931
+ }
13932
+ const isDup = await this.checkDeduplication(anomalies.dedupKey);
13933
+ if (isDup) {
13934
+ this.logger.info(`\u{1F4CA} [AnomalyAlert] Suppressed duplicate alert: ${anomalies.dedupKey}`);
13935
+ return false;
13936
+ }
13937
+ try {
13938
+ const message = this.formatSlackMessage(telemetry);
13939
+ await this.sendSlackAlert(message);
13940
+ this.logger.info(`\u{1F4CA} [AnomalyAlert] Alert sent for ${anomalies.primaryAnomaly} (score: ${anomalies.anomalyScore})`);
13941
+ return true;
13942
+ } catch (error) {
13943
+ this.logger.error(`\u{1F4CA} [AnomalyAlert] Failed to send alert:`, error);
13944
+ return false;
13945
+ }
13946
+ }
13947
+ /**
13948
+ * Check deduplication and claim the key atomically.
13949
+ * Uses distributed MongoDB cache when available, falls back to in-memory.
13950
+ *
13951
+ * @returns true if this is a duplicate (should not send alert), false if we can proceed
13952
+ */
13953
+ async checkDeduplication(dedupKey) {
13954
+ const windowMs = (this.config.dedupWindowMinutes ?? 5) * 60 * 1e3;
13955
+ const cacheKey = `${_AnomalyAlertService.DEDUP_KEY_PREFIX}${dedupKey}`;
13956
+ if (this.cacheRepository) {
13957
+ try {
13958
+ const result = await this.cacheRepository.claimDedup(cacheKey, { dedupKey, claimedAt: Date.now(), count: 1 }, windowMs);
13959
+ return !result.claimed;
13960
+ } catch (error) {
13961
+ this.logger.warn(`\u{1F4CA} [AnomalyAlert] Distributed dedup failed, using in-memory:`, error);
13962
+ }
13963
+ }
13964
+ return this.checkInMemoryDedup(dedupKey, windowMs);
13965
+ }
13966
+ /**
13967
+ * In-memory deduplication check and record (fallback)
13968
+ */
13969
+ checkInMemoryDedup(dedupKey, windowMs) {
13970
+ const entry = this.dedupCache.get(dedupKey);
13971
+ if (entry) {
13972
+ const timeSinceLastAlert = Date.now() - entry.lastAlertTime;
13973
+ if (timeSinceLastAlert < windowMs) {
13974
+ return true;
13975
+ }
13976
+ }
13977
+ this.recordInMemoryAlert(dedupKey);
13978
+ return false;
13979
+ }
13980
+ /**
13981
+ * Record an alert in the in-memory cache
13982
+ */
13983
+ recordInMemoryAlert(dedupKey) {
13984
+ const existing = this.dedupCache.get(dedupKey);
13985
+ this.dedupCache.set(dedupKey, {
13986
+ dedupKey,
13987
+ lastAlertTime: Date.now(),
13988
+ count: (existing?.count ?? 0) + 1
13989
+ });
13990
+ const oneHourAgo = Date.now() - 60 * 60 * 1e3;
13991
+ for (const [key, entry] of this.dedupCache.entries()) {
13992
+ if (entry.lastAlertTime < oneHourAgo) {
13993
+ this.dedupCache.delete(key);
13994
+ }
13995
+ }
13996
+ if (this.dedupCache.size > _AnomalyAlertService.MAX_CACHE_ENTRIES) {
13997
+ const entries = Array.from(this.dedupCache.entries()).sort((a, b) => a[1].lastAlertTime - b[1].lastAlertTime);
13998
+ const toRemove = entries.slice(0, this.dedupCache.size - _AnomalyAlertService.MAX_CACHE_ENTRIES);
13999
+ for (const [key] of toRemove) {
14000
+ this.dedupCache.delete(key);
14001
+ }
14002
+ }
14003
+ }
14004
+ /**
14005
+ * Format telemetry into a Slack Block Kit message
14006
+ */
14007
+ formatSlackMessage(telemetry) {
14008
+ const { anomalies, model, contextWindow, performance: performance2, tools, subagents } = telemetry;
14009
+ const isCritical = anomalies.anomalyScore >= (this.config.criticalThreshold ?? ALERT_THRESHOLDS.critical);
14010
+ const emoji = this.getSeverityEmoji(anomalies.severity);
14011
+ const severityText = anomalies.severity.toUpperCase();
14012
+ const title = `${emoji} Context Telemetry Alert: ${this.formatAnomalyType(anomalies.primaryAnomaly)}`;
14013
+ const summaryText = `${severityText} anomaly detected (score: ${anomalies.anomalyScore}) - ${anomalies.primaryAnomaly}`;
14014
+ const blocks = [
14015
+ // Header
14016
+ {
14017
+ type: "header",
14018
+ text: {
14019
+ type: "plain_text",
14020
+ text: title,
14021
+ emoji: true
14022
+ }
14023
+ },
14024
+ // Severity and score
14025
+ {
14026
+ type: "section",
14027
+ fields: [
14028
+ {
14029
+ type: "mrkdwn",
14030
+ text: `*Severity:*
14031
+ ${emoji} ${severityText}`
14032
+ },
14033
+ {
14034
+ type: "mrkdwn",
14035
+ text: `*Anomaly Score:*
14036
+ ${anomalies.anomalyScore}/100`
14037
+ },
14038
+ {
14039
+ type: "mrkdwn",
14040
+ text: `*Model:*
14041
+ ${model.modelId}`
14042
+ },
14043
+ {
14044
+ type: "mrkdwn",
14045
+ text: `*Provider:*
14046
+ ${model.provider}`
14047
+ }
14048
+ ]
14049
+ },
14050
+ // Divider
14051
+ { type: "divider" }
14052
+ ];
14053
+ const anomalyDetails = this.buildAnomalyDetails(anomalies);
14054
+ if (anomalyDetails.length > 0) {
14055
+ blocks.push({
14056
+ type: "section",
14057
+ text: {
14058
+ type: "mrkdwn",
14059
+ text: `*Detected Anomalies:*
14060
+ ${anomalyDetails.join("\n")}`
14061
+ }
14062
+ });
14063
+ }
14064
+ blocks.push({
14065
+ type: "section",
14066
+ fields: [
14067
+ {
14068
+ type: "mrkdwn",
14069
+ text: `*Input Tokens:*
14070
+ ${contextWindow.inputTokens.toLocaleString()}`
14071
+ },
14072
+ {
14073
+ type: "mrkdwn",
14074
+ text: `*Utilization:*
14075
+ ${contextWindow.utilizationPercentage.toFixed(1)}%`
14076
+ },
14077
+ {
14078
+ type: "mrkdwn",
14079
+ text: `*Response Time:*
14080
+ ${performance2.totalResponseTimeMs.toLocaleString()}ms`
14081
+ },
14082
+ {
14083
+ type: "mrkdwn",
14084
+ text: `*First Token:*
14085
+ ${performance2.firstTokenTimeMs?.toLocaleString() ?? "N/A"}ms`
14086
+ }
14087
+ ]
14088
+ });
14089
+ const failedTools = tools?.filter((t) => t.failureCount > 0) ?? [];
14090
+ if (failedTools.length > 0) {
14091
+ const toolDetails = failedTools.map((t) => `\u2022 \`${t.toolName}\`: ${t.failureCount} failures${t.lastError ? ` - ${sanitizeTelemetryError(t.lastError, 50)}` : ""}`).join("\n");
14092
+ blocks.push({
14093
+ type: "section",
14094
+ text: {
14095
+ type: "mrkdwn",
14096
+ text: `*Tool Failures:*
14097
+ ${toolDetails}`
14098
+ }
14099
+ });
14100
+ }
14101
+ const timedOutAgents = subagents?.filter((s) => s.timeoutCount > 0) ?? [];
14102
+ if (timedOutAgents.length > 0) {
14103
+ const agentDetails = timedOutAgents.map((s) => `\u2022 \`${s.agentName}\`: ${s.timeoutCount} timeouts, ${s.totalDurationMs.toLocaleString()}ms total`).join("\n");
14104
+ blocks.push({
14105
+ type: "section",
14106
+ text: {
14107
+ type: "mrkdwn",
14108
+ text: `*Subagent Timeouts:*
14109
+ ${agentDetails}`
14110
+ }
14111
+ });
14112
+ }
14113
+ if (model.fallbackUsed) {
14114
+ blocks.push({
14115
+ type: "section",
14116
+ text: {
14117
+ type: "mrkdwn",
14118
+ text: `*Fallback Used:*
14119
+ ${model.originalModelId} \u2192 ${model.modelId}
14120
+ Reason: ${model.fallbackReason ?? "Unknown"}`
14121
+ }
14122
+ });
14123
+ }
14124
+ blocks.push({ type: "divider" }, {
14125
+ type: "context",
14126
+ elements: [
14127
+ {
14128
+ type: "mrkdwn",
14129
+ text: `Timestamp: ${telemetry.timestamp} | Dedup Key: \`${anomalies.dedupKey}\``
14130
+ }
14131
+ ]
14132
+ });
14133
+ if (isCritical) {
14134
+ blocks.splice(1, 0, {
14135
+ type: "section",
14136
+ text: {
14137
+ type: "mrkdwn",
14138
+ text: "<!here> Critical anomaly requires attention!"
14139
+ }
14140
+ });
14141
+ }
14142
+ return {
14143
+ text: summaryText,
14144
+ blocks
14145
+ };
14146
+ }
14147
+ /**
14148
+ * Build list of detected anomaly details
14149
+ */
14150
+ buildAnomalyDetails(anomalies) {
14151
+ const details = [];
14152
+ if (anomalies.contextOverflow) {
14153
+ details.push("\u{1F6A8} Context window overflow detected");
14154
+ }
14155
+ if (anomalies.criticalUtilization) {
14156
+ details.push("\u26A0\uFE0F Critical context utilization (\u226595%)");
14157
+ } else if (anomalies.highUtilization) {
14158
+ details.push("\u26A0\uFE0F High context utilization (\u226590%)");
14159
+ }
14160
+ if (anomalies.criticalTruncation) {
14161
+ details.push("\u26A0\uFE0F Critical message truncation (\u226575%)");
14162
+ } else if (anomalies.highTruncation) {
14163
+ details.push("\u26A0\uFE0F High message truncation (\u226550%)");
14164
+ }
14165
+ if (anomalies.toolFailureSpike) {
14166
+ details.push("\u{1F527} Tool failure spike (\u22653 failures)");
14167
+ }
14168
+ if (anomalies.toolTimeout) {
14169
+ details.push("\u23F1\uFE0F Tool timeout detected (>30s)");
14170
+ }
14171
+ if (anomalies.subagentTimeout) {
14172
+ details.push("\u{1F916} Subagent timeout detected (>5min)");
14173
+ }
14174
+ if (anomalies.slowTotalResponse) {
14175
+ details.push("\u{1F40C} Slow total response time (>60s)");
14176
+ }
14177
+ if (anomalies.slowFirstToken) {
14178
+ details.push("\u{1F40C} Slow first token time (>10s)");
14179
+ }
14180
+ return details;
14181
+ }
14182
+ /**
14183
+ * Get emoji for severity level
14184
+ */
14185
+ getSeverityEmoji(severity) {
14186
+ switch (severity) {
14187
+ case "critical":
14188
+ return "\u{1F534}";
14189
+ case "high":
14190
+ return "\u{1F7E0}";
14191
+ case "medium":
14192
+ return "\u{1F7E1}";
14193
+ case "low":
14194
+ return "\u{1F7E2}";
14195
+ default:
14196
+ return "\u26AA";
14197
+ }
14198
+ }
14199
+ /**
14200
+ * Format anomaly type for display
14201
+ */
14202
+ formatAnomalyType(type) {
14203
+ switch (type) {
14204
+ case "context_overflow":
14205
+ return "Context Overflow";
14206
+ case "high_truncation":
14207
+ return "High Truncation";
14208
+ case "tool_failure":
14209
+ return "Tool Failure";
14210
+ case "subagent_timeout":
14211
+ return "Subagent Timeout";
14212
+ case "slow_response":
14213
+ return "Slow Response";
14214
+ case "multiple":
14215
+ return "Multiple Anomalies";
14216
+ case "none":
14217
+ return "Unknown";
14218
+ default:
14219
+ return type;
14220
+ }
14221
+ }
14222
+ /**
14223
+ * Send the formatted message to Slack using the configured sender
14224
+ */
14225
+ async sendSlackAlert(message) {
14226
+ if (!this.slackSender || !this.config.slackWorkspaceId || !this.config.slackChannelId) {
14227
+ throw new Error("Slack integration not configured");
14228
+ }
14229
+ await this.slackSender.sendMessage(this.config.slackWorkspaceId, this.config.slackChannelId, message);
14230
+ }
14231
+ /**
14232
+ * Get deduplication statistics for monitoring
14233
+ */
14234
+ getDedupStats() {
14235
+ const fiveMinutesAgo = Date.now() - 5 * 60 * 1e3;
14236
+ const recentAlerts = Array.from(this.dedupCache.values()).filter((e) => e.lastAlertTime >= fiveMinutesAgo).length;
14237
+ return {
14238
+ totalEntries: this.dedupCache.size,
14239
+ recentAlerts,
14240
+ distributedDedupEnabled: !!this.cacheRepository
14241
+ };
14242
+ }
14243
+ };
14244
+ AnomalyAlertService.MAX_CACHE_ENTRIES = 1e3;
14245
+ AnomalyAlertService.DEDUP_KEY_PREFIX = "anomaly-alert-dedup:";
14246
+
13897
14247
  // ../../b4m-core/packages/services/dist/src/llm/ChatCompletionProcess.js
13898
14248
  var DISABLE_SERVER_THROTTLING = process.env.DISABLE_SERVER_THROTTLING === "true";
13899
14249
  var questSaveMutex = new Mutex();
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ChatModels
4
- } from "./chunk-QI3M7KVC.js";
4
+ } from "./chunk-MRKLVT3J.js";
5
5
  import {
6
6
  DEFAULT_SANDBOX_CONFIG
7
7
  } from "./chunk-4BIBE3J7.js";
@@ -7,11 +7,11 @@ import {
7
7
  getSettingsMap,
8
8
  getSettingsValue,
9
9
  secureParameters
10
- } from "./chunk-GONER47A.js";
10
+ } from "./chunk-C76VBMTC.js";
11
11
  import {
12
12
  KnowledgeType,
13
13
  SupportedFabFileMimeTypes
14
- } from "./chunk-QI3M7KVC.js";
14
+ } from "./chunk-MRKLVT3J.js";
15
15
 
16
16
  // ../../b4m-core/packages/services/dist/src/fabFileService/create.js
17
17
  import { z } from "zod";
@@ -6,12 +6,12 @@ import {
6
6
  getSettingsByNames,
7
7
  obfuscateApiKey,
8
8
  secureParameters
9
- } from "./chunk-GONER47A.js";
9
+ } from "./chunk-C76VBMTC.js";
10
10
  import {
11
11
  ApiKeyType,
12
12
  MementoTier,
13
13
  isSupportedEmbeddingModel
14
- } from "./chunk-QI3M7KVC.js";
14
+ } from "./chunk-MRKLVT3J.js";
15
15
 
16
16
  // ../../b4m-core/packages/services/dist/src/apiKeyService/get.js
17
17
  import { z } from "zod";