@juspay/neurolink 9.25.1 → 9.26.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/CHANGELOG.md +12 -0
- package/dist/adapters/providerImageAdapter.d.ts +3 -27
- package/dist/adapters/providerImageAdapter.js +9 -199
- package/dist/agent/directTools.d.ts +35 -3
- package/dist/agent/directTools.js +122 -0
- package/dist/cli/commands/config.d.ts +6 -6
- package/dist/context/contextCompactor.d.ts +1 -2
- package/dist/context/contextCompactor.js +7 -1
- package/dist/context/prompts/summarizationPrompt.d.ts +3 -3
- package/dist/context/prompts/summarizationPrompt.js +16 -9
- package/dist/context/stages/structuredSummarizer.d.ts +2 -2
- package/dist/context/stages/structuredSummarizer.js +80 -30
- package/dist/lib/adapters/providerImageAdapter.d.ts +3 -27
- package/dist/lib/adapters/providerImageAdapter.js +9 -199
- package/dist/lib/agent/directTools.d.ts +33 -1
- package/dist/lib/agent/directTools.js +122 -0
- package/dist/lib/context/contextCompactor.d.ts +1 -2
- package/dist/lib/context/contextCompactor.js +7 -1
- package/dist/lib/context/prompts/summarizationPrompt.d.ts +3 -3
- package/dist/lib/context/prompts/summarizationPrompt.js +16 -9
- package/dist/lib/context/stages/structuredSummarizer.d.ts +2 -2
- package/dist/lib/context/stages/structuredSummarizer.js +80 -30
- package/dist/lib/mcp/servers/agent/directToolsServer.js +2 -0
- package/dist/lib/mcp/toolRegistry.d.ts +8 -0
- package/dist/lib/mcp/toolRegistry.js +20 -0
- package/dist/lib/neurolink.d.ts +10 -0
- package/dist/lib/neurolink.js +350 -46
- package/dist/lib/providers/googleAiStudio.js +13 -7
- package/dist/lib/types/configTypes.d.ts +3 -0
- package/dist/lib/types/contextTypes.d.ts +5 -2
- package/dist/lib/types/contextTypes.js +8 -8
- package/dist/lib/types/generateTypes.d.ts +25 -0
- package/dist/lib/types/modelTypes.d.ts +2 -2
- package/dist/lib/utils/messageBuilder.js +2 -0
- package/dist/lib/utils/modelAliasResolver.d.ts +17 -0
- package/dist/lib/utils/modelAliasResolver.js +55 -0
- package/dist/lib/utils/pdfProcessor.d.ts +1 -1
- package/dist/lib/utils/pdfProcessor.js +7 -7
- package/dist/lib/utils/toolUtils.d.ts +8 -0
- package/dist/lib/utils/toolUtils.js +15 -0
- package/dist/lib/workflow/config.d.ts +24 -24
- package/dist/mcp/servers/agent/directToolsServer.js +2 -0
- package/dist/mcp/toolRegistry.d.ts +8 -0
- package/dist/mcp/toolRegistry.js +20 -0
- package/dist/neurolink.d.ts +10 -0
- package/dist/neurolink.js +350 -46
- package/dist/providers/googleAiStudio.js +13 -7
- package/dist/server/utils/validation.d.ts +2 -2
- package/dist/types/configTypes.d.ts +3 -0
- package/dist/types/contextTypes.d.ts +5 -2
- package/dist/types/contextTypes.js +8 -8
- package/dist/types/generateTypes.d.ts +25 -0
- package/dist/utils/messageBuilder.js +2 -0
- package/dist/utils/modelAliasResolver.d.ts +17 -0
- package/dist/utils/modelAliasResolver.js +54 -0
- package/dist/utils/pdfProcessor.d.ts +1 -1
- package/dist/utils/pdfProcessor.js +7 -7
- package/dist/utils/toolUtils.d.ts +8 -0
- package/dist/utils/toolUtils.js +15 -0
- package/dist/workflow/config.d.ts +82 -82
- package/package.json +1 -1
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { createGoogleGenerativeAI } from "@ai-sdk/google";
|
|
2
2
|
import { embed, embedMany, streamText, } from "ai";
|
|
3
3
|
import { ErrorCategory, ErrorSeverity, GoogleAIModels, } from "../constants/enums.js";
|
|
4
|
-
import { estimateTokens } from "../utils/tokenEstimation.js";
|
|
5
4
|
import { BaseProvider } from "../core/baseProvider.js";
|
|
6
5
|
import { DEFAULT_MAX_STEPS } from "../core/constants.js";
|
|
7
6
|
import { streamAnalyticsCollector } from "../core/streamAnalytics.js";
|
|
7
|
+
import { ATTR, tracers, withClientSpan } from "../telemetry/index.js";
|
|
8
8
|
import { AuthenticationError, NetworkError, ProviderError, RateLimitError, } from "../types/errors.js";
|
|
9
9
|
import { ERROR_CODES, NeuroLinkError } from "../utils/errorHandling.js";
|
|
10
10
|
import { logger } from "../utils/logger.js";
|
|
11
11
|
import { isGemini3Model } from "../utils/modelDetection.js";
|
|
12
|
-
import { tracers, ATTR, withClientSpan } from "../telemetry/index.js";
|
|
13
12
|
import { composeAbortSignals, createTimeoutController, TimeoutError, } from "../utils/timeout.js";
|
|
14
|
-
import {
|
|
13
|
+
import { estimateTokens } from "../utils/tokenEstimation.js";
|
|
14
|
+
import { buildNativeConfig, buildNativeToolDeclarations, collectStreamChunks, computeMaxSteps, executeNativeToolCalls, extractTextFromParts, handleMaxStepsTermination, pushModelResponseToHistory, sanitizeToolsForGemini, } from "./googleNativeGemini3.js";
|
|
15
15
|
// Google AI Live API types now imported from ../types/providerSpecific.js
|
|
16
16
|
// Import proper types for multimodal message handling
|
|
17
17
|
// Create Google GenAI client
|
|
@@ -626,9 +626,12 @@ export class GoogleAIStudioProvider extends BaseProvider {
|
|
|
626
626
|
// Add model response with ALL parts (including thoughtSignature) to history
|
|
627
627
|
pushModelResponseToHistory(currentContents, chunkResult.rawResponseParts, chunkResult.stepFunctionCalls);
|
|
628
628
|
const functionResponses = await executeNativeToolCalls("[GoogleAIStudio]", chunkResult.stepFunctionCalls, executeMap, failedTools, allToolCalls, { abortSignal: composedSignal });
|
|
629
|
-
// Add function responses to history
|
|
629
|
+
// Add function responses to history — the @google/genai SDK
|
|
630
|
+
// only accepts "user" and "model" as valid roles in contents.
|
|
631
|
+
// Function/tool responses must use role: "user" (matching the
|
|
632
|
+
// SDK's own automaticFunctionCalling implementation).
|
|
630
633
|
currentContents.push({
|
|
631
|
-
role: "
|
|
634
|
+
role: "user",
|
|
632
635
|
parts: functionResponses,
|
|
633
636
|
});
|
|
634
637
|
}
|
|
@@ -776,9 +779,12 @@ export class GoogleAIStudioProvider extends BaseProvider {
|
|
|
776
779
|
// This is critical for Gemini 3 - it requires thought signatures in subsequent turns
|
|
777
780
|
pushModelResponseToHistory(currentContents, chunkResult.rawResponseParts, chunkResult.stepFunctionCalls);
|
|
778
781
|
const functionResponses = await executeNativeToolCalls("[GoogleAIStudio]", chunkResult.stepFunctionCalls, executeMap, failedTools, allToolCalls, { toolExecutions, abortSignal: composedSignal });
|
|
779
|
-
// Add function responses to history
|
|
782
|
+
// Add function responses to history — the @google/genai SDK
|
|
783
|
+
// only accepts "user" and "model" as valid roles in contents.
|
|
784
|
+
// Function/tool responses must use role: "user" (matching the
|
|
785
|
+
// SDK's own automaticFunctionCalling implementation).
|
|
780
786
|
currentContents.push({
|
|
781
|
-
role: "
|
|
787
|
+
role: "user",
|
|
782
788
|
parts: functionResponses,
|
|
783
789
|
});
|
|
784
790
|
}
|
|
@@ -40,9 +40,9 @@ export declare const AgentExecuteRequestSchema: z.ZodObject<{
|
|
|
40
40
|
userId?: string | undefined;
|
|
41
41
|
stream?: boolean | undefined;
|
|
42
42
|
sessionId?: string | undefined;
|
|
43
|
-
temperature?: number | undefined;
|
|
44
43
|
maxTokens?: number | undefined;
|
|
45
44
|
systemPrompt?: string | undefined;
|
|
45
|
+
temperature?: number | undefined;
|
|
46
46
|
tools?: string[] | undefined;
|
|
47
47
|
}, {
|
|
48
48
|
input: string | {
|
|
@@ -55,9 +55,9 @@ export declare const AgentExecuteRequestSchema: z.ZodObject<{
|
|
|
55
55
|
userId?: string | undefined;
|
|
56
56
|
stream?: boolean | undefined;
|
|
57
57
|
sessionId?: string | undefined;
|
|
58
|
-
temperature?: number | undefined;
|
|
59
58
|
maxTokens?: number | undefined;
|
|
60
59
|
systemPrompt?: string | undefined;
|
|
60
|
+
temperature?: number | undefined;
|
|
61
61
|
tools?: string[] | undefined;
|
|
62
62
|
}>;
|
|
63
63
|
/**
|
|
@@ -27,6 +27,7 @@ export type NeurolinkConstructorConfig = {
|
|
|
27
27
|
hitl?: HITLConfig;
|
|
28
28
|
toolRegistry?: MCPToolRegistry;
|
|
29
29
|
observability?: ObservabilityConfig;
|
|
30
|
+
modelAliasConfig?: import("./generateTypes.js").ModelAliasConfig;
|
|
30
31
|
};
|
|
31
32
|
/**
|
|
32
33
|
* Provider-specific configuration
|
|
@@ -117,6 +118,8 @@ export type ToolConfig = {
|
|
|
117
118
|
maxToolsPerProvider?: number;
|
|
118
119
|
/** Whether MCP tools should be enabled */
|
|
119
120
|
enableMCPTools?: boolean;
|
|
121
|
+
/** Whether the bash command execution tool should be enabled (opt-in, defaults to false) */
|
|
122
|
+
enableBashTool?: boolean;
|
|
120
123
|
};
|
|
121
124
|
/**
|
|
122
125
|
* Backup metadata information
|
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
* Context Types for NeuroLink - Factory Pattern Implementation
|
|
3
3
|
* Provides type-safe context integration for AI generation
|
|
4
4
|
*/
|
|
5
|
-
import type { JsonObject } from "./common.js";
|
|
6
5
|
import type { ExecutionContext } from "../types/tools.js";
|
|
6
|
+
import type { JsonObject } from "./common.js";
|
|
7
7
|
import type { ChatMessage, ConversationMemoryConfig } from "./conversation.js";
|
|
8
|
-
import type { CompactionStage } from "../context/contextCompactor.js";
|
|
9
8
|
/**
|
|
10
9
|
* Base context type for all AI operations
|
|
11
10
|
*/
|
|
@@ -173,6 +172,8 @@ export declare class ContextConverter {
|
|
|
173
172
|
private static inferProvider;
|
|
174
173
|
private static extractCustomData;
|
|
175
174
|
}
|
|
175
|
+
/** Stages available in the compaction pipeline. */
|
|
176
|
+
export type CompactionStage = "prune" | "deduplicate" | "summarize" | "truncate";
|
|
176
177
|
/** Result of multi-stage context compaction. */
|
|
177
178
|
export type CompactionResult = {
|
|
178
179
|
compacted: boolean;
|
|
@@ -447,6 +448,8 @@ export type SummarizeConfig = {
|
|
|
447
448
|
model?: string;
|
|
448
449
|
keepRecentRatio?: number;
|
|
449
450
|
memoryConfig?: Partial<ConversationMemoryConfig>;
|
|
451
|
+
/** Target token budget — when set, split uses token counting instead of message count */
|
|
452
|
+
targetTokens?: number;
|
|
450
453
|
};
|
|
451
454
|
/** Result of structured LLM summarization (Stage 3). */
|
|
452
455
|
export type SummarizeResult = {
|
|
@@ -155,12 +155,12 @@ export class ContextFactory {
|
|
|
155
155
|
*/
|
|
156
156
|
static processContext(context, config = {}) {
|
|
157
157
|
const startTime = Date.now();
|
|
158
|
-
const finalConfig = { ...
|
|
158
|
+
const finalConfig = { ...ContextFactory.DEFAULT_CONFIG, ...config };
|
|
159
159
|
let processedContext = null;
|
|
160
160
|
const template = "default";
|
|
161
161
|
let truncated = false;
|
|
162
162
|
if (finalConfig.includeInPrompt && finalConfig.mode !== "metadata_only") {
|
|
163
|
-
processedContext =
|
|
163
|
+
processedContext = ContextFactory.formatContextForPrompt(context, finalConfig);
|
|
164
164
|
// Truncate if necessary
|
|
165
165
|
if (finalConfig.maxLength &&
|
|
166
166
|
processedContext.length > finalConfig.maxLength) {
|
|
@@ -188,13 +188,13 @@ export class ContextFactory {
|
|
|
188
188
|
static formatContextForPrompt(context, config) {
|
|
189
189
|
switch (config.mode) {
|
|
190
190
|
case "prompt_prefix":
|
|
191
|
-
return
|
|
191
|
+
return ContextFactory.formatAsPrefix(context);
|
|
192
192
|
case "prompt_suffix":
|
|
193
|
-
return
|
|
193
|
+
return ContextFactory.formatAsSuffix(context);
|
|
194
194
|
case "system_prompt":
|
|
195
|
-
return
|
|
195
|
+
return ContextFactory.formatForSystemPrompt(context);
|
|
196
196
|
case "structured_prompt":
|
|
197
|
-
return
|
|
197
|
+
return ContextFactory.formatStructured(context);
|
|
198
198
|
case "metadata_only":
|
|
199
199
|
case "none":
|
|
200
200
|
default:
|
|
@@ -304,7 +304,7 @@ export class ContextConverter {
|
|
|
304
304
|
legacyContext.authToken ||
|
|
305
305
|
legacyContext.accessToken,
|
|
306
306
|
endpoint: legacyContext.apiEndpoint || legacyContext.serviceUrl,
|
|
307
|
-
provider:
|
|
307
|
+
provider: ContextConverter.inferProvider(legacyContext),
|
|
308
308
|
},
|
|
309
309
|
platformConfig: {
|
|
310
310
|
type: legacyContext.platformType || "generic",
|
|
@@ -328,7 +328,7 @@ export class ContextConverter {
|
|
|
328
328
|
}
|
|
329
329
|
: {}),
|
|
330
330
|
// Include all additional custom data
|
|
331
|
-
...
|
|
331
|
+
...ContextConverter.extractCustomData(legacyContext),
|
|
332
332
|
},
|
|
333
333
|
},
|
|
334
334
|
metadata: includeMetadata
|
|
@@ -548,6 +548,13 @@ export type GenerateResult = {
|
|
|
548
548
|
workflowId: string;
|
|
549
549
|
workflowName: string;
|
|
550
550
|
};
|
|
551
|
+
retries?: {
|
|
552
|
+
count: number;
|
|
553
|
+
errors: Array<{
|
|
554
|
+
code: string;
|
|
555
|
+
message: string;
|
|
556
|
+
}>;
|
|
557
|
+
};
|
|
551
558
|
};
|
|
552
559
|
/**
|
|
553
560
|
* Unified options for both generation and streaming
|
|
@@ -899,6 +906,13 @@ export type TextGenerationResult = {
|
|
|
899
906
|
imageOutput?: {
|
|
900
907
|
base64: string;
|
|
901
908
|
} | null;
|
|
909
|
+
retries?: {
|
|
910
|
+
count: number;
|
|
911
|
+
errors: Array<{
|
|
912
|
+
code: string;
|
|
913
|
+
message: string;
|
|
914
|
+
}>;
|
|
915
|
+
};
|
|
902
916
|
};
|
|
903
917
|
/**
|
|
904
918
|
* Enhanced result type with optional analytics/evaluation
|
|
@@ -907,3 +921,14 @@ export type EnhancedGenerateResult = GenerateResult & {
|
|
|
907
921
|
analytics?: AnalyticsData;
|
|
908
922
|
evaluation?: EvaluationData;
|
|
909
923
|
};
|
|
924
|
+
/**
|
|
925
|
+
* NL-004: Model alias/deprecation configuration.
|
|
926
|
+
* Allows mapping deprecated model names to their replacements.
|
|
927
|
+
*/
|
|
928
|
+
export type ModelAliasConfig = {
|
|
929
|
+
aliases: Record<string, {
|
|
930
|
+
target: string;
|
|
931
|
+
action: "warn" | "redirect" | "block";
|
|
932
|
+
reason?: string;
|
|
933
|
+
}>;
|
|
934
|
+
};
|
|
@@ -1182,6 +1182,8 @@ async function downloadImageFromUrl(url) {
|
|
|
1182
1182
|
* - Supports alt text for accessibility (included as context in text parts)
|
|
1183
1183
|
*/
|
|
1184
1184
|
async function convertSimpleImagesToProviderFormat(text, images, provider, _model) {
|
|
1185
|
+
// Validate image count against provider-specific limits before processing
|
|
1186
|
+
ProviderImageAdapter.validateImageCount(images.length, provider, _model);
|
|
1185
1187
|
// For Vercel AI SDK, we need to return the content in the standard format
|
|
1186
1188
|
// The Vercel AI SDK will handle provider-specific formatting internally
|
|
1187
1189
|
// IMPORTANT: Generate alt text descriptions BEFORE URL downloading to maintain correct image numbering
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NL-004: Model alias/deprecation resolver.
|
|
3
|
+
*
|
|
4
|
+
* Resolves model names against an alias configuration map and applies the
|
|
5
|
+
* configured action (warn, redirect, or block).
|
|
6
|
+
*/
|
|
7
|
+
import type { ModelAliasConfig } from "../types/generateTypes.js";
|
|
8
|
+
/**
|
|
9
|
+
* Resolve model aliases/deprecations.
|
|
10
|
+
* Checks the model name against the alias map and applies the configured action.
|
|
11
|
+
*
|
|
12
|
+
* @param model - The requested model name (may be undefined).
|
|
13
|
+
* @param config - The alias configuration containing model mappings.
|
|
14
|
+
* @returns The resolved model name (original or redirected).
|
|
15
|
+
* @throws {NeuroLinkError} When the alias action is "block".
|
|
16
|
+
*/
|
|
17
|
+
export declare function resolveModel(model: string | undefined, config: ModelAliasConfig | undefined): string | undefined;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NL-004: Model alias/deprecation resolver.
|
|
3
|
+
*
|
|
4
|
+
* Resolves model names against an alias configuration map and applies the
|
|
5
|
+
* configured action (warn, redirect, or block).
|
|
6
|
+
*/
|
|
7
|
+
import { ErrorCategory, ErrorSeverity } from "../constants/enums.js";
|
|
8
|
+
import { NeuroLinkError } from "./errorHandling.js";
|
|
9
|
+
import { logger } from "./logger.js";
|
|
10
|
+
/**
|
|
11
|
+
* Resolve model aliases/deprecations.
|
|
12
|
+
* Checks the model name against the alias map and applies the configured action.
|
|
13
|
+
*
|
|
14
|
+
* @param model - The requested model name (may be undefined).
|
|
15
|
+
* @param config - The alias configuration containing model mappings.
|
|
16
|
+
* @returns The resolved model name (original or redirected).
|
|
17
|
+
* @throws {NeuroLinkError} When the alias action is "block".
|
|
18
|
+
*/
|
|
19
|
+
export function resolveModel(model, config) {
|
|
20
|
+
if (!model || !config?.aliases) {
|
|
21
|
+
return model;
|
|
22
|
+
}
|
|
23
|
+
const alias = config.aliases[model];
|
|
24
|
+
if (!alias) {
|
|
25
|
+
return model;
|
|
26
|
+
}
|
|
27
|
+
switch (alias.action) {
|
|
28
|
+
case "block":
|
|
29
|
+
throw new NeuroLinkError({
|
|
30
|
+
code: "MODEL_DEPRECATED",
|
|
31
|
+
message: `Model '${model}' is blocked. ${alias.reason || `Use '${alias.target}' instead.`}`,
|
|
32
|
+
category: ErrorCategory.VALIDATION,
|
|
33
|
+
severity: ErrorSeverity.HIGH,
|
|
34
|
+
retriable: false,
|
|
35
|
+
context: {
|
|
36
|
+
requestedModel: model,
|
|
37
|
+
suggestedModel: alias.target,
|
|
38
|
+
reason: alias.reason,
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
case "warn":
|
|
42
|
+
logger.warn(`[ModelAlias] Model '${model}' is deprecated. ${alias.reason || `Redirecting to '${alias.target}'.`}`, {
|
|
43
|
+
requestedModel: model,
|
|
44
|
+
targetModel: alias.target,
|
|
45
|
+
reason: alias.reason,
|
|
46
|
+
});
|
|
47
|
+
return alias.target;
|
|
48
|
+
case "redirect":
|
|
49
|
+
logger.debug(`[ModelAlias] Redirecting model '${model}' to '${alias.target}'`);
|
|
50
|
+
return alias.target;
|
|
51
|
+
default:
|
|
52
|
+
return model;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*
|
|
8
8
|
* The conversion uses pdf-to-img package (MuPDF-based) for high-quality conversion.
|
|
9
9
|
*/
|
|
10
|
-
import type { FileProcessingResult,
|
|
10
|
+
import type { FileProcessingResult, PDFProcessorOptions, PDFProviderConfig } from "../types/fileTypes.js";
|
|
11
11
|
/**
|
|
12
12
|
* Options for PDF to image conversion
|
|
13
13
|
*/
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
* The conversion uses pdf-to-img package (MuPDF-based) for high-quality conversion.
|
|
9
9
|
*/
|
|
10
10
|
import { PDF_LIMITS } from "../core/constants.js";
|
|
11
|
-
import { logger } from "./logger.js";
|
|
12
11
|
import { ErrorFactory } from "./errorHandling.js";
|
|
12
|
+
import { logger } from "./logger.js";
|
|
13
13
|
/**
|
|
14
14
|
* Provider configurations for PDF handling
|
|
15
15
|
*
|
|
@@ -98,7 +98,7 @@ const PDF_PROVIDER_CONFIGS = {
|
|
|
98
98
|
"openai-compatible": {
|
|
99
99
|
maxSizeMB: 10,
|
|
100
100
|
maxPages: 100,
|
|
101
|
-
supportsNative:
|
|
101
|
+
supportsNative: false, // LiteLLM is a proxy — underlying model may not support native PDF; default to safe text extraction
|
|
102
102
|
requiresCitations: false,
|
|
103
103
|
apiType: "files-api",
|
|
104
104
|
},
|
|
@@ -133,7 +133,7 @@ export class PDFProcessor {
|
|
|
133
133
|
static async process(content, options) {
|
|
134
134
|
const provider = (options?.provider || "unknown").toLowerCase();
|
|
135
135
|
const config = PDF_PROVIDER_CONFIGS[provider];
|
|
136
|
-
if (!
|
|
136
|
+
if (!PDFProcessor.isValidPDF(content)) {
|
|
137
137
|
throw new Error("Invalid PDF file format. File must start with %PDF- header.");
|
|
138
138
|
}
|
|
139
139
|
if (!config) {
|
|
@@ -149,7 +149,7 @@ export class PDFProcessor {
|
|
|
149
149
|
if (sizeMB > config.maxSizeMB) {
|
|
150
150
|
throw new Error(`PDF size ${sizeMB.toFixed(2)}MB exceeds ${config.maxSizeMB}MB limit for ${provider}`);
|
|
151
151
|
}
|
|
152
|
-
const metadata =
|
|
152
|
+
const metadata = PDFProcessor.extractBasicMetadata(content);
|
|
153
153
|
if (metadata.estimatedPages && metadata.estimatedPages > config.maxPages) {
|
|
154
154
|
const enforceLimits = options?.enforceLimits !== false;
|
|
155
155
|
if (enforceLimits) {
|
|
@@ -205,7 +205,7 @@ export class PDFProcessor {
|
|
|
205
205
|
if (buffer.length < 5) {
|
|
206
206
|
return false;
|
|
207
207
|
}
|
|
208
|
-
return buffer.subarray(0, 5).equals(
|
|
208
|
+
return buffer.subarray(0, 5).equals(PDFProcessor.PDF_SIGNATURE);
|
|
209
209
|
}
|
|
210
210
|
static extractBasicMetadata(buffer) {
|
|
211
211
|
const headerSize = Math.min(10000, buffer.length);
|
|
@@ -274,7 +274,7 @@ export class PDFProcessor {
|
|
|
274
274
|
"A valid PDF must be at least 5 bytes (PDF header).");
|
|
275
275
|
}
|
|
276
276
|
// 2. Validate PDF magic bytes (%PDF-)
|
|
277
|
-
if (!
|
|
277
|
+
if (!PDFProcessor.isValidPDF(pdfBuffer)) {
|
|
278
278
|
throw new Error("Invalid PDF: File must start with %PDF- header. " +
|
|
279
279
|
"The provided buffer does not appear to be a valid PDF file.");
|
|
280
280
|
}
|
|
@@ -354,7 +354,7 @@ export class PDFProcessor {
|
|
|
354
354
|
static async convertFromPath(pdfPath, options) {
|
|
355
355
|
const fs = await import("fs/promises");
|
|
356
356
|
const pdfBuffer = await fs.readFile(pdfPath);
|
|
357
|
-
return
|
|
357
|
+
return PDFProcessor.convertToImages(pdfBuffer, options);
|
|
358
358
|
}
|
|
359
359
|
/**
|
|
360
360
|
* Check if PDF to image conversion is available
|
|
@@ -24,6 +24,14 @@ export declare function shouldAllowCustomTools(toolConfig?: ToolConfig): boolean
|
|
|
24
24
|
* @returns true if MCP tools should be enabled
|
|
25
25
|
*/
|
|
26
26
|
export declare function shouldEnableMCPTools(toolConfig?: ToolConfig): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Check if the bash command execution tool should be enabled.
|
|
29
|
+
* This is opt-in only (defaults to false) for security reasons.
|
|
30
|
+
*
|
|
31
|
+
* @param toolConfig - Optional tool configuration (if available from config)
|
|
32
|
+
* @returns true if the bash tool should be enabled
|
|
33
|
+
*/
|
|
34
|
+
export declare function shouldEnableBashTool(toolConfig?: ToolConfig): boolean;
|
|
27
35
|
/**
|
|
28
36
|
* Get maximum tools per provider
|
|
29
37
|
* @param toolConfig - Optional tool configuration
|
package/dist/utils/toolUtils.js
CHANGED
|
@@ -40,6 +40,21 @@ export function shouldEnableMCPTools(toolConfig) {
|
|
|
40
40
|
}
|
|
41
41
|
return process.env.NEUROLINK_DISABLE_MCP_TOOLS !== "true";
|
|
42
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Check if the bash command execution tool should be enabled.
|
|
45
|
+
* This is opt-in only (defaults to false) for security reasons.
|
|
46
|
+
*
|
|
47
|
+
* @param toolConfig - Optional tool configuration (if available from config)
|
|
48
|
+
* @returns true if the bash tool should be enabled
|
|
49
|
+
*/
|
|
50
|
+
export function shouldEnableBashTool(toolConfig) {
|
|
51
|
+
// Priority: explicit config > environment variable > default (false)
|
|
52
|
+
if (toolConfig?.enableBashTool !== undefined) {
|
|
53
|
+
return toolConfig.enableBashTool;
|
|
54
|
+
}
|
|
55
|
+
// Single source of truth for environment variable access
|
|
56
|
+
return process.env.NEUROLINK_ENABLE_BASH_TOOL === "true";
|
|
57
|
+
}
|
|
43
58
|
/**
|
|
44
59
|
* Get maximum tools per provider
|
|
45
60
|
* @param toolConfig - Optional tool configuration
|