Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@
"adm-zip": "^0.5.16",
"ai": "4.3.19",
"chalk": "^5.6.2",
"croner": "^10.0.1",
"csv-parser": "^3.2.0",
"dotenv": "^16.6.1",
"exceljs": "^4.4.0",
Expand Down Expand Up @@ -237,21 +238,21 @@
"@opentelemetry/sdk-trace-node": "^2.0.0"
},
"optionalDependencies": {
"@fastify/cors": "^11.2.0",
"@fastify/rate-limit": "^10.3.0",
"@hono/node-server": "^1.13.0",
"@koa/cors": "^5.0.0",
"@koa/router": "^15.3.0",
"canvas": "^3.2.0",
"cors": "^2.8.5",
"express": "^5.1.0",
"express-rate-limit": "^7.4.0",
"fastify": "^5.7.2",
"ffmpeg-static": "^5.3.0",
"ffprobe-static": "^3.1.0",
"sharp": "^0.34.5",
"@fastify/rate-limit": "^10.3.0",
"fastify": "^5.7.2",
"@fastify/cors": "^11.2.0",
"@koa/cors": "^5.0.0",
"@koa/router": "^15.3.0",
"koa": "^3.1.1",
"koa-bodyparser": "^4.4.1",
"express": "^5.1.0",
"cors": "^2.8.5"
"sharp": "^0.34.5"
},
"devDependencies": {
"@actions/core": "^2.0.2",
Expand Down
49 changes: 47 additions & 2 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions src/lib/agent/directTools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import * as path from "path";
import { logger } from "../utils/logger.js";
import { VertexAI } from "@google-cloud/vertexai";
import { CSVProcessor } from "../utils/csvProcessor.js";
import { shouldDisableCronTools } from "../utils/toolUtils.js";
import { createCronTools } from "../cron/cronTools.js";
import type { CronManager } from "../cron/cronManager.js";

// Runtime Google Search tool creation - bypasses TypeScript strict typing
function createGoogleSearchTools() {
Expand Down Expand Up @@ -896,3 +899,21 @@ export function validateToolStructure(): boolean {
return false;
}
}

// --- Cron Tools Integration ---

/**
* Get cron tools bound to a specific CronManager getter.
* Returns empty object if disabled via env var.
*
* @param getCronManager - Function that returns the CronManager instance
* from the owning NeuroLink instance. This avoids module-global state
* and supports multiple NeuroLink instances correctly.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function getCronTools(getCronManager?: () => CronManager | undefined): Record<string, any> {
if (shouldDisableCronTools()) {
return {};
}
return createCronTools(getCronManager ?? (() => undefined));
}
18 changes: 13 additions & 5 deletions src/lib/core/baseProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import type { CoreMessage, LanguageModelV1, Tool } from "ai";
import { SpanKind, SpanStatusCode } from "@opentelemetry/api";
import { tracers } from "../telemetry/tracers.js";
import { directAgentTools } from "../agent/directTools.js";
import { directAgentTools, getCronTools } from "../agent/directTools.js";
import type { AIProviderName } from "../constants/enums.js";
import { IMAGE_GENERATION_MODELS } from "../core/constants.js";
import type { EvaluationData } from "../index.js";
Expand Down Expand Up @@ -59,10 +59,10 @@
protected readonly defaultTimeout: number = 30000; // 30 seconds
protected middlewareOptions?: MiddlewareFactoryOptions; // TODO: Implement global level middlewares that can be used

// Tools are conditionally included based on centralized configuration
protected readonly directTools = shouldDisableBuiltinTools()
? {}
: directAgentTools;
// Tools are conditionally included based on centralized configuration.
// Cron tools are merged in the constructor after this.neurolink is assigned,
// binding to the correct NeuroLink instance (avoids module-global state).
protected directTools: Record<string, unknown> = {};
protected mcpTools?: Record<string, Tool>; // MCP tools loaded dynamically when available
protected customTools?: Map<string, unknown>; // Custom tools from registerTool()
protected toolExecutor?: (
Expand Down Expand Up @@ -92,6 +92,14 @@
this.neurolink = neurolink;
this.middlewareOptions = middleware;

// Initialize direct tools (built-in + cron) bound to this instance's NeuroLink
if (!shouldDisableBuiltinTools()) {
const cronTools = getCronTools(
() => this.neurolink?.getCronManager?.(),
);
this.directTools = { ...directAgentTools, ...cronTools };
}

// Initialize composition modules
this.messageBuilder = new MessageBuilder(this.providerName, this.modelName);
this.streamHandler = new StreamHandler(this.providerName, this.modelName);
Expand Down Expand Up @@ -674,14 +682,14 @@
* IMPLEMENTATION NOTE: Uses streamText() under the hood and accumulates results
* for consistency and better performance
*/
async generate(

Check warning on line 685 in src/lib/core/baseProvider.ts

View workflow job for this annotation

GitHub Actions / 🛡️ Code Quality & Security Gate

Async method 'generate' has too many lines (317). Maximum allowed is 300
optionsOrPrompt: TextGenerationOptions | string,
_analysisSchema?: ValidationSchema,
): Promise<EnhancedGenerateResult | null> {
return providerTracer.startActiveSpan(
"neurolink.provider.generate",
{ kind: SpanKind.INTERNAL },
async (span) => {

Check warning on line 692 in src/lib/core/baseProvider.ts

View workflow job for this annotation

GitHub Actions / 🛡️ Code Quality & Security Gate

Async arrow function has too many lines (308). Maximum allowed is 300
const options = this.normalizeTextOptions(optionsOrPrompt);
this.validateOptions(options);
const startTime = Date.now();
Expand Down
Loading
Loading