@bike4mind/cli 0.2.30 → 0.2.31-b4m-cli-undo-command.19534
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/bin/bike4mind-cli.mjs +48 -0
- package/dist/{HydrationEngine-WGYKF46H.js → HydrationEngine-YL2HWJ3V.js} +1 -1
- package/dist/{artifactExtractor-JQMWU272.js → artifactExtractor-T6NJ7V7P.js} +1 -1
- package/dist/{chunk-LBTTUQJM.js → chunk-32PKF3N7.js} +16 -15
- package/dist/{chunk-BQAPZP5Y.js → chunk-3SPW5FYJ.js} +236 -18
- package/dist/{chunk-U63VANTQ.js → chunk-ERV5G6MX.js} +3 -3
- package/dist/{chunk-LLA44SW7.js → chunk-F4PXVLZX.js} +2 -2
- package/dist/{chunk-RUI6HNLO.js → chunk-GQGOWACU.js} +8 -4
- package/dist/{chunk-WIB75EEX.js → chunk-JWJF6O4L.js} +3 -3
- package/dist/{chunk-T4VPCTBM.js → chunk-NI22LIK3.js} +998 -167
- package/dist/{chunk-OCYRD7D6.js → chunk-PFBYGCOW.js} +109 -31
- package/dist/chunk-WVFOWKNW.js +244 -0
- package/dist/commands/doctorCommand.js +87 -0
- package/dist/commands/mcpCommand.js +1 -1
- package/dist/commands/updateCommand.js +42 -0
- package/dist/create-XOEMSBER.js +12 -0
- package/dist/index.js +3373 -669
- package/dist/{llmMarkdownGenerator-2O24TMGD.js → llmMarkdownGenerator-NPX7ULSW.js} +1 -1
- package/dist/{markdownGenerator-6LAK3FQM.js → markdownGenerator-TVJ2RQXC.js} +1 -1
- package/dist/{mementoService-NRR7NQ4C.js → mementoService-HGH2XVLM.js} +4 -4
- package/dist/{notificationDeduplicator-UTHJHMSZ.js → notificationDeduplicator-HUC53NEW.js} +1 -1
- package/dist/{src-VMQ5TKYR.js → src-2BRBILH7.js} +27 -1
- package/dist/{src-3FQBHGOM.js → src-JZ6OHGTX.js} +13 -3
- package/dist/{subtractCredits-HK72MSDY.js → subtractCredits-4VIHTUR4.js} +4 -4
- package/package.json +9 -9
- package/dist/create-4WOBQ5JM.js +0 -12
package/bin/bike4mind-cli.mjs
CHANGED
|
@@ -88,6 +88,8 @@ const argv = await yargs(hideBin(process.argv))
|
|
|
88
88
|
})
|
|
89
89
|
.demandCommand(1, 'You must provide a subcommand (list, add, remove, enable, disable)');
|
|
90
90
|
})
|
|
91
|
+
.command('update', 'Check for and install CLI updates')
|
|
92
|
+
.command('doctor', 'Run diagnostic checks on CLI installation')
|
|
91
93
|
.help()
|
|
92
94
|
.alias('help', 'h')
|
|
93
95
|
.version()
|
|
@@ -149,6 +151,52 @@ if (argv._[0] === 'mcp') {
|
|
|
149
151
|
}
|
|
150
152
|
}
|
|
151
153
|
|
|
154
|
+
// Handle update command (external command)
|
|
155
|
+
if (argv._[0] === 'update') {
|
|
156
|
+
try {
|
|
157
|
+
let handleUpdateCommand;
|
|
158
|
+
|
|
159
|
+
if (isDev) {
|
|
160
|
+
const { register } = require('tsx/esm/api');
|
|
161
|
+
register();
|
|
162
|
+
const module = await import('../src/commands/updateCommand.ts');
|
|
163
|
+
handleUpdateCommand = module.handleUpdateCommand;
|
|
164
|
+
} else {
|
|
165
|
+
const module = await import('../dist/commands/updateCommand.js');
|
|
166
|
+
handleUpdateCommand = module.handleUpdateCommand;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
await handleUpdateCommand();
|
|
170
|
+
process.exit(0);
|
|
171
|
+
} catch (error) {
|
|
172
|
+
console.error('Error:', error.message);
|
|
173
|
+
process.exit(1);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Handle doctor command (external command)
|
|
178
|
+
if (argv._[0] === 'doctor') {
|
|
179
|
+
try {
|
|
180
|
+
let handleDoctorCommand;
|
|
181
|
+
|
|
182
|
+
if (isDev) {
|
|
183
|
+
const { register } = require('tsx/esm/api');
|
|
184
|
+
register();
|
|
185
|
+
const module = await import('../src/commands/doctorCommand.ts');
|
|
186
|
+
handleDoctorCommand = module.handleDoctorCommand;
|
|
187
|
+
} else {
|
|
188
|
+
const module = await import('../dist/commands/doctorCommand.js');
|
|
189
|
+
handleDoctorCommand = module.handleDoctorCommand;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
await handleDoctorCommand();
|
|
193
|
+
process.exit(0);
|
|
194
|
+
} catch (error) {
|
|
195
|
+
console.error('Error:', error.message);
|
|
196
|
+
process.exit(1);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
152
200
|
if (isDev) {
|
|
153
201
|
// Show dev mode indicator for developers
|
|
154
202
|
console.log('🔧 Running in development mode (using TypeScript source)\n');
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
CurationArtifactType
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-NI22LIK3.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;
|
|
@@ -269,24 +269,25 @@ var AuthTokensSchema = z.object({
|
|
|
269
269
|
userId: z.string()
|
|
270
270
|
});
|
|
271
271
|
var ApiConfigSchema = z.object({
|
|
272
|
-
customUrl: z.
|
|
272
|
+
customUrl: z.url().optional()
|
|
273
273
|
});
|
|
274
274
|
var McpServerSchema = z.object({
|
|
275
275
|
name: z.string(),
|
|
276
276
|
command: z.string().optional(),
|
|
277
277
|
args: z.array(z.string()).optional(),
|
|
278
|
-
env: z.record(z.string()).
|
|
279
|
-
enabled: z.boolean().
|
|
278
|
+
env: z.record(z.string(), z.string()).prefault({}),
|
|
279
|
+
enabled: z.boolean().prefault(true)
|
|
280
280
|
});
|
|
281
281
|
var McpServersSchema = z.union([
|
|
282
282
|
// Array format (B4M native)
|
|
283
283
|
z.array(McpServerSchema),
|
|
284
284
|
// Object format (portable - compatible with Claude Code)
|
|
285
285
|
z.record(
|
|
286
|
+
z.string(),
|
|
286
287
|
z.object({
|
|
287
288
|
command: z.string().optional(),
|
|
288
289
|
args: z.array(z.string()).optional(),
|
|
289
|
-
env: z.record(z.string()).optional(),
|
|
290
|
+
env: z.record(z.string(), z.string()).optional(),
|
|
290
291
|
enabled: z.boolean().optional()
|
|
291
292
|
})
|
|
292
293
|
)
|
|
@@ -325,24 +326,24 @@ var CliConfigSchema = z.object({
|
|
|
325
326
|
maxTokens: z.number(),
|
|
326
327
|
temperature: z.number(),
|
|
327
328
|
autoSave: z.boolean(),
|
|
328
|
-
autoCompact: z.boolean().optional().
|
|
329
|
+
autoCompact: z.boolean().optional().prefault(true),
|
|
329
330
|
theme: z.enum(["light", "dark"]),
|
|
330
331
|
exportFormat: z.enum(["markdown", "json"]),
|
|
331
|
-
maxIterations: z.number().nullable().
|
|
332
|
-
enableSkillTool: z.boolean().optional().
|
|
332
|
+
maxIterations: z.number().nullable().prefault(10),
|
|
333
|
+
enableSkillTool: z.boolean().optional().prefault(true)
|
|
333
334
|
}),
|
|
334
335
|
tools: z.object({
|
|
335
336
|
enabled: z.array(z.string()),
|
|
336
337
|
disabled: z.array(z.string()),
|
|
337
|
-
config: z.record(z.any())
|
|
338
|
+
config: z.record(z.string(), z.any())
|
|
338
339
|
}),
|
|
339
|
-
trustedTools: z.array(z.string()).optional().
|
|
340
|
+
trustedTools: z.array(z.string()).optional().prefault([])
|
|
340
341
|
});
|
|
341
342
|
var ProjectConfigSchema = z.object({
|
|
342
343
|
tools: z.object({
|
|
343
344
|
enabled: z.array(z.string()).optional(),
|
|
344
345
|
denied: z.array(z.string()).optional(),
|
|
345
|
-
config: z.record(z.any()).optional()
|
|
346
|
+
config: z.record(z.string(), z.any()).optional()
|
|
346
347
|
}).optional(),
|
|
347
348
|
defaultModel: z.string().optional(),
|
|
348
349
|
mcpServers: McpServersSchema.optional(),
|
|
@@ -432,7 +433,7 @@ async function loadProjectConfig(projectDir) {
|
|
|
432
433
|
return null;
|
|
433
434
|
}
|
|
434
435
|
if (error instanceof z.ZodError) {
|
|
435
|
-
console.error("Project config validation error:", error.
|
|
436
|
+
console.error("Project config validation error:", error.issues);
|
|
436
437
|
return null;
|
|
437
438
|
}
|
|
438
439
|
console.error("Failed to load project config:", error);
|
|
@@ -455,7 +456,7 @@ async function loadProjectLocalConfig(projectDir) {
|
|
|
455
456
|
return null;
|
|
456
457
|
}
|
|
457
458
|
if (error instanceof z.ZodError) {
|
|
458
|
-
console.error("Project local config validation error:", error.
|
|
459
|
+
console.error("Project local config validation error:", error.issues);
|
|
459
460
|
return null;
|
|
460
461
|
}
|
|
461
462
|
console.error("Failed to load project local config:", error);
|
|
@@ -478,7 +479,7 @@ async function loadMcpJsonConfig(projectDir) {
|
|
|
478
479
|
return null;
|
|
479
480
|
}
|
|
480
481
|
if (error instanceof z.ZodError) {
|
|
481
|
-
console.error(".mcp.json validation error:", error.
|
|
482
|
+
console.error(".mcp.json validation error:", error.issues);
|
|
482
483
|
return null;
|
|
483
484
|
}
|
|
484
485
|
console.error("Failed to load .mcp.json:", error);
|
|
@@ -620,7 +621,7 @@ var ConfigStore = class {
|
|
|
620
621
|
if (error.code === "ENOENT") {
|
|
621
622
|
globalConfig = { ...DEFAULT_CONFIG };
|
|
622
623
|
} else if (error instanceof z.ZodError) {
|
|
623
|
-
console.error("Global config validation error:", error.
|
|
624
|
+
console.error("Global config validation error:", error.issues);
|
|
624
625
|
console.error("Using default configuration");
|
|
625
626
|
globalConfig = { ...DEFAULT_CONFIG };
|
|
626
627
|
} else {
|
|
@@ -657,7 +658,7 @@ var ConfigStore = class {
|
|
|
657
658
|
return this.reset();
|
|
658
659
|
}
|
|
659
660
|
if (error instanceof z.ZodError) {
|
|
660
|
-
console.error("Config validation error:", error.
|
|
661
|
+
console.error("Config validation error:", error.issues);
|
|
661
662
|
console.error("Resetting to default configuration");
|
|
662
663
|
return this.reset();
|
|
663
664
|
}
|
|
@@ -16,10 +16,10 @@ import {
|
|
|
16
16
|
dayjsConfig_default,
|
|
17
17
|
extractSnippetMeta,
|
|
18
18
|
settingsMap
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-NI22LIK3.js";
|
|
20
20
|
import {
|
|
21
21
|
Logger
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-PFBYGCOW.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";
|
|
@@ -591,6 +591,125 @@ function getSettingsCacheStats() {
|
|
|
591
591
|
// ../../b4m-core/packages/utils/dist/src/ingest.js
|
|
592
592
|
import axios from "axios";
|
|
593
593
|
import mime2 from "mime-types";
|
|
594
|
+
|
|
595
|
+
// ../../b4m-core/packages/utils/dist/src/ssrfProtection.js
|
|
596
|
+
import dns from "dns";
|
|
597
|
+
import { promisify } from "util";
|
|
598
|
+
var dnsResolve4 = promisify(dns.resolve4);
|
|
599
|
+
var dnsResolve6 = promisify(dns.resolve6);
|
|
600
|
+
function isPrivateIPv4(ip) {
|
|
601
|
+
const ipv4Match = ip.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/);
|
|
602
|
+
if (!ipv4Match)
|
|
603
|
+
return false;
|
|
604
|
+
const [, a, b, c] = ipv4Match.map(Number);
|
|
605
|
+
if (a === 10)
|
|
606
|
+
return true;
|
|
607
|
+
if (a === 172 && b >= 16 && b <= 31)
|
|
608
|
+
return true;
|
|
609
|
+
if (a === 192 && b === 168)
|
|
610
|
+
return true;
|
|
611
|
+
if (a === 127)
|
|
612
|
+
return true;
|
|
613
|
+
if (a === 169 && b === 254)
|
|
614
|
+
return true;
|
|
615
|
+
if (a === 0)
|
|
616
|
+
return true;
|
|
617
|
+
if (a === 100 && b >= 64 && b <= 127)
|
|
618
|
+
return true;
|
|
619
|
+
if (a === 192 && b === 0 && c === 0)
|
|
620
|
+
return true;
|
|
621
|
+
if (a === 192 && b === 0 && c === 2 || a === 198 && b === 51 && c === 100 || a === 203 && b === 0 && c === 113)
|
|
622
|
+
return true;
|
|
623
|
+
if (a >= 224 && a <= 239)
|
|
624
|
+
return true;
|
|
625
|
+
if (a >= 240)
|
|
626
|
+
return true;
|
|
627
|
+
return false;
|
|
628
|
+
}
|
|
629
|
+
function isPrivateIPv6(ip) {
|
|
630
|
+
const normalized = ip.toLowerCase();
|
|
631
|
+
if (normalized === "::1" || normalized === "0:0:0:0:0:0:0:1")
|
|
632
|
+
return true;
|
|
633
|
+
if (normalized === "::" || normalized === "0:0:0:0:0:0:0:0")
|
|
634
|
+
return true;
|
|
635
|
+
if (normalized.startsWith("fe8") || normalized.startsWith("fe9") || normalized.startsWith("fea") || normalized.startsWith("feb"))
|
|
636
|
+
return true;
|
|
637
|
+
if (normalized.startsWith("fc") || normalized.startsWith("fd"))
|
|
638
|
+
return true;
|
|
639
|
+
if (normalized.startsWith("ff"))
|
|
640
|
+
return true;
|
|
641
|
+
const ipv4MappedMatch = normalized.match(/^::ffff:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/);
|
|
642
|
+
if (ipv4MappedMatch) {
|
|
643
|
+
return isPrivateIPv4(ipv4MappedMatch[1]);
|
|
644
|
+
}
|
|
645
|
+
if (normalized.startsWith("2001:db8:") || normalized.startsWith("2001:0db8:"))
|
|
646
|
+
return true;
|
|
647
|
+
if (normalized.startsWith("100::") || normalized.startsWith("0100::"))
|
|
648
|
+
return true;
|
|
649
|
+
if (normalized.startsWith("64:ff9b:") || normalized.startsWith("0064:ff9b:"))
|
|
650
|
+
return true;
|
|
651
|
+
return false;
|
|
652
|
+
}
|
|
653
|
+
function isPrivateIP(ip) {
|
|
654
|
+
if (/^(\d{1,3}\.){3}\d{1,3}$/.test(ip)) {
|
|
655
|
+
return isPrivateIPv4(ip);
|
|
656
|
+
}
|
|
657
|
+
return isPrivateIPv6(ip);
|
|
658
|
+
}
|
|
659
|
+
function isPrivateOrInternalHostname(hostname) {
|
|
660
|
+
const normalized = hostname.toLowerCase();
|
|
661
|
+
if (normalized === "localhost" || normalized === "127.0.0.1" || normalized === "::1" || normalized === "0.0.0.0" || normalized.endsWith(".localhost") || normalized.endsWith(".local")) {
|
|
662
|
+
return true;
|
|
663
|
+
}
|
|
664
|
+
if (normalized === "169.254.169.254" || normalized === "instance-data" || normalized === "metadata.google.internal" || normalized === "metadata.internal") {
|
|
665
|
+
return true;
|
|
666
|
+
}
|
|
667
|
+
if (normalized.endsWith(".cluster.local") || normalized.endsWith(".svc.cluster.local") || normalized.endsWith(".pod.cluster.local")) {
|
|
668
|
+
return true;
|
|
669
|
+
}
|
|
670
|
+
if (/^(\d{1,3}\.){3}\d{1,3}$/.test(normalized)) {
|
|
671
|
+
return isPrivateIPv4(normalized);
|
|
672
|
+
}
|
|
673
|
+
if (normalized.includes(":")) {
|
|
674
|
+
return isPrivateIPv6(normalized);
|
|
675
|
+
}
|
|
676
|
+
return false;
|
|
677
|
+
}
|
|
678
|
+
async function validateUrlForFetch(url) {
|
|
679
|
+
try {
|
|
680
|
+
const parsed = new URL(url);
|
|
681
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
682
|
+
return { valid: false, error: "URL must use HTTP or HTTPS protocol" };
|
|
683
|
+
}
|
|
684
|
+
if (isPrivateOrInternalHostname(parsed.hostname)) {
|
|
685
|
+
return { valid: false, error: "URL points to a private or internal network" };
|
|
686
|
+
}
|
|
687
|
+
const isIPv4Address = /^(\d{1,3}\.){3}\d{1,3}$/.test(parsed.hostname);
|
|
688
|
+
const isIPv6Address = parsed.hostname.includes(":");
|
|
689
|
+
if (!isIPv4Address && !isIPv6Address) {
|
|
690
|
+
try {
|
|
691
|
+
const ipv4Addresses = await dnsResolve4(parsed.hostname).catch(() => []);
|
|
692
|
+
const ipv6Addresses = await dnsResolve6(parsed.hostname).catch(() => []);
|
|
693
|
+
const allAddresses = [...ipv4Addresses, ...ipv6Addresses];
|
|
694
|
+
if (allAddresses.length === 0) {
|
|
695
|
+
return { valid: false, error: "Could not resolve hostname" };
|
|
696
|
+
}
|
|
697
|
+
for (const ip of allAddresses) {
|
|
698
|
+
if (isPrivateIP(ip)) {
|
|
699
|
+
return { valid: false, error: `Hostname resolves to private IP address (${ip})` };
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
} catch {
|
|
703
|
+
return { valid: false, error: "Could not resolve hostname" };
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
return { valid: true };
|
|
707
|
+
} catch {
|
|
708
|
+
return { valid: false, error: "Invalid URL format" };
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
// ../../b4m-core/packages/utils/dist/src/ingest.js
|
|
594
713
|
var URL_REGEX = /https?:\/\/(?:[-\w.])+(?:\:[0-9]+)?(?:\/(?:[\w\/_.])*(?:\?(?:[\w&=%.])*)?(?:\#(?:[\w.])*)?)?/gi;
|
|
595
714
|
function detectURLs(string) {
|
|
596
715
|
const urlsFound = string.match(URL_REGEX) || [];
|
|
@@ -603,15 +722,22 @@ function urlExists(stringWithPossibleUrl) {
|
|
|
603
722
|
const cleanString = stringWithPossibleUrl.replace(/\n/g, " ").replace(/,/g, " ");
|
|
604
723
|
return detectURLs(cleanString);
|
|
605
724
|
}
|
|
725
|
+
var URL_FETCH_TIMEOUT_MS = 1e4;
|
|
606
726
|
async function fetchAndParseURL(url, { logger }) {
|
|
607
727
|
logger.updateMetadata({ failedUrl: null });
|
|
608
728
|
try {
|
|
729
|
+
const ssrfValidation = await validateUrlForFetch(url);
|
|
730
|
+
if (!ssrfValidation.valid) {
|
|
731
|
+
throw new Error(`URL blocked for security reasons: ${ssrfValidation.error}`);
|
|
732
|
+
}
|
|
609
733
|
let urlMimeType = "text/plain";
|
|
610
734
|
if (url.split(".")?.pop()?.startsWith("pdf")) {
|
|
611
735
|
urlMimeType = "application/pdf";
|
|
612
736
|
}
|
|
613
737
|
const response = await axios.get(url, {
|
|
614
|
-
responseType: ["application/pdf"].includes(urlMimeType) ? "arraybuffer" : "text"
|
|
738
|
+
responseType: ["application/pdf"].includes(urlMimeType) ? "arraybuffer" : "text",
|
|
739
|
+
timeout: URL_FETCH_TIMEOUT_MS
|
|
740
|
+
// Prevent Lambda timeout exhaustion
|
|
615
741
|
});
|
|
616
742
|
const cheerio = await import("cheerio");
|
|
617
743
|
const htmlContent = response.data;
|
|
@@ -619,17 +745,19 @@ async function fetchAndParseURL(url, { logger }) {
|
|
|
619
745
|
const title = $("title").text() || url.split("/")?.pop();
|
|
620
746
|
let urlContent = null;
|
|
621
747
|
switch (urlMimeType) {
|
|
622
|
-
case "application/pdf":
|
|
748
|
+
case "application/pdf": {
|
|
623
749
|
const pdfbuffer = Buffer.from(response.data);
|
|
624
750
|
urlContent = pdfbuffer;
|
|
625
751
|
break;
|
|
626
|
-
|
|
752
|
+
}
|
|
753
|
+
default: {
|
|
627
754
|
let textContent = "";
|
|
628
755
|
$("body").find("p").each((index, element) => {
|
|
629
756
|
textContent += $(element).text() + "\n";
|
|
630
757
|
});
|
|
631
758
|
urlContent = textContent || htmlContent;
|
|
632
759
|
break;
|
|
760
|
+
}
|
|
633
761
|
}
|
|
634
762
|
logger.log(`Fetched ${title} with mimetype ${urlMimeType} and parsed ${url}`);
|
|
635
763
|
return { title, textContent: urlContent, mimeType: urlMimeType, ext: mime2.extension(urlMimeType) || null };
|
|
@@ -1155,8 +1283,30 @@ function separateUrls(urls) {
|
|
|
1155
1283
|
const nonImageUrls = urls.filter((url) => !imageExtensions.some((ext) => url.toLowerCase().endsWith(ext)));
|
|
1156
1284
|
return { imageUrls, nonImageUrls };
|
|
1157
1285
|
}
|
|
1158
|
-
|
|
1159
|
-
|
|
1286
|
+
function sanitizeUrlForLogging(url) {
|
|
1287
|
+
try {
|
|
1288
|
+
const parsed = new URL(url);
|
|
1289
|
+
const sensitiveParams = [
|
|
1290
|
+
"token",
|
|
1291
|
+
"key",
|
|
1292
|
+
"api_key",
|
|
1293
|
+
"apikey",
|
|
1294
|
+
"secret",
|
|
1295
|
+
"password",
|
|
1296
|
+
"session",
|
|
1297
|
+
"auth",
|
|
1298
|
+
"access_token"
|
|
1299
|
+
];
|
|
1300
|
+
sensitiveParams.forEach((param) => {
|
|
1301
|
+
if (parsed.searchParams.has(param)) {
|
|
1302
|
+
parsed.searchParams.set(param, "[REDACTED]");
|
|
1303
|
+
}
|
|
1304
|
+
});
|
|
1305
|
+
return parsed.toString();
|
|
1306
|
+
} catch {
|
|
1307
|
+
return url.substring(0, 100) + (url.length > 100 ? "..." : "");
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1160
1310
|
async function processUrlsFromPrompt(userPrompt, maxContentBuffer, userId, sendStatusUpdate, logger, options = { verbose: false }) {
|
|
1161
1311
|
if (!hasURLs(userPrompt)) {
|
|
1162
1312
|
if (options?.verbose) {
|
|
@@ -1164,6 +1314,7 @@ async function processUrlsFromPrompt(userPrompt, maxContentBuffer, userId, sendS
|
|
|
1164
1314
|
}
|
|
1165
1315
|
return { userMessages: [], remainingPrompt: userPrompt };
|
|
1166
1316
|
}
|
|
1317
|
+
const urlContentCache = /* @__PURE__ */ new Map();
|
|
1167
1318
|
sendStatusUpdate("Processing URLs from user prompt...");
|
|
1168
1319
|
const userMessages = [];
|
|
1169
1320
|
const promptMeta = extractSnippetMeta(userPrompt);
|
|
@@ -1191,20 +1342,26 @@ async function processUrlsFromPrompt(userPrompt, maxContentBuffer, userId, sendS
|
|
|
1191
1342
|
try {
|
|
1192
1343
|
const cached = urlContentCache.get(url);
|
|
1193
1344
|
let textContent;
|
|
1194
|
-
if (cached
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1345
|
+
if (cached) {
|
|
1346
|
+
logger.info("URL_FETCH", {
|
|
1347
|
+
userId,
|
|
1348
|
+
url: sanitizeUrlForLogging(url),
|
|
1349
|
+
cacheHit: true,
|
|
1350
|
+
source: "same-request-dedup"
|
|
1351
|
+
});
|
|
1352
|
+
textContent = cached;
|
|
1199
1353
|
} else {
|
|
1200
1354
|
const result = await fetchAndParseURL(url, { logger });
|
|
1201
1355
|
if (typeof result.textContent !== "string")
|
|
1202
1356
|
throw new Error("textContent is not a string");
|
|
1203
1357
|
textContent = result.textContent;
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1358
|
+
logger.info("URL_FETCH", {
|
|
1359
|
+
userId,
|
|
1360
|
+
url: sanitizeUrlForLogging(url),
|
|
1361
|
+
cacheHit: false,
|
|
1362
|
+
contentLength: textContent.length
|
|
1207
1363
|
});
|
|
1364
|
+
urlContentCache.set(url, textContent);
|
|
1208
1365
|
}
|
|
1209
1366
|
const message = {
|
|
1210
1367
|
role: "user",
|
|
@@ -7634,7 +7791,7 @@ function secureParameters(params, schema) {
|
|
|
7634
7791
|
return schema.parse(params);
|
|
7635
7792
|
} catch (e) {
|
|
7636
7793
|
if (isZodError(e)) {
|
|
7637
|
-
throw new UnprocessableEntityError(e.
|
|
7794
|
+
throw new UnprocessableEntityError(e.issues.map((err) => `${err.path.join(".")}: ${err.message}`).join(", "));
|
|
7638
7795
|
}
|
|
7639
7796
|
throw new InternalServerError();
|
|
7640
7797
|
}
|
|
@@ -11600,6 +11757,9 @@ function findAutomaticFallback(originalModel, availableModels, apiKeyTable, logg
|
|
|
11600
11757
|
"gemini-2.5-flash-preview-05-20": ["claude-3-5-haiku-20241022", "gpt-4o-mini", "claude-3-haiku-20240307"],
|
|
11601
11758
|
"gemini-1.5-pro": ["claude-3-5-sonnet-20241022", "gpt-4o", "claude-3-opus-20240229"],
|
|
11602
11759
|
"gemini-1.5-flash": ["claude-3-5-haiku-20241022", "gpt-4o-mini", "claude-3-haiku-20240307"],
|
|
11760
|
+
// Claude 4.5/4.6 Opus models fallback to Sonnet 4.5
|
|
11761
|
+
"claude-opus-4-5-20251101": ["claude-sonnet-4-5-20250929", "gpt-5", "claude-haiku-4-5-20251001"],
|
|
11762
|
+
"claude-opus-4-6": ["claude-sonnet-4-5-20250929", "gpt-5", "claude-haiku-4-5-20251001"],
|
|
11603
11763
|
// Claude models fallback to other Claude models or GPT
|
|
11604
11764
|
"claude-3-5-sonnet-20241022": ["claude-3-opus-20240229", "gpt-4o", "claude-3-sonnet-20240229"],
|
|
11605
11765
|
"claude-3-opus-20240229": ["claude-3-5-sonnet-20241022", "gpt-4o", "claude-3-sonnet-20240229"],
|
|
@@ -11609,7 +11769,7 @@ function findAutomaticFallback(originalModel, availableModels, apiKeyTable, logg
|
|
|
11609
11769
|
};
|
|
11610
11770
|
const preferences = fallbackPreferences[originalModel.id] || [];
|
|
11611
11771
|
if (preferences.length === 0) {
|
|
11612
|
-
preferences.push("claude-
|
|
11772
|
+
preferences.push("claude-sonnet-4-5-20250929", "gpt-5", "claude-haiku-4-5-20251001");
|
|
11613
11773
|
}
|
|
11614
11774
|
for (const modelId of preferences) {
|
|
11615
11775
|
const fallbackModel = availableModels.find((m) => m.id === modelId);
|
|
@@ -11998,6 +12158,59 @@ function buildVoiceInstructions(baseInstructions, historyContext) {
|
|
|
11998
12158
|
return `${baseInstructions}${historyContext}`;
|
|
11999
12159
|
}
|
|
12000
12160
|
|
|
12161
|
+
// ../../b4m-core/packages/utils/dist/src/lambdaErrorHandler.js
|
|
12162
|
+
var isRegistered = false;
|
|
12163
|
+
function classifyError(error) {
|
|
12164
|
+
if (error instanceof TypeError) {
|
|
12165
|
+
if (error.message === "terminated" || error.message.includes("fetch failed")) {
|
|
12166
|
+
return "network_terminated";
|
|
12167
|
+
}
|
|
12168
|
+
}
|
|
12169
|
+
if (error instanceof Error) {
|
|
12170
|
+
if (error.name === "AbortError") {
|
|
12171
|
+
return "network_timeout";
|
|
12172
|
+
}
|
|
12173
|
+
const connectionErrors = ["ECONNRESET", "ETIMEDOUT", "ECONNREFUSED", "EPIPE", "ENOTFOUND"];
|
|
12174
|
+
if (connectionErrors.some((code) => error.message.includes(code))) {
|
|
12175
|
+
return "network_connection";
|
|
12176
|
+
}
|
|
12177
|
+
}
|
|
12178
|
+
return "unhandled_rejection";
|
|
12179
|
+
}
|
|
12180
|
+
function buildLogEntry(error, category) {
|
|
12181
|
+
return {
|
|
12182
|
+
error: error instanceof Error ? error.message : String(error),
|
|
12183
|
+
stack: error instanceof Error ? error.stack : void 0,
|
|
12184
|
+
category,
|
|
12185
|
+
functionName: process.env.AWS_LAMBDA_FUNCTION_NAME,
|
|
12186
|
+
stage: process.env.SEED_STAGE_NAME,
|
|
12187
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
12188
|
+
};
|
|
12189
|
+
}
|
|
12190
|
+
function registerLambdaErrorHandlers(logger) {
|
|
12191
|
+
if (isRegistered)
|
|
12192
|
+
return;
|
|
12193
|
+
isRegistered = true;
|
|
12194
|
+
const log = logger || console;
|
|
12195
|
+
process.on("unhandledRejection", (reason) => {
|
|
12196
|
+
const category = classifyError(reason);
|
|
12197
|
+
const isNetworkError = category.startsWith("network_");
|
|
12198
|
+
const logEntry = buildLogEntry(reason, category);
|
|
12199
|
+
if (isNetworkError) {
|
|
12200
|
+
log.warn("[Lambda] Network error (unhandled rejection)", logEntry);
|
|
12201
|
+
} else {
|
|
12202
|
+
log.error("[Lambda] Unhandled promise rejection", logEntry);
|
|
12203
|
+
}
|
|
12204
|
+
});
|
|
12205
|
+
process.on("uncaughtException", (error) => {
|
|
12206
|
+
const logEntry = buildLogEntry(error, "uncaught_exception");
|
|
12207
|
+
log.error("[Lambda] Uncaught exception", logEntry);
|
|
12208
|
+
});
|
|
12209
|
+
}
|
|
12210
|
+
function _resetLambdaErrorHandlers() {
|
|
12211
|
+
isRegistered = false;
|
|
12212
|
+
}
|
|
12213
|
+
|
|
12001
12214
|
export {
|
|
12002
12215
|
BaseStorage,
|
|
12003
12216
|
S3Storage,
|
|
@@ -12015,6 +12228,9 @@ export {
|
|
|
12015
12228
|
warmUpSettingsCache,
|
|
12016
12229
|
shutdownSettingsCache,
|
|
12017
12230
|
getSettingsCacheStats,
|
|
12231
|
+
isPrivateIP,
|
|
12232
|
+
isPrivateOrInternalHostname,
|
|
12233
|
+
validateUrlForFetch,
|
|
12018
12234
|
URL_REGEX,
|
|
12019
12235
|
detectURLs,
|
|
12020
12236
|
hasURLs,
|
|
@@ -12132,5 +12348,7 @@ export {
|
|
|
12132
12348
|
calculateRetryDelay,
|
|
12133
12349
|
withRetry,
|
|
12134
12350
|
formatVoiceHistory,
|
|
12135
|
-
buildVoiceInstructions
|
|
12351
|
+
buildVoiceInstructions,
|
|
12352
|
+
registerLambdaErrorHandlers,
|
|
12353
|
+
_resetLambdaErrorHandlers
|
|
12136
12354
|
};
|
|
@@ -7,11 +7,11 @@ import {
|
|
|
7
7
|
getSettingsMap,
|
|
8
8
|
getSettingsValue,
|
|
9
9
|
secureParameters
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-3SPW5FYJ.js";
|
|
11
11
|
import {
|
|
12
12
|
KnowledgeType,
|
|
13
13
|
SupportedFabFileMimeTypes
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-NI22LIK3.js";
|
|
15
15
|
|
|
16
16
|
// ../../b4m-core/packages/services/dist/src/fabFileService/create.js
|
|
17
17
|
import { z } from "zod";
|
|
@@ -20,7 +20,7 @@ var createFabFileSchema = z.object({
|
|
|
20
20
|
fileName: z.string(),
|
|
21
21
|
mimeType: z.string(),
|
|
22
22
|
fileSize: z.number(),
|
|
23
|
-
type: z.
|
|
23
|
+
type: z.enum(KnowledgeType),
|
|
24
24
|
content: z.union([z.string(), z.instanceof(Buffer)]).optional(),
|
|
25
25
|
organizationId: z.string().optional(),
|
|
26
26
|
/**
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
BadRequestError,
|
|
4
4
|
secureParameters
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-3SPW5FYJ.js";
|
|
6
6
|
import {
|
|
7
7
|
CompletionApiUsageTransaction,
|
|
8
8
|
GenericCreditDeductTransaction,
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
TextGenerationUsageTransaction,
|
|
13
13
|
TransferCreditTransaction,
|
|
14
14
|
VideoGenerationUsageTransaction
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-NI22LIK3.js";
|
|
16
16
|
|
|
17
17
|
// ../../b4m-core/packages/services/dist/src/creditService/subtractCredits.js
|
|
18
18
|
import { z } from "zod";
|
|
@@ -595,12 +595,13 @@ var HydrationEngine = class {
|
|
|
595
595
|
return numericInputs[0] / numericInputs[1];
|
|
596
596
|
case "ABS":
|
|
597
597
|
return numericInputs.length > 0 ? Math.abs(numericInputs[0]) : 0;
|
|
598
|
-
case "ROUND":
|
|
598
|
+
case "ROUND": {
|
|
599
599
|
if (numericInputs.length === 0)
|
|
600
600
|
return 0;
|
|
601
601
|
const decimals = numericInputs[1] ?? 0;
|
|
602
602
|
const factor = Math.pow(10, decimals);
|
|
603
603
|
return Math.round(numericInputs[0] * factor) / factor;
|
|
604
|
+
}
|
|
604
605
|
case "FLOOR":
|
|
605
606
|
return numericInputs.length > 0 ? Math.floor(numericInputs[0]) : 0;
|
|
606
607
|
case "CEIL":
|
|
@@ -624,12 +625,13 @@ var HydrationEngine = class {
|
|
|
624
625
|
return numericInputs.length > 0 ? Math.max(...numericInputs) : 0;
|
|
625
626
|
case "COUNT":
|
|
626
627
|
return inputs.filter((v) => v !== null).length;
|
|
627
|
-
case "MEDIAN":
|
|
628
|
+
case "MEDIAN": {
|
|
628
629
|
if (numericInputs.length === 0)
|
|
629
630
|
return 0;
|
|
630
631
|
const sorted = [...numericInputs].sort((a, b) => a - b);
|
|
631
632
|
const mid = Math.floor(sorted.length / 2);
|
|
632
633
|
return sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];
|
|
634
|
+
}
|
|
633
635
|
// Logical
|
|
634
636
|
case "IF":
|
|
635
637
|
return inputs[0] ? inputs[1] : inputs[2];
|
|
@@ -649,13 +651,14 @@ var HydrationEngine = class {
|
|
|
649
651
|
return inputs.length >= 2 && inputs[0] >= inputs[1];
|
|
650
652
|
case "LESS_THAN_OR_EQUAL":
|
|
651
653
|
return inputs.length >= 2 && inputs[0] <= inputs[1];
|
|
652
|
-
case "BETWEEN":
|
|
654
|
+
case "BETWEEN": {
|
|
653
655
|
if (inputs.length < 3)
|
|
654
656
|
return false;
|
|
655
657
|
const val = inputs[0];
|
|
656
658
|
const min = inputs[1];
|
|
657
659
|
const max = inputs[2];
|
|
658
660
|
return val >= min && val <= max;
|
|
661
|
+
}
|
|
659
662
|
// Financial
|
|
660
663
|
case "PERCENT_OF":
|
|
661
664
|
if (numericInputs.length < 2 || numericInputs[1] === 0)
|
|
@@ -714,11 +717,12 @@ var HydrationEngine = class {
|
|
|
714
717
|
case "REFERENCE":
|
|
715
718
|
return inputs[0];
|
|
716
719
|
// Pass through
|
|
717
|
-
case "LOOKUP":
|
|
720
|
+
case "LOOKUP": {
|
|
718
721
|
if (inputs.length < 2)
|
|
719
722
|
return null;
|
|
720
723
|
const index = inputs[0];
|
|
721
724
|
return inputs[Math.min(index + 1, inputs.length - 1)];
|
|
725
|
+
}
|
|
722
726
|
default:
|
|
723
727
|
context.errors.push({
|
|
724
728
|
type: "INVALID_OPERATION",
|
|
@@ -6,17 +6,17 @@ import {
|
|
|
6
6
|
getSettingsByNames,
|
|
7
7
|
obfuscateApiKey,
|
|
8
8
|
secureParameters
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-3SPW5FYJ.js";
|
|
10
10
|
import {
|
|
11
11
|
ApiKeyType,
|
|
12
12
|
MementoTier,
|
|
13
13
|
isSupportedEmbeddingModel
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-NI22LIK3.js";
|
|
15
15
|
|
|
16
16
|
// ../../b4m-core/packages/services/dist/src/apiKeyService/get.js
|
|
17
17
|
import { z } from "zod";
|
|
18
18
|
var getApiKeySchema = z.object({
|
|
19
|
-
type: z.
|
|
19
|
+
type: z.enum(ApiKeyType),
|
|
20
20
|
nullIfMissing: z.boolean().optional(),
|
|
21
21
|
obfuscate: z.boolean().optional(),
|
|
22
22
|
demoKeyName: z.string().optional()
|