@juspay/neurolink 9.40.0 → 9.42.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/README.md +7 -1
- package/dist/auth/anthropicOAuth.d.ts +18 -3
- package/dist/auth/anthropicOAuth.js +137 -4
- package/dist/auth/providers/firebase.js +5 -1
- package/dist/auth/providers/jwt.js +5 -1
- package/dist/auth/providers/workos.js +5 -1
- package/dist/auth/sessionManager.d.ts +1 -1
- package/dist/auth/sessionManager.js +58 -27
- package/dist/browser/neurolink.min.js +471 -445
- package/dist/cli/commands/mcp.js +3 -0
- package/dist/cli/commands/proxy.d.ts +2 -1
- package/dist/cli/commands/proxy.js +279 -16
- package/dist/cli/commands/task.d.ts +56 -0
- package/dist/cli/commands/task.js +838 -0
- package/dist/cli/factories/commandFactory.d.ts +2 -0
- package/dist/cli/factories/commandFactory.js +38 -0
- package/dist/cli/parser.js +8 -4
- package/dist/client/aiSdkAdapter.js +3 -0
- package/dist/client/streamingClient.js +30 -10
- package/dist/core/modules/GenerationHandler.js +3 -2
- package/dist/core/redisConversationMemoryManager.js +7 -3
- package/dist/evaluation/BatchEvaluator.js +4 -1
- package/dist/evaluation/hooks/observabilityHooks.js +5 -3
- package/dist/evaluation/pipeline/evaluationPipeline.d.ts +3 -2
- package/dist/evaluation/pipeline/evaluationPipeline.js +20 -8
- package/dist/evaluation/pipeline/strategies/batchStrategy.js +6 -3
- package/dist/evaluation/pipeline/strategies/samplingStrategy.js +18 -10
- package/dist/lib/auth/anthropicOAuth.d.ts +18 -3
- package/dist/lib/auth/anthropicOAuth.js +137 -4
- package/dist/lib/auth/providers/firebase.js +5 -1
- package/dist/lib/auth/providers/jwt.js +5 -1
- package/dist/lib/auth/providers/workos.js +5 -1
- package/dist/lib/auth/sessionManager.d.ts +1 -1
- package/dist/lib/auth/sessionManager.js +58 -27
- package/dist/lib/client/aiSdkAdapter.js +3 -0
- package/dist/lib/client/streamingClient.js +30 -10
- package/dist/lib/core/modules/GenerationHandler.js +3 -2
- package/dist/lib/core/redisConversationMemoryManager.js +7 -3
- package/dist/lib/evaluation/BatchEvaluator.js +4 -1
- package/dist/lib/evaluation/hooks/observabilityHooks.js +5 -3
- package/dist/lib/evaluation/pipeline/evaluationPipeline.d.ts +3 -2
- package/dist/lib/evaluation/pipeline/evaluationPipeline.js +20 -8
- package/dist/lib/evaluation/pipeline/strategies/batchStrategy.js +6 -3
- package/dist/lib/evaluation/pipeline/strategies/samplingStrategy.js +18 -10
- package/dist/lib/neurolink.d.ts +18 -1
- package/dist/lib/neurolink.js +367 -484
- package/dist/lib/observability/otelBridge.d.ts +2 -2
- package/dist/lib/observability/otelBridge.js +12 -3
- package/dist/lib/providers/amazonBedrock.js +2 -4
- package/dist/lib/providers/anthropic.d.ts +9 -5
- package/dist/lib/providers/anthropic.js +19 -14
- package/dist/lib/providers/anthropicBaseProvider.d.ts +3 -3
- package/dist/lib/providers/anthropicBaseProvider.js +5 -4
- package/dist/lib/providers/azureOpenai.d.ts +1 -1
- package/dist/lib/providers/azureOpenai.js +5 -4
- package/dist/lib/providers/googleAiStudio.js +30 -1
- package/dist/lib/providers/googleVertex.js +28 -6
- package/dist/lib/providers/huggingFace.d.ts +3 -3
- package/dist/lib/providers/huggingFace.js +6 -8
- package/dist/lib/providers/litellm.js +41 -29
- package/dist/lib/providers/mistral.js +2 -1
- package/dist/lib/providers/ollama.js +80 -23
- package/dist/lib/providers/openAI.js +3 -2
- package/dist/lib/providers/openRouter.js +2 -1
- package/dist/lib/providers/openaiCompatible.d.ts +4 -4
- package/dist/lib/providers/openaiCompatible.js +4 -4
- package/dist/lib/proxy/claudeFormat.d.ts +3 -2
- package/dist/lib/proxy/claudeFormat.js +25 -20
- package/dist/lib/proxy/cloaking/plugins/sessionIdentity.d.ts +2 -6
- package/dist/lib/proxy/cloaking/plugins/sessionIdentity.js +9 -33
- package/dist/lib/proxy/modelRouter.js +3 -0
- package/dist/lib/proxy/oauthFetch.d.ts +1 -1
- package/dist/lib/proxy/oauthFetch.js +65 -72
- package/dist/lib/proxy/proxyConfig.js +44 -24
- package/dist/lib/proxy/proxyEnv.d.ts +19 -0
- package/dist/lib/proxy/proxyEnv.js +73 -0
- package/dist/lib/proxy/proxyFetch.js +50 -4
- package/dist/lib/proxy/proxyTracer.d.ts +133 -0
- package/dist/lib/proxy/proxyTracer.js +645 -0
- package/dist/lib/proxy/rawStreamCapture.d.ts +10 -0
- package/dist/lib/proxy/rawStreamCapture.js +83 -0
- package/dist/lib/proxy/requestLogger.d.ts +32 -5
- package/dist/lib/proxy/requestLogger.js +406 -37
- package/dist/lib/proxy/sseInterceptor.d.ts +97 -0
- package/dist/lib/proxy/sseInterceptor.js +402 -0
- package/dist/lib/proxy/usageStats.d.ts +4 -3
- package/dist/lib/proxy/usageStats.js +25 -12
- package/dist/lib/rag/chunkers/MarkdownChunker.js +13 -5
- package/dist/lib/rag/chunking/markdownChunker.js +15 -6
- package/dist/lib/server/routes/claudeProxyRoutes.d.ts +7 -2
- package/dist/lib/server/routes/claudeProxyRoutes.js +1737 -508
- package/dist/lib/services/server/ai/observability/instrumentation.d.ts +7 -1
- package/dist/lib/services/server/ai/observability/instrumentation.js +240 -40
- package/dist/lib/tasks/backends/bullmqBackend.d.ts +33 -0
- package/dist/lib/tasks/backends/bullmqBackend.js +196 -0
- package/dist/lib/tasks/backends/nodeTimeoutBackend.d.ts +27 -0
- package/dist/lib/tasks/backends/nodeTimeoutBackend.js +141 -0
- package/dist/lib/tasks/backends/taskBackendRegistry.d.ts +31 -0
- package/dist/lib/tasks/backends/taskBackendRegistry.js +66 -0
- package/dist/lib/tasks/errors.d.ts +31 -0
- package/dist/lib/tasks/errors.js +18 -0
- package/dist/lib/tasks/store/fileTaskStore.d.ts +43 -0
- package/dist/lib/tasks/store/fileTaskStore.js +179 -0
- package/dist/lib/tasks/store/redisTaskStore.d.ts +43 -0
- package/dist/lib/tasks/store/redisTaskStore.js +197 -0
- package/dist/lib/tasks/taskExecutor.d.ts +21 -0
- package/dist/lib/tasks/taskExecutor.js +166 -0
- package/dist/lib/tasks/taskManager.d.ts +63 -0
- package/dist/lib/tasks/taskManager.js +426 -0
- package/dist/lib/tasks/tools/taskTools.d.ts +135 -0
- package/dist/lib/tasks/tools/taskTools.js +274 -0
- package/dist/lib/telemetry/index.d.ts +2 -1
- package/dist/lib/telemetry/index.js +2 -1
- package/dist/lib/telemetry/telemetryService.d.ts +3 -0
- package/dist/lib/telemetry/telemetryService.js +65 -5
- package/dist/lib/types/cli.d.ts +10 -0
- package/dist/lib/types/configTypes.d.ts +3 -0
- package/dist/lib/types/generateTypes.d.ts +13 -0
- package/dist/lib/types/index.d.ts +1 -0
- package/dist/lib/types/proxyTypes.d.ts +37 -5
- package/dist/lib/types/streamTypes.d.ts +25 -3
- package/dist/lib/types/taskTypes.d.ts +275 -0
- package/dist/lib/types/taskTypes.js +37 -0
- package/dist/lib/utils/messageBuilder.js +3 -2
- package/dist/lib/utils/providerHealth.d.ts +18 -0
- package/dist/lib/utils/providerHealth.js +240 -9
- package/dist/lib/utils/providerUtils.js +14 -8
- package/dist/lib/utils/toolChoice.d.ts +4 -0
- package/dist/lib/utils/toolChoice.js +7 -0
- package/dist/neurolink.d.ts +18 -1
- package/dist/neurolink.js +367 -484
- package/dist/observability/otelBridge.d.ts +2 -2
- package/dist/observability/otelBridge.js +12 -3
- package/dist/providers/amazonBedrock.js +2 -4
- package/dist/providers/anthropic.d.ts +9 -5
- package/dist/providers/anthropic.js +19 -14
- package/dist/providers/anthropicBaseProvider.d.ts +3 -3
- package/dist/providers/anthropicBaseProvider.js +5 -4
- package/dist/providers/azureOpenai.d.ts +1 -1
- package/dist/providers/azureOpenai.js +5 -4
- package/dist/providers/googleAiStudio.js +30 -1
- package/dist/providers/googleVertex.js +28 -6
- package/dist/providers/huggingFace.d.ts +3 -3
- package/dist/providers/huggingFace.js +6 -7
- package/dist/providers/litellm.js +41 -29
- package/dist/providers/mistral.js +2 -1
- package/dist/providers/ollama.js +80 -23
- package/dist/providers/openAI.js +3 -2
- package/dist/providers/openRouter.js +2 -1
- package/dist/providers/openaiCompatible.d.ts +4 -4
- package/dist/providers/openaiCompatible.js +4 -3
- package/dist/proxy/claudeFormat.d.ts +3 -2
- package/dist/proxy/claudeFormat.js +25 -20
- package/dist/proxy/cloaking/plugins/sessionIdentity.d.ts +2 -6
- package/dist/proxy/cloaking/plugins/sessionIdentity.js +9 -33
- package/dist/proxy/modelRouter.js +3 -0
- package/dist/proxy/oauthFetch.d.ts +1 -1
- package/dist/proxy/oauthFetch.js +65 -72
- package/dist/proxy/proxyConfig.js +44 -24
- package/dist/proxy/proxyEnv.d.ts +19 -0
- package/dist/proxy/proxyEnv.js +72 -0
- package/dist/proxy/proxyFetch.js +50 -4
- package/dist/proxy/proxyTracer.d.ts +133 -0
- package/dist/proxy/proxyTracer.js +644 -0
- package/dist/proxy/rawStreamCapture.d.ts +10 -0
- package/dist/proxy/rawStreamCapture.js +82 -0
- package/dist/proxy/requestLogger.d.ts +32 -5
- package/dist/proxy/requestLogger.js +406 -37
- package/dist/proxy/sseInterceptor.d.ts +97 -0
- package/dist/proxy/sseInterceptor.js +401 -0
- package/dist/proxy/usageStats.d.ts +4 -3
- package/dist/proxy/usageStats.js +25 -12
- package/dist/rag/chunkers/MarkdownChunker.js +13 -5
- package/dist/rag/chunking/markdownChunker.js +15 -6
- package/dist/server/routes/claudeProxyRoutes.d.ts +7 -2
- package/dist/server/routes/claudeProxyRoutes.js +1737 -508
- package/dist/services/server/ai/observability/instrumentation.d.ts +7 -1
- package/dist/services/server/ai/observability/instrumentation.js +240 -40
- package/dist/tasks/backends/bullmqBackend.d.ts +33 -0
- package/dist/tasks/backends/bullmqBackend.js +195 -0
- package/dist/tasks/backends/nodeTimeoutBackend.d.ts +27 -0
- package/dist/tasks/backends/nodeTimeoutBackend.js +140 -0
- package/dist/tasks/backends/taskBackendRegistry.d.ts +31 -0
- package/dist/tasks/backends/taskBackendRegistry.js +65 -0
- package/dist/tasks/errors.d.ts +31 -0
- package/dist/tasks/errors.js +17 -0
- package/dist/tasks/store/fileTaskStore.d.ts +43 -0
- package/dist/tasks/store/fileTaskStore.js +178 -0
- package/dist/tasks/store/redisTaskStore.d.ts +43 -0
- package/dist/tasks/store/redisTaskStore.js +196 -0
- package/dist/tasks/taskExecutor.d.ts +21 -0
- package/dist/tasks/taskExecutor.js +165 -0
- package/dist/tasks/taskManager.d.ts +63 -0
- package/dist/tasks/taskManager.js +425 -0
- package/dist/tasks/tools/taskTools.d.ts +135 -0
- package/dist/tasks/tools/taskTools.js +273 -0
- package/dist/telemetry/index.d.ts +2 -1
- package/dist/telemetry/index.js +2 -1
- package/dist/telemetry/telemetryService.d.ts +3 -0
- package/dist/telemetry/telemetryService.js +65 -5
- package/dist/types/cli.d.ts +10 -0
- package/dist/types/configTypes.d.ts +3 -0
- package/dist/types/generateTypes.d.ts +13 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/proxyTypes.d.ts +37 -5
- package/dist/types/streamTypes.d.ts +25 -3
- package/dist/types/taskTypes.d.ts +275 -0
- package/dist/types/taskTypes.js +36 -0
- package/dist/utils/messageBuilder.js +3 -2
- package/dist/utils/providerHealth.d.ts +18 -0
- package/dist/utils/providerHealth.js +240 -9
- package/dist/utils/providerUtils.js +14 -8
- package/dist/utils/toolChoice.d.ts +4 -0
- package/dist/utils/toolChoice.js +6 -0
- package/docs/assets/dashboards/neurolink-proxy-observability-dashboard.json +6609 -0
- package/docs/changelog.md +252 -0
- package/package.json +19 -1
- package/scripts/observability/check-proxy-telemetry.mjs +235 -0
- package/scripts/observability/docker-compose.proxy-observability.yaml +55 -0
- package/scripts/observability/import-openobserve-dashboard.mjs +240 -0
- package/scripts/observability/manage-local-openobserve.sh +184 -0
- package/scripts/observability/otel-collector.proxy-observability.yaml +78 -0
- package/scripts/observability/proxy-observability.env.example +23 -0
package/dist/cli/commands/mcp.js
CHANGED
|
@@ -565,6 +565,7 @@ export class MCPCommandFactory {
|
|
|
565
565
|
? null
|
|
566
566
|
: ora("Testing MCP server connections...").start();
|
|
567
567
|
const sdk = new NeuroLink();
|
|
568
|
+
await sdk.getMCPStatus();
|
|
568
569
|
let serversToTest = await sdk.listMCPServers();
|
|
569
570
|
if (targetServer) {
|
|
570
571
|
serversToTest = serversToTest.filter((s) => s.name === targetServer);
|
|
@@ -654,6 +655,7 @@ export class MCPCommandFactory {
|
|
|
654
655
|
}
|
|
655
656
|
}
|
|
656
657
|
const sdk = new NeuroLink();
|
|
658
|
+
await sdk.getMCPStatus();
|
|
657
659
|
// Check if server exists and is connected
|
|
658
660
|
const allServers = await sdk.listMCPServers();
|
|
659
661
|
const server = allServers.find((s) => s.name === serverName);
|
|
@@ -762,6 +764,7 @@ export class MCPCommandFactory {
|
|
|
762
764
|
process.exit(1);
|
|
763
765
|
}
|
|
764
766
|
const sdk = new NeuroLink();
|
|
767
|
+
await sdk.getMCPStatus();
|
|
765
768
|
const allServers = await sdk.listMCPServers();
|
|
766
769
|
const server = allServers.find((s) => s.name === serverName);
|
|
767
770
|
if (!server) {
|
|
@@ -10,10 +10,11 @@
|
|
|
10
10
|
* (generate/stream), with an optional ModelRouter for model remapping.
|
|
11
11
|
*/
|
|
12
12
|
import type { CommandModule } from "yargs";
|
|
13
|
-
import type { ProxyStartArgs, ProxyStatusArgs, ProxyGuardArgs } from "../../lib/types/index.js";
|
|
13
|
+
import type { ProxyStartArgs, ProxyStatusArgs, ProxyGuardArgs, ProxyTelemetryArgs } from "../../lib/types/index.js";
|
|
14
14
|
export declare function mapClaudeErrorTypeToStatus(errorType?: string): number;
|
|
15
15
|
export declare const proxyStartCommand: CommandModule<object, ProxyStartArgs>;
|
|
16
16
|
export declare const proxyStatusCommand: CommandModule<object, ProxyStatusArgs>;
|
|
17
|
+
export declare const proxyTelemetryCommand: CommandModule<object, ProxyTelemetryArgs>;
|
|
17
18
|
export declare const proxyGuardCommand: CommandModule<object, ProxyGuardArgs>;
|
|
18
19
|
export declare const proxySetupCommand: CommandModule;
|
|
19
20
|
export declare const proxyInstallCommand: CommandModule;
|
|
@@ -16,9 +16,12 @@ import chalk from "chalk";
|
|
|
16
16
|
import ora from "ora";
|
|
17
17
|
import { logger } from "../../lib/utils/logger.js";
|
|
18
18
|
import { formatUptime, isProcessRunning, StateFileManager, } from "../utils/serverUtils.js";
|
|
19
|
+
import { loadProxyEnvFile, resolveProxyEnvFile, } from "../../lib/proxy/proxyEnv.js";
|
|
19
20
|
import { createRequire } from "node:module";
|
|
21
|
+
import { fileURLToPath } from "node:url";
|
|
20
22
|
const _require = createRequire(import.meta.url);
|
|
21
23
|
const { version: PROXY_VERSION } = _require("../../../package.json");
|
|
24
|
+
const PROXY_TELEMETRY_SCRIPT_PATH = fileURLToPath(new URL("../../../scripts/observability/manage-local-openobserve.sh", import.meta.url));
|
|
22
25
|
// =============================================================================
|
|
23
26
|
// STATE MANAGEMENT
|
|
24
27
|
// =============================================================================
|
|
@@ -220,6 +223,32 @@ function spawnFailOpenGuard(host, port, parentPid) {
|
|
|
220
223
|
return undefined;
|
|
221
224
|
}
|
|
222
225
|
}
|
|
226
|
+
async function runProxyTelemetryManager(command) {
|
|
227
|
+
const { existsSync } = await import("fs");
|
|
228
|
+
if (!existsSync(PROXY_TELEMETRY_SCRIPT_PATH)) {
|
|
229
|
+
throw new Error("Proxy telemetry helper files were not found in this installation. Reinstall NeuroLink with observability assets included.");
|
|
230
|
+
}
|
|
231
|
+
await new Promise((resolve, reject) => {
|
|
232
|
+
const child = spawn("bash", [PROXY_TELEMETRY_SCRIPT_PATH, command], {
|
|
233
|
+
stdio: "inherit",
|
|
234
|
+
env: process.env,
|
|
235
|
+
});
|
|
236
|
+
child.on("error", (error) => {
|
|
237
|
+
reject(error);
|
|
238
|
+
});
|
|
239
|
+
child.on("exit", (code, signal) => {
|
|
240
|
+
if (signal) {
|
|
241
|
+
reject(new Error(`proxy telemetry ${command} terminated by signal ${signal}`));
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
if (code !== 0) {
|
|
245
|
+
reject(new Error(`proxy telemetry ${command} exited with code ${code ?? 1}`));
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
resolve();
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
}
|
|
223
252
|
// =============================================================================
|
|
224
253
|
// STARTUP BANNER
|
|
225
254
|
// =============================================================================
|
|
@@ -313,6 +342,16 @@ export const proxyStartCommand = {
|
|
|
313
342
|
alias: "c",
|
|
314
343
|
description: "Path to proxy config file (YAML/JSON)",
|
|
315
344
|
defaultDescription: "~/.neurolink/proxy-config.yaml",
|
|
345
|
+
})
|
|
346
|
+
.option("env-file", {
|
|
347
|
+
type: "string",
|
|
348
|
+
alias: "envFile",
|
|
349
|
+
description: "Path to proxy provider env file (overrides cwd .env for the proxy process)",
|
|
350
|
+
})
|
|
351
|
+
.option("passthrough", {
|
|
352
|
+
type: "boolean",
|
|
353
|
+
default: false,
|
|
354
|
+
description: "Run in transparent passthrough mode (no retry, no rotation, no polyfill)",
|
|
316
355
|
})
|
|
317
356
|
.example("neurolink proxy start", "Start proxy on default port 55669 with fill-first strategy")
|
|
318
357
|
.example("neurolink proxy start -p 8080 -s fill-first", "Start proxy on port 8080 with fill-first")
|
|
@@ -357,6 +396,22 @@ export const proxyStartCommand = {
|
|
|
357
396
|
// -----------------------------------------------------------------
|
|
358
397
|
// 1. Create NeuroLink instance — reads all env vars automatically
|
|
359
398
|
// -----------------------------------------------------------------
|
|
399
|
+
let loadedEnvFile;
|
|
400
|
+
try {
|
|
401
|
+
const envResult = await loadProxyEnvFile({
|
|
402
|
+
explicitEnvFile: argv.envFile,
|
|
403
|
+
});
|
|
404
|
+
loadedEnvFile = envResult.path;
|
|
405
|
+
if (spinner && loadedEnvFile) {
|
|
406
|
+
spinner.text = `Loaded proxy env from ${loadedEnvFile}`;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
catch (envError) {
|
|
410
|
+
if (spinner) {
|
|
411
|
+
spinner.fail(chalk.red(envError instanceof Error ? envError.message : String(envError)));
|
|
412
|
+
}
|
|
413
|
+
process.exit(1);
|
|
414
|
+
}
|
|
360
415
|
// Skip MCP initialization for proxy — tools come from Claude Code, not MCP servers
|
|
361
416
|
process.env.NEUROLINK_SKIP_MCP = "true";
|
|
362
417
|
const { NeuroLink } = await import("../../lib/neurolink.js");
|
|
@@ -433,15 +488,24 @@ export const proxyStartCommand = {
|
|
|
433
488
|
},
|
|
434
489
|
}, 502);
|
|
435
490
|
});
|
|
436
|
-
const
|
|
491
|
+
const passthrough = argv.passthrough ?? false;
|
|
492
|
+
const routeGroup = createClaudeProxyRoutes(modelRouter, "", strategy, passthrough);
|
|
437
493
|
// Register proxy routes — inject NeuroLink into ServerContext
|
|
438
494
|
for (const route of routeGroup.routes) {
|
|
439
495
|
const method = route.method.toLowerCase();
|
|
440
496
|
app[method](route.path, async (c) => {
|
|
441
497
|
const emptyBody = {};
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
498
|
+
let body;
|
|
499
|
+
let rawBody;
|
|
500
|
+
if (method === "post") {
|
|
501
|
+
rawBody = await c.req.text().catch(() => undefined);
|
|
502
|
+
try {
|
|
503
|
+
body = rawBody ? JSON.parse(rawBody) : emptyBody;
|
|
504
|
+
}
|
|
505
|
+
catch {
|
|
506
|
+
body = emptyBody;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
445
509
|
// Log incoming request
|
|
446
510
|
const model = body?.model ?? "-";
|
|
447
511
|
const stream = body?.stream
|
|
@@ -461,6 +525,7 @@ export const proxyStartCommand = {
|
|
|
461
525
|
query: Object.fromEntries(new URL(c.req.url).searchParams.entries()),
|
|
462
526
|
params: c.req.param(),
|
|
463
527
|
body,
|
|
528
|
+
rawBody, // Preserve original bytes for passthrough mode
|
|
464
529
|
neurolink, // NeuroLink instance for generate/stream
|
|
465
530
|
toolRegistry: neurolink.getToolRegistry(),
|
|
466
531
|
timestamp: Date.now(),
|
|
@@ -564,6 +629,7 @@ export const proxyStartCommand = {
|
|
|
564
629
|
uptime: process.uptime(),
|
|
565
630
|
version: PROXY_VERSION,
|
|
566
631
|
stats: {
|
|
632
|
+
totalAttempts: stats.totalAttempts,
|
|
567
633
|
totalRequests: stats.totalRequests,
|
|
568
634
|
totalSuccess: stats.totalSuccess,
|
|
569
635
|
totalErrors: stats.totalErrors,
|
|
@@ -571,7 +637,8 @@ export const proxyStartCommand = {
|
|
|
571
637
|
accounts: Object.values(stats.accounts).map((a) => ({
|
|
572
638
|
label: a.label,
|
|
573
639
|
type: a.type,
|
|
574
|
-
|
|
640
|
+
attempts: a.attemptCount,
|
|
641
|
+
requests: a.attemptCount,
|
|
575
642
|
success: a.successCount,
|
|
576
643
|
errors: a.errorCount,
|
|
577
644
|
rateLimits: a.rateLimitCount,
|
|
@@ -583,7 +650,55 @@ export const proxyStartCommand = {
|
|
|
583
650
|
});
|
|
584
651
|
});
|
|
585
652
|
// -----------------------------------------------------------------
|
|
586
|
-
// 5.
|
|
653
|
+
// 5. Initialize OpenTelemetry for proxy observability
|
|
654
|
+
// -----------------------------------------------------------------
|
|
655
|
+
try {
|
|
656
|
+
const otlpEndpoint = process.env.OTEL_EXPORTER_OTLP_ENDPOINT;
|
|
657
|
+
if (!process.env.OTEL_SERVICE_NAME) {
|
|
658
|
+
process.env.OTEL_SERVICE_NAME = "neurolink-proxy";
|
|
659
|
+
}
|
|
660
|
+
// Merge resource attributes (preserving any existing ones)
|
|
661
|
+
process.env.OTEL_RESOURCE_ATTRIBUTES = [
|
|
662
|
+
`service.name=neurolink-proxy`,
|
|
663
|
+
`service.version=${PROXY_VERSION}`,
|
|
664
|
+
`deployment.environment=local`,
|
|
665
|
+
process.env.OTEL_RESOURCE_ATTRIBUTES,
|
|
666
|
+
]
|
|
667
|
+
.filter(Boolean)
|
|
668
|
+
.join(",");
|
|
669
|
+
const { initializeOpenTelemetry, isOpenTelemetryInitialized } = await import("../../lib/services/server/ai/observability/instrumentation.js");
|
|
670
|
+
const { buildObservabilityConfigFromEnv } = await import("../../lib/utils/observabilityHelpers.js");
|
|
671
|
+
if (!isOpenTelemetryInitialized()) {
|
|
672
|
+
const observabilityConfig = buildObservabilityConfigFromEnv();
|
|
673
|
+
const langfuseConfig = observabilityConfig?.langfuse;
|
|
674
|
+
const langfuseEnabled = langfuseConfig?.enabled === true;
|
|
675
|
+
initializeOpenTelemetry({
|
|
676
|
+
enabled: langfuseEnabled,
|
|
677
|
+
publicKey: langfuseConfig?.publicKey || "",
|
|
678
|
+
secretKey: langfuseConfig?.secretKey || "",
|
|
679
|
+
baseUrl: langfuseConfig?.baseUrl,
|
|
680
|
+
environment: "proxy",
|
|
681
|
+
release: PROXY_VERSION,
|
|
682
|
+
userId: "neurolink-proxy",
|
|
683
|
+
autoDetectOperationName: true,
|
|
684
|
+
});
|
|
685
|
+
if (langfuseEnabled) {
|
|
686
|
+
logger.always(`[proxy] Langfuse enabled — exporting to ${langfuseConfig.baseUrl || "https://cloud.langfuse.com"} (environment=proxy)`);
|
|
687
|
+
}
|
|
688
|
+
if (otlpEndpoint) {
|
|
689
|
+
logger.always(`[proxy] OTLP exporter enabled — exporting to ${otlpEndpoint} (service.name=neurolink-proxy)`);
|
|
690
|
+
}
|
|
691
|
+
if (!langfuseEnabled && !otlpEndpoint) {
|
|
692
|
+
logger.always("[proxy] OpenTelemetry exporters disabled — set OTEL_EXPORTER_OTLP_ENDPOINT or Langfuse credentials to enable proxy observability");
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
catch (otelError) {
|
|
697
|
+
// OTel is non-critical — proxy must still work without it
|
|
698
|
+
logger.debug(`[proxy] OpenTelemetry init failed (non-fatal): ${otelError instanceof Error ? otelError.message : String(otelError)}`);
|
|
699
|
+
}
|
|
700
|
+
// -----------------------------------------------------------------
|
|
701
|
+
// 6. Start listening
|
|
587
702
|
// -----------------------------------------------------------------
|
|
588
703
|
const port = argv.port ?? 55669;
|
|
589
704
|
const host = argv.host ?? "127.0.0.1";
|
|
@@ -608,9 +723,13 @@ export const proxyStartCommand = {
|
|
|
608
723
|
host,
|
|
609
724
|
strategy,
|
|
610
725
|
startTime: new Date().toISOString(),
|
|
726
|
+
envFile: loadedEnvFile,
|
|
611
727
|
fallbackChain,
|
|
612
728
|
guardPid,
|
|
613
|
-
managedBy: "
|
|
729
|
+
managedBy: process.platform === "darwin" && process.ppid === 1
|
|
730
|
+
? "launchd"
|
|
731
|
+
: "manual",
|
|
732
|
+
passthrough,
|
|
614
733
|
};
|
|
615
734
|
saveProxyState(state);
|
|
616
735
|
if (spinner) {
|
|
@@ -619,6 +738,10 @@ export const proxyStartCommand = {
|
|
|
619
738
|
const normalizedHost = host === "0.0.0.0" ? "localhost" : host;
|
|
620
739
|
const url = `http://${normalizedHost}:${port}`;
|
|
621
740
|
printProxyBanner(url, strategy);
|
|
741
|
+
logger.always(` ${chalk.bold("Mode:")} ${chalk.cyan(passthrough ? "passthrough" : "full")}`);
|
|
742
|
+
if (loadedEnvFile) {
|
|
743
|
+
logger.always(` ${chalk.bold("Env File:")} ${chalk.cyan(loadedEnvFile)}`);
|
|
744
|
+
}
|
|
622
745
|
// Auto-configure Claude Code — use the normalized URL (localhost, not 0.0.0.0)
|
|
623
746
|
try {
|
|
624
747
|
await setClaudeProxySettings(url);
|
|
@@ -630,7 +753,7 @@ export const proxyStartCommand = {
|
|
|
630
753
|
(e instanceof Error ? e.message : String(e)));
|
|
631
754
|
}
|
|
632
755
|
// -----------------------------------------------------------------
|
|
633
|
-
//
|
|
756
|
+
// 7. Background token refresh (every 30 seconds)
|
|
634
757
|
// -----------------------------------------------------------------
|
|
635
758
|
const { needsRefresh, refreshToken, persistTokens } = await import("../../lib/proxy/tokenRefresh.js");
|
|
636
759
|
const { tokenStore } = await import("../../lib/auth/tokenStore.js");
|
|
@@ -697,12 +820,21 @@ export const proxyStartCommand = {
|
|
|
697
820
|
cleanupLogs(7, 500);
|
|
698
821
|
}, 60 * 60 * 1000);
|
|
699
822
|
// -----------------------------------------------------------------
|
|
700
|
-
//
|
|
823
|
+
// 8. Graceful shutdown
|
|
701
824
|
// -----------------------------------------------------------------
|
|
702
825
|
const shutdown = async (signal) => {
|
|
703
826
|
clearInterval(refreshInterval);
|
|
704
827
|
clearInterval(logCleanupInterval);
|
|
705
828
|
logger.always(`\nShutting down proxy (${signal})...`);
|
|
829
|
+
// Flush and shutdown OpenTelemetry before closing the server
|
|
830
|
+
try {
|
|
831
|
+
const { flushOpenTelemetry, shutdownOpenTelemetry } = await import("../../lib/services/server/ai/observability/instrumentation.js");
|
|
832
|
+
await flushOpenTelemetry();
|
|
833
|
+
await shutdownOpenTelemetry();
|
|
834
|
+
}
|
|
835
|
+
catch {
|
|
836
|
+
/* non-fatal — proxy shutdown must not block on OTel */
|
|
837
|
+
}
|
|
706
838
|
// Only clear Claude settings on user-initiated stop (SIGINT).
|
|
707
839
|
// On SIGTERM (launchd restart cycle), leave settings intact so
|
|
708
840
|
// the restarted proxy picks up seamlessly.
|
|
@@ -746,7 +878,10 @@ export const proxyStartCommand = {
|
|
|
746
878
|
};
|
|
747
879
|
function printStatusStats(stats) {
|
|
748
880
|
console.info(`\n Stats:`);
|
|
749
|
-
|
|
881
|
+
if (stats.totalAttempts !== undefined) {
|
|
882
|
+
console.info(` Attempts: ${stats.totalAttempts}`);
|
|
883
|
+
}
|
|
884
|
+
console.info(` Completed: ${stats.totalRequests} total, ${stats.totalSuccess} success, ${stats.totalErrors} errors`);
|
|
750
885
|
console.info(` Rate limits: ${stats.totalRateLimits}`);
|
|
751
886
|
if (stats.accounts?.length) {
|
|
752
887
|
console.info(`\n Accounts:`);
|
|
@@ -754,7 +889,11 @@ function printStatusStats(stats) {
|
|
|
754
889
|
const acctStatus = a.cooling
|
|
755
890
|
? chalk.red("cooling")
|
|
756
891
|
: chalk.green("active");
|
|
757
|
-
|
|
892
|
+
const attempts = a.attempts ?? a.requests ?? 0;
|
|
893
|
+
const success = a.success ?? 0;
|
|
894
|
+
const errors = a.errors ?? 0;
|
|
895
|
+
const rateLimits = a.rateLimits ?? 0;
|
|
896
|
+
console.info(` ${a.label.padEnd(20)} ${a.type.padEnd(8)} ${String(attempts).padEnd(6)} attempts ${String(success).padEnd(6)} success ${String(errors).padEnd(6)} errors ${String(rateLimits).padEnd(6)} rl ${acctStatus}`);
|
|
758
897
|
}
|
|
759
898
|
}
|
|
760
899
|
}
|
|
@@ -793,6 +932,7 @@ export const proxyStatusCommand = {
|
|
|
793
932
|
uptime: null,
|
|
794
933
|
startTime: null,
|
|
795
934
|
url: null,
|
|
935
|
+
envFile: null,
|
|
796
936
|
fallbackChain: null,
|
|
797
937
|
};
|
|
798
938
|
if (state && isProcessRunning(state.pid)) {
|
|
@@ -804,10 +944,25 @@ export const proxyStatusCommand = {
|
|
|
804
944
|
status.startTime = state.startTime;
|
|
805
945
|
status.uptime = Date.now() - new Date(state.startTime).getTime();
|
|
806
946
|
status.url = `http://${state.host === "0.0.0.0" ? "localhost" : state.host}:${state.port}`;
|
|
947
|
+
status.envFile = state.envFile ?? null;
|
|
807
948
|
status.fallbackChain = state.fallbackChain ?? null;
|
|
808
949
|
}
|
|
950
|
+
// Fetch live stats before rendering (JSON or text)
|
|
951
|
+
let liveStats = null;
|
|
952
|
+
if (status.running && status.url) {
|
|
953
|
+
try {
|
|
954
|
+
const statusResp = await fetch(`${status.url}/status`);
|
|
955
|
+
if (statusResp.ok) {
|
|
956
|
+
const statusData = (await statusResp.json());
|
|
957
|
+
liveStats = statusData.stats;
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
catch {
|
|
961
|
+
// Non-fatal — live stats unavailable
|
|
962
|
+
}
|
|
963
|
+
}
|
|
809
964
|
if (argv.format === "json") {
|
|
810
|
-
logger.always(JSON.stringify(status, null, 2));
|
|
965
|
+
logger.always(JSON.stringify({ ...status, stats: liveStats }, null, 2));
|
|
811
966
|
return;
|
|
812
967
|
}
|
|
813
968
|
// Text format
|
|
@@ -822,6 +977,9 @@ export const proxyStatusCommand = {
|
|
|
822
977
|
logger.always(` ${chalk.bold("Strategy:")} ${chalk.cyan(status.strategy)}`);
|
|
823
978
|
logger.always(` ${chalk.bold("Started:")} ${chalk.cyan(status.startTime)}`);
|
|
824
979
|
logger.always(` ${chalk.bold("Uptime:")} ${chalk.cyan(formatUptime(status.uptime ?? 0))}`);
|
|
980
|
+
if (status.envFile) {
|
|
981
|
+
logger.always(` ${chalk.bold("Env File:")} ${chalk.cyan(status.envFile)}`);
|
|
982
|
+
}
|
|
825
983
|
// Display fallback chain if configured
|
|
826
984
|
if (status.fallbackChain && status.fallbackChain.length > 0) {
|
|
827
985
|
logger.always("");
|
|
@@ -875,6 +1033,58 @@ export const proxyStatusCommand = {
|
|
|
875
1033
|
},
|
|
876
1034
|
};
|
|
877
1035
|
// =============================================================================
|
|
1036
|
+
// PROXY TELEMETRY COMMAND
|
|
1037
|
+
// =============================================================================
|
|
1038
|
+
const PROXY_TELEMETRY_ACTIONS = [
|
|
1039
|
+
"setup",
|
|
1040
|
+
"start",
|
|
1041
|
+
"stop",
|
|
1042
|
+
"status",
|
|
1043
|
+
"logs",
|
|
1044
|
+
"import-dashboard",
|
|
1045
|
+
];
|
|
1046
|
+
export const proxyTelemetryCommand = {
|
|
1047
|
+
command: "telemetry <action>",
|
|
1048
|
+
describe: "Manage the local OpenObserve stack and dashboard for proxy observability",
|
|
1049
|
+
builder: (yargs) => yargs
|
|
1050
|
+
.positional("action", {
|
|
1051
|
+
type: "string",
|
|
1052
|
+
choices: [...PROXY_TELEMETRY_ACTIONS],
|
|
1053
|
+
describe: "Telemetry action: setup, start, stop, status, logs, or import-dashboard",
|
|
1054
|
+
})
|
|
1055
|
+
.option("quiet", {
|
|
1056
|
+
type: "boolean",
|
|
1057
|
+
alias: "q",
|
|
1058
|
+
default: false,
|
|
1059
|
+
description: "Suppress the local CLI spinner and delegate directly",
|
|
1060
|
+
})
|
|
1061
|
+
.example("neurolink proxy telemetry setup", "Start OpenObserve, start the OTEL collector, and import the dashboard")
|
|
1062
|
+
.example("neurolink proxy telemetry start", "Start the local proxy telemetry stack without re-importing the dashboard")
|
|
1063
|
+
.example("neurolink proxy telemetry stop", "Stop the local OpenObserve and OTEL collector containers"),
|
|
1064
|
+
handler: async (argv) => {
|
|
1065
|
+
const action = argv.action;
|
|
1066
|
+
const spinner = argv.quiet
|
|
1067
|
+
? null
|
|
1068
|
+
: ora(`Running proxy telemetry ${action}...`).start();
|
|
1069
|
+
try {
|
|
1070
|
+
if (spinner) {
|
|
1071
|
+
spinner.stop();
|
|
1072
|
+
}
|
|
1073
|
+
await runProxyTelemetryManager(action);
|
|
1074
|
+
if (spinner) {
|
|
1075
|
+
spinner.succeed(`proxy telemetry ${action} completed`);
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
catch (error) {
|
|
1079
|
+
if (spinner) {
|
|
1080
|
+
spinner.fail(`proxy telemetry ${action} failed`);
|
|
1081
|
+
}
|
|
1082
|
+
logger.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
|
|
1083
|
+
process.exit(1);
|
|
1084
|
+
}
|
|
1085
|
+
},
|
|
1086
|
+
};
|
|
1087
|
+
// =============================================================================
|
|
878
1088
|
// PROXY FAIL-OPEN GUARD COMMAND (HIDDEN)
|
|
879
1089
|
// =============================================================================
|
|
880
1090
|
export const proxyGuardCommand = {
|
|
@@ -1152,6 +1362,11 @@ export const proxySetupCommand = {
|
|
|
1152
1362
|
type: "boolean",
|
|
1153
1363
|
default: false,
|
|
1154
1364
|
description: "Skip service installation and start proxy in foreground instead",
|
|
1365
|
+
})
|
|
1366
|
+
.option("env-file", {
|
|
1367
|
+
type: "string",
|
|
1368
|
+
alias: "envFile",
|
|
1369
|
+
description: "Path to proxy provider env file to persist for the proxy",
|
|
1155
1370
|
})
|
|
1156
1371
|
.example("neurolink proxy setup", "Full setup with defaults")
|
|
1157
1372
|
.example("neurolink proxy setup -p 9000", "Setup on custom port")
|
|
@@ -1253,9 +1468,27 @@ export const proxySetupCommand = {
|
|
|
1253
1468
|
// =============================================================================
|
|
1254
1469
|
// PROXY INSTALL / UNINSTALL — launchd service (macOS)
|
|
1255
1470
|
// =============================================================================
|
|
1256
|
-
function
|
|
1257
|
-
|
|
1258
|
-
|
|
1471
|
+
function escapeXml(s) {
|
|
1472
|
+
return s
|
|
1473
|
+
.replace(/&/g, "&")
|
|
1474
|
+
.replace(/</g, "<")
|
|
1475
|
+
.replace(/>/g, ">")
|
|
1476
|
+
.replace(/"/g, """)
|
|
1477
|
+
.replace(/'/g, "'");
|
|
1478
|
+
}
|
|
1479
|
+
function buildPlist(port, host, envFile, configFile) {
|
|
1480
|
+
const nodeExec = escapeXml(process.execPath);
|
|
1481
|
+
const entryScript = escapeXml(process.argv[1] ?? join(__dirname, "..", "index.js"));
|
|
1482
|
+
const envFileArgs = envFile
|
|
1483
|
+
? `
|
|
1484
|
+
<string>--env-file</string>
|
|
1485
|
+
<string>${escapeXml(envFile)}</string>`
|
|
1486
|
+
: "";
|
|
1487
|
+
const configArgs = configFile
|
|
1488
|
+
? `
|
|
1489
|
+
<string>--config</string>
|
|
1490
|
+
<string>${escapeXml(configFile)}</string>`
|
|
1491
|
+
: "";
|
|
1259
1492
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
1260
1493
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
|
|
1261
1494
|
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
@@ -1274,6 +1507,8 @@ function buildPlist(port, host) {
|
|
|
1274
1507
|
<string>${port}</string>
|
|
1275
1508
|
<string>--host</string>
|
|
1276
1509
|
<string>${host}</string>
|
|
1510
|
+
${envFileArgs}
|
|
1511
|
+
${configArgs}
|
|
1277
1512
|
<string>--quiet</string>
|
|
1278
1513
|
</array>
|
|
1279
1514
|
|
|
@@ -1320,6 +1555,15 @@ export const proxyInstallCommand = {
|
|
|
1320
1555
|
type: "string",
|
|
1321
1556
|
default: "127.0.0.1",
|
|
1322
1557
|
description: "Proxy host",
|
|
1558
|
+
})
|
|
1559
|
+
.option("env-file", {
|
|
1560
|
+
type: "string",
|
|
1561
|
+
alias: "envFile",
|
|
1562
|
+
description: "Path to proxy provider env file to persist for the service",
|
|
1563
|
+
})
|
|
1564
|
+
.option("config", {
|
|
1565
|
+
type: "string",
|
|
1566
|
+
description: "Path to proxy routing config file to persist for the service",
|
|
1323
1567
|
})
|
|
1324
1568
|
.example("neurolink proxy install", "Install with defaults (port 55669)")
|
|
1325
1569
|
.example("neurolink proxy install -p 9000", "Install on custom port");
|
|
@@ -1333,6 +1577,21 @@ export const proxyInstallCommand = {
|
|
|
1333
1577
|
process.exit(1);
|
|
1334
1578
|
}
|
|
1335
1579
|
const { writeFileSync, mkdirSync, existsSync } = await import("fs");
|
|
1580
|
+
const envResolution = resolveProxyEnvFile({
|
|
1581
|
+
explicitEnvFile: argv.envFile,
|
|
1582
|
+
});
|
|
1583
|
+
const envFile = envResolution.path;
|
|
1584
|
+
const explicitConfig = argv.config;
|
|
1585
|
+
const configPath = explicitConfig ?? join(homedir(), ".neurolink", "proxy-config.yaml");
|
|
1586
|
+
if (explicitConfig && !existsSync(configPath)) {
|
|
1587
|
+
console.info(chalk.red(`Proxy config file not found: ${configPath}`));
|
|
1588
|
+
process.exit(1);
|
|
1589
|
+
}
|
|
1590
|
+
const configFile = existsSync(configPath) ? configPath : undefined;
|
|
1591
|
+
if (envFile && !existsSync(envFile)) {
|
|
1592
|
+
console.info(chalk.red(`Proxy env file not found: ${envFile}`));
|
|
1593
|
+
process.exit(1);
|
|
1594
|
+
}
|
|
1336
1595
|
const logsDir = join(homedir(), ".neurolink", "logs");
|
|
1337
1596
|
if (!existsSync(logsDir)) {
|
|
1338
1597
|
mkdirSync(logsDir, { recursive: true });
|
|
@@ -1340,9 +1599,12 @@ export const proxyInstallCommand = {
|
|
|
1340
1599
|
if (!existsSync(PLIST_DIR)) {
|
|
1341
1600
|
mkdirSync(PLIST_DIR, { recursive: true });
|
|
1342
1601
|
}
|
|
1343
|
-
const plist = buildPlist(port, host);
|
|
1602
|
+
const plist = buildPlist(port, host, envFile, configFile);
|
|
1344
1603
|
writeFileSync(PLIST_PATH, plist, "utf-8");
|
|
1345
1604
|
console.info(chalk.green(`✓ Plist written to ${PLIST_PATH}`));
|
|
1605
|
+
if (envFile) {
|
|
1606
|
+
console.info(chalk.green(`✓ Proxy env file: ${envFile}`));
|
|
1607
|
+
}
|
|
1346
1608
|
try {
|
|
1347
1609
|
const { execFileSync } = await import("node:child_process");
|
|
1348
1610
|
execFileSync("launchctl", ["unload", PLIST_PATH], {
|
|
@@ -1375,6 +1637,7 @@ export const proxyInstallCommand = {
|
|
|
1375
1637
|
host,
|
|
1376
1638
|
strategy: "fill-first",
|
|
1377
1639
|
startTime: new Date().toISOString(),
|
|
1640
|
+
envFile,
|
|
1378
1641
|
managedBy: "launchd",
|
|
1379
1642
|
});
|
|
1380
1643
|
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task CLI Commands for NeuroLink
|
|
3
|
+
*
|
|
4
|
+
* Implements commands for task scheduling and management:
|
|
5
|
+
* - neurolink task create — Create a scheduled task (pure store write, exits immediately)
|
|
6
|
+
* - neurolink task list — List all tasks
|
|
7
|
+
* - neurolink task get — Show task details
|
|
8
|
+
* - neurolink task run — Run a task immediately
|
|
9
|
+
* - neurolink task pause — Pause a task
|
|
10
|
+
* - neurolink task resume — Resume a paused task
|
|
11
|
+
* - neurolink task update — Update a task
|
|
12
|
+
* - neurolink task delete — Delete a task
|
|
13
|
+
* - neurolink task logs — View run history
|
|
14
|
+
* - neurolink task start — Start worker (keeps process alive for scheduled tasks)
|
|
15
|
+
* - neurolink task stop — Stop a running daemon worker
|
|
16
|
+
* - neurolink task status — Show worker status
|
|
17
|
+
*/
|
|
18
|
+
import type { CommandModule } from "yargs";
|
|
19
|
+
export declare class TaskCommandFactory {
|
|
20
|
+
static createTaskCommands(): CommandModule;
|
|
21
|
+
/**
|
|
22
|
+
* Get a full NeuroLink instance (with MCP, tools, providers).
|
|
23
|
+
* Used only by commands that execute AI: run, start/_worker.
|
|
24
|
+
*/
|
|
25
|
+
private static getNeuroLink;
|
|
26
|
+
/**
|
|
27
|
+
* Get a direct TaskStore instance for pure store operations.
|
|
28
|
+
* Bypasses NeuroLink entirely — no MCP, no providers, no tools.
|
|
29
|
+
* Respects the same backend selection as TaskManager so both paths
|
|
30
|
+
* read/write the same store (Redis for bullmq, file for node-timeout).
|
|
31
|
+
*
|
|
32
|
+
* Used by all management commands: create, list, get, delete, logs, pause, resume, update.
|
|
33
|
+
*/
|
|
34
|
+
private static getStore;
|
|
35
|
+
/** Attach event listeners and keep the process alive for scheduled task execution */
|
|
36
|
+
private static enterWorkerMode;
|
|
37
|
+
/**
|
|
38
|
+
* Create — pure store write, no NeuroLink needed.
|
|
39
|
+
* Builds the Task object directly, saves to the task store, exits immediately.
|
|
40
|
+
*/
|
|
41
|
+
private static executeCreate;
|
|
42
|
+
private static executeList;
|
|
43
|
+
private static executeGet;
|
|
44
|
+
private static executeRun;
|
|
45
|
+
private static executePause;
|
|
46
|
+
private static executeResume;
|
|
47
|
+
private static executeUpdate;
|
|
48
|
+
private static executeDelete;
|
|
49
|
+
private static executeLogs;
|
|
50
|
+
private static executeStart;
|
|
51
|
+
private static executeStop;
|
|
52
|
+
private static executeStatus;
|
|
53
|
+
private static spawnDaemon;
|
|
54
|
+
private static runForegroundWorker;
|
|
55
|
+
private static executeWorkerProcess;
|
|
56
|
+
}
|