@juspay/neurolink 13.8.17 → 13.8.18

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.
Files changed (192) hide show
  1. package/CHANGELOG.md +2 -2
  2. package/README.md +1 -1
  3. package/dist/action/actionExecutor.d.ts +33 -3
  4. package/dist/action/actionExecutor.js +71 -15
  5. package/dist/action/actionInputs.js +4 -1
  6. package/dist/action/cliVersion.d.ts +25 -0
  7. package/dist/action/cliVersion.js +26 -0
  8. package/dist/action/index.d.ts +2 -1
  9. package/dist/action/index.js +2 -1
  10. package/dist/adapters/video/directorPipeline.js +46 -36
  11. package/dist/adapters/video/ffmpegAdapter.d.ts +17 -0
  12. package/dist/adapters/video/ffmpegAdapter.js +32 -5
  13. package/dist/adapters/video/frameExtractor.js +1 -1
  14. package/dist/adapters/video/videoMerger.js +5 -2
  15. package/dist/agent/arithmeticEvaluator.d.ts +32 -0
  16. package/dist/agent/arithmeticEvaluator.js +349 -0
  17. package/dist/agent/directTools.d.ts +6 -18
  18. package/dist/agent/directTools.js +17 -56
  19. package/dist/artifacts/artifactStore.d.ts +22 -1
  20. package/dist/artifacts/artifactStore.js +66 -6
  21. package/dist/auth/anthropicOAuth.d.ts +26 -1
  22. package/dist/auth/anthropicOAuth.js +81 -5
  23. package/dist/auth/secureFiles.d.ts +37 -0
  24. package/dist/auth/secureFiles.js +95 -0
  25. package/dist/auth/tokenStore.d.ts +43 -6
  26. package/dist/auth/tokenStore.js +260 -79
  27. package/dist/avatar/providers/DIDAvatar.js +49 -45
  28. package/dist/avatar/providers/ReplicateAvatar.js +33 -40
  29. package/dist/browser/neurolink.min.js +485 -558
  30. package/dist/cli/commands/auth.js +112 -70
  31. package/dist/cli/commands/proxy.d.ts +4 -0
  32. package/dist/cli/commands/proxy.js +128 -13
  33. package/dist/cli/commands/serve.d.ts +10 -1
  34. package/dist/cli/commands/serve.js +98 -17
  35. package/dist/cli/commands/server.js +17 -5
  36. package/dist/cli/index.js +146 -5
  37. package/dist/cli/loop/optionsSchema.d.ts +1 -1
  38. package/dist/cli/utils/envManager.js +17 -3
  39. package/dist/cli/utils/serverUtils.d.ts +39 -3
  40. package/dist/cli/utils/serverUtils.js +63 -6
  41. package/dist/core/baseProvider.js +7 -1
  42. package/dist/core/modules/MessageBuilder.js +5 -0
  43. package/dist/core/modules/ToolsManager.d.ts +46 -1
  44. package/dist/core/modules/ToolsManager.js +190 -43
  45. package/dist/files/fileReferenceRegistry.d.ts +2 -23
  46. package/dist/files/fileReferenceRegistry.js +55 -5
  47. package/dist/hitl/hitlManager.js +1 -0
  48. package/dist/index.d.ts +2 -1
  49. package/dist/index.js +6 -1
  50. package/dist/mcp/auth/tokenStorage.d.ts +7 -0
  51. package/dist/mcp/auth/tokenStorage.js +23 -4
  52. package/dist/mcp/externalServerManager.d.ts +13 -3
  53. package/dist/mcp/externalServerManager.js +154 -136
  54. package/dist/mcp/index.d.ts +2 -0
  55. package/dist/mcp/index.js +3 -0
  56. package/dist/mcp/mcpClientFactory.d.ts +14 -0
  57. package/dist/mcp/mcpClientFactory.js +70 -7
  58. package/dist/mcp/projectConfigTrust.d.ts +72 -0
  59. package/dist/mcp/projectConfigTrust.js +237 -0
  60. package/dist/mcp/transportUrlPolicy.d.ts +39 -0
  61. package/dist/mcp/transportUrlPolicy.js +172 -0
  62. package/dist/music/providers/BeatovenMusic.js +35 -46
  63. package/dist/music/providers/ReplicateMusic.js +33 -40
  64. package/dist/neurolink.d.ts +16 -1
  65. package/dist/neurolink.js +64 -11
  66. package/dist/processors/archive/ArchiveProcessor.js +15 -1
  67. package/dist/processors/archive/zipEntryIndex.d.ts +22 -0
  68. package/dist/processors/archive/zipEntryIndex.js +33 -0
  69. package/dist/processors/base/BaseFileProcessor.d.ts +9 -21
  70. package/dist/processors/base/BaseFileProcessor.js +40 -111
  71. package/dist/processors/data/YamlProcessor.d.ts +13 -1
  72. package/dist/processors/data/YamlProcessor.js +93 -2
  73. package/dist/processors/document/OpenDocumentProcessor.js +7 -2
  74. package/dist/processors/document/PptxProcessor.js +12 -7
  75. package/dist/processors/media/VideoProcessor.js +93 -15
  76. package/dist/proxy/inboundAuth.d.ts +89 -0
  77. package/dist/proxy/inboundAuth.js +219 -0
  78. package/dist/proxy/tokenRefresh.d.ts +6 -0
  79. package/dist/proxy/tokenRefresh.js +13 -1
  80. package/dist/proxy/updateState.js +4 -4
  81. package/dist/rag/document/loaders.d.ts +0 -6
  82. package/dist/rag/document/loaders.js +16 -10
  83. package/dist/rag/ragIntegration.d.ts +2 -2
  84. package/dist/rag/ragIntegration.js +35 -10
  85. package/dist/rag/retrieval/vectorQueryTool.d.ts +7 -0
  86. package/dist/rag/retrieval/vectorQueryTool.js +54 -17
  87. package/dist/server/abstract/baseServerAdapter.d.ts +43 -0
  88. package/dist/server/abstract/baseServerAdapter.js +119 -6
  89. package/dist/server/adapters/expressAdapter.d.ts +3 -0
  90. package/dist/server/adapters/expressAdapter.js +78 -6
  91. package/dist/server/adapters/fastifyAdapter.d.ts +3 -0
  92. package/dist/server/adapters/fastifyAdapter.js +165 -70
  93. package/dist/server/adapters/honoAdapter.d.ts +9 -1
  94. package/dist/server/adapters/honoAdapter.js +99 -21
  95. package/dist/server/adapters/koaAdapter.d.ts +1 -0
  96. package/dist/server/adapters/koaAdapter.js +153 -74
  97. package/dist/server/index.d.ts +2 -0
  98. package/dist/server/index.js +4 -0
  99. package/dist/server/middleware/auth.js +6 -2
  100. package/dist/server/middleware/cache.js +6 -1
  101. package/dist/server/middleware/rateLimit.js +29 -4
  102. package/dist/server/routes/agentRoutes.js +24 -11
  103. package/dist/server/routes/claudeProxyRoutes.d.ts +1 -0
  104. package/dist/server/routes/claudeProxyRoutes.js +273 -84
  105. package/dist/server/routes/codexProxyRoutes.d.ts +2 -2
  106. package/dist/server/routes/codexProxyRoutes.js +125 -40
  107. package/dist/server/routes/index.d.ts +4 -0
  108. package/dist/server/routes/index.js +35 -4
  109. package/dist/server/routes/mcpRoutes.d.ts +6 -2
  110. package/dist/server/routes/mcpRoutes.js +21 -7
  111. package/dist/server/routes/memoryRoutes.js +7 -6
  112. package/dist/server/routes/toolRoutes.d.ts +12 -2
  113. package/dist/server/routes/toolRoutes.js +33 -3
  114. package/dist/server/routes/transcribeRoutes.js +60 -13
  115. package/dist/server/utils/clientAddress.d.ts +23 -0
  116. package/dist/server/utils/clientAddress.js +65 -0
  117. package/dist/server/utils/clientError.d.ts +35 -0
  118. package/dist/server/utils/clientError.js +129 -0
  119. package/dist/server/utils/pathMatch.d.ts +21 -0
  120. package/dist/server/utils/pathMatch.js +41 -0
  121. package/dist/server/utils/validation.d.ts +9 -0
  122. package/dist/server/utils/validation.js +9 -0
  123. package/dist/server/websocket/WebSocketHandler.js +22 -3
  124. package/dist/server/websocket/frameQueue.d.ts +19 -0
  125. package/dist/server/websocket/frameQueue.js +41 -3
  126. package/dist/server/websocket/transcribeWebSocket.d.ts +8 -1
  127. package/dist/server/websocket/transcribeWebSocket.js +223 -34
  128. package/dist/skills/skillStores.js +5 -0
  129. package/dist/tasks/store/fileTaskStore.d.ts +2 -0
  130. package/dist/tasks/store/fileTaskStore.js +11 -4
  131. package/dist/types/attachments.d.ts +117 -0
  132. package/dist/types/attachments.js +15 -0
  133. package/dist/types/auth.d.ts +6 -0
  134. package/dist/types/cli.d.ts +4 -0
  135. package/dist/types/config.d.ts +56 -0
  136. package/dist/types/file.d.ts +8 -0
  137. package/dist/types/hitl.d.ts +8 -0
  138. package/dist/types/index.d.ts +1 -0
  139. package/dist/types/index.js +1 -0
  140. package/dist/types/mcp.d.ts +98 -0
  141. package/dist/types/multimodal.js +0 -41
  142. package/dist/types/processor.d.ts +14 -1
  143. package/dist/types/proxy.d.ts +62 -3
  144. package/dist/types/rag.d.ts +9 -0
  145. package/dist/types/safeFetch.d.ts +40 -0
  146. package/dist/types/server.d.ts +206 -10
  147. package/dist/types/tools.d.ts +57 -0
  148. package/dist/types/transcribe.d.ts +6 -0
  149. package/dist/utils/attachmentPolicy.d.ts +89 -0
  150. package/dist/utils/attachmentPolicy.js +327 -0
  151. package/dist/utils/dotenvBootstrap.d.ts +48 -19
  152. package/dist/utils/dotenvBootstrap.js +172 -31
  153. package/dist/utils/fileDetector.js +115 -65
  154. package/dist/utils/json/coerce.js +11 -1
  155. package/dist/utils/logSanitize.d.ts +5 -0
  156. package/dist/utils/logSanitize.js +8 -0
  157. package/dist/utils/logger.js +73 -1
  158. package/dist/utils/messageBuilder.d.ts +2 -2
  159. package/dist/utils/messageBuilder.js +118 -105
  160. package/dist/utils/multimodalOptionsBuilder.d.ts +1 -0
  161. package/dist/utils/multimodalOptionsBuilder.js +2 -0
  162. package/dist/utils/redis.d.ts +12 -0
  163. package/dist/utils/redis.js +72 -0
  164. package/dist/utils/safeFetch.d.ts +22 -1
  165. package/dist/utils/safeFetch.js +132 -38
  166. package/dist/utils/safeStoreId.d.ts +19 -0
  167. package/dist/utils/safeStoreId.js +29 -0
  168. package/dist/utils/schemaConversion.d.ts +30 -3
  169. package/dist/utils/schemaConversion.js +457 -84
  170. package/dist/utils/sizeGuard.js +2 -2
  171. package/dist/utils/ssrfGuard.d.ts +3 -3
  172. package/dist/utils/ssrfGuard.js +71 -39
  173. package/dist/voice/eval/sttEvalStore.d.ts +26 -3
  174. package/dist/voice/eval/sttEvalStore.js +77 -12
  175. package/dist/voice/livekit/agentDefinition.d.ts +18 -0
  176. package/dist/voice/livekit/agentDefinition.js +22 -0
  177. package/dist/voice/livekit/realtimeMcpTools.d.ts +1 -1
  178. package/dist/voice/livekit/realtimeMcpTools.js +8 -7
  179. package/dist/voice/livekit/realtimeVoiceAgent.d.ts +2 -4
  180. package/dist/voice/livekit/realtimeVoiceAgent.js +18 -7
  181. package/dist/voice/livekit/voiceAgent.d.ts +2 -2
  182. package/dist/voice/livekit/voiceAgent.js +2 -1
  183. package/dist/voice/livekit/xaiSessionWatch.d.ts +0 -5
  184. package/dist/voice/livekit/xaiSessionWatch.js +30 -0
  185. package/dist/voice/providers/GeminiLive.js +21 -6
  186. package/dist/voice/providers/GoogleSTT.js +8 -5
  187. package/dist/voice/transcribe.d.ts +2 -2
  188. package/dist/voice/transcribe.js +34 -18
  189. package/dist/voice/whistle/audio.js +11 -5
  190. package/docs-site/static/search-index.json +71 -49
  191. package/package.json +171 -156
  192. package/scripts/observability/import-openobserve-dashboard.mjs +11 -3
@@ -9,7 +9,7 @@ import type { MCPToolRegistry } from "../mcp/toolRegistry.js";
9
9
  import type { NeuroLink } from "../neurolink.js";
10
10
  import type { JsonObject, JsonValue } from "./common.js";
11
11
  import type { ExternalMCPServerStatus } from "./externalMcp.js";
12
- import type { ProxyRuntimeConfigProvider } from "./proxy.js";
12
+ import type { ProxyInboundAuthOptions, ProxyRuntimeConfigProvider } from "./proxy.js";
13
13
  import type { TTSAudioFormat } from "./tts.js";
14
14
  import type { STTCorrectionOptions, STTDecisionRecord, STTDictionaryEntry, STTEngineInfo, STTFallbackOptions, STTOutputOptions, STTOutputRendering, STTRoutingOptions, STTStreamingOptions, TranscribeTimings } from "./transcribe.js";
15
15
  /**
@@ -18,7 +18,12 @@ import type { STTCorrectionOptions, STTDecisionRecord, STTDictionaryEntry, STTEn
18
18
  export type ServerAdapterConfig = {
19
19
  /** Server port (default: 3000) */
20
20
  port?: number;
21
- /** Server host (default: "0.0.0.0") */
21
+ /**
22
+ * Interface to bind (default: `"127.0.0.1"`, loopback only). Pass
23
+ * `"0.0.0.0"` or `"::"` to listen on every interface; a server reachable from
24
+ * the network should register authentication middleware first, since the
25
+ * tool, MCP and memory routes act on this host.
26
+ */
22
27
  host?: string;
23
28
  /** Base path for all routes (default: "/api") */
24
29
  basePath?: string;
@@ -140,10 +145,33 @@ export type RateLimitConfig = {
140
145
  maxRequests?: number;
141
146
  /** Custom error message */
142
147
  message?: string;
143
- /** Skip rate limiting for certain paths */
148
+ /**
149
+ * Skip rate limiting for certain paths. An entry matches the path itself and
150
+ * everything under it at a segment boundary: `/api/health` matches
151
+ * `/api/health` and `/api/health/live`, never `/api/healthz`.
152
+ */
144
153
  skipPaths?: string[];
145
- /** Custom key generator function */
154
+ /**
155
+ * Custom key generator function. Without one, requests are counted per
156
+ * client address: the TCP peer, or, with `trustProxy`, the client address a
157
+ * trusted reverse proxy reports in `X-Forwarded-For`.
158
+ */
146
159
  keyGenerator?: (ctx: ServerContext) => string;
160
+ /**
161
+ * Read the client address from `X-Forwarded-For` (default: `false`). Off,
162
+ * the header is ignored and every request is counted against the TCP peer,
163
+ * so a client cannot pick its own bucket by sending the header. Turn it on
164
+ * only behind a reverse proxy that overwrites or appends to the header.
165
+ */
166
+ trustProxy?: boolean;
167
+ /**
168
+ * Addresses of the reverse proxies in front of this server, consulted with
169
+ * `trustProxy`. Hops listed here are skipped from the right of
170
+ * `X-Forwarded-For`, so the key is the last hop no trusted proxy added, i.e.
171
+ * the client the outermost trusted proxy saw. Empty (the default) takes the
172
+ * rightmost entry, the one the nearest proxy appended.
173
+ */
174
+ trustedProxies?: string[];
147
175
  };
148
176
  /**
149
177
  * Required rate limit configuration
@@ -155,6 +183,8 @@ export type RequiredRateLimitConfig = {
155
183
  message: string;
156
184
  skipPaths?: string[];
157
185
  keyGenerator?: (ctx: ServerContext) => string;
186
+ trustProxy: boolean;
187
+ trustedProxies: string[];
158
188
  };
159
189
  /**
160
190
  * Body parser configuration
@@ -311,6 +341,12 @@ export type ServerContext = {
311
341
  params: Record<string, string>;
312
342
  /** Request body (parsed) */
313
343
  body?: unknown;
344
+ /**
345
+ * The TCP peer's address, as the runtime reports it (`undefined` when the
346
+ * runtime does not expose it). Never read from a header, so a client cannot
347
+ * choose it; the rate limiters key on it.
348
+ */
349
+ remoteAddress?: string;
314
350
  /** NeuroLink SDK instance */
315
351
  neurolink: NeuroLink;
316
352
  /** Tool registry instance */
@@ -454,10 +490,22 @@ export type MiddlewareDefinition = {
454
490
  order?: number;
455
491
  /** Middleware handler */
456
492
  handler: MiddlewareHandler;
457
- /** Paths to apply middleware to (default: all) */
493
+ /**
494
+ * Paths to apply middleware to (default: all). An entry matches the path
495
+ * itself and everything under it at a segment boundary (`/api/agent` matches
496
+ * `/api/agent/execute`, never `/api/agents`).
497
+ */
458
498
  paths?: string[];
459
- /** Paths to exclude from middleware */
499
+ /** Paths to exclude from middleware, matched the same way as `paths`. */
460
500
  excludePaths?: string[];
501
+ /**
502
+ * `true` when this middleware authenticates requests (sets `ctx.user` or
503
+ * refuses). `createAuthMiddleware` and `createBearerAuthMiddleware` set it.
504
+ * The adapter's `hasAuthenticationMiddleware()` reads it, and so the tool
505
+ * and MCP execution routes decide whether the server is open to anyone who
506
+ * can reach it. Set it on your own authentication middleware.
507
+ */
508
+ authenticates?: boolean;
461
509
  };
462
510
  /**
463
511
  * Middleware handler function
@@ -1301,6 +1349,14 @@ export type CreateRoutesOptions = {
1301
1349
  codexProxy?: boolean;
1302
1350
  /** Enable the Gemini door on its own, for the same reason. */
1303
1351
  geminiProxy?: boolean;
1352
+ /**
1353
+ * Inbound authentication for the Claude and Codex proxy route groups. The
1354
+ * token defaults to `NEUROLINK_PROXY_INBOUND_TOKEN`; `allowUnauthenticated`
1355
+ * falls back to the top-level `allowUnauthenticated`. Mounting a proxy door
1356
+ * with neither logs a loud warning, because anyone who reaches the port can
1357
+ * spend the pooled subscriptions.
1358
+ */
1359
+ proxyAuth?: ProxyInboundAuthOptions;
1304
1360
  /**
1305
1361
  * Runtime config provider for engines that read it (currently: Codex
1306
1362
  * outbound fallback). NOTE: this option alone cannot make the Codex
@@ -1328,6 +1384,31 @@ export type CreateRoutesOptions = {
1328
1384
  * the top-level `perUserAuth`, which is why it is not accepted here.
1329
1385
  */
1330
1386
  agent?: Omit<ServerAgentRouteOptions, "perUserAuth">;
1387
+ /**
1388
+ * `false` leaves the tool routes (`GET/POST <basePath>/tools/*`) out. They
1389
+ * execute whatever the server's registry holds, including the built-in
1390
+ * filesystem tools when those are enabled, so a server that only generates
1391
+ * text has no reason to mount them. Default: mounted.
1392
+ */
1393
+ tools?: boolean;
1394
+ /**
1395
+ * Serve the tool and MCP execution routes to callers the server has not
1396
+ * authenticated. By default those routes answer 403 whenever the server has
1397
+ * no authentication middleware (see `hasAuthentication`), because they run
1398
+ * tools and remove MCP servers on behalf of anyone who can reach the port.
1399
+ * `true` restores the open behaviour for a server that is protected some
1400
+ * other way (a reverse proxy, a private network). The environment variable
1401
+ * `NEUROLINK_SERVER_ALLOW_UNAUTHENTICATED=1` has the same effect.
1402
+ */
1403
+ allowUnauthenticated?: boolean;
1404
+ /**
1405
+ * Tells the tool and MCP execution routes whether the server authenticates
1406
+ * its callers; read on every request. `registerAllRoutes()` supplies one
1407
+ * that asks the adapter for middleware marked `authenticates: true`. With
1408
+ * neither this nor `allowUnauthenticated`, `createAllRoutes()` cannot tell
1409
+ * and leaves those routes open, as before.
1410
+ */
1411
+ hasAuthentication?: () => boolean;
1331
1412
  /**
1332
1413
  * Set to `true` when the authentication middleware identifies individual
1333
1414
  * people (one credential per person). The agent routes then take `userId`
@@ -1365,6 +1446,54 @@ export type CreateRoutesOptions = {
1365
1446
  */
1366
1447
  perUserAuth?: boolean;
1367
1448
  };
1449
+ /**
1450
+ * Options of the route groups that act on the host (tool execution, MCP
1451
+ * server execution and removal). `createAllRoutes` derives them from
1452
+ * `CreateRoutesOptions.allowUnauthenticated` / `hasAuthentication`.
1453
+ */
1454
+ export type ServerSensitiveRouteOptions = {
1455
+ /**
1456
+ * Whether the server authenticates its callers, read on every request. When
1457
+ * it answers `false` the execution routes refuse with 403. Omitted, the
1458
+ * routes cannot tell and stay open.
1459
+ */
1460
+ hasAuthentication?: () => boolean;
1461
+ /** Serve the execution routes to unauthenticated callers regardless. */
1462
+ allowUnauthenticated?: boolean;
1463
+ };
1464
+ /** `neurolink serve` flags that relax its network hardening. */
1465
+ export type ServerServeHardeningArgs = {
1466
+ /**
1467
+ * `--allow-unauthenticated`: listen on a non-loopback host without
1468
+ * `NEUROLINK_SERVER_API_KEY`, and serve the tool and MCP execution routes
1469
+ * to anyone who can reach the port.
1470
+ */
1471
+ allowUnauthenticated?: boolean;
1472
+ /**
1473
+ * `--enable-builtin-tools`: keep NeuroLink's built-in tools (file reads and
1474
+ * writes under the server's working directory among them) in the server's
1475
+ * registry. Off by default, so `/tools/execute` and the agent routes cannot
1476
+ * reach the host's filesystem.
1477
+ */
1478
+ enableBuiltinTools?: boolean;
1479
+ };
1480
+ /** What a route may tell the client about a failure, with the status to send it under. */
1481
+ export type ServerClientFacingError = {
1482
+ code: string;
1483
+ message: string;
1484
+ status: number;
1485
+ };
1486
+ /** What `resolveClientAddress()` needs to name the client of a request. */
1487
+ export type ServerClientAddressInput = {
1488
+ /** The TCP peer, as the runtime reports it. */
1489
+ remoteAddress: string | undefined;
1490
+ /** The request's `X-Forwarded-For` header, if any. */
1491
+ forwardedFor: string | undefined;
1492
+ /** Consult `forwardedFor` at all. */
1493
+ trustProxy: boolean;
1494
+ /** Reverse proxies whose hops are skipped from the right of `forwardedFor`. */
1495
+ trustedProxies: readonly string[];
1496
+ };
1368
1497
  /** Options for `createTranscribeRoutes()`. */
1369
1498
  /**
1370
1499
  * What `GET /agent/transcribe/providers` reports: the engines this server
@@ -1414,7 +1543,10 @@ export type ServerTranscribeRouteOptions = {
1414
1543
  openaiBasePath?: string;
1415
1544
  /**
1416
1545
  * The STT evaluation collector, `POST <openaiBasePath>/v1/evals/stt`.
1417
- * On by default; `false` removes its routes.
1546
+ * Off by default: it stores every transcript a caller posts and lets any
1547
+ * caller read them back. Pass an options object (`{}` for the defaults) to
1548
+ * mount it, or set `NEUROLINK_STT_EVAL_ENABLED=1`; `false` keeps it off
1549
+ * whatever the environment says.
1418
1550
  */
1419
1551
  evals?: ServerSTTEvalOptions | false;
1420
1552
  };
@@ -1429,6 +1561,12 @@ export type ServerSTTEvalOptions = {
1429
1561
  maxCalls?: number;
1430
1562
  /** Segments kept per call; later new ids are counted as `ignored`. Default 50,000. */
1431
1563
  maxSegmentsPerCall?: number;
1564
+ /**
1565
+ * Bytes of segment text and metadata held in memory across every call;
1566
+ * when a batch pushes the total over it the least recently updated calls
1567
+ * are evicted (still on disk when `dir` is set). Default 64 MiB.
1568
+ */
1569
+ maxBytes?: number;
1432
1570
  };
1433
1571
  /** One finalized transcript segment, from the STT people saw or the one run alongside it. */
1434
1572
  export type ServerSTTEvalSegment = {
@@ -1461,6 +1599,10 @@ export type ServerSTTEvalBatchRequest = {
1461
1599
  };
1462
1600
  segments: ServerSTTEvalSegment[];
1463
1601
  };
1602
+ /** One line of a call's JSON-lines file: the batch as sent, plus who sent it when the server knew. */
1603
+ export type ServerSTTEvalStoredBatch = ServerSTTEvalBatchRequest & {
1604
+ owner?: string;
1605
+ };
1464
1606
  /** Answer to `POST /v1/evals/stt`. */
1465
1607
  export type ServerSTTEvalBatchResponse = {
1466
1608
  call_id: string;
@@ -1555,6 +1697,14 @@ export type ServerSTTEvalCallRecord = {
1555
1697
  batches: Set<number>;
1556
1698
  segments: Map<string, ServerSTTEvalSegment>;
1557
1699
  updatedAt: number;
1700
+ /** Approximate bytes the call's segments take in memory; what `maxBytes` budgets. */
1701
+ bytes: number;
1702
+ /**
1703
+ * The authenticated caller that created the call, when the server identified
1704
+ * one; the call is then listed and readable only by that caller. `undefined`
1705
+ * for a call made under no authentication or a shared key.
1706
+ */
1707
+ owner?: string;
1558
1708
  };
1559
1709
  /** Word edit distance between two readings, and the reference's word count. */
1560
1710
  export type ServerSTTEvalAlignment = {
@@ -1652,11 +1802,57 @@ export type ServerTranscribeWebSocketOptions = {
1652
1802
  /** Upgrade path. Default `/v1/audio/transcriptions/stream`. */
1653
1803
  path?: string;
1654
1804
  /**
1655
- * Token(s) required on the upgrade (`Authorization: Bearer` header or
1656
- * `?token=`). `neurolink serve` passes the same keys as its HTTP routes
1657
- * (`NEUROLINK_SERVER_API_KEY`, comma-separated), so one setting guards both.
1805
+ * Token(s) required on the upgrade, as `Authorization: Bearer <token>` or,
1806
+ * for a browser (which cannot set headers), as the subprotocol
1807
+ * `neurolink-api-key.<token>` offered next to `neurolink` in
1808
+ * `Sec-WebSocket-Protocol` (the realtime path also takes OpenAI's
1809
+ * `openai-insecure-api-key.<token>`). `neurolink serve` passes the same keys
1810
+ * as its HTTP routes (`NEUROLINK_SERVER_API_KEY`, comma-separated), so one
1811
+ * setting guards both.
1658
1812
  */
1659
1813
  authToken?: string | readonly string[];
1814
+ /**
1815
+ * Also accept the token as `?token=<token>` in the upgrade URL (default:
1816
+ * `false`). A URL is written to access logs, proxies and `Referer` headers,
1817
+ * so a key carried there leaks; prefer the subprotocol carrier.
1818
+ */
1819
+ allowQueryToken?: boolean;
1820
+ /**
1821
+ * Most sockets open at once across every path this attaches (default 100).
1822
+ * A further upgrade is answered `503 Service Unavailable` before the
1823
+ * handshake, so it costs no transcription engine.
1824
+ */
1825
+ maxConnections?: number;
1826
+ /** Most sockets open at once from one remote address (default 16); the next is answered 503. */
1827
+ maxConnectionsPerAddress?: number;
1828
+ /**
1829
+ * Queued audio bytes per socket above which the socket is paused until the
1830
+ * engine catches up (TCP backpressure; default 8 MiB). Audio beyond
1831
+ * `maxQueuedBytes` (16 MiB live, 512 MiB in file mode) still closes the
1832
+ * socket with 1009.
1833
+ */
1834
+ highWaterMark?: number;
1835
+ /**
1836
+ * Queued audio bytes across every socket of this process (default 512 MiB).
1837
+ * A socket whose frame would push the total past it is closed with 1013
1838
+ * (try again later), so one burst of uploads cannot take the process down.
1839
+ */
1840
+ maxTotalQueuedBytes?: number;
1841
+ /**
1842
+ * Serve `mode: "file"` (whole recordings, buffered up to 512 MiB a socket)
1843
+ * to callers the server has not authenticated while it listens on a
1844
+ * non-loopback address (default: `false`, such a request is refused with
1845
+ * 1008). With `authToken` set, or on a loopback listener, file mode is open.
1846
+ */
1847
+ allowUnauthenticatedFileMode?: boolean;
1848
+ /**
1849
+ * Require a session secret (default: `false`). A speaker that opens a
1850
+ * session may pass `?secret=<value>`; from then on every speaker and
1851
+ * listener joining that `?session=` must present the same secret, or is
1852
+ * refused with 1008. `true` refuses a new session that sets no secret, so
1853
+ * no session can be joined by guessing its id.
1854
+ */
1855
+ requireSessionSecret?: boolean;
1660
1856
  /**
1661
1857
  * Browser origins allowed to upgrade. A browser always sends `Origin` on a
1662
1858
  * WebSocket upgrade, and an upgrade whose `Origin` is not listed is refused
@@ -447,6 +447,63 @@ export type AllToolsMap = {
447
447
  writeFile: Tool;
448
448
  executeBashCommand?: Tool;
449
449
  };
450
+ /**
451
+ * Outcome of evaluating a `calculateMath` expression with the built-in
452
+ * arithmetic parser (no dynamic code). A result that is not a finite number
453
+ * is reported as an error rather than as `Infinity`/`NaN`.
454
+ */
455
+ export type ArithmeticEvaluation = {
456
+ ok: true;
457
+ value: number;
458
+ } | {
459
+ ok: false;
460
+ error: string;
461
+ };
462
+ /** One lexical token of a `calculateMath` expression (`at` is its offset). */
463
+ export type ArithmeticToken = {
464
+ kind: "number";
465
+ value: number;
466
+ at: number;
467
+ } | {
468
+ kind: "identifier";
469
+ name: string;
470
+ at: number;
471
+ } | {
472
+ kind: "operator";
473
+ value: "+" | "-" | "*" | "/" | "%" | "**";
474
+ at: number;
475
+ } | {
476
+ kind: "paren";
477
+ value: "(" | ")";
478
+ at: number;
479
+ } | {
480
+ kind: "comma";
481
+ at: number;
482
+ } | {
483
+ kind: "end";
484
+ at: number;
485
+ };
486
+ /** A JSON Schema node as the JSON-Schema-to-Zod converter walks it. */
487
+ export type SchemaConversionNode = Record<string, unknown>;
488
+ /** State threaded through one JSON-Schema-to-Zod conversion. */
489
+ export type SchemaConversionContext = {
490
+ /** The document root, for resolving local `$ref`s. */
491
+ root: SchemaConversionNode;
492
+ /** `$ref` targets on the current path, so a self-referential schema terminates. */
493
+ refStack: Set<string>;
494
+ /** Called for each `pattern` the converter refused to compile. */
495
+ onRegexDrop: (drop: SchemaRegexDrop) => void;
496
+ };
497
+ /**
498
+ * One regular expression removed from a JSON Schema before the schema is
499
+ * compiled, because `vetRegexPattern` judged it able to stall the process.
500
+ * `path` is the JSON-pointer-like location of the keyword (`properties/name/pattern`).
501
+ */
502
+ export type SchemaRegexDrop = {
503
+ path: string;
504
+ pattern: string;
505
+ reason: string;
506
+ };
450
507
  /**
451
508
  * Tool registry entry
452
509
  */
@@ -29,6 +29,7 @@
29
29
  import type { ZodUnknownSchema } from "./aliases.js";
30
30
  import type { TTSAudioFormat } from "./tts.js";
31
31
  import type { STTHandler, STTOptions, STTResult, TranscriptionSegment, WordTiming } from "./stt.js";
32
+ import type { AttachmentPolicy } from "./attachments.js";
32
33
  /**
33
34
  * Audio for `transcribe()`: bytes, a path or `file://` / `http(s)://` URL, or
34
35
  * an async stream of PCM16LE frames (see `STTStreamingOptions.sampleRate`).
@@ -781,6 +782,11 @@ export type TranscribeDeps = STTCorrectionDeps & {
781
782
  /** Resolves `undefined`, `""` or an alias to a registered provider name, or throws a typed error. */
782
783
  resolveProvider: (name?: string) => string;
783
784
  getHandler: (name: string) => STTHandler | undefined;
785
+ /**
786
+ * Attachment policy applied when `audio` is a path or URL. The
787
+ * environment-derived default applies when absent.
788
+ */
789
+ attachmentPolicy?: AttachmentPolicy;
784
790
  };
785
791
  /** Resolved endpointer tuning: `STTStreamingOptions` with every default applied, plus the input rate. */
786
792
  export type STTEndpointerConfig = {
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Attachment policy — one answer for every SDK loader that turns a
3
+ * caller-supplied string into bytes.
4
+ *
5
+ * Two primitives, both policy-aware:
6
+ *
7
+ * - {@link readAttachmentFile}: realpath containment in `allowedRoots`
8
+ * (when configured), `O_NOFOLLOW` open on the real path, regular files
9
+ * only, size-capped read that notices a file growing under it.
10
+ * - {@link downloadAttachment}: `safeDownloadWithMeta` with the policy's
11
+ * URL switches — HTTPS-only and public hosts by default, redirects
12
+ * re-validated per hop, caller headers never replayed across one.
13
+ *
14
+ * The policy itself is resolved by {@link resolveAttachmentPolicy} from the
15
+ * constructor's `attachments` config and the `NEUROLINK_ATTACHMENT_*`
16
+ * variables, and travels on the per-call options (`attachmentPolicy`). A
17
+ * loader that is reached without one — a host calling `WebLoader` directly, a
18
+ * processor used on its own — falls back to the environment-derived default,
19
+ * so the operator switches apply everywhere.
20
+ *
21
+ * @module utils/attachmentPolicy
22
+ */
23
+ import type { AttachmentDownloadOptions, AttachmentPolicy, AttachmentReadOptions, AttachmentReadResult, AttachmentRefusalCode, AttachmentsConfig, SafeDownloadResult } from "../types/index.js";
24
+ /**
25
+ * An error the loaders throw when the policy refuses an attachment. Carries a
26
+ * stable `code`; the message names the option that would allow the read.
27
+ */
28
+ export declare class AttachmentRefusedError extends Error {
29
+ readonly code: AttachmentRefusalCode;
30
+ constructor(code: AttachmentRefusalCode, message: string, cause?: unknown);
31
+ }
32
+ /**
33
+ * Resolve the policy an instance runs under. An explicit config field wins
34
+ * over its environment variable; the defaults are the safe ones.
35
+ */
36
+ export declare function resolveAttachmentPolicy(config?: AttachmentsConfig): AttachmentPolicy;
37
+ /** Runtime guard for a policy that travelled on an untyped options bag. */
38
+ export declare function isAttachmentPolicy(value: unknown): value is AttachmentPolicy;
39
+ /**
40
+ * The policy stamped on a call's options, or the environment-derived default.
41
+ * Accepts any options bag so loaders deep in the file pipeline can read it off
42
+ * whatever reached them.
43
+ */
44
+ export declare function getAttachmentPolicy(carrier: {
45
+ attachmentPolicy?: unknown;
46
+ } | undefined | null): AttachmentPolicy;
47
+ /** The lower of a loader's own cap and the policy's global cap. */
48
+ export declare function effectiveAttachmentCap(policy: AttachmentPolicy, loaderCap: number): number;
49
+ /**
50
+ * Check `filePath` against the policy's roots and return the real path to
51
+ * open. Without roots the real path is still resolved (so the later
52
+ * `O_NOFOLLOW` open behaves identically for a symlinked input), and the
53
+ * one-time warning fires.
54
+ *
55
+ * @throws {AttachmentRefusedError} `ATTACHMENT_OUTSIDE_ROOTS`
56
+ */
57
+ export declare function resolveAttachmentPath(filePath: string, policy: AttachmentPolicy, label: string): Promise<string>;
58
+ /**
59
+ * Read a local attachment under the policy.
60
+ *
61
+ * Containment is judged on the real path (see {@link resolveAttachmentPath});
62
+ * the open is `O_NOFOLLOW | O_NONBLOCK` on that real path so a symlink swapped
63
+ * in after the check is refused by the kernel and a FIFO cannot park a worker;
64
+ * the descriptor is then stat'd (regular files only, size under the cap) and
65
+ * drained under the same cap.
66
+ *
67
+ * @throws {AttachmentRefusedError} with `ATTACHMENT_OUTSIDE_ROOTS`,
68
+ * `ATTACHMENT_NOT_A_FILE` or `ATTACHMENT_TOO_LARGE`; other file-system
69
+ * errors (ENOENT, EACCES, ELOOP, …) propagate unchanged.
70
+ */
71
+ export declare function readAttachmentFile(filePath: string, options: AttachmentReadOptions): Promise<AttachmentReadResult>;
72
+ /**
73
+ * Quick scheme check that names the switch, so a refused `http://` URL tells
74
+ * the caller what to set rather than only that HTTPS is required.
75
+ *
76
+ * @throws {AttachmentRefusedError} `ATTACHMENT_URL_REFUSED`
77
+ */
78
+ export declare function assertAttachmentUrlScheme(url: string, policy: AttachmentPolicy, label: string): void;
79
+ /**
80
+ * Download a caller-supplied URL under the policy. Builds on
81
+ * `safeDownloadWithMeta`: DNS-pinned connection, bounded body, redirects only
82
+ * when the policy allows and then re-validated per hop with the caller's
83
+ * headers dropped.
84
+ *
85
+ * @throws {AttachmentRefusedError} `ATTACHMENT_URL_REFUSED` when the URL is
86
+ * refused by the policy or the SSRF guard; transport and HTTP errors
87
+ * propagate as plain errors from `safeDownloadWithMeta`.
88
+ */
89
+ export declare function downloadAttachment(url: string, options: AttachmentDownloadOptions): Promise<SafeDownloadResult>;