@juspay/neurolink 13.0.2 β†’ 13.1.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.
@@ -103,7 +103,7 @@
103
103
  {"objectID":"624d9b04ee8ca9e20b22705b38854cdc36c2862d45180aabe659fe9bd779bf75","title":"Glossary","url":"/docs/WORKFLOW-ENGINE-HLD#glossary","content":"Ensemble: Running multiple models in parallel for the same input\nJudge Model: AI model that evaluates and scores responses\nConditioning: Post-processing response based on metadata/confidence\nWorkflow: Declarative configuration of ensemble + judge + conditioning\nConsensus: Agreement level between ensemble models\nConfidence: Calculated metric representing response reliability","hierarchy":{"lvl0":"WORKFLOW ENGINE HLD","lvl1":"Workflow Engine - High-Level Design","lvl2":"Glossary","lvl3":""}},
104
104
  {"objectID":"423325794855f388b799b430c455088465891e911c501107a83e0e529c61b82a","title":"Assumptions","url":"/docs/WORKFLOW-ENGINE-HLD#assumptions","content":"All providers support concurrent requests\nJudge models support structured output (Zod schemas)\nSufficient API rate limits for parallel execution\nNetwork latency is manageable (\\<1s per model)","hierarchy":{"lvl0":"WORKFLOW ENGINE HLD","lvl1":"Workflow Engine - High-Level Design","lvl2":"Assumptions","lvl3":""}},
105
105
  {"objectID":"a7ab1de94e36ceac18730ad11f02b864c2e60a0b59035af0bcd81c97ac348da2","title":"Constraints","url":"/docs/WORKFLOW-ENGINE-HLD#constraints","content":"Maximum 10 models per ensemble (performance/cost)\nMaximum 3 judges per workflow (complexity)\nMinimum 2 models for meaningful ensemble\nJudge model must differ from ensemble models (bias prevention)\n\nDocument Status: βœ… Approved for Implementation \nNext Step: Low-Level Design (LLD) document","hierarchy":{"lvl0":"WORKFLOW ENGINE HLD","lvl1":"Workflow Engine - High-Level Design","lvl2":"Constraints","lvl3":""}},
106
- {"objectID":"4fdd7a391289334fa4825866a2532b3957bb7f79382f75b58a1b52f4096d7d57","title":"Workflow Engine - Low-Level Design","url":"/docs/WORKFLOW-ENGINE-LLD","content":"Neurolink Workflow Engine - Low-Level Design (LLD)\n\nVersion: 1.0 \nDate: November 28, 2025 \nStatus: Implementation Complete \nAuthor: Neurolink Team\n\nπŸ“‹ Document Overview\n\nThis document provides detailed implementation specifications for the Neurolink Workflow Engine, including:\nDetailed module interfaces and method signatures\nData structures and type definitions\nAlgorithm implementations\nIntegration patterns with existing codebase\nError handling strategies\nTesting approach\n\nπŸ—‚οΈ File Structure\n\nTotal Estimated Lines: ~3,000 lines\n\nπŸ“¦ Module Specifications\nTypes Module (workflow/types.ts)\n\nCore Type Definitions\nConfiguration Module (workflow/config.ts)\n\nConfiguration Schemas & Defaults\nWorkflow Runner (workflow/core/workflowRunner.ts)\n\nMain Orchestrator Implementation\nEnsemble Executor (workflow/core/ensembleExecutor.ts)\n\nParallel Model Execution\n\nDue to length constraints, I'll continue with the remaining modules in a structured format.\nJudge Scorer (workflow/core/judgeScorer.ts) - Key Methods\n\nKey Algorithm: Judge Prompt Generation\nResponse Conditioner (workflow/core/responseConditioner.ts) - Key Methods\n\nTone Adjustment Algorithm:\nWorkflow Registry (workflow/core/workflowRegistry.ts) - Key Methods\nIntegration with NeuroLink Class\n\nModifications to src/lib/neurolink.ts\nTesting Strategy\n\nUnit Tests\n\nIntegration Tests\nError Handling Strategy\n\nError Hierarchy\n\nRetry Logic\nPerformance Optimizations\n\nParallel Execution Optimization\nObservability & Monitoring\n\nStructured Logging\n\nMetrics Collection\nSecurity Considerations\n\nInput Validation\n\n[^]*\n\nCost Controls\nBuilt-in Workflow Implementations\n\nConsensus Workflow\nAPI Usage Examples\n\nBasic Usage\n\nCustom Workflow\nMigration Path for Existing Users\n\nBackward Compatibility\n\nGradual Adoption\nPhase 1: Users can try workflows alongside existing methods\nPhase 2: Workflows become recommended for high-stakes queries\nPhase 3: Workflows are default with single-model as fallback\nPerformance Benchmarks (Expected)\n\n| Workflow | Models | Judge | Latency (p50) | Latency (p95) | Cost Multiplier |\n| ------------- | ------ | ----- | ------------- | ------------- | --------------- |\n| consensus-3 | 3 | 1 | 3.2s | 5.1s | 4.2x |\n| fast-fallback | 1-2 | 0 | 1.1s | 2.8s | 1.3x |\n| quality-max | 2 | 1 | 3.5s | 4.9s | 3.1x |\n| multi-judge-5 | 3 | 2 | 4.8s | 6.7s | 5.3x |\nFuture Enhancements\n\nPhase 2: Streaming Support\n\nPhase 3: Workflow Chaining\n\nπŸ“ Implementation Checklist\n[ ] Create src/workflow/ directory structure\n[ ] Implement types.ts with all interfaces\n[ ] Implement config.ts with Zod schemas\n[ ] Implement ensembleExecutor.ts\n[ ] Implement judgeScorer.ts\n[ ] Implement responseConditioner.ts\n[ ] Implement workflowRegistry.ts\n[ ] Implement workflowRunner.ts\n[ ] Create built-in workflows (consensus, fallback, quality-max)\n[ ] Add methods to NeuroLink class\n[ ] Export types from src/lib/index.ts\n[ ] Write unit tests (80% coverage target)\n[ ] Write integration tests\n[ ] Add JSDoc documentation\n[ ] Create user guide with examples\n[ ] Add CLI support (optional Phase 2)\n\nDocument Status: βœ… Ready for Implementation \nNext Step: Code generation upon approval","hierarchy":{"lvl0":"WORKFLOW ENGINE LLD","lvl1":"Workflow Engine - Low-Level Design","lvl2":"","lvl3":""}},
106
+ {"objectID":"4fdd7a391289334fa4825866a2532b3957bb7f79382f75b58a1b52f4096d7d57","title":"Workflow Engine - Low-Level Design","url":"/docs/WORKFLOW-ENGINE-LLD","content":"Neurolink Workflow Engine - Low-Level Design (LLD)\n\nVersion: 1.0 \nDate: November 28, 2025 \nStatus: Implementation Complete \nAuthor: Neurolink Team\n\nπŸ“‹ Document Overview\n\nThis document provides detailed implementation specifications for the Neurolink Workflow Engine, including:\nDetailed module interfaces and method signatures\nData structures and type definitions\nAlgorithm implementations\nIntegration patterns with existing codebase\nError handling strategies\nTesting approach\n\nπŸ—‚οΈ File Structure\n\nTotal Estimated Lines: ~3,000 lines\n\nπŸ“¦ Module Specifications\nTypes Module (workflow/types.ts)\n\nCore Type Definitions\nConfiguration Module (workflow/config.ts)\n\nConfiguration Schemas & Defaults\nWorkflow Runner (workflow/core/workflowRunner.ts)\n\nMain Orchestrator Implementation\nEnsemble Executor (workflow/core/ensembleExecutor.ts)\n\nParallel Model Execution\n\nDue to length constraints, I'll continue with the remaining modules in a structured format.\nJudge Scorer (workflow/core/judgeScorer.ts) - Key Methods\n\nKey Algorithm: Judge Prompt Generation\nResponse Conditioner (workflow/core/responseConditioner.ts) - Key Methods\n\nTone Adjustment Algorithm:\nWorkflow Registry (workflow/core/workflowRegistry.ts) - Key Methods\nIntegration with NeuroLink Class\n\nModifications to src/lib/neurolink.ts\nTesting Strategy\n\nUnit Tests\n\nIntegration Tests\nError Handling Strategy\n\nError Hierarchy\n\nRetry Logic\nPerformance Optimizations\n\nParallel Execution Optimization\nObservability & Monitoring\n\nStructured Logging\n\nMetrics Collection\nSecurity Considerations\n\nInput Validation\n\n[^]*\n\nCost Controls\nBuilt-in Workflow Implementations\n\nConsensus Workflow\nAPI Usage Examples\n\nBasic Usage\n\nCustom Workflow\nMigration Path for Existing Users\n\nBackward Compatibility\n\nGradual Adoption\nPhase 1: Users can try workflows alongside existing methods\nPhase 2: Workflows become recommended for high-stakes queries\nPhase 3: Workflows are default with single-model as fallback\nPerformance Benchmarks (Expected)\n\n| Workflow | Models | Judge | Latency (p50) | Latency (p95) | Cost Multiplier |\n| ------------- | ------ | ----- | ------------- | ------------- | --------------- |\n| consensus-3 | 3 | 1 | 3.2s | 5.1s | 4.2x |\n| fast-fallback | 1-2 | 0 | 1.1s | 2.8s | 1.3x |\n| quality-max | 2 | 1 | 3.5s | 4.9s | 3.1x |\n| multi-judge-5 | 3 | 2 | 4.8s | 6.7s | 5.3x |\nFuture Enhancements\n\nPhase 2: Streaming Support\n\nPhase 3: Workflow Chaining\n\nPlanned: createWorkflowPipeline() is not in the current release.\n\nπŸ“ Implementation Checklist\n[ ] Create src/workflow/ directory structure\n[ ] Implement types.ts with all interfaces\n[ ] Implement config.ts with Zod schemas\n[ ] Implement ensembleExecutor.ts\n[ ] Implement judgeScorer.ts\n[ ] Implement responseConditioner.ts\n[ ] Implement workflowRegistry.ts\n[ ] Implement workflowRunner.ts\n[ ] Create built-in workflows (consensus, fallback, quality-max)\n[ ] Add methods to NeuroLink class\n[ ] Export types from src/lib/index.ts\n[ ] Write unit tests (80% coverage target)\n[ ] Write integration tests\n[ ] Add JSDoc documentation\n[ ] Create user guide with examples\n[ ] Add CLI support (optional Phase 2)\n\nDocument Status: βœ… Ready for Implementation \nNext Step: Code generation upon approval","hierarchy":{"lvl0":"WORKFLOW ENGINE LLD","lvl1":"Workflow Engine - Low-Level Design","lvl2":"","lvl3":""}},
107
107
  {"objectID":"09827c37ad3040e69ed732fa3c3eb6b085f3e0487d33d9c3c4732fe4b7ac438e","title":"Neurolink Workflow Engine - Low-Level Design (LLD)","url":"/docs/WORKFLOW-ENGINE-LLD#neurolink-workflow-engine---low-level-design-lld","content":"Version: 1.0 \nDate: November 28, 2025 \nStatus: Implementation Complete \nAuthor: Neurolink Team","hierarchy":{"lvl0":"WORKFLOW ENGINE LLD","lvl1":"Workflow Engine - Low-Level Design","lvl2":"Neurolink Workflow Engine - Low-Level Design (LLD)","lvl3":""}},
108
108
  {"objectID":"620e7c78ac33a864e4096464f34f4c9f30186495f0a378070ac56e8a850372dc","title":"πŸ“‹ Document Overview","url":"/docs/WORKFLOW-ENGINE-LLD#-document-overview","content":"This document provides detailed implementation specifications for the Neurolink Workflow Engine, including:\nDetailed module interfaces and method signatures\nData structures and type definitions\nAlgorithm implementations\nIntegration patterns with existing codebase\nError handling strategies\nTesting approach","hierarchy":{"lvl0":"WORKFLOW ENGINE LLD","lvl1":"Workflow Engine - Low-Level Design","lvl2":"πŸ“‹ Document Overview","lvl3":""}},
109
109
  {"objectID":"232ab9a608adc21115b101ec04f925b776fe0c2bd548d444a929e836ff3660cf","title":"πŸ—‚οΈ File Structure","url":"/docs/WORKFLOW-ENGINE-LLD#-file-structure","content":"Total Estimated Lines: ~3,000 lines","hierarchy":{"lvl0":"WORKFLOW ENGINE LLD","lvl1":"Workflow Engine - Low-Level Design","lvl2":"πŸ—‚οΈ File Structure","lvl3":""}},
@@ -113,6 +113,7 @@
113
113
  {"objectID":"e171ea65deea448bb34b70ba170da90245765fb638ef81d5b29dfba71490b482","title":"Input Validation","url":"/docs/WORKFLOW-ENGINE-LLD#input-validation","content":"[^]*","hierarchy":{"lvl0":"WORKFLOW ENGINE LLD","lvl1":"Workflow Engine - Low-Level Design","lvl2":"Input Validation","lvl3":""}},
114
114
  {"objectID":"b38e417fcd8ea5d3b983875efebb5b5a309883fdfe8bfdc80300e473bea5e081","title":"Gradual Adoption","url":"/docs/WORKFLOW-ENGINE-LLD#gradual-adoption","content":"Phase 1: Users can try workflows alongside existing methods\nPhase 2: Workflows become recommended for high-stakes queries\nPhase 3: Workflows are default with single-model as fallback","hierarchy":{"lvl0":"WORKFLOW ENGINE LLD","lvl1":"Workflow Engine - Low-Level Design","lvl2":"Gradual Adoption","lvl3":""}},
115
115
  {"objectID":"2127ec4796813559375c700e37b4944f77c72f22a0410fe93bd6f5f7cff8a4c0","title":"17. Performance Benchmarks (Expected)","url":"/docs/WORKFLOW-ENGINE-LLD#17-performance-benchmarks-expected","content":"| Workflow | Models | Judge | Latency (p50) | Latency (p95) | Cost Multiplier |\n| ------------- | ------ | ----- | ------------- | ------------- | --------------- |\n| consensus-3 | 3 | 1 | 3.2s | 5.1s | 4.2x |\n| fast-fallback | 1-2 | 0 | 1.1s | 2.8s | 1.3x |\n| quality-max | 2 | 1 | 3.5s | 4.9s | 3.1x |\n| multi-judge-5 | 3 | 2 | 4.8s | 6.7s | 5.3x |","hierarchy":{"lvl0":"WORKFLOW ENGINE LLD","lvl1":"Workflow Engine - Low-Level Design","lvl2":"17. Performance Benchmarks (Expected)","lvl3":""}},
116
+ {"objectID":"fe375b96a61c82af8b72bb5f813525686c6901fd124a47eaecb87b3475939ee2","title":"Phase 3: Workflow Chaining","url":"/docs/WORKFLOW-ENGINE-LLD#phase-3-workflow-chaining","content":"Planned: createWorkflowPipeline() is not in the current release.","hierarchy":{"lvl0":"WORKFLOW ENGINE LLD","lvl1":"Workflow Engine - Low-Level Design","lvl2":"Phase 3: Workflow Chaining","lvl3":""}},
116
117
  {"objectID":"2f54303255393f1b5c8695c6342964ce83cb786fd3ae00f535bf17c44cae16cd","title":"πŸ“ Implementation Checklist","url":"/docs/WORKFLOW-ENGINE-LLD#-implementation-checklist","content":"[ ] Create src/workflow/ directory structure\n[ ] Implement types.ts with all interfaces\n[ ] Implement config.ts with Zod schemas\n[ ] Implement ensembleExecutor.ts\n[ ] Implement judgeScorer.ts\n[ ] Implement responseConditioner.ts\n[ ] Implement workflowRegistry.ts\n[ ] Implement workflowRunner.ts\n[ ] Create built-in workflows (consensus, fallback, quality-max)\n[ ] Add methods to NeuroLink class\n[ ] Export types from src/lib/index.ts\n[ ] Write unit tests (80% coverage target)\n[ ] Write integration tests\n[ ] Add JSDoc documentation\n[ ] Create user guide with examples\n[ ] Add CLI support (optional Phase 2)\n\nDocument Status: βœ… Ready for Implementation \nNext Step: Code generation upon approval","hierarchy":{"lvl0":"WORKFLOW ENGINE LLD","lvl1":"Workflow Engine - Low-Level Design","lvl2":"πŸ“ Implementation Checklist","lvl3":""}},
117
118
  {"objectID":"de72b620d608319199e3abf25b54298afc8fe5f294c73c538956a2feb63fe9b1","title":"The Nervous System Model","url":"/docs/about/nervous-system-model","content":"The Nervous System Model\n\nNeuroLink is built around a biological metaphor β€” not as decoration, but as a structural model that governs every architectural decision.\n\nThe Three Components\n\nNeurons β€” LLM Providers\n\nNeurons are where intelligence is generated. In NeuroLink, neurons are the AI providers, including: Anthropic, OpenAI, Google (AI Studio + Vertex), AWS (Bedrock + SageMaker), Azure, Mistral, LiteLLM, OpenRouter, Ollama, Hugging Face, DeepSeek, NVIDIA NIM, LM Studio, llama.cpp, OpenAI-compatible endpoints, TypeSafe Jev, Laya, XOR, SubQ, Perplexity Decisions, Cloudflare Clef and OpenAI Decisions (decision-only) β€” plus voice neurons (OpenAI TTS, ElevenLabs, Google TTS, Azure TTS, Whisper, Deepgram, Azure STT, Google STT), realtime neurons (OpenAI Realtime, Gemini Live), and media-generation neurons (image, video, music, avatar).\n\nEach provider is a different type of neuron β€” different capabilities, different costs, different latency profiles. NeuroLink's ProviderRegistry gives you access to all of them through one interface, switchable with a single line.\n\nThe Pipe β€” NeuroLink\n\nThe pipe is the vascular layer that carries streams between neurons and organs. This is NeuroLink itself.\n\nWhat the pipe does every time you call generate() or stream():\nContext Building β€” RAG retrieval, memory lookup, file processing merge into the prompt\nBudget Check β€” BudgetChecker validates the assembled context fits the model's window\nProvider Dispatch β€” ProviderRegistry routes to the correct neuron\nStream Emission β€” Tokens flow as an async iterable\nTool Interception β€” When the model calls a tool, the stream pauses, MCP tool executes, result injects, stream continues\nObservability β€” Every stage emits OpenTelemetry spans\n\nOrgans β€” Connectors\n\nOrgans are the applications that consume the pipe. They connect to the vascular layer and open a gateway β€” a specific way for people or systems to interact with AI.\n\nEvery application built on NeuroLink is an organ. Production organs today:\nAutomatic β€” Shopify operations hub: address intelligence, RTO risk scoring\nTara β€” Slack engineering assistant: conversational AI with MCP tool access\nYama β€” Code review judge: automated PR analysis and governance\n\nWhy This Model Works\n\nThe metaphor enforces good architecture:\n\nSeparation of concerns: Neurons (generation) and organs (consumption) are completely decoupled. Changing AI provider doesn't touch the application. Changing the application doesn't touch the provider.\n\nSingle flow direction: Intelligence flows one way β€” neuron β†’ pipe β†’ organ. There's no confusion about where logic lives.\n\nObservable by default: A vascular system you can't monitor is dangerous. Every stage of the pipe emits telemetry by design.\n\nComposable: Multiple organs can share the same pipe. One NeuroLink instance serves many connectors.\n\nExtending the System\n\nThe nervous system model scales in three directions:\nAdd neurons β€” New AI provider? Register it in ProviderRegistry.\nExtend the pipe β€” New capability (chunking strategy, reranker, compaction stage)? Add it to the pipeline.\nBuild organs β€” New application? Import NeuroLink, connect to the pipe, open your gateway.\n\nSee Pipe Architecture β†’ for the technical implementation.","hierarchy":{"lvl0":"About","lvl1":"The Nervous System Model","lvl2":"","lvl3":""}},
118
119
  {"objectID":"27ef114b7e0cecc6ca45dbf3e9285980b691cd27d21e1912f2a27a7f309f68fe","title":"The Nervous System Model","url":"/docs/about/nervous-system-model#the-nervous-system-model","content":"NeuroLink is built around a biological metaphor β€” not as decoration, but as a structural model that governs every architectural decision.","hierarchy":{"lvl0":"About","lvl1":"The Nervous System Model","lvl2":"The Nervous System Model","lvl3":""}},
@@ -1303,18 +1304,18 @@
1303
1304
  {"objectID":"a47e5e14159068d21360e6285d07afda53eef0794d49a3446798a53bdfc3f61f","title":"NeuroLink Integration","url":"/docs/connectors/yama#neurolink-integration","content":"Features used:\nLiteLLM provider (NeuroLink's gateway to private model deployments)\nBitbucket Server MCP (read-only tool set)\nFile-based memory bank (memory-bank/*.md for project context)\nKnowledge base (.yama/knowledge-base.md β€” max 50 entries, auto-summarized)\nAnalytics export to .yama/analytics/","hierarchy":{"lvl0":"Connectors","lvl1":"Yama","lvl2":"NeuroLink Integration","lvl3":""}},
1304
1305
  {"objectID":"296378ae0b5ffa480fb59449ce9148cf7497671c2c4fdd76817b295a54f0ab80","title":"Gateway Unlocked","url":"/docs/connectors/yama#gateway-unlocked","content":"Yama gives engineering teams:\nSecurity gate β€” CRITICAL findings block merge (configurable)\nConsistent reviews β€” every PR gets the same analysis, no reviewer fatigue\nContext-aware β€” reads memory bank for project standards before reviewing\nLow noise β€” excludes lock files, images, minified assets automatically\nCost-bounded β€” hard limits on review duration (15min) and cost ($2)","hierarchy":{"lvl0":"Connectors","lvl1":"Yama","lvl2":"Gateway Unlocked","lvl3":""}},
1305
1306
  {"objectID":"3c2c8c47c4bc2f188f28fc89fc930b2930d1d792aa19db29e3b69c3fe941d30e","title":"Operational Notes","url":"/docs/connectors/yama#operational-notes","content":"File strategy: Reviews files one-by-one (not the entire diff at once) β€” more accurate, fits within context limits\nSmart filtering: Auto-excludes lock files, images, minified JS, source maps\nPR guard: Calls get_branch() first β€” skips review if no open PR or if target branch is not main\nMemory bank: Reads memory-bank/project-overview.md, architecture.md, coding-standards.md, security-guidelines.md before each review\nKnowledge base: Accumulates review learnings in .yama/knowledge-base.md; auto-summarized when > 50 entries\nCost guard: Warning at $1.50, hard stop at $2.00 per review\nAnalytics: Tool calls, AI decisions, and token usage exported to .yama/analytics/ as JSON","hierarchy":{"lvl0":"Connectors","lvl1":"Yama","lvl2":"Operational Notes","lvl3":""}},
1306
- {"objectID":"97e432655392f70ff51f3b644e1f4eb5b8ce4f6307296f11d84d263e4fa7f775","title":"AutoResearch Quickstart","url":"/docs/cookbook/autoresearch-quickstart","content":"AutoResearch Quickstart\n\nProblem\n\nYou have a training script and a metric you want to optimize (e.g., validation loss), and you want an AI agent to autonomously iterate on the code β€” proposing changes, running experiments, keeping improvements, and reverting failures β€” without manual intervention.\n\nSolution\n\nUse NeuroLink's AutoResearch engine. Initialize a config pointing at your repo, define the metric to optimize, and run experiment cycles. Each cycle: the AI reads your code, proposes a change, commits it to a branch, runs the experiment, parses the metric, and keeps or reverts the change.\n\nCode\n\nCLI β€” Single Experiment Cycle\n\nSDK β€” Single Experiment Cycle\n\nSDK β€” Scheduled via TaskManager\n\nNote: saveTask() only persists the task definition. You must call startTaskWorker() (SDK) or run neurolink task start (CLI) to begin execution.\n\nExplanation\nInitialization\n\nautoresearch init (CLI) or createResearchWorker() (SDK) sets up the config:\nmutablePaths β€” Files the AI is allowed to edit (your training script)\nimmutablePaths β€” Files the AI can read but not modify (research program, dataset configs)\nrunCommand β€” Shell command to execute the experiment\nmetric β€” Name, regex pattern to extract the value from stdout, and optimization direction (lower or higher)\ntimeoutMs β€” Max wall-clock time per experiment run\n\nThe CLI writes this to .autoresearch/config.json and creates a dedicated git branch.\nExperiment Cycle\n\nEach runExperimentCycle() call goes through 9 phases:\nbootstrap β€” Read the research program and understand the codebase\nanalyze β€” Study current results and identify improvement opportunities\nplan β€” Propose a specific code change\nimplement β€” Apply the change to mutable files\nvalidate β€” Verify the code is syntactically valid\ncommit β€” Git-commit the candidate change\nexecute β€” Run the experiment command\nevaluate β€” Parse the metric from stdout using the regex pattern\ndecide β€” Keep the commit if the metric improved, revert otherwise\nArtifacts\n\nAfter running, check .autoresearch/ in your repo:\n\n| File | Contents |\n| ------------- | ------------------------------------------------------------------------------ |\n| config.json | Persisted configuration |\n| state.json | Current best metric, cycle count, phase, branch name |\n| results.tsv | Tab-separated log: commit, metric name, memory_gb, status, description |\n| runs.jsonl | Full JSON audit log β€” one JSON object per completed cycle |\nEvents\n\nThe SDK emits 10 typed events via neurolink.getEventEmitter():\n\n| Event | Fired when |\n| ------------------------------ | ----------------------------------- |\n| autoresearch:cycle:start | A cycle begins |\n| autoresearch:cycle:end | A cycle completes (success or fail) |\n| autoresearch:phase:enter | Worker enters a new phase |\n| autoresearch:phase:exit | Worker exits a phase |\n| autoresearch:metric:recorded | A metric value is parsed |\n| autoresearch:commit:created | A candidate commit is made |\n| autoresearch:commit:reverted | A candidate commit is reverted |\n| autoresearch:error | An error occurs |\n| autoresearch:timeout | Experiment exceeds time limit |\n| autoresearch:stopped | Worker stops (manual or max-runs) |\n\nVariations\n\nUse a Different Provider\n\nReplace the provider/model in the config. AutoResearch works with any NeuroLink-supported provider:\n\nOr via CLI:\n\nOptimize a Higher-is-Better Metric\n\nSet direction: \"higher\" for metrics like accuracy:\n\nReset and Start Over\n\nPause and Resume (TaskManager)\n\nNote: pause, resume, and stop update the stored task status but do not interact with the TaskManager runtime directly. The task worker checks status before each cycle.\n\nSee Also\nAutoResearch Feature Guide β€” Full reference with phase diagrams, configuration, and architecture\nTool Chaining β€” AutoResearch uses phase-gated tool chaining internally\nStructured Output with JSON Schema β€” Extract structured data from experiment outputs\nAPI Reference","hierarchy":{"lvl0":"Cookbook","lvl1":"AutoResearch Quickstart","lvl2":"","lvl3":""}},
1307
+ {"objectID":"97e432655392f70ff51f3b644e1f4eb5b8ce4f6307296f11d84d263e4fa7f775","title":"AutoResearch Quickstart","url":"/docs/cookbook/autoresearch-quickstart","content":"AutoResearch Quickstart\n\nProblem\n\nYou have a training script and a metric you want to optimize (e.g., validation loss), and you want an AI agent to autonomously iterate on the code β€” proposing changes, running experiments, keeping improvements, and reverting failures β€” without manual intervention.\n\nSolution\n\nUse NeuroLink's AutoResearch engine. Initialize a config pointing at your repo, define the metric to optimize, and run experiment cycles. Each cycle: the AI reads your code, proposes a change, commits it to a branch, runs the experiment, parses the metric, and keeps or reverts the change.\n\nCode\n\nCLI β€” Single Experiment Cycle\n\nSDK β€” Single Experiment Cycle\n\nSDK β€” Scheduled via TaskManager\n\nNote: neurolink.tasks.create() registers the task with the configured TaskManager backend, and the schedule runs there. With the default in-process backend the timers live only as long as your process, so keep it running. From the CLI, neurolink autoresearch start only saves the task and neurolink task start runs the worker.\n\nExplanation\nInitialization\n\nautoresearch init (CLI) or new ResearchWorker(config) (SDK) sets up the config:\nmutablePaths β€” Files the AI is allowed to edit (your training script)\nimmutablePaths β€” Files the AI can read but not modify (research program, dataset configs)\nrunCommand β€” Shell command to execute the experiment\nmetric β€” Name, regex pattern to extract the value from stdout, and optimization direction (lower or higher)\ntimeoutMs β€” Max wall-clock time per experiment run\n\nThe CLI writes this to .autoresearch/config.json and creates a dedicated git branch.\nExperiment Cycle\n\nEach runExperimentCycle() call goes through 9 phases:\nbootstrap β€” Read the research program and understand the codebase\nanalyze β€” Study current results and identify improvement opportunities\nplan β€” Propose a specific code change\nimplement β€” Apply the change to mutable files\nvalidate β€” Verify the code is syntactically valid\ncommit β€” Git-commit the candidate change\nexecute β€” Run the experiment command\nevaluate β€” Parse the metric from stdout using the regex pattern\ndecide β€” Keep the commit if the metric improved, revert otherwise\nArtifacts\n\nAfter running, check .autoresearch/ in your repo:\n\n| File | Contents |\n| ------------- | ------------------------------------------------------------------------------ |\n| config.json | Persisted configuration |\n| state.json | Current best metric, cycle count, phase, branch name |\n| results.tsv | Tab-separated log: commit, metric name, memory_gb, status, description |\n| runs.jsonl | Full JSON audit log β€” one JSON object per completed cycle |\nEvents\n\nThe SDK emits 10 typed events via neurolink.getEventEmitter(). A ResearchWorker created directly emits them once you pass it that emitter with worker.setEmitter(); tasks created through neurolink.tasks are wired for you:\n\n| Event | Fired when |\n| ----------------------------------- | ----------------------------------------------- |\n| autoresearch:initialized | A research session is created |\n| autoresearch:resumed | An existing research session is resumed |\n| autoresearch:phase-changed | The worker moves to a new phase |\n| autoresearch:experiment-started | An experiment cycle begins |\n| autoresearch:experiment-completed | An experiment cycle completes (success or fail) |\n| autoresearch:metric-improved | The best metric value improves |\n| autoresearch:revert | A candidate commit is reverted |\n| autoresearch:revert-failed | Reverting a candidate commit fails |\n| autoresearch:state-updated | The persisted state is updated |\n| autoresearch:error | An error occurs |\n\nVariations\n\nUse a Different Provider\n\nReplace the provider/model in the config. AutoResearch works with any NeuroLink-supported provider:\n\nOr via CLI:\n\nOptimize a Higher-is-Better Metric\n\nSet direction: \"higher\" for metrics like accuracy:\n\nReset and Start Over\n\nPause and Resume (TaskManager)\n\nNote: pause, resume, and stop update the stored task status but do not interact with the TaskManager runtime directly. The task worker checks status before each cycle.\n\nSee Also\nAutoResearch Feature Guide β€” Full reference with phase diagrams, configuration, and architecture\nTool Chaining β€” AutoResearch uses phase-gated tool chaining internally\nStructured Output with JSON Schema β€” Extract structured data from experiment outputs\nAPI Reference","hierarchy":{"lvl0":"Cookbook","lvl1":"AutoResearch Quickstart","lvl2":"","lvl3":""}},
1307
1308
  {"objectID":"91e8ee4260b2834f556661f4704b999b57a6f12f6a9a523f64cfc360de8bd32e","title":"Problem","url":"/docs/cookbook/autoresearch-quickstart#problem","content":"You have a training script and a metric you want to optimize (e.g., validation loss), and you want an AI agent to autonomously iterate on the code β€” proposing changes, running experiments, keeping improvements, and reverting failures β€” without manual intervention.","hierarchy":{"lvl0":"Cookbook","lvl1":"AutoResearch Quickstart","lvl2":"Problem","lvl3":""}},
1308
1309
  {"objectID":"689e68fb0668bf0c621c7ec5c845596bc3858a1b9fe24fa4cad27d843b3ebb7f","title":"Solution","url":"/docs/cookbook/autoresearch-quickstart#solution","content":"Use NeuroLink's AutoResearch engine. Initialize a config pointing at your repo, define the metric to optimize, and run experiment cycles. Each cycle: the AI reads your code, proposes a change, commits it to a branch, runs the experiment, parses the metric, and keeps or reverts the change.","hierarchy":{"lvl0":"Cookbook","lvl1":"AutoResearch Quickstart","lvl2":"Solution","lvl3":""}},
1309
1310
  {"objectID":"56114b15cdfe5a456bc2be2adb1647403e4a23f3dd91dc85b81f2d4cb0072e4f","title":"CLI β€” Single Experiment Cycle","url":"/docs/cookbook/autoresearch-quickstart#cli-single-experiment-cycle","content":"`bash","hierarchy":{"lvl0":"Cookbook","lvl1":"AutoResearch Quickstart","lvl2":"CLI β€” Single Experiment Cycle","lvl3":""}},
1310
1311
  {"objectID":"4db16dfc9b8a014290d64b57443821d873c60140b52307d1bc3c91eec9eb09a7","title":"1. Initialize AutoResearch in your repo","url":"/docs/cookbook/autoresearch-quickstart#1-initialize-autoresearch-in-your-repo","content":"neurolink autoresearch init /path/to/repo \\\n --tag \"run1\" \\\n --target \"train.py\" \\\n --immutable \"program.md\" \\\n --run-command \"python3 train.py\" \\\n --metric-name val_bpb \\\n --metric-pattern \"^val_bpb:\\\\s+([\\\\d.]+)\" \\\n --metric-direction lower \\\n --timeout 120","hierarchy":{"lvl0":"Cookbook","lvl1":"AutoResearch Quickstart","lvl2":"1. Initialize AutoResearch in your repo","lvl3":""}},
1311
1312
  {"objectID":"ffb51179e59d6e9405aa7dcb33e0ce9070fa0ec7bea84a3cf1b4446e984a8d6c","title":"2. Run one cycle (propose β†’ execute β†’ evaluate β†’ keep/revert)","url":"/docs/cookbook/autoresearch-quickstart#2-run-one-cycle-propose-execute-evaluate-keeprevert","content":"neurolink autoresearch run-once /path/to/repo","hierarchy":{"lvl0":"Cookbook","lvl1":"AutoResearch Quickstart","lvl2":"2. Run one cycle (propose β†’ execute β†’ evaluate β†’ keep/revert)","lvl3":""}},
1312
1313
  {"objectID":"c18bc40162224e29bba22390a339ecbc8c69f360e425c883926f244e50c9fc8e","title":"3. Check results","url":"/docs/cookbook/autoresearch-quickstart#3-check-results","content":"neurolink autoresearch status /path/to/repo\nneurolink autoresearch results /path/to/repo\n`","hierarchy":{"lvl0":"Cookbook","lvl1":"AutoResearch Quickstart","lvl2":"3. Check results","lvl3":""}},
1313
- {"objectID":"5717d08a9d39494089e504ea264e42e8a7eeba9e9636b248b8fb2643e1878026","title":"SDK β€” Scheduled via TaskManager","url":"/docs/cookbook/autoresearch-quickstart#sdk-scheduled-via-taskmanager","content":"Note: saveTask() only persists the task definition. You must call startTaskWorker() (SDK) or run neurolink task start (CLI) to begin execution.","hierarchy":{"lvl0":"Cookbook","lvl1":"AutoResearch Quickstart","lvl2":"SDK β€” Scheduled via TaskManager","lvl3":""}},
1314
- {"objectID":"7cee02de46fd8368e76cbc9071b91158131d031fc5034e157e30ef3d9d8b23f1","title":"1. Initialization","url":"/docs/cookbook/autoresearch-quickstart#1-initialization","content":"autoresearch init (CLI) or createResearchWorker() (SDK) sets up the config:\nmutablePaths β€” Files the AI is allowed to edit (your training script)\nimmutablePaths β€” Files the AI can read but not modify (research program, dataset configs)\nrunCommand β€” Shell command to execute the experiment\nmetric β€” Name, regex pattern to extract the value from stdout, and optimization direction (lower or higher)\ntimeoutMs β€” Max wall-clock time per experiment run\n\nThe CLI writes this to .autoresearch/config.json and creates a dedicated git branch.","hierarchy":{"lvl0":"Cookbook","lvl1":"AutoResearch Quickstart","lvl2":"1. Initialization","lvl3":""}},
1314
+ {"objectID":"5717d08a9d39494089e504ea264e42e8a7eeba9e9636b248b8fb2643e1878026","title":"SDK β€” Scheduled via TaskManager","url":"/docs/cookbook/autoresearch-quickstart#sdk-scheduled-via-taskmanager","content":"Note: neurolink.tasks.create() registers the task with the configured TaskManager backend, and the schedule runs there. With the default in-process backend the timers live only as long as your process, so keep it running. From the CLI, neurolink autoresearch start only saves the task and neurolink task start runs the worker.","hierarchy":{"lvl0":"Cookbook","lvl1":"AutoResearch Quickstart","lvl2":"SDK β€” Scheduled via TaskManager","lvl3":""}},
1315
+ {"objectID":"7cee02de46fd8368e76cbc9071b91158131d031fc5034e157e30ef3d9d8b23f1","title":"1. Initialization","url":"/docs/cookbook/autoresearch-quickstart#1-initialization","content":"autoresearch init (CLI) or new ResearchWorker(config) (SDK) sets up the config:\nmutablePaths β€” Files the AI is allowed to edit (your training script)\nimmutablePaths β€” Files the AI can read but not modify (research program, dataset configs)\nrunCommand β€” Shell command to execute the experiment\nmetric β€” Name, regex pattern to extract the value from stdout, and optimization direction (lower or higher)\ntimeoutMs β€” Max wall-clock time per experiment run\n\nThe CLI writes this to .autoresearch/config.json and creates a dedicated git branch.","hierarchy":{"lvl0":"Cookbook","lvl1":"AutoResearch Quickstart","lvl2":"1. Initialization","lvl3":""}},
1315
1316
  {"objectID":"c3429e15cb82ee310f2c1e8a2d142b6c68630b3c5744833a05fe6d8423fc6181","title":"2. Experiment Cycle","url":"/docs/cookbook/autoresearch-quickstart#2-experiment-cycle","content":"Each runExperimentCycle() call goes through 9 phases:\nbootstrap β€” Read the research program and understand the codebase\nanalyze β€” Study current results and identify improvement opportunities\nplan β€” Propose a specific code change\nimplement β€” Apply the change to mutable files\nvalidate β€” Verify the code is syntactically valid\ncommit β€” Git-commit the candidate change\nexecute β€” Run the experiment command\nevaluate β€” Parse the metric from stdout using the regex pattern\ndecide β€” Keep the commit if the metric improved, revert otherwise","hierarchy":{"lvl0":"Cookbook","lvl1":"AutoResearch Quickstart","lvl2":"2. Experiment Cycle","lvl3":""}},
1316
1317
  {"objectID":"a7fbb04d65ab40f22ca92e6c93f77400db68136ab69039e05e5fa6830189ecc0","title":"3. Artifacts","url":"/docs/cookbook/autoresearch-quickstart#3-artifacts","content":"After running, check .autoresearch/ in your repo:\n\n| File | Contents |\n| ------------- | ------------------------------------------------------------------------------ |\n| config.json | Persisted configuration |\n| state.json | Current best metric, cycle count, phase, branch name |\n| results.tsv | Tab-separated log: commit, metric name, memory_gb, status, description |\n| runs.jsonl | Full JSON audit log β€” one JSON object per completed cycle |","hierarchy":{"lvl0":"Cookbook","lvl1":"AutoResearch Quickstart","lvl2":"3. Artifacts","lvl3":""}},
1317
- {"objectID":"21cab0b2c003cc954d9deb08ec2b6481b574559d3b37bc2ee52725d55ccd22a0","title":"4. Events","url":"/docs/cookbook/autoresearch-quickstart#4-events","content":"The SDK emits 10 typed events via neurolink.getEventEmitter():\n\n| Event | Fired when |\n| ------------------------------ | ----------------------------------- |\n| autoresearch:cycle:start | A cycle begins |\n| autoresearch:cycle:end | A cycle completes (success or fail) |\n| autoresearch:phase:enter | Worker enters a new phase |\n| autoresearch:phase:exit | Worker exits a phase |\n| autoresearch:metric:recorded | A metric value is parsed |\n| autoresearch:commit:created | A candidate commit is made |\n| autoresearch:commit:reverted | A candidate commit is reverted |\n| autoresearch:error | An error occurs |\n| autoresearch:timeout | Experiment exceeds time limit |\n| autoresearch:stopped | Worker stops (manual or max-runs) |","hierarchy":{"lvl0":"Cookbook","lvl1":"AutoResearch Quickstart","lvl2":"4. Events","lvl3":""}},
1318
+ {"objectID":"21cab0b2c003cc954d9deb08ec2b6481b574559d3b37bc2ee52725d55ccd22a0","title":"4. Events","url":"/docs/cookbook/autoresearch-quickstart#4-events","content":"The SDK emits 10 typed events via neurolink.getEventEmitter(). A ResearchWorker created directly emits them once you pass it that emitter with worker.setEmitter(); tasks created through neurolink.tasks are wired for you:\n\n| Event | Fired when |\n| ----------------------------------- | ----------------------------------------------- |\n| autoresearch:initialized | A research session is created |\n| autoresearch:resumed | An existing research session is resumed |\n| autoresearch:phase-changed | The worker moves to a new phase |\n| autoresearch:experiment-started | An experiment cycle begins |\n| autoresearch:experiment-completed | An experiment cycle completes (success or fail) |\n| autoresearch:metric-improved | The best metric value improves |\n| autoresearch:revert | A candidate commit is reverted |\n| autoresearch:revert-failed | Reverting a candidate commit fails |\n| autoresearch:state-updated | The persisted state is updated |\n| autoresearch:error | An error occurs |","hierarchy":{"lvl0":"Cookbook","lvl1":"AutoResearch Quickstart","lvl2":"4. Events","lvl3":""}},
1318
1319
  {"objectID":"a20b4135ed6c40134e76db4dd1fcaa1ddd2e36f461c39acada1b02e7758754e2","title":"Use a Different Provider","url":"/docs/cookbook/autoresearch-quickstart#use-a-different-provider","content":"Replace the provider/model in the config. AutoResearch works with any NeuroLink-supported provider:\n\nOr via CLI:","hierarchy":{"lvl0":"Cookbook","lvl1":"AutoResearch Quickstart","lvl2":"Use a Different Provider","lvl3":""}},
1319
1320
  {"objectID":"feab9bdcb7bb4d800d47eaa83199235f1136259d8853ed3531f424f94aabb9d2","title":"Optimize a Higher-is-Better Metric","url":"/docs/cookbook/autoresearch-quickstart#optimize-a-higher-is-better-metric","content":"Set direction: \"higher\" for metrics like accuracy:","hierarchy":{"lvl0":"Cookbook","lvl1":"AutoResearch Quickstart","lvl2":"Optimize a Higher-is-Better Metric","lvl3":""}},
1320
1321
  {"objectID":"b4631e1ea89f85ce6dfda4dbc040560531dcbf16f4fafe7a08392f533bb1fba3","title":"Reset and Start Over","url":"/docs/cookbook/autoresearch-quickstart#reset-and-start-over","content":"`bash","hierarchy":{"lvl0":"Cookbook","lvl1":"AutoResearch Quickstart","lvl2":"Reset and Start Over","lvl3":""}},
@@ -2079,7 +2080,7 @@
2079
2080
  {"objectID":"cf7efb25d3b7a2babf2584abb6a92798e06c9006b03567b643fdb4b282fbe41f","title":"πŸŽ₯ Video Generation Handler Architecture","url":"/docs/development/factory-architecture#-video-generation-handler-architecture","content":"Video generation via Veo 3.1 follows the same factory pattern architecture with specialized handling for long-running operations.","hierarchy":{"lvl0":"Development","lvl1":"🏭 Factory Pattern Architecture","lvl2":"πŸŽ₯ Video Generation Handler Architecture","lvl3":""}},
2080
2081
  {"objectID":"18e3ab07fb9afe2bb09eb6f3e0204902695fc594c24895a123a0bbec044aab5c","title":"Factory Pattern Benefits for Video Generation","url":"/docs/development/factory-architecture#factory-pattern-benefits-for-video-generation","content":"Provider-Specific Features: Video generation is only available on Vertex AI, but the architecture allows graceful handling:\nAutomatic Provider Routing: Factory can route video requests to Vertex AI:\nConsistent Error Handling: Video-specific errors follow the same pattern:","hierarchy":{"lvl0":"Development","lvl1":"🏭 Factory Pattern Architecture","lvl2":"Factory Pattern Benefits for Video Generation","lvl3":""}},
2081
2082
  {"objectID":"8ffc8d10abcc7bd7ec83d262a7379a2e2ffa95d496588f05961fec9bdeed4f1e","title":"Key Design Decisions","url":"/docs/development/factory-architecture#key-design-decisions","content":"Separation of Concerns: Video handler is separate from core provider logic\nExtensibility: Easy to add image generation, audio generation, etc.\nConsistent Interface: Same generate() method for text and video\nProvider-Specific Features: Only Vertex AI supports video, handled gracefully\nError Handling: Unified error codes across all features\n\nUnderstanding the architecture helps you build better AI applications! πŸš€","hierarchy":{"lvl0":"Development","lvl1":"🏭 Factory Pattern Architecture","lvl2":"Key Design Decisions","lvl3":""}},
2082
- {"objectID":"c88e3be7a10c50ed72123bdbd5a139b6be2b1056947b4dbdfcc5bd6682059814","title":"Factory Pattern Migration Guide","url":"/docs/development/factory-migration","content":"Factory Pattern Migration Guide\n\nComprehensive guide for migrating to NeuroLink's factory pattern architecture, ensuring consistent provider management and scalable implementation.\n\n🏭 Factory Pattern Overview\n\nWhy Factory Patterns\n\nThe factory pattern in NeuroLink provides:\nConsistent Provider Creation: Standardized instantiation across all AI providers\nCentralized Configuration: Single source of truth for provider settings\nLifecycle Management: Proper initialization, caching, and cleanup\nType Safety: Full TypeScript support with compile-time validation\nExtensibility: Easy addition of new providers without code changes\n\nCore Factory Components\n\nπŸ”„ Migration Steps\n\nStep 1: Assess Current Implementation\n\nPre-Migration Checklist:\n\nStep 2: Install and Configure NeuroLink\n\nInitial Configuration:\n\nStep 3: Refactor Provider Instantiation\n\nBefore (Legacy Pattern):\n\nAfter (Factory Pattern):\n\nStep 4: Migrate Configuration Management\n\nBefore (Environment Variables):\n\nAfter (Centralized Configuration):\n\nStep 5: Update Error Handling\n\nBefore (Manual Error Handling):\n\nAfter (Factory-Managed Error Handling):\n\nπŸ§ͺ Testing Migration\n\nUnit Tests for Factory Pattern\n\nIntegration Tests\n\nπŸ“Š Performance Optimization\n\nCaching Strategy\n\nLoad Balancing\n\nπŸ” Monitoring and Observability\n\nMigration Metrics\n\nLogging and Debugging\n\nπŸš€ Advanced Migration Patterns\n\nGradual Migration Strategy\n\nFeature Flag Integration\n\nπŸ“‹ Migration Checklist\n\nPre-Migration\n[ ] Audit existing provider usage patterns\n[ ] Identify all provider instantiation points\n[ ] Document current configuration management\n[ ] Assess error handling strategies\n[ ] Measure baseline performance metrics\n[ ] Plan rollback strategy\n\nDuring Migration\n[ ] Install NeuroLink with factory support\n[ ] Configure provider factory settings\n[ ] Refactor provider instantiation code\n[ ] Update configuration management\n[ ] Implement unified error handling\n[ ] Add comprehensive testing\n[ ] Enable monitoring and logging\n\nPost-Migration\n[ ] Verify all provider functionality\n[ ] Confirm performance improvements\n[ ] Validate error handling behavior\n[ ] Test failover scenarios\n[ ] Monitor production metrics\n[ ] Document new patterns for team\n[ ] Clean up legacy code\n\nValidation Tests\n\n🎯 Success Metrics\n\nKey Performance Indicators\n\nThis comprehensive migration guide ensures a smooth transition to NeuroLink's factory pattern architecture, maximizing the benefits of standardized provider management while minimizing migration risks.\n\nπŸ“š Related Documentation\nSystem Architecture - Overall system design\nTesting Strategy - Quality assurance approaches\nContributing Guide - Development workflow\nAdvanced Patterns - Factory implementation details","hierarchy":{"lvl0":"Development","lvl1":"Factory Pattern Migration Guide","lvl2":"","lvl3":""}},
2083
+ {"objectID":"c88e3be7a10c50ed72123bdbd5a139b6be2b1056947b4dbdfcc5bd6682059814","title":"Factory Pattern Migration Guide","url":"/docs/development/factory-migration","content":"Factory Pattern Migration Guide\n\nComprehensive guide for migrating to NeuroLink's factory pattern architecture, ensuring consistent provider management and scalable implementation.\n\n🏭 Factory Pattern Overview\n\nWhy Factory Patterns\n\nThe factory pattern in NeuroLink provides:\nConsistent Provider Creation: Standardized instantiation across all AI providers\nCentralized Configuration: Single source of truth for provider settings\nLifecycle Management: Proper initialization, caching, and cleanup\nType Safety: Full TypeScript support with compile-time validation\nExtensibility: Easy addition of new providers without code changes\n\nCore Factory Components\n\nπŸ”„ Migration Steps\n\nStep 1: Assess Current Implementation\n\nPre-Migration Checklist:\n\nStep 2: Install and Configure NeuroLink\n\nInitial Configuration:\n\nStep 3: Refactor Provider Instantiation\n\nBefore (Legacy Pattern):\n\nAfter (Factory Pattern):\n\nStep 4: Migrate Configuration Management\n\nBefore (Environment Variables):\n\nAfter (Centralized Configuration):\n\nStep 5: Update Error Handling\n\nBefore (Manual Error Handling):\n\nAfter (Factory-Managed Error Handling):\n\nπŸ§ͺ Testing Migration\n\nUnit Tests for Factory Pattern\n\nPlanned: this example uses a factory instance (neurolink.getProviderFactory()) that the current release does not have. ProviderFactory exposes static methods such as ProviderFactory.createProvider(name).\n\nIntegration Tests\n\nπŸ“Š Performance Optimization\n\nCaching Strategy\n\nLoad Balancing\n\nπŸ” Monitoring and Observability\n\nMigration Metrics\n\nLogging and Debugging\n\nπŸš€ Advanced Migration Patterns\n\nGradual Migration Strategy\n\nFeature Flag Integration\n\nπŸ“‹ Migration Checklist\n\nPre-Migration\n[ ] Audit existing provider usage patterns\n[ ] Identify all provider instantiation points\n[ ] Document current configuration management\n[ ] Assess error handling strategies\n[ ] Measure baseline performance metrics\n[ ] Plan rollback strategy\n\nDuring Migration\n[ ] Install NeuroLink with factory support\n[ ] Configure provider factory settings\n[ ] Refactor provider instantiation code\n[ ] Update configuration management\n[ ] Implement unified error handling\n[ ] Add comprehensive testing\n[ ] Enable monitoring and logging\n\nPost-Migration\n[ ] Verify all provider functionality\n[ ] Confirm performance improvements\n[ ] Validate error handling behavior\n[ ] Test failover scenarios\n[ ] Monitor production metrics\n[ ] Document new patterns for team\n[ ] Clean up legacy code\n\nValidation Tests\n\n🎯 Success Metrics\n\nKey Performance Indicators\n\nThis comprehensive migration guide ensures a smooth transition to NeuroLink's factory pattern architecture, maximizing the benefits of standardized provider management while minimizing migration risks.\n\nπŸ“š Related Documentation\nSystem Architecture - Overall system design\nTesting Strategy - Quality assurance approaches\nContributing Guide - Development workflow\nAdvanced Patterns - Factory implementation details","hierarchy":{"lvl0":"Development","lvl1":"Factory Pattern Migration Guide","lvl2":"","lvl3":""}},
2083
2084
  {"objectID":"b77353b8a14000713eaef315f5c67fae4aa8fdc2924e7e1364ebb371c65cbaee","title":"Factory Pattern Migration Guide","url":"/docs/development/factory-migration#factory-pattern-migration-guide","content":"Comprehensive guide for migrating to NeuroLink's factory pattern architecture, ensuring consistent provider management and scalable implementation.","hierarchy":{"lvl0":"Development","lvl1":"Factory Pattern Migration Guide","lvl2":"Factory Pattern Migration Guide","lvl3":""}},
2084
2085
  {"objectID":"f49c6c009f0bcdcecc8fb48ca17029ea660152a934848791a61dd4703825663c","title":"Why Factory Patterns","url":"/docs/development/factory-migration#why-factory-patterns","content":"The factory pattern in NeuroLink provides:\nConsistent Provider Creation: Standardized instantiation across all AI providers\nCentralized Configuration: Single source of truth for provider settings\nLifecycle Management: Proper initialization, caching, and cleanup\nType Safety: Full TypeScript support with compile-time validation\nExtensibility: Easy addition of new providers without code changes","hierarchy":{"lvl0":"Development","lvl1":"Factory Pattern Migration Guide","lvl2":"Why Factory Patterns","lvl3":""}},
2085
2086
  {"objectID":"e98fa4fbd395967337fec1d58d1c960279534030ed9d6ad02d810a5e0eab3b11","title":"Step 1: Assess Current Implementation","url":"/docs/development/factory-migration#step-1-assess-current-implementation","content":"Pre-Migration Checklist:","hierarchy":{"lvl0":"Development","lvl1":"Factory Pattern Migration Guide","lvl2":"Step 1: Assess Current Implementation","lvl3":""}},
@@ -2089,6 +2090,7 @@
2089
2090
  {"objectID":"9c1caca4263c63876f9f76fbc21ee1a79d73ac2bd8ed6b930a9d00a98218da2f","title":"Step 3: Refactor Provider Instantiation","url":"/docs/development/factory-migration#step-3-refactor-provider-instantiation","content":"Before (Legacy Pattern):\n\nAfter (Factory Pattern):","hierarchy":{"lvl0":"Development","lvl1":"Factory Pattern Migration Guide","lvl2":"Step 3: Refactor Provider Instantiation","lvl3":""}},
2090
2091
  {"objectID":"8d8cde70c29af2594584dc5841e19302c7d5ac3338961613760d63a3ec5a48a4","title":"Step 4: Migrate Configuration Management","url":"/docs/development/factory-migration#step-4-migrate-configuration-management","content":"Before (Environment Variables):\n\nAfter (Centralized Configuration):","hierarchy":{"lvl0":"Development","lvl1":"Factory Pattern Migration Guide","lvl2":"Step 4: Migrate Configuration Management","lvl3":""}},
2091
2092
  {"objectID":"fd93fbe3bf98a96c1b04be17f42e34ff62cda078fc46e16f0bfb3da03519b92d","title":"Step 5: Update Error Handling","url":"/docs/development/factory-migration#step-5-update-error-handling","content":"Before (Manual Error Handling):\n\nAfter (Factory-Managed Error Handling):","hierarchy":{"lvl0":"Development","lvl1":"Factory Pattern Migration Guide","lvl2":"Step 5: Update Error Handling","lvl3":""}},
2093
+ {"objectID":"a6b382e016038701ecd499b5dd7d936a2987099b236043eaf58835d543deec77","title":"Unit Tests for Factory Pattern","url":"/docs/development/factory-migration#unit-tests-for-factory-pattern","content":"Planned: this example uses a factory instance (neurolink.getProviderFactory()) that the current release does not have. ProviderFactory exposes static methods such as ProviderFactory.createProvider(name).","hierarchy":{"lvl0":"Development","lvl1":"Factory Pattern Migration Guide","lvl2":"Unit Tests for Factory Pattern","lvl3":""}},
2092
2094
  {"objectID":"a442c73665ddece0ee8a9fb5ca7c44c77aadc0d12a2c08dbf45a83779a98a0ae","title":"Pre-Migration","url":"/docs/development/factory-migration#pre-migration","content":"[ ] Audit existing provider usage patterns\n[ ] Identify all provider instantiation points\n[ ] Document current configuration management\n[ ] Assess error handling strategies\n[ ] Measure baseline performance metrics\n[ ] Plan rollback strategy","hierarchy":{"lvl0":"Development","lvl1":"Factory Pattern Migration Guide","lvl2":"Pre-Migration","lvl3":""}},
2093
2095
  {"objectID":"974f1ce9e4b095356c1e6f72d0730878e935dccb20daff68a0df595478d7e81f","title":"During Migration","url":"/docs/development/factory-migration#during-migration","content":"[ ] Install NeuroLink with factory support\n[ ] Configure provider factory settings\n[ ] Refactor provider instantiation code\n[ ] Update configuration management\n[ ] Implement unified error handling\n[ ] Add comprehensive testing\n[ ] Enable monitoring and logging","hierarchy":{"lvl0":"Development","lvl1":"Factory Pattern Migration Guide","lvl2":"During Migration","lvl3":""}},
2094
2096
  {"objectID":"b67926d8a755ad92e57bdd16c8f17d1f7f0a0ce03c42865cb1f341959b146e2e","title":"Post-Migration","url":"/docs/development/factory-migration#post-migration","content":"[ ] Verify all provider functionality\n[ ] Confirm performance improvements\n[ ] Validate error handling behavior\n[ ] Test failover scenarios\n[ ] Monitor production metrics\n[ ] Document new patterns for team\n[ ] Clean up legacy code","hierarchy":{"lvl0":"Development","lvl1":"Factory Pattern Migration Guide","lvl2":"Post-Migration","lvl3":""}},
@@ -3355,19 +3357,19 @@
3355
3357
  {"objectID":"a78bcf758e0d2cbf2d2e9ad39bb04c851848618fb55718447904be31d350055b","title":"Limitations","url":"/docs/features/csv-support#limitations","content":"Max file size: 10MB by default (configurable)\nMax rows: 1000 by default (configurable)\nEncoding: auto-detected via BOM + chardet (UTF-8 / UTF-16 / Windows-1252 / Latin-1 …), or forced with encoding (#362)\nPer-row size: a single row is capped at 10MB to bound memory; larger rows fail fast with a clear error (#371)\nParse timeout: parsing is time-bounded (30s strings / 5min files); on timeout partial rows are returned with metadata.parseTimedOut (#379)\nRow shape: parsed rows are validated to be string-keyed objects with string values; a malformed row aborts the parse with [CSVProcessor] Invalid CSV row <n> (#384)\nToken limits: Large CSV files may exceed provider token limits\nStreaming: CSV content is parsed and formatted before sending (not streamed to LLM)","hierarchy":{"lvl0":"Features","lvl1":"CSV File Support","lvl2":"Limitations","lvl3":""}},
3356
3358
  {"objectID":"1e48831d1c4fc775af2633d0340bdeb3d11c96abc213cbdd814a53d14ce500df","title":"Related Features","url":"/docs/features/csv-support#related-features","content":"Office Documents: DOCX, PPTX, XLSX processing\nPDF Support: PDF document processing\nImage Support: Similar multimodal input for images\nFile Detection: Auto-detect file types with confidence scores\nMemory Efficient: Streaming parser for large files\nProvider Agnostic: Works across supported providers\nCLI Integration: Full CLI support with options","hierarchy":{"lvl0":"Features","lvl1":"CSV File Support","lvl2":"Related Features","lvl3":""}},
3357
3359
  {"objectID":"19734b9ffaeb8376dfcebd944730a4cedae77bc1e7ed769733b8b71b1758c421","title":"Summary","url":"/docs/features/csv-support#summary","content":"CSV support is multimodal input (like images)\nUse csvFiles array or files array (auto-detect)\nCustomize with csvOptions (maxRows, formatStyle, includeHeaders)\nWorks across supported providers (not just vision models)\nMemory efficient streaming parser\nCLI support with --csv, --file, --csv-max-rows, --csv-format\nOnly types exposed from package (not classes)","hierarchy":{"lvl0":"Features","lvl1":"CSV File Support","lvl2":"Summary","lvl3":""}},
3358
- {"objectID":"fce0b532226adb069bbeb5459dc5e4ec28037617ca805845768d918653ddbfd5","title":"The `decide` inference type","url":"/docs/features/decide-inference-type","content":"The decide inference type\n\nDeep-dive: generate, stream, decide: a third inference type for NeuroLink β€”\nwhy this shipped as a provider rather than a subsystem, the five call sites, and the four\ntransport bugs found by adding the Vercel AI Gateway (two of which produced plausible output).\n\nNeuroLink recognises three inference types. Two of them produce text:\n\n| Type | Call | Produces |\n| ------------ | ------------------------ | ------------------------------ |\n| generate | neurolink.generate() | text |\n| stream | neurolink.stream() | text, incrementally |\n| decide | neurolink.decide() | typed judgements β€” no text |\n\nA decision model takes one state plus a map of named, typed questions and\nreturns one typed answer per question, all evaluated in a single parallel pass.\nThere is no text anywhere in the response, so nothing has to be parsed back out\nof prose. The decide providers are TypeSafe's Jev, Convai Innovations'\nopen-weights Laya, Juspay's open-weights XOR, which also reads images and\nvideo, Subquadratic's hosted SubQ Snap, Perplexity's hosted Decisions\nAPI, which also reads images,\nCloudflare's Clef models on Workers AI,\nwhich also read images, and OpenAI's\nDecisions API (a public beta), which also reads images.\n\nThis is not neurolink.evaluate(), which scores an\nalready-generated response with RAGAS scorers. Different feature, different\nword.\n\nThe three primitives\n\n| Type | Question | Answer fields |\n| --------- | ------------------------------ | ------------------------------------------------ |\n| boolean | Is this statement true? | probability (0–1) β€” no confidence |\n| choice | Which option from this set? | choice, probabilities, confidence |\n| score | Rate against an ordered rubric | score, legend, probabilities, confidence |\n\nAll three mix freely in one call.\n\nVocabulary note. TypeSafe calls the yes/no primitive a noul and answers\nit in a field of the same name. The Vercel AI SDK and Pydantic AI both renamed\nthat to boolean/probability when exposing it, and NeuroLink follows them β€”\nthe vendor's spelling is translated inside TypeSafeProvider, so another\ndecision provider slots in without changing any call site.\n\nConfidence is not probability\n\nprobabilities says what the model thinks. confidence says _whether you\nshould act on it_. On TypeSafe's Jev it is calibrated β€” derived from the\ndistribution, not self-reported β€” which is what makes it usable as a gate. Each\nprovider reports its own: Perplexity's is, in Perplexity's words, the model's own\ncertainty estimate and not the top probability, Perplexity does not call it\ncalibrated, and NeuroLink has not measured whether it is, so tune a threshold on\nyour own data (see the\nPerplexity guide).\n\nCalibration is a property of groups of answers, not a promise about any\none. Where a confidence is calibrated, answers scored 0.8 are right about 80%\nof the time across many answers. It does not mean a specific 0.8 answer is right.\n\nA boolean carries no confidence of its own. Use decisionBooleanConfidence(p)\nβ€” distance from a coin flip, so 0.5 β†’ 0 and 0/1 β†’ 1. Note also that a boolean\nand an equivalent two-option choice are not guaranteed to agree, and\ncomplementary booleans do not reliably sum to 1, so a threshold tuned on one\nquestion shape does not transfer to another.\n\nEnabling it\n\nGet a key at console.typesafe.ai/keys.\n\nLaya, at a Laya server or a LiteLLM proxy route\n\nLaya has no built-in endpoint. The base URL and key can equally come from the\nconfig passed to the SDK, new NeuroLink({ credentials: { laya: { baseURL, apiKey } } }),\nor per call; config set there counts when NeuroLink picks the default decision\nprovider, exactly as the environment does.\n\nWhen a TypeSafe key (TYPESAFE_API_KEY or AI_GATEWAY_API_KEY) is configured\nalongside Laya, TypeSafe is the default; Laya runs where a caller names it\n(provider: \"laya\") or when neither TypeSafe key is set. Laya counts as\nconfigured only with both its key and its base URL. See the\nLaya provider guide.\n\nXOR, at a deployment or a LiteLLM proxy route\n\nXOR, Juspay's open-weights decision model, has no built-in endpoint either.\nNeuroLink calls <base URL>/v1/systemone, and a trailing /v1 on the base URL\nis accepted. The base URL and key can equally come from the config passed to the\nSDK, new NeuroLink({ credentials: { xor: { baseURL, apiKey } } }), or per\ncall; config set there counts when NeuroLink picks the default decision\nprovider, exactly as the environment does. On a LiteLLM proxy the key's team\nmust allow xor-1.1, otherwise the proxy answers 403 team_model_access_denied.\n\nBuilt-in features use the first configured decision provider in the order\nTypeSafe, Laya, XOR, SubQ, Perplexity, Cloudflare Clef, OpenAI Decisions. XOR counts as configured only with both its key\nand its base URL, and runs where a caller names it (provider: ","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"","lvl3":""}},
3360
+ {"objectID":"fce0b532226adb069bbeb5459dc5e4ec28037617ca805845768d918653ddbfd5","title":"The `decide` inference type","url":"/docs/features/decide-inference-type","content":"The decide inference type\n\nDeep-dive: generate, stream, decide: a third inference type for NeuroLink β€”\nwhy this shipped as a provider rather than a subsystem, the five call sites, and the four\ntransport bugs found by adding the Vercel AI Gateway (two of which produced plausible output).\n\nNeuroLink recognises three inference types. Two of them produce text:\n\n| Type | Call | Produces |\n| ------------ | ------------------------ | ------------------------------ |\n| generate | neurolink.generate() | text |\n| stream | neurolink.stream() | text, incrementally |\n| decide | neurolink.decide() | typed judgements β€” no text |\n\nA decision model takes one state plus a map of named, typed questions and\nreturns one typed answer per question, all evaluated in a single parallel pass.\nThere is no text anywhere in the response, so nothing has to be parsed back out\nof prose. The decide providers are TypeSafe's Jev, Convai Innovations'\nopen-weights Laya, Juspay's open-weights XOR, which also reads images and\nvideo, Subquadratic's hosted SubQ Snap, Perplexity's hosted Decisions\nAPI, which also reads images,\nCloudflare's Clef models on Workers AI,\nwhich also read images, and OpenAI's\nDecisions API (a public beta), which also reads images.\n\nThis is not neurolink.evaluate(), which scores an\nalready-generated response with RAGAS scorers. Different feature, different\nword.\n\nThe three primitives\n\n| Type | Question | Answer fields |\n| --------- | ------------------------------ | ------------------------------------------------ |\n| boolean | Is this statement true? | probability (0–1) β€” no confidence |\n| choice | Which option from this set? | choice, probabilities, confidence |\n| score | Rate against an ordered rubric | score, legend, probabilities, confidence |\n\nAll three mix freely in one call.\n\nVocabulary note. TypeSafe calls the yes/no primitive a noul and answers\nit in a field of the same name. The Vercel AI SDK and Pydantic AI both renamed\nthat to boolean/probability when exposing it, and NeuroLink follows them β€”\nthe vendor's spelling is translated inside TypeSafeProvider, so another\ndecision provider slots in without changing any call site.\n\nConfidence is not probability\n\nprobabilities says what the model thinks. confidence says _whether you\nshould act on it_. On TypeSafe's Jev it is calibrated β€” derived from the\ndistribution, not self-reported β€” which is what makes it usable as a gate. Each\nprovider reports its own: Perplexity's is, in Perplexity's words, the model's own\ncertainty estimate and not the top probability, Perplexity does not call it\ncalibrated, and NeuroLink has not measured whether it is, so tune a threshold on\nyour own data (see the\nPerplexity guide).\n\nCalibration is a property of groups of answers, not a promise about any\none. Where a confidence is calibrated, answers scored 0.8 are right about 80%\nof the time across many answers. It does not mean a specific 0.8 answer is right.\n\nA boolean carries no confidence of its own. Use decisionBooleanConfidence(p)\nβ€” distance from a coin flip, so 0.5 β†’ 0 and 0/1 β†’ 1. Note also that a boolean\nand an equivalent two-option choice are not guaranteed to agree, and\ncomplementary booleans do not reliably sum to 1, so a threshold tuned on one\nquestion shape does not transfer to another.\n\nEnabling it\n\nGet a key at console.typesafe.ai/keys.\n\nLaya, at a Laya server or a LiteLLM proxy route\n\nLaya has no built-in endpoint. The base URL and key can equally come from the\nconfig passed to the SDK, new NeuroLink({ credentials: { laya: { baseURL, apiKey } } }),\nor per call; config set there counts when NeuroLink picks the default decision\nprovider, exactly as the environment does.\n\nWhen a TypeSafe key (TYPESAFE_API_KEY or AI_GATEWAY_API_KEY) is configured\nalongside Laya, TypeSafe is the default; Laya runs where a caller names it\n(provider: \"laya\") or when neither TypeSafe key is set. Laya counts as\nconfigured only with both its key and its base URL. See the\nLaya provider guide.\n\nXOR, at a deployment or a LiteLLM proxy route\n\nXOR, Juspay's open-weights decision model, has no built-in endpoint either.\nNeuroLink calls <base URL>/v1/systemone, and a trailing /v1 on the base URL\nis accepted. The base URL must be https://; http:// is accepted only for\nlocalhost, 127.0.0.1 and [::1], because every request carries the key and\nthe state. A redirect from the endpoint is refused, not followed. The base URL\nand key can equally come from the config passed to the SDK,\nnew NeuroLink({ credentials: { xor: { baseURL, apiKey } } }), or per call; config set there counts when NeuroLink picks the default decision\nprovider, exactly as the environment does. On a LiteLLM proxy the key's team\nmust allow xor-1.1, otherwise the proxy answers 403 team_model_access_denied.\n\nBuilt-in features use the first configured decision provid","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"","lvl3":""}},
3359
3361
  {"objectID":"f91e7ef7473aa411ff8c0d3b04381325781477c1876408ffd5469dbaf2d9584c","title":"The decide inference type","url":"/docs/features/decide-inference-type#the-decide-inference-type","content":"Deep-dive: generate, stream, decide: a third inference type for NeuroLink β€”\nwhy this shipped as a provider rather than a subsystem, the five call sites, and the four\ntransport bugs found by adding the Vercel AI Gateway (two of which produced plausible output).\n\nNeuroLink recognises three inference types. Two of them produce text:\n\n| Type | Call | Produces |\n| ------------ | ------------------------ | ------------------------------ |\n| generate | neurolink.generate() | text |\n| stream | neurolink.stream() | text, incrementally |\n| decide | neurolink.decide() | typed judgements β€” no text |\n\nA decision model takes one state plus a map of named, typed questions and\nreturns one typed answer per question, all evaluated in a single parallel pass.\nThere is no text anywhere in the response, so nothing has to be parsed back out\nof prose. The decide providers are TypeSafe's Jev, Convai Innovations'\nopen-weights Laya, Juspay's open-weights XOR, which also reads images and\nvideo, Subquadratic's hosted SubQ Snap, Perplexity's hosted Decisions\nAPI, which also reads images,\nCloudflare's Clef models on Workers AI,\nwhich also read images, and OpenAI's\nDecisions API (a public beta), which also reads images.\n\nThis is not neurolink.evaluate(), which scores an\nalready-generated response with RAGAS scorers. Different feature, different\nword.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"The decide inference type","lvl3":""}},
3360
3362
  {"objectID":"2c0f154b9ae29f0af1a097de9ccb435db1e8f5c35a4df8bb91526eadb7b5eb97","title":"The three primitives","url":"/docs/features/decide-inference-type#the-three-primitives","content":"| Type | Question | Answer fields |\n| --------- | ------------------------------ | ------------------------------------------------ |\n| boolean | Is this statement true? | probability (0–1) β€” no confidence |\n| choice | Which option from this set? | choice, probabilities, confidence |\n| score | Rate against an ordered rubric | score, legend, probabilities, confidence |\n\nAll three mix freely in one call.\n\nVocabulary note. TypeSafe calls the yes/no primitive a noul and answers\nit in a field of the same name. The Vercel AI SDK and Pydantic AI both renamed\nthat to boolean/probability when exposing it, and NeuroLink follows them β€”\nthe vendor's spelling is translated inside TypeSafeProvider, so another\ndecision provider slots in without changing any call site.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"The three primitives","lvl3":""}},
3361
3363
  {"objectID":"ff28050e2ddf3c21c910bc84ca32105968e1f7ffdbc3b19a983bb9adc6e9cc36","title":"Confidence is not probability","url":"/docs/features/decide-inference-type#confidence-is-not-probability","content":"probabilities says what the model thinks. confidence says _whether you\nshould act on it_. On TypeSafe's Jev it is calibrated β€” derived from the\ndistribution, not self-reported β€” which is what makes it usable as a gate. Each\nprovider reports its own: Perplexity's is, in Perplexity's words, the model's own\ncertainty estimate and not the top probability, Perplexity does not call it\ncalibrated, and NeuroLink has not measured whether it is, so tune a threshold on\nyour own data (see the\nPerplexity guide).\n\nCalibration is a property of groups of answers, not a promise about any\none. Where a confidence is calibrated, answers scored 0.8 are right about 80%\nof the time across many answers. It does not mean a specific 0.8 answer is right.\n\nA boolean carries no confidence of its own. Use decisionBooleanConfidence(p)\nβ€” distance from a coin flip, so 0.5 β†’ 0 and 0/1 β†’ 1. Note also that a boolean\nand an equivalent two-option choice are not guaranteed to agree, and\ncomplementary booleans do not reliably sum to 1, so a threshold tuned on one\nquestion shape does not transfer to another.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"Confidence is not probability","lvl3":""}},
3362
3364
  {"objectID":"91bfa1275464235c40e00d8a9ac0805e9e181450cccb6235fabd43178bef7c02","title":"Enabling it","url":"/docs/features/decide-inference-type#enabling-it","content":"Get a key at console.typesafe.ai/keys.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"Enabling it","lvl3":""}},
3363
3365
  {"objectID":"71509585343bb3860ff000ad67405f6ed19fbc26f8eb973ac1fe58088af460b4","title":"Laya, at a Laya server or a LiteLLM proxy route","url":"/docs/features/decide-inference-type#laya-at-a-laya-server-or-a-litellm-proxy-route","content":"Laya has no built-in endpoint. The base URL and key can equally come from the\nconfig passed to the SDK, new NeuroLink({ credentials: { laya: { baseURL, apiKey } } }),\nor per call; config set there counts when NeuroLink picks the default decision\nprovider, exactly as the environment does.\n\nWhen a TypeSafe key (TYPESAFE_API_KEY or AI_GATEWAY_API_KEY) is configured\nalongside Laya, TypeSafe is the default; Laya runs where a caller names it\n(provider: \"laya\") or when neither TypeSafe key is set. Laya counts as\nconfigured only with both its key and its base URL. See the\nLaya provider guide.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"Laya, at a Laya server or a LiteLLM proxy route","lvl3":""}},
3364
- {"objectID":"19994573e52cd09183db8050eadaea8ece3e291ef40c3009a5c44dfa959bf99c","title":"XOR, at a deployment or a LiteLLM proxy route","url":"/docs/features/decide-inference-type#xor-at-a-deployment-or-a-litellm-proxy-route","content":"XOR, Juspay's open-weights decision model, has no built-in endpoint either.\nNeuroLink calls <base URL>/v1/systemone, and a trailing /v1 on the base URL\nis accepted. The base URL and key can equally come from the config passed to the\nSDK, new NeuroLink({ credentials: { xor: { baseURL, apiKey } } }), or per\ncall; config set there counts when NeuroLink picks the default decision\nprovider, exactly as the environment does. On a LiteLLM proxy the key's team\nmust allow xor-1.1, otherwise the proxy answers 403 team_model_access_denied.\n\nBuilt-in features use the first configured decision provider in the order\nTypeSafe, Laya, XOR, SubQ, Perplexity, Cloudflare Clef, OpenAI Decisions. XOR counts as configured only with both its key\nand its base URL, and runs where a caller names it (provider: \"xor\") or when\nneither TypeSafe nor Laya is configured. It reads images and video; see\nImages and video and the\nXOR provider guide.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"XOR, at a deployment or a LiteLLM proxy route","lvl3":""}},
3366
+ {"objectID":"19994573e52cd09183db8050eadaea8ece3e291ef40c3009a5c44dfa959bf99c","title":"XOR, at a deployment or a LiteLLM proxy route","url":"/docs/features/decide-inference-type#xor-at-a-deployment-or-a-litellm-proxy-route","content":"XOR, Juspay's open-weights decision model, has no built-in endpoint either.\nNeuroLink calls <base URL>/v1/systemone, and a trailing /v1 on the base URL\nis accepted. The base URL must be https://; http:// is accepted only for\nlocalhost, 127.0.0.1 and [::1], because every request carries the key and\nthe state. A redirect from the endpoint is refused, not followed. The base URL\nand key can equally come from the config passed to the SDK,\nnew NeuroLink({ credentials: { xor: { baseURL, apiKey } } }), or per call; config set there counts when NeuroLink picks the default decision\nprovider, exactly as the environment does. On a LiteLLM proxy the key's team\nmust allow xor-1.1, otherwise the proxy answers 403 team_model_access_denied.\n\nBuilt-in features use the first configured decision provider in the order\nTypeSafe, Laya, XOR, SubQ, Perplexity, Cloudflare Clef, OpenAI Decisions. XOR counts as configured only with both its key\nand its base URL, and runs where a caller names it (provider: \"xor\") or when\nneither TypeSafe nor Laya is configured. It reads images and video; see\nImages and video and the\nXOR provider guide.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"XOR, at a deployment or a LiteLLM proxy route","lvl3":""}},
3365
3367
  {"objectID":"99d5ee10748044f10d6dd1e54785276aac1cf4375eca8dc6a1c9db90fc0c2158","title":"SubQ, at its hosted endpoint","url":"/docs/features/decide-inference-type#subq-at-its-hosted-endpoint","content":"Subquadratic's subq-snap-preview (public preview) speaks the same System One\nwire as TypeSafe, at a public endpoint, so a key alone configures it and there\nis no base URL to set. The key and base URL can equally come from the config\npassed to the SDK, new NeuroLink({ credentials: { subq: { apiKey, baseURL } } }),\nor per call. The provider id is subq; subquadratic and subq-snap name it\ntoo. It comes after TypeSafe, Laya and XOR and ahead of Perplexity and Cloudflare\nClef: its key belongs to no other provider, so it is set on purpose, whereas\ntheirs are shared with text providers and must not displace it. NeuroLink sends it no images or video: SubQ's image format is not\none the decide catalog can describe yet, so an image attached to a call is\nrefused before any request. The state window NeuroLink reports for it is advisory\n(reported, never enforced, not a guarantee); see the\nSubQ provider guide.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"SubQ, at its hosted endpoint","lvl3":""}},
3366
3368
  {"objectID":"dc8b9e9a2c66b1d2a60305a09a44263ceca755d40f04b6771e0a7c05a5237a64","title":"Perplexity, at its hosted endpoint","url":"/docs/features/decide-inference-type#perplexity-at-its-hosted-endpoint","content":"Perplexity's pplx-decider-v1-27b is a hosted API at a public endpoint, so a key\nalone configures it and there is no base URL to set. NeuroLink calls\n<base URL>/v1/decisions; a trailing /v1 on an override is accepted. The key\ncan equally come from the config passed to the SDK,\nnew NeuroLink({ credentials: { perplexityDecider: { apiKey } } }), or per call;\nconfig set there counts when a decide() call picks the default decision\nprovider, exactly as the environment does. The classifier router's auto gate\ncounts them too, per-call credentials included, so a\ncredentials.perplexityDecider passed on one call can make auto pick jev.\nThe provider id is perplexity-decider: the perplexity provider is the\nSonar text provider, which serves generate() and stream() and not decide().\n\nPERPLEXITY_API_KEY is shared with that text provider. A host that set it\nonly to use Sonar has therefore also configured decide, and built-in features\nwill use Perplexity whenever none of TypeSafe, Laya, XOR or SubQ is configured.\nPerplexity comes after XOR and SubQ in descriptor order, so it never displaces\none that is. Context compaction's relevance stage and summary gate need no opt-in of their\nown, so earlier conversation text starts going to Perplexity the first time a\nconversation outgrows its budget; model routing, tool routing and RAG planning do\nnothing unless enabled. To keep the shared key from activating decisions, pass\nthe text provider's key as credentials.perplexity instead of through the\nenvironment, and keep it out of .env too, because the SDK and the CLI load that\nfile into the environment, or configure one of TypeSafe, Laya, XOR and SubQ, which then\nreceives those texts instead. The Perplexity provider guide lists\nwhat each consumer sends\nand the\nexact switches.\nIt reads images but no video; see Images and video.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"Perplexity, at its hosted endpoint","lvl3":""}},
3367
3369
  {"objectID":"86d184ec9e501d4e94e973c833eaee71bb40744e683334ad36c497c3f625387f","title":"Cloudflare Clef, on Workers AI","url":"/docs/features/decide-inference-type#cloudflare-clef-on-workers-ai","content":"Cloudflare's clef and clef-flash are hosted on Workers AI at a public\nendpoint, so there is no base URL to set. The account id is part of the route, so\nClef counts as configured only with both the token and the account id. They can\nequally come from the config passed to the SDK,\nnew NeuroLink({ credentials: { cloudflareClef: { apiKey, accountId } } })\n(baseURL is optional), or per call; config set there counts when a decide()\ncall picks the default decision provider, exactly as the environment does. The\nclassifier router's auto gate counts them too, per-call credentials included,\nso a credentials.cloudflareClef passed on one call can make auto pick jev.\nThe provider id is cloudflare-clef: the cloudflare provider is the Workers AI text\nprovider, which serves generate() and stream() and not decide(), and\ncredentials.cloudflare does not configure decide.\n\nThe Workers AI endpoint's state window changed during October 2026.\nCloudflare documents a 64K window; until 2026-10-04 text past about 2,048 tokens\nwas ignored without an error, and on 2026-10-07 states of at least 190,153 tokens\n(clef-flash) and 52,154 (clef) were read in full (hosted service or model:\nunknown). NeuroLink refuses a state it estimates at more than 16,000 tokens with\nmax_tokens_exceeded, which every built-in consumer treats as \"carry on as\nbefore\"; see Limits and gotchas. Latency grows with the\nstate, about 0.2 s per 1,000 tokens on large ones, so NeuroLink's default timeout\nadds 250 ms per 1,000 estimated tokens.\n\nCLOUDFLARE_API_KEY and CLOUDFLARE_ACCOUNT_ID are shared with that text\nprovider. A host that set them only to use Workers AI text has therefore also\nconfigured decide, and built-in features will use Clef whenever none of\nTypeSafe, Laya, XOR, SubQ or Perplexity is configured. Clef comes after\nTypeSafe, Laya, XOR, SubQ and Perplexity, so it never displaces one that is. No switch turns it off while the two\nvariables are set.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"Cloudflare Clef, on Workers AI","lvl3":""}},
3368
3370
  {"objectID":"08fd87a8baa41fd742824c8457907e72804c393825cb2f67997a356c98b4211b","title":"OpenAI Decisions, at its hosted endpoint","url":"/docs/features/decide-inference-type#openai-decisions-at-its-hosted-endpoint","content":"OpenAI's Decisions API is a public beta at a public endpoint, so a key alone\nconfigures it and there is no base URL to set. NeuroLink calls\n<base URL>/v1/decisions; a trailing /v1 on an override is accepted. The key\ncan equally come from the config passed to the SDK,\nnew NeuroLink({ credentials: { openaiDecisions: { apiKey } } }), or per call;\nconfig set there counts when a decide() call picks the default decision\nprovider, exactly as the environment does. The classifier router's auto gate is\nread differently: it looks at the constructor's credentials and the environment\nonly, so a credentials.openaiDecisions passed on one call does not influence\nit. The provider id is openai-decisions: the openai provider is the chat\nprovider, which serves generate() and stream() and not decide(), and\ncredentials.openai does not configure decide. Its wire is OpenAI's own (named\nquestions in an array, an array of answers), so NeuroLink translates both ways;\nthe question types you write are unchanged. See the provider guide's\nwire mapping.\n\nOPENAI_API_KEY is shared with that chat provider. A host that set it only to\nuse OpenAI chat has therefore also configured decide, and built-in features will\nuse OpenAI Decisions whenever none of TypeSafe, Laya, XOR, SubQ, Perplexity or Cloudflare\nClef is configured. It comes last in the order, so it never displaces one that is.\nThe built-in consumers (model routing, tool routing, relevance compaction, the\nsummary gate, RAG planning) and the speech-to-text correction check then make paid\ndecision calls, though they still fail open. No switch turns it off while the key\nis set (short of a gateway OPENAI_BASE_URL, below). neurolink.decide() and tryDecide() build a fresh provider for every\ncall, so a key OpenAI rejects costs one failing request per decision site each\ntime, and the 401 latch never carries across calls. The provider guide explains\nwhen NeuroLink uses it\nand\nhow the two providers share the key.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"OpenAI Decisions, at its hosted endpoint","lvl3":""}},
3369
3371
  {"objectID":"7990ffc08aca0afbeae4310cfdcd3758daf52da4d9edd1da90a82b683f4d7d41","title":"Two transports","url":"/docs/features/decide-inference-type#two-transports","content":"The same model is reachable two ways. Which one runs is decided once, in the\nconstructor:\n\n| | Direct | Vercel AI Gateway |\n| ------------------- | ------------------ | --------------------------------------------- |\n| Key | TYPESAFE_API_KEY | AI_GATEWAY_API_KEY |\n| Endpoint | api.typesafe.ai | ai-gateway.vercel.sh/v4/ai/evaluation-model |\n| Model named in | request body | ai-model-id header |\n| Question vocabulary | noul | boolean |\n| confidence | on each answer | on providerMetadata, not on the answer |\n| Billed by | TypeSafe | Vercel |\n\nHolding both keys keeps the direct transport, so the confidence figures a\nhost already sees do not shift underneath it when a second key appears. Both\ntransports report the vendor's calibrated confidence β€” the gateway simply puts\nit somewhere else, under providerMetadata.typesafe.confidence.<questionId>,\nleaving the answer objects without one. Set TYPESAFE_TRANSPORT=gateway (or\ncredentials.typesafe.transport) to override.\n\n⚠️ Read that field, not the distribution peak. It is tempting to take\nmax(probabilities) when an answer carries no confidence, and on a\nnear-certain answer the two agree. On an uncertain one they do not, and not by a\nlittle: a measured four-way choice returned probabilities\n{alpha 0.16, beta 0.28, gamma 0.33, delta 0.23} β€” a peak of 0.33 against a\nreported confidence of 0.10. That gap straddles the default\nminUpgradeConfidence of 0.3, so the derived number clears a bar the real one\nfails and a near-random pick gets acted on as a confident one. The peak stays as\nthe fallback when neither source reports a confidence, and it is genuinely a\ndifferent quantity: an even distribution over N options lands near 1/N, not 0.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"Two transports","lvl3":""}},
3370
- {"objectID":"e5df7db87d4cb31c67fcce769cf5a3573764cb358ed9ee4b41f7ce86cb3954b7","title":"Using it","url":"/docs/features/decide-inference-type#using-it","content":"readDecisionBoolean / readDecisionChoice / readDecisionScore validate at\nruntime and return undefined for a missing id or a mismatched type, so no\ncall site needs a type assertion.\n\nUse decide() instead of tryDecide() when you want the failure to surface;\nit throws a ProviderError whose cause carries a typed kind\n(authentication, rate_limit, max_tokens_exceeded, …).\n\nMore questions than a provider takes. A provider that caps the questions in\none request (Laya and Cloudflare Clef take 64) refuses a longer map from decide() with\nmax_tokens_exceeded. tryDecide(), which every built-in consumer calls,\nsplits the map at the cap instead, keeps the questions in the order given, runs\nup to four batches at a time and joins the answers into one result: usage is\nsummed, the latency is the slowest batch's, and requestId lists the batches'\nids. A batch that fails costs only its own questions, which then have no answer\n(the read* helpers return undefined for them, and every built-in consumer\ncarries on without that decision); tryDecide() returns null only when every\nbatch failed. The state and any media are sent with each batch, so a split\nrequest costs the state's tokens once for each batch. A provider with no cap\n(TypeSafe, XOR, OpenAI Decisions) always gets one request.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"Using it","lvl3":""}},
3372
+ {"objectID":"e5df7db87d4cb31c67fcce769cf5a3573764cb358ed9ee4b41f7ce86cb3954b7","title":"Using it","url":"/docs/features/decide-inference-type#using-it","content":"readDecisionBoolean / readDecisionChoice / readDecisionScore validate at\nruntime and return undefined for a missing id or a mismatched type, so no\ncall site needs a type assertion.\n\nticketText is attacker-controlled, so the verdict is a hint: keep assignTo\nreversible or put a deterministic check in front of it (see the Untrusted input\nbullet under What it is bad at).\n\nUse decide() instead of tryDecide() when you want the failure to surface;\nit throws a ProviderError whose cause carries a typed kind\n(authentication, rate_limit, max_tokens_exceeded, …).\n\nMore questions than a provider takes. A provider that caps the questions in\none request (Laya and Cloudflare Clef take 64) refuses a longer map from decide() with\nmax_tokens_exceeded. tryDecide(), which every built-in consumer calls,\nsplits the map at the cap instead, keeps the questions in the order given, runs\nup to four batches at a time and joins the answers into one result: usage is\nsummed, the latency is the slowest batch's, and requestId lists the batches'\nids. A batch that fails costs only its own questions, which then have no answer\n(the read* helpers return undefined for them, and every built-in consumer\ncarries on without that decision); tryDecide() returns null only when every\nbatch failed. The state and any media are sent with each batch, so a split\nrequest costs the state's tokens once for each batch. A provider with no cap\n(TypeSafe, XOR, OpenAI Decisions) always gets one request.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"Using it","lvl3":""}},
3371
3373
  {"objectID":"7232a490e9e72e01dbe1a12de9470a38ed66ef91aa076b8c8cc745770eb03545","title":"From the CLI","url":"/docs/features/decide-inference-type#from-the-cli","content":"The same primitive is available as neurolink decide [state], which calls\ndecide() (not tryDecide()) and prints one line per answer:\n\nTo ask about an image or a video, add --image <path> (repeatable) or\n--video <path>. XOR reads both, Perplexity, Cloudflare Clef and OpenAI Decisions\nread images only, and TypeSafe, Laya and SubQ read neither:\n\nSee the CLI command reference for the full flag\nlist, including --state-file, --questions-file, --image, --video and\n--format json.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"From the CLI","lvl3":""}},
3372
3374
  {"objectID":"3b801c727cb399feb7390c3ad67aba9ea5f77581096bb852b7aafb87b70998aa","title":"A choice answer is also a ranking","url":"/docs/features/decide-inference-type#a-choice-answer-is-also-a-ranking","content":"readDecisionChoice returns ranked β€” every option sorted by probability,\nhighest first. One choice question over N options therefore ranks all N in a\nsingle request. This is the basis for picking from a large catalogue.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"A choice answer is also a ranking","lvl3":""}},
3373
3375
  {"objectID":"e67682840a5ce9650dba2a1d437b0dfbba456cae60fa3f607127e209bf1ec3e7","title":"Images and video","url":"/docs/features/decide-inference-type#images-and-video","content":"A decision provider whose descriptor declares media limits reads images, and\npossibly one video, alongside state. XOR does, and so do Perplexity, Cloudflare\nClef and OpenAI Decisions, which declare images only and no video; TypeSafe, Laya and SubQ\ndo not. Two optional fields on the request carry them, for decide() and\ntryDecide() alike:\nimages β€” up to 8 images, the limit XOR, Perplexity and OpenAI Decisions each\n declare (OpenAI's is NeuroLink's own allowance, not a limit OpenAI documents);\n Cloudflare Clef takes up to 4.\nvideo β€” one video, for a provider that declares video (XOR).\n\nEach image and the video takes the same three input forms:\na Buffer;\na local file path;\na data:image/…;base64, or data:video/…;base64, URL.\n\nNeuroLink identifies a Buffer or a file from its bytes, not its extension β€” PNG,\nJPEG, WebP and GIF images, and MP4, MOV and WebM video β€”\nand sends it as a data: URL. A data: URL you pass yourself must hold base64\nimage or video content. Clef normalizes image/jpg to image/jpeg; other data URLs are sent as given. Perplexity and Cloudflare Clef read\nPNG, JPEG and WebP only, and refuse a GIF before any request. OpenAI Decisions\nsends every image as an inline data URL and checks no format list, because\nOpenAI's list is not established.\n\nWhat is refused. Everything NeuroLink can check is refused before any\nrequest, as a non-retryable invalid_request:\nan http(s) URL β€” media is not fetched for you, so pass a Buffer, a file path\n or a data: URL;\na string that is not a file path or a data: URL, such as bare base64 or a\n URL with another scheme;\na missing file, a directory, or an empty Buffer or file;\nsomething that is not an image or a video;\nmore than 8 images, or more than 4 for Cloudflare Clef;\na request body over the provider's limit: 8 MB for XOR, 32 MiB for Perplexity\n and for OpenAI Decisions (NeuroLink's own number for the latter), 256,000 bytes\n for Cloudflare Clef.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"Images and video","lvl3":""}},
@@ -3381,7 +3383,7 @@
3381
3383
  {"objectID":"e399806055971566454170aeec7214ec9b5948c8e3a35731a9c64b4ee2be7c21","title":"One funnel for all five sites","url":"/docs/features/decide-inference-type#one-funnel-for-all-five-sites","content":"Every one of those calls is stamped with a site β€” routing, toolRouting,\ncontextRelevance, summaryGate or ragPlan (the DecisionSite union) β€” and\ngoes through one private path on NeuroLink, which is also where a bound\ntryDecide() lands. For the four sites that run inside a NeuroLink request β€”\nrouting, toolRouting, contextRelevance and summaryGate β€” that path\nforwards the outer generate() / stream() call's per-call credentials,\nabortSignal and requestId (the top-level option, else\ncontext.requestId) to the decision, so a request that carries\ncredentials: { laya: {...} } routes and compacts against that account\nrather than the instance's; for routing the per-call credentials also count\ntowards the auto strategy's activation, so a host that holds no decision key\nitself still routes a request that carries one. ragPlan runs inside a\nhost-wired RAGPipeline, outside any NeuroLink request, so it receives only\nwhat the host puts on the options it hands tryDecide (see \"Host-wired\nconsumers\" below). The path also adds decision.site and\ndecision.host_question_count to the model.decision span; emits\ndecision:before / decision:after on the instance emitter; and runs the\ndecisionHooks described next. Without hooks or listeners, the decision\npayload β€” state and questions β€” is unchanged; per-call credentials are still\nforwarded, so the full request on the wire (account, base URL) can differ from\nthe instance's.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"One funnel for all five sites","lvl3":""}},
3382
3384
  {"objectID":"a472e427cc594fbcc2ea01a87a8ebf99f49ebb52d71a7d5e6ff8baa6667707d1","title":"Riding along: decisionHooks","url":"/docs/features/decide-inference-type#riding-along-decisionhooks","content":"Latency on a decision model is flat in question count, so a host with its own\nquestions about the same request pays nothing to ask them in the round trip\nNeuroLink is already making. decisionHooks on the constructor does exactly\nthat β€” one request per site, never a second:\n\nWhat the funnel guarantees:\n\n| Concern | Behaviour |\n| ----------------------- |","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"Riding along: decisionHooks","lvl3":""}},
3383
3385
  {"objectID":"fff45cefe577cc88ce4956ce2fbd51677da0f1d953c7c3330d96f4e26737da7e","title":"Reading the limits before you send: decisionLimits()","url":"/docs/features/decide-inference-type#reading-the-limits-before-you-send-decisionlimits","content":"neurolink.decisionLimits({ provider?, model?, credentials? }) returns the\nfigures the pre-flight check compares against, resolved for one model β€”\nprovider as decide() resolves it, model as model ?? the model decide() sends\n(the one registered for the provider: LAYA_MODEL / TYPESAFE_MODEL as read\nwhen providers were registered, else the default β€” a later change to the\nvariable moves neither), the per-model entry flattened over the base:\n\nmaxQuestions is present only for a provider that caps by question count\n(Laya); a reading without the key has no count cap, and a host should test\nfor the key rather than compare against Infinity. media is present only\nfor a provider that reads images or video (XOR, Perplexity, Cloudflare Clef,\nOpenAI Decisions); its absence is what the media refusal for TypeSafe and Laya is\nbased on.\n\nenforcedLocally says who refuses: NeuroLink itself, before any network call\n(Laya and XOR, whose servers would silently truncate or fail inside the\nengine), or the provider's server\n(TypeSafe and OpenAI Decisions, whose descriptor rows are marked advisory and are\nreported but never enforced here β€” a local refusal would turn a server ceiling\ninto a client one that drifts from it). estimateDecisionStateTokens is the very\nfunction the pre-flight refusal uses, so a state it sizes as fitting is sent\nand one it sizes as over is refused; pass the reading so non-ASCII text is\ncharged at the model's measured rate. A named provider is read whether or\nnot it is configured β€” its limits are facts about the model β€” while the\ndefault requires a configured provider, as tryDecide() does.\n\nLaya reads far less than Jev. About 768 tokens of state on\ntyped-decisions and multilingual, and 320 on english, auto or an\nunrecognised model name, against Jev's ~33,000. Laya's server does not refuse a\nlonger state; it answers from the first 1,024 tokens (512 on english).","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"Reading the limits before you send: decisionLimits()","lvl3":""}},
3384
- {"objectID":"f6543a204326fbf7f27ac5c61c2f10b76f0541f3acb61eec93291921404e1a37","title":"What it is bad at","url":"/docs/features/decide-inference-type#what-it-is-bad-at","content":"\"Cannot hallucinate\" is a claim about output shape, not answer\ncorrectness: a decision model cannot return malformed JSON or an option you\ndid not offer, but it can still be wrong. TypeSafe reports ~68% accuracy on its\nown 711-case benchmark, against ~73% for a frontier model. It wins cost and\nlatency on every row and loses accuracy on every row β€” so it is right for\ndecisions that are gated and reversible, and wrong for final answers.\nIt reads literally. It answers the question you wrote, not the one you\n meant. Split an ambiguous question into two and combine them in code.\nAsk about the act, not the subject. \"This task touches money\" scores high\n on ordinary code that merely concerns money. The risk question in\n classifyJev is worded to exclude writing and testing such code, precisely\n because the naive phrasing escalated everything.\nIt is not a calculator. Counting, arithmetic and date comparison are\n unreliable β€” dates are read as text, not ordered quantities. A score is for\n thresholding and ranking, not for reading an exact magnitude off.\nIrrelevant state costs accuracy. Filter before sending.\nIt never explains itself. No rationale field exists, which rules it out\n where a decision must be auditable.\nOption order can matter. Test with reordered criteria if a call is close.\nDon't invert criteria. A boolean whose true description means \"no\"\n performs measurably worse.\n\nTune thresholds on your own labelled data if the decision matters, and once you\nhave, pin TYPESAFE_MODEL to a version id such as jev-1.13.0 β€” jev-latest\nis an alias and can move under you, invalidating a tuned threshold silently.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"What it is bad at","lvl3":""}},
3386
+ {"objectID":"f6543a204326fbf7f27ac5c61c2f10b76f0541f3acb61eec93291921404e1a37","title":"What it is bad at","url":"/docs/features/decide-inference-type#what-it-is-bad-at","content":"\"Cannot hallucinate\" is a claim about output shape, not answer\ncorrectness: a decision model cannot return malformed JSON or an option you\ndid not offer, but it can still be wrong. TypeSafe reports ~68% accuracy on its\nown 711-case benchmark, against ~73% for a frontier model. It wins cost and\nlatency on every row and loses accuracy on every row β€” so it is right for\ndecisions that are gated and reversible, and wrong for final answers.\nIt reads literally. It answers the question you wrote, not the one you\n meant. Split an ambiguous question into two and combine them in code.\nAsk about the act, not the subject. \"This task touches money\" scores high\n on ordinary code that merely concerns money. The risk question in\n classifyJev is worded to exclude writing and testing such code, precisely\n because the naive phrasing escalated everything.\nIt is not a calculator. Counting, arithmetic and date comparison are\n unreliable β€” dates are read as text, not ordered quantities. A score is for\n thresholding and ranking, not for reading an exact magnitude off.\nIrrelevant state costs accuracy. Filter before sending.\nIt never explains itself. No rationale field exists, which rules it out\n where a decision must be auditable.\nOption order can matter. Test with reordered criteria if a call is close.\nDon't invert criteria. A boolean whose true description means \"no\"\n performs measurably worse.\nUntrusted input. Any text in state can steer a verdict: a user prompt,\n a ticket, an earlier message, a retrieved document, tool output, a\n transcript, a third-party server's description. A decision model can only\n return an option you offered, but text written to push it can still pick the\n option the author wants. The built-in consumers are advisory and fail-open,\n and none of them feeds human-in-the-loop approval or a guardrail. Their reach\n is bounded, not zero.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"What it is bad at","lvl3":""}},
3385
3387
  {"objectID":"f51228c123e6f86e1889f9990b2592debd24cc90c1584ad7d35d1f9a7aac8b82","title":"Adding another decision provider","url":"/docs/features/decide-inference-type#adding-another-decision-provider","content":"The decide inference type is provider-neutral by construction. Another\ndecision model needs:\nAn AIProviderName member and a <Name>Models enum\n (src/lib/constants/enums.ts, outside the generated regions).\nA provider class extending SystemOneDecisionProvider\n (src/lib/providers/systemOneDecision.ts), which owns the request loop,\n retries, the auth circuit breaker and answer parsing, and supplies the\n throwing getAISDKModel() / executeStream() stubs, the same shape the\n embedding-only providers (voyage.ts, jina.ts) use. The class supplies\n its endpoint, headers, body, error parsing and messages.\nA descriptor with inferenceKinds: [\"decide\"], no auto-select ranks, and\n healthCheck: \"env-only\". That one field is what keeps a text-less model out\n of every generation fallback chain; nothing else needs to know the provider\n by name. A provider that reads images or video also declares\n decisionLimits.media; without it, a request that carries media is refused\n before any network call.\nA registration block, a credentials slice, a manifest, and the usual Tier-3\n onboarding artifacts β€” pnpm run verify:provider-onboarding enumerates them.\n\nThe Tier-2 catalog JSON path cannot be used: its schema pins tier: 2, accepts\nonly an 8-flag text-generation capability vocabulary, and requires\ndefaultMaxOutputTokens and pricingPerMTok.output β€” none of which a model\nthat emits no text can honestly supply.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"Adding another decision provider","lvl3":""}},
3386
3388
  {"objectID":"31d00aee561a454dc5082ad8002f9dbc0e33f15463cfee1636497043c8f9ee55","title":"Testing","url":"/docs/features/decide-inference-type#testing","content":"The suite drives dist/index.js only. Live tests skip without\nTYPESAFE_API_KEY; the degradation and discriminator tests run unconditionally,\nbecause \"behaves correctly with no key\" and \"a text-less provider is unreachable\nfrom generation\" are the contracts that matter most.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"Testing","lvl3":""}},
3387
3389
  {"objectID":"d0993177d0de353bf96138199dbc9fad84b1bdff72bb534dc7c6a510266e3be9","title":"Embeddings","url":"/docs/features/embeddings","content":"Embeddings\n\nStatus: Stable | Availability: SDK + CLI + Server\n\nOverview\n\nEmbeddings convert text into dense numerical vectors that capture semantic meaning. Two texts with similar meanings produce vectors that are close together in the embedding space, enabling use cases like:\nSemantic search -- find documents by meaning rather than exact keyword match\nRAG pipelines -- retrieve relevant context before generating answers\nSimilarity comparison -- measure how related two pieces of text are\nClustering and classification -- group or categorize text automatically\n\nNeuroLink exposes embeddings through two provider methods (embed() and embedMany()), two server endpoints, and indirectly through the CLI's RAG commands. Every implementation calls its provider's embeddings API directly.\n\nQuick Start\n\nProvider Support\n\nNine providers implement embedding support: OpenAI, Google AI Studio, Google Vertex, Amazon Bedrock, Cohere, Voyage, Jina, Ollama, and LiteLLM. Ollama requires a locally available embedding model; LiteLLM requires an embedding deployment on its gateway. Other providers throw a descriptive error when embed() or embedMany() is called (see Unsupported Providers below).\n\n| Provider | Default Model | Env Override | Dimensions |\n| ---------------- | ------------------------------ | --------------------------- | -------------------- |\n| OpenAI | text-embedding-3-small | OPENAI_EMBEDDING_MODEL | 1536 |\n| Google AI Studio | gemini-embedding-001 | GOOGLE_AI_EMBEDDING_MODEL | 3072 |\n| Google Vertex | text-embedding-004 | VERTEX_EMBEDDING_MODEL | 768 |\n| Amazon Bedrock | amazon.titan-embed-text-v2:0 | BEDROCK_EMBEDDING_MODEL | 1024 |\n| Cohere | embed-english-v3.0 | modelName argument | Model dependent |\n| Voyage | voyage-3.5 | VOYAGE_MODEL | Model dependent |\n| Jina | jina-embeddings-v3 | JINA_MODEL | Model dependent |\n| Ollama | nomic-embed-text | OLLAMA_EMBEDDING_MODEL | Model dependent |\n| LiteLLM | gemini-embedding-001 | LITELLM_EMBEDDING_MODEL | Deployment dependent |\n\nGoogle AI Studio and Google Vertex also accept GOOGLE_EMBEDDING_MODEL as a shared fallback environment variable.\n\nAmazon Bedrock also accepts AWS_EMBEDDING_MODEL as an alternative environment variable.\n\nSDK API\n\nprovider.embed(text, modelName?)\n\nGenerate an embedding vector for a single text string.\n\nParameters:\n\n| Name | Type | Required | Description |\n| ----------- | -------- | -------- | ------------------------------------------------------ |\n| text | string | Yes | The text to embed |\n| modelName | string | No | Override the default embedding model for this provider |\n\nReturns: Promise<number[]> -- the embedding vector.\n\nprovider.embedMany(texts, modelName?)\n\nGenerate embedding vectors for multiple texts in a single batch. Each provider implementation handles its own batching, so a model that imposes a batch-size limit is chunked to fit it. Amazon Bedrock processes each text individually via Promise.all because the Titan Embed API accepts one input at a time.\n\nParameters:\n\n| Name | Type | Required | Description |\n| ----------- | ---------- | -------- | ------------------------------------------------------ |\n| texts | string[] | Yes | The texts to embed |\n| modelName | string | No | Override the default embedding model for this provider |\n\nReturns: Promise<number[][]> -- one embedding vector per input text.\n\nResponse validation\n\nCohere, Voyage, and Jina reject responses containing empty vectors or values\nthat are not finite numbers. This changes malformed responses that previously\nreturned an empty or unusable vector into rejected promises. Valid vectors,\nincluding zero and negative values, retain their original values.\n\nEach batch must return one vector per input. Voyage and Jina additionally\nrequire complete index coverage and restore the input order when the response\narrives out of order. Cohere's float envelope and legacy flat vector envelope\nare both supported. Cohere splits inputs at 96 texts and Voyage at 128; a\nmalformed later batch rejects the entire operation instead of returning partial\nresults. Passing an empty input array to these three providers returns []\nwithout a request.\n\nValidation errors retain the providers' existing error types: ProviderError\nfor Cohere and Voyage, and Error for Jina. These checks validate the response\nboundary; they do not establish a vendor model's availability.\n\nServer API\n\nThe NeuroLink server exposes two embedding endpoints under the /api/agent route group. Both ","hierarchy":{"lvl0":"Features","lvl1":"Embeddings","lvl2":"","lvl3":""}},
@@ -3477,14 +3479,14 @@
3477
3479
  {"objectID":"422196a1c2e1508dcd31ea7fb0c1dba130bfbeb917925ceb9f6c80a762fcfd30","title":"Using the all Preset","url":"/docs/features/guardrails-ai#using-the-all-preset","content":"If you want to use guardrails in combination with other built-in middleware like analytics, you can use the all preset.","hierarchy":{"lvl0":"Features","lvl1":"Guardrails AI Integration with Middleware","lvl2":"Using the all Preset","lvl3":""}},
3478
3480
  {"objectID":"4b7a1fe97ea0f23a386d90548d3214e8e24a6f36ffcff4df7d5859a78e6f9271","title":"Customizing Guardrails","url":"/docs/features/guardrails-ai#customizing-guardrails","content":"While presets provide a great starting point, you can also customize the behavior of the guardrails middleware by providing a custom configuration.\n\nThis new, streamlined approach provides a clean and scalable way to add safety and other enhancements to your AI models within the NeuroLink ecosystem.","hierarchy":{"lvl0":"Features","lvl1":"Guardrails AI Integration with Middleware","lvl2":"Customizing Guardrails","lvl3":""}},
3479
3481
  {"objectID":"1c07c45bcdcf7be8441182379a01af46db12b22af1ce3115ca29218979bd43bb","title":"See Also","url":"/docs/features/guardrails-ai#see-also","content":"For configuration examples, best practices, and troubleshooting, see the Guardrails Middleware Feature Guide.","hierarchy":{"lvl0":"Features","lvl1":"Guardrails AI Integration with Middleware","lvl2":"See Also","lvl3":""}},
3480
- {"objectID":"8630e6d05c16d6e1a2c3602641ac4460913f4744b471e4fd9de3e8f20a15a451","title":"Guardrails Implementation Guide","url":"/docs/features/guardrails-implementation","content":"Guardrails Implementation Guide\n\nThis document provides comprehensive documentation for the NeuroLink guardrails implementation, including pre-call filtering, content sanitization, and AI-powered evaluation.\n\nOverview\n\nThe guardrails implementation provides advanced content filtering and safety mechanisms for AI interactions. It includes:\nPre-call Evaluation: AI-powered safety assessment before processing\nContent Filtering: Bad words and regex pattern filtering\nParameter Sanitization: Input cleaning and modification\nEvaluation Actions: Configurable responses (block, sanitize, warn, log)\nVisual Proof: Screenshots demonstrating filtering in action\n\nArchitecture\n\nCore Components\nGuardrails Middleware (src/lib/middleware/builtin/guardrails.ts)\n\nThe main middleware component that orchestrates all guardrail functionality:\nGuardrails Utilities (src/lib/middleware/utils/guardrailsUtils.ts)\n\nCore utility functions for evaluation and filtering:\nperformPrecallEvaluation() - AI-powered safety assessment\napplyEvaluationActions() - Execute configured actions based on evaluation\napplySanitization() - Clean and modify request parameters\napplyContentFiltering() - Filter content using patterns and word lists\nType Definitions (src/lib/types/guardrails.ts)\n\nComplete TypeScript interfaces for configuration and results:\n\nConfiguration\n\nBasic Configuration\n\nAdvanced Configuration\n\nFeatures\n\nPre-call Evaluation\n\nAI-powered evaluation of user input before processing:\n\nContent Filtering\n\nTwo-tier filtering system:\nRegex Patterns (Priority 1)\nWord Lists (Priority 2)\n \n\nEvaluation Actions\n\nConfigurable responses based on evaluation results:\nblock: Prevent request processing entirely\nsanitize: Clean content and continue processing\nwarn: Log warning but allow processing\nlog: Record for monitoring but allow processing\n\nDemo Component\n\nUsing the Demo (neurolink-demo/middleware/guardrails-precall-demo.ts)\n\nDemo Features\nInteractive testing of guardrail functionality\nVisual feedback on filtering actions\nPerformance metrics and timing\nBefore/after content comparison\n\nVisual Proof\n\nScreenshots demonstrating guardrails in action:\nPre-call Filtering (guardrails-pre-call-filtering.png)\nShows evaluation process and decision making\nDisplays safety scores and reasoning\nContent Sanitization (guardrails-pre-call-filtering-2.png)\nBefore and after content comparison\nFiltering statistics and applied rules\nBlock Actions (guardrails-pre-call-filtering-3.png)\nDemonstrates request blocking for unsafe content\nShows error messages and user feedback\nPerformance Metrics (guardrails-pre-call-filtering-4.png)\nEvaluation timing and processing speeds\nImpact on overall request latency\n\nIntegration Examples\n\nWith MiddlewareFactory\n\nDirect Integration\n\nStreaming Support\n\nPerformance Considerations\n\nEvaluation Timing\nPre-call evaluation: ~2-5 seconds (depending on model)\nContent filtering: \\<100ms\nParameter sanitization: \\<50ms\n\nOptimization Tips\nUse faster evaluation models for real-time applications\nCache evaluation results for repeated content\nImplement timeout handling for slow evaluations\nMonitor provider availability and implement fallbacks\n\nError Handling\n\nGraceful Degradation\n\nError Scenarios\nEvaluation provider unavailable β†’ Fall back to content filtering only\nInvalid regex patterns β†’ Log error and skip pattern\nNetwork timeouts β†’ Use cached results or allow processing\n\nBest Practices\nConfiguration Management\nStart with conservative settings and adjust based on usage\nMonitor false positives and adjust thresholds\nUse different configurations for different use cases\nPerformance Optimization\nUse appropriate evaluation models (faster for real-time, more accurate for batch)\nImplement caching for repeated evaluations\nMonitor and optimize regex patterns\nContent Filtering\nPrioritize regex patterns over word lists for better performance\nTest regex patterns thoroughly before deployment\nKeep word lists updated and relevant\nMonitoring and Logging\nTrack evaluation results and actions taken\nMonitor performance impact on response times\nSet up alerts for high blocking rates\n\nAPI Reference\n\nCore Interfaces\n\nUtility Functions\n\nTroubleshooting\n\nCommon Issues\nEvaluation Taking Too Long\nCheck evaluation model availability\nImplement timeout handling\nConsider using faster models\nToo Many False Positives\nAdjust evaluation thresholds\nReview and refine regex patterns\nCheck word list relevance\nRegex Patterns Not Working\nValidate regex syntax\nTest patterns with sample content\nCheck for proper escaping\nPerformance Impact\nMonitor evaluation timing\nOptimize configuration settings\nConsider caching strategies\n\nDebug Mode\n\nEnable debug logging for detailed information:\n\nMigration Guide\n\nFrom Previous Implementations\n\nIf upgrading from older guardrail implementations:\nUpdate configuration format to new interfaces\nReplace deprecated methods with new utility functions\nTest evaluation thresholds and adjust as needed\nUpdate error handling to use new patterns\n\nBreaking Changes\nConfiguration structu","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Implementation Guide","lvl2":"","lvl3":""}},
3482
+ {"objectID":"8630e6d05c16d6e1a2c3602641ac4460913f4744b471e4fd9de3e8f20a15a451","title":"Guardrails Implementation Guide","url":"/docs/features/guardrails-implementation","content":"Guardrails Implementation Guide\n\nThis document provides comprehensive documentation for the NeuroLink guardrails implementation, including pre-call filtering, content sanitization, and AI-powered evaluation.\n\nOverview\n\nThe guardrails implementation provides advanced content filtering and safety mechanisms for AI interactions. It includes:\nPre-call Evaluation: AI-powered safety assessment before processing\nContent Filtering: Bad words and regex pattern filtering\nParameter Sanitization: Input cleaning and modification\nEvaluation Actions: Configurable responses (block, sanitize, warn, log)\nVisual Proof: Screenshots demonstrating filtering in action\n\nArchitecture\n\nCore Components\nGuardrails Middleware (src/lib/middleware/builtin/guardrails.ts)\n\nThe main middleware component that orchestrates all guardrail functionality:\nGuardrails Utilities (src/lib/middleware/utils/guardrailsUtils.ts)\n\nCore utility functions for evaluation and filtering:\nperformPrecallEvaluation() - AI-powered safety assessment\napplyEvaluationActions() - Execute configured actions based on evaluation\napplySanitization() - Clean and modify request parameters\napplyContentFiltering() - Filter content using patterns and word lists\nType Definitions (src/lib/types/guardrails.ts)\n\nComplete TypeScript interfaces for configuration and results:\n\nConfiguration\n\nBasic Configuration\n\nAdvanced Configuration\n\nFeatures\n\nPre-call Evaluation\n\nAI-powered evaluation of user input before processing:\n\nContent Filtering\n\nTwo-tier filtering system:\nRegex Patterns (Priority 1)\nWord Lists (Priority 2)\n \n\nRegex patterns run synchronously on the whole response (and sanitizationPatterns on the whole user prompt), so a pattern that can backtrack catastrophically would stall the process. Before a pattern is compiled it is checked, and it is refused when it:\nis longer than 1000 characters;\nrepeats a group in which a variable-length part (+, *, ?, {n,m}) can match the same text as what follows it, such as (a+)+, (\\w+\\s*)*, (.*a){10}, (a?a?)+ or (a{1,30}){1,30};\nrepeats a group whose alternatives may overlap, such as (a|aa)+;\nchains more than 8 optional parts (a?a?a?...) or more than 4 open-ended overlapping ones (.*a.*b.*c.*d.*e);\nuses a repetition bound above 500, such as a{1,1000}.\n\nRepeated groups whose variable parts are separated by a character they cannot match, such as (\\d{1,3}\\.){3} or ([a-z0-9-]+\\.)+, are accepted.\n\nA refused pattern is skipped and logged with logger.error (Refusing regex pattern ... for regexPatterns, Refusing sanitization pattern ... for sanitizationPatterns), the same way an invalid regex is. Nothing is thrown at the caller and the remaining patterns still run, but a skipped pattern filters nothing. The check is static and conservative: it refuses some safe patterns, compares classes on a sample of characters, only partly covers exponential shapes built from optional parts, and accepts polynomial ones (.*.*.*x), so test patterns on long input.\n\nEvaluation Actions\n\nConfigurable responses based on evaluation results:\nblock: Prevent request processing entirely\nsanitize: Clean content and continue processing\nwarn: Log warning but allow processing\nlog: Record for monitoring but allow processing\n\nDemo Component\n\nUsing the Demo (neurolink-demo/middleware/guardrails-precall-demo.ts)\n\nDemo Features\nInteractive testing of guardrail functionality\nVisual feedback on filtering actions\nPerformance metrics and timing\nBefore/after content comparison\n\nVisual Proof\n\nScreenshots demonstrating guardrails in action:\nPre-call Filtering (guardrails-pre-call-filtering.png)\nShows evaluation process and decision making\nDisplays safety scores and reasoning\nContent Sanitization (guardrails-pre-call-filtering-2.png)\nBefore and after content comparison\nFiltering statistics and applied rules\nBlock Actions (guardrails-pre-call-filtering-3.png)\nDemonstrates request blocking for unsafe content\nShows error messages and user feedback\nPerformance Metrics (guardrails-pre-call-filtering-4.png)\nEvaluation timing and processing speeds\nImpact on overall request latency\n\nIntegration Examples\n\nWith MiddlewareFactory\n\nDirect Integration\n\nStreaming Support\n\nPerformance Considerations\n\nEvaluation Timing\nPre-call evaluation: ~2-5 seconds (depending on model)\nContent filtering: \\<100ms\nParameter sanitization: \\<50ms\n\nOptimization Tips\nUse faster evaluation models for real-time applications\nCache evaluation results for repeated content\nImplement timeout handling for slow evaluations\nMonitor provider availability and implement fallbacks\n\nError Handling\n\nGraceful Degradation\n\nError Scenarios\nEvaluation provider unavailable β†’ Fall back to content filtering only\nInvalid regex patterns β†’ Log error and skip pattern\nRegex patterns that are too long or can backtrack catastrophically β†’ Log error and skip pattern\nNetwork timeouts β†’ Use cached results or allow processing\n\nBest Practices\nConfiguration Management\nStart with conservative settings and adjust based on usage\nMonitor false positives and adjust t","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Implementation Guide","lvl2":"","lvl3":""}},
3481
3483
  {"objectID":"383c860f3ae1b7853acf60fd6299eed129d62d3e71afb6c26144f6f0cbed9a80","title":"Guardrails Implementation Guide","url":"/docs/features/guardrails-implementation#guardrails-implementation-guide","content":"This document provides comprehensive documentation for the NeuroLink guardrails implementation, including pre-call filtering, content sanitization, and AI-powered evaluation.","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Implementation Guide","lvl2":"Guardrails Implementation Guide","lvl3":""}},
3482
3484
  {"objectID":"ce8ca8c8e86bce1454a2cba496271c6e2028e6d3ee90723038ba6c81bfa5adc0","title":"Overview","url":"/docs/features/guardrails-implementation#overview","content":"The guardrails implementation provides advanced content filtering and safety mechanisms for AI interactions. It includes:\nPre-call Evaluation: AI-powered safety assessment before processing\nContent Filtering: Bad words and regex pattern filtering\nParameter Sanitization: Input cleaning and modification\nEvaluation Actions: Configurable responses (block, sanitize, warn, log)\nVisual Proof: Screenshots demonstrating filtering in action","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Implementation Guide","lvl2":"Overview","lvl3":""}},
3483
3485
  {"objectID":"2ce9f7788ba64a029854af4b2be3f17be411fbff733a5d624975c8bdfb9b1970","title":"1. Guardrails Middleware (src/lib/middleware/builtin/guardrails.ts)","url":"/docs/features/guardrails-implementation#1-guardrails-middleware-srclibmiddlewarebuiltinguardrailsts","content":"The main middleware component that orchestrates all guardrail functionality:","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Implementation Guide","lvl2":"1. Guardrails Middleware (src/lib/middleware/builtin/guardrails.ts)","lvl3":""}},
3484
3486
  {"objectID":"c012b8fb66b8801d618d2c40d0050f0849e443e83a0910406fe2e9cb1685c3b6","title":"2. Guardrails Utilities (src/lib/middleware/utils/guardrailsUtils.ts)","url":"/docs/features/guardrails-implementation#2-guardrails-utilities-srclibmiddlewareutilsguardrailsutilsts","content":"Core utility functions for evaluation and filtering:\nperformPrecallEvaluation() - AI-powered safety assessment\napplyEvaluationActions() - Execute configured actions based on evaluation\napplySanitization() - Clean and modify request parameters\napplyContentFiltering() - Filter content using patterns and word lists","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Implementation Guide","lvl2":"2. Guardrails Utilities (src/lib/middleware/utils/guardrailsUtils.ts)","lvl3":""}},
3485
3487
  {"objectID":"1bc60d0ef7ba5a5ca4a41951c21889f0f552d51e95d51bbba1bc70b62ad023df","title":"3. Type Definitions (src/lib/types/guardrails.ts)","url":"/docs/features/guardrails-implementation#3-type-definitions-srclibtypesguardrailsts","content":"Complete TypeScript interfaces for configuration and results:","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Implementation Guide","lvl2":"3. Type Definitions (src/lib/types/guardrails.ts)","lvl3":""}},
3486
3488
  {"objectID":"a372d9788fafdbac2d714c40d26b659706f7a41828359a9a41adcaaacb77d5ce","title":"Pre-call Evaluation","url":"/docs/features/guardrails-implementation#pre-call-evaluation","content":"AI-powered evaluation of user input before processing:","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Implementation Guide","lvl2":"Pre-call Evaluation","lvl3":""}},
3487
- {"objectID":"9d5a28dea7ab8ab636c7420fc299cc04876d9121f3027c7c080db855ec6148a7","title":"Content Filtering","url":"/docs/features/guardrails-implementation#content-filtering","content":"Two-tier filtering system:\nRegex Patterns (Priority 1)\nWord Lists (Priority 2)","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Implementation Guide","lvl2":"Content Filtering","lvl3":""}},
3489
+ {"objectID":"9d5a28dea7ab8ab636c7420fc299cc04876d9121f3027c7c080db855ec6148a7","title":"Content Filtering","url":"/docs/features/guardrails-implementation#content-filtering","content":"Two-tier filtering system:\nRegex Patterns (Priority 1)\nWord Lists (Priority 2)\n \n\nRegex patterns run synchronously on the whole response (and sanitizationPatterns on the whole user prompt), so a pattern that can backtrack catastrophically would stall the process. Before a pattern is compiled it is checked, and it is refused when it:\nis longer than 1000 characters;\nrepeats a group in which a variable-length part (+, *, ?, {n,m}) can match the same text as what follows it, such as (a+)+, (\\w+\\s*)*, (.*a){10}, (a?a?)+ or (a{1,30}){1,30};\nrepeats a group whose alternatives may overlap, such as (a|aa)+;\nchains more than 8 optional parts (a?a?a?...) or more than 4 open-ended overlapping ones (.*a.*b.*c.*d.*e);\nuses a repetition bound above 500, such as a{1,1000}.\n\nRepeated groups whose variable parts are separated by a character they cannot match, such as (\\d{1,3}\\.){3} or ([a-z0-9-]+\\.)+, are accepted.\n\nA refused pattern is skipped and logged with logger.error (Refusing regex pattern ... for regexPatterns, Refusing sanitization pattern ... for sanitizationPatterns), the same way an invalid regex is. Nothing is thrown at the caller and the remaining patterns still run, but a skipped pattern filters nothing. The check is static and conservative: it refuses some safe patterns, compares classes on a sample of characters, only partly covers exponential shapes built from optional parts, and accepts polynomial ones (.*.*.*x), so test patterns on long input.","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Implementation Guide","lvl2":"Content Filtering","lvl3":""}},
3488
3490
  {"objectID":"967b0fafd8884e3b4d842ef103c84c8969c876c6b31b15ae9ec88996a980da3d","title":"Evaluation Actions","url":"/docs/features/guardrails-implementation#evaluation-actions","content":"Configurable responses based on evaluation results:\nblock: Prevent request processing entirely\nsanitize: Clean content and continue processing\nwarn: Log warning but allow processing\nlog: Record for monitoring but allow processing","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Implementation Guide","lvl2":"Evaluation Actions","lvl3":""}},
3489
3491
  {"objectID":"0a40edef1b5df8cc19e7fc791a193e9278de181ce392fb2a644fa6e606210d7c","title":"Demo Features","url":"/docs/features/guardrails-implementation#demo-features","content":"Interactive testing of guardrail functionality\nVisual feedback on filtering actions\nPerformance metrics and timing\nBefore/after content comparison","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Implementation Guide","lvl2":"Demo Features","lvl3":""}},
3490
3492
  {"objectID":"4e6eb8cfec697a821d6fd51cda1acf36aeb80d1556c412fc161443c89eba35ee","title":"Visual Proof","url":"/docs/features/guardrails-implementation#visual-proof","content":"Screenshots demonstrating guardrails in action:","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Implementation Guide","lvl2":"Visual Proof","lvl3":""}},
@@ -3494,17 +3496,17 @@
3494
3496
  {"objectID":"31cb61833523bb940829d5bdb046a7fa64daaac466fe5f65cd770974c08e7111","title":"4. Performance Metrics (guardrails-pre-call-filtering-4.png)","url":"/docs/features/guardrails-implementation#4-performance-metrics-guardrails-pre-call-filtering-4png","content":"Evaluation timing and processing speeds\nImpact on overall request latency","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Implementation Guide","lvl2":"4. Performance Metrics (guardrails-pre-call-filtering-4.png)","lvl3":""}},
3495
3497
  {"objectID":"aebb402c05dd85869d75b1afe713152ca5f7649723144286d23363b2d7bd7d5a","title":"Evaluation Timing","url":"/docs/features/guardrails-implementation#evaluation-timing","content":"Pre-call evaluation: ~2-5 seconds (depending on model)\nContent filtering: \\<100ms\nParameter sanitization: \\<50ms","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Implementation Guide","lvl2":"Evaluation Timing","lvl3":""}},
3496
3498
  {"objectID":"7949aa919de62755bae484fc2cb0e92d172449cd20eef803ccdf96676efe4afa","title":"Optimization Tips","url":"/docs/features/guardrails-implementation#optimization-tips","content":"Use faster evaluation models for real-time applications\nCache evaluation results for repeated content\nImplement timeout handling for slow evaluations\nMonitor provider availability and implement fallbacks","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Implementation Guide","lvl2":"Optimization Tips","lvl3":""}},
3497
- {"objectID":"315fe7f9334e36d3eb715d2fd0b52502c9269388ccb6562daee7ecbf8bb24259","title":"Error Scenarios","url":"/docs/features/guardrails-implementation#error-scenarios","content":"Evaluation provider unavailable β†’ Fall back to content filtering only\nInvalid regex patterns β†’ Log error and skip pattern\nNetwork timeouts β†’ Use cached results or allow processing","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Implementation Guide","lvl2":"Error Scenarios","lvl3":""}},
3499
+ {"objectID":"315fe7f9334e36d3eb715d2fd0b52502c9269388ccb6562daee7ecbf8bb24259","title":"Error Scenarios","url":"/docs/features/guardrails-implementation#error-scenarios","content":"Evaluation provider unavailable β†’ Fall back to content filtering only\nInvalid regex patterns β†’ Log error and skip pattern\nRegex patterns that are too long or can backtrack catastrophically β†’ Log error and skip pattern\nNetwork timeouts β†’ Use cached results or allow processing","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Implementation Guide","lvl2":"Error Scenarios","lvl3":""}},
3498
3500
  {"objectID":"31db420da5dd6e99aef6d88a4873c07d60e0950475954fb77ce15bfe0ad29abc","title":"1. Configuration Management","url":"/docs/features/guardrails-implementation#1-configuration-management","content":"Start with conservative settings and adjust based on usage\nMonitor false positives and adjust thresholds\nUse different configurations for different use cases","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Implementation Guide","lvl2":"1. Configuration Management","lvl3":""}},
3499
3501
  {"objectID":"07b7a1afdaf13e0c41efaac1f8ea575ebd413d16e94cccd38b0ec2116875d266","title":"2. Performance Optimization","url":"/docs/features/guardrails-implementation#2-performance-optimization","content":"Use appropriate evaluation models (faster for real-time, more accurate for batch)\nImplement caching for repeated evaluations\nMonitor and optimize regex patterns","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Implementation Guide","lvl2":"2. Performance Optimization","lvl3":""}},
3500
- {"objectID":"013589424f1598041108580d35e211fe0153a0646a7a43bbf181799f3ac0fc0c","title":"3. Content Filtering","url":"/docs/features/guardrails-implementation#3-content-filtering","content":"Prioritize regex patterns over word lists for better performance\nTest regex patterns thoroughly before deployment\nKeep word lists updated and relevant","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Implementation Guide","lvl2":"3. Content Filtering","lvl3":""}},
3502
+ {"objectID":"013589424f1598041108580d35e211fe0153a0646a7a43bbf181799f3ac0fc0c","title":"3. Content Filtering","url":"/docs/features/guardrails-implementation#3-content-filtering","content":"Prioritize regex patterns over word lists for better performance\nTest regex patterns thoroughly before deployment\nKeep regex patterns flat: separate the variable-length parts of a repeated group with a character they cannot match, and use word lists for plain terms\nCheck the error log after changing a pattern; a refused pattern is skipped silently from the caller's point of view\nKeep word lists updated and relevant","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Implementation Guide","lvl2":"3. Content Filtering","lvl3":""}},
3501
3503
  {"objectID":"b1ea141539248e0c28e299c88431ce34bff4dd35bc9c57ff52f0aa00cccf0448","title":"4. Monitoring and Logging","url":"/docs/features/guardrails-implementation#4-monitoring-and-logging","content":"Track evaluation results and actions taken\nMonitor performance impact on response times\nSet up alerts for high blocking rates","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Implementation Guide","lvl2":"4. Monitoring and Logging","lvl3":""}},
3502
- {"objectID":"d7b5be686443d662ce20573642991953e1b20aee5d846d17d27450e170aafe87","title":"Common Issues","url":"/docs/features/guardrails-implementation#common-issues","content":"Evaluation Taking Too Long\nCheck evaluation model availability\nImplement timeout handling\nConsider using faster models\nToo Many False Positives\nAdjust evaluation thresholds\nReview and refine regex patterns\nCheck word list relevance\nRegex Patterns Not Working\nValidate regex syntax\nTest patterns with sample content\nCheck for proper escaping\nPerformance Impact\nMonitor evaluation timing\nOptimize configuration settings\nConsider caching strategies","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Implementation Guide","lvl2":"Common Issues","lvl3":""}},
3504
+ {"objectID":"d7b5be686443d662ce20573642991953e1b20aee5d846d17d27450e170aafe87","title":"Common Issues","url":"/docs/features/guardrails-implementation#common-issues","content":"Evaluation Taking Too Long\nCheck evaluation model availability\nImplement timeout handling\nConsider using faster models\nToo Many False Positives\nAdjust evaluation thresholds\nReview and refine regex patterns\nCheck word list relevance\nRegex Patterns Not Working\nValidate regex syntax\nLook for Refusing regex pattern in the error log: patterns over 1000 characters or with ambiguous nested repetition are skipped\nTest patterns with sample content\nCheck for proper escaping\nPerformance Impact\nMonitor evaluation timing\nOptimize configuration settings\nConsider caching strategies","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Implementation Guide","lvl2":"Common Issues","lvl3":""}},
3503
3505
  {"objectID":"66e117b8b1dbbfecd14e9466d5243f21abc23e2c9682c9bcab843b594784ae24","title":"Debug Mode","url":"/docs/features/guardrails-implementation#debug-mode","content":"Enable debug logging for detailed information:","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Implementation Guide","lvl2":"Debug Mode","lvl3":""}},
3504
3506
  {"objectID":"062ba86ed5fa937d989ef36219f6bc4d2673654750f6c4fbfee623527282bc03","title":"From Previous Implementations","url":"/docs/features/guardrails-implementation#from-previous-implementations","content":"If upgrading from older guardrail implementations:\nUpdate configuration format to new interfaces\nReplace deprecated methods with new utility functions\nTest evaluation thresholds and adjust as needed\nUpdate error handling to use new patterns","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Implementation Guide","lvl2":"From Previous Implementations","lvl3":""}},
3505
3507
  {"objectID":"1d4cfe18f157b91540119afedbf464d626c2c320e56551b69d5b3f853541e3c4","title":"Breaking Changes","url":"/docs/features/guardrails-implementation#breaking-changes","content":"Configuration structure has been updated for better organization\nSome utility function signatures have changed\nError handling patterns have been improved","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Implementation Guide","lvl2":"Breaking Changes","lvl3":""}},
3506
3508
  {"objectID":"214fe14d9f320f468b5ed10d5b5cf315a7aa2a0fcb1a32598f42a622570e177d","title":"Conclusion","url":"/docs/features/guardrails-implementation#conclusion","content":"The NeuroLink guardrails implementation provides comprehensive content safety and filtering capabilities with:\nβœ… AI-powered pre-call evaluation\nβœ… Flexible content filtering options\nβœ… Configurable response actions\nβœ… Visual proof and demonstrations\nβœ… High performance and scalability\nβœ… Comprehensive error handling\nβœ… TypeScript support throughout\n\nFor additional support or questions, refer to the main NeuroLink documentation or create an issue in the repository.","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Implementation Guide","lvl2":"Conclusion","lvl3":""}},
3507
- {"objectID":"540c47bd7c6e059a9673d6acb056728c913d14a87db9e96c85e9ad17847af52d","title":"Guardrails Middleware","url":"/docs/features/guardrails","content":"Guardrails Middleware\n\nSince: v7.42.0 | Status: Stable | Availability: SDK (CLI + SDK)\n\nOverview\n\nWhat it does: Guardrails middleware provides real-time content filtering and policy enforcement for AI model outputs, blocking profanity, PII, unsafe content, and custom-defined terms.\n\nWhy use it: Protect your application from generating harmful, inappropriate, or non-compliant content. Ensures AI responses meet safety standards and regulatory requirements.\n\nCommon use cases:\nContent moderation for user-facing applications\nPII (Personally Identifiable Information) redaction\nProfanity filtering for family-friendly apps\nCompliance with industry regulations (COPPA, GDPR, etc.)\nBrand safety and reputation management\n\nQuick Start\n\nGuardrails work out of the box with the security preset. No custom configuration required for basic content filtering.\n\nSDK Example with Security Preset\nEnables guardrails middleware with default configuration\nPass middleware on every call that should be filtered; the NeuroLink constructor does not take this option\nContent is already filtered - safe to display to users\n\nCustom Guardrails Configuration\nMaster switch for guardrails middleware\nEnable keyword-based filtering (fast, regex-based)\nCustom terms to filter/redact from outputs\nEnable AI-powered content safety check (slower, more accurate)\nUse fast, cheap model for safety evaluation\n\nCLI Usage\n\nConfiguration\n\n| Option | Type | Default | Required | Description |\n| ------------------------- | ---------- | ------- | -------- | ------------------------------------ |\n| enabled | boolean | true | No | Enable/disable guardrails middleware |\n| badWords.enabled | boolean | false | No | Enable keyword-based filtering |\n| badWords.list | string[] | [] | No | List of terms to filter/redact |\n| modelFilter.enabled | boolean | false | No | Enable AI-based content safety check |\n| modelFilter.filterModel | string | - | No | Model to use for safety evaluation |\n\nEnvironment Variables\n\nConfig File\n\nHow It Works\n\nFiltering Pipeline\nUser prompt β†’ Sent to AI model\nAI generates response β†’ Initial content created\nGuardrails middleware intercepts:\nBad word filtering: Regex-based term replacement\nModel-based filtering: AI evaluates content safety\nFiltered response β†’ Delivered to user\n\nBad Word Filtering\n\nSimple regex-based replacement:\nCase-insensitive matching\nReplaces each match with a fixed string, [REDACTED] by default (not length-preserving asterisks) β€” override it with badWords.replacementText\nWorks in both generate and stream modes\n\nModel-Based Filtering\n\nWhile guardrails filter common PII patterns, always review critical outputs manually. False negatives can occur with obfuscated data or uncommon PII formats. For high-stakes compliance, combine with dedicated PII detection services.\n\nAI-powered safety check:\nUses separate, lightweight model (e.g., gpt-4o-mini)\nBinary safe/unsafe classification\nFull redaction on unsafe detection\n\nAdvanced Usage\n\nCombining with Other Middleware\n\nStreaming with Guardrails\n\nDynamic Guardrails\n\nAPI Reference\n\nMiddleware Configuration\npreset: \"security\" β†’ Enables guardrails with defaults\npreset: \"all\" β†’ Enables guardrails + all other middleware\nmiddlewareConfig.guardrails β†’ Custom guardrails configuration\n\nSee guardrails-ai-integration.md for complete integration guide.\n\nTroubleshooting\n\nProblem: Guardrails not filtering content\n\nCause: Middleware not enabled or preset not configured\nSolution:\n\nProblem: Too many false positives (legitimate content filtered)\n\nCause: Overly aggressive bad word list\nSolution:\n\nProblem: Model-based filter is slow\n\nCause: Using large/expensive model for filtering\nSolution:\n\nProblem: Guardrails not working in streaming mode\n\nCause: Streaming guardrails only support bad word filtering (not model-based)\nSolution:\n\nBest Practices\n\nContent Filtering Strategy\nStart with presets - Use preset: \"security\" as baseline\nLayer protections - Combine bad words + model filtering\nUse lightweight filter models - gpt-4o-mini for speed\nTest thoroughly - Verify filtering doesn't break legitimate content\nMonitor and iterate - Track false positives/negatives\n\nBad Word List Curation\n\nβœ… Do:\nInclude specific harmful terms\nUse exact phrases, not single characters\nRegularly update based on user reports\nConsider context-specific terms for your domain\n\n❌ Don't:\nAdd common English words (high false positive rate)\nInclude single letters or short words\nRely solely on bad words (use model filter too)\n\nPerformance Optimization\n\nCompliance Use Cases\n\nCOPPA (Children's Online Privacy)\n\nGDPR Data Protection\n\nRelated Features\nHITL Workflows - User approval for risky actions\nMiddleware Architecture - Custom middleware development\nAnalytics Integration - Track filtered content metrics\n\nMigration Notes\n\nIf upgrading from versions before v7.42.0:\nGuardrails are now enabled via middleware pres","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Middleware","lvl2":"","lvl3":""}},
3509
+ {"objectID":"540c47bd7c6e059a9673d6acb056728c913d14a87db9e96c85e9ad17847af52d","title":"Guardrails Middleware","url":"/docs/features/guardrails","content":"Guardrails Middleware\n\nSince: v7.42.0 | Status: Stable | Availability: SDK (CLI + SDK)\n\nOverview\n\nWhat it does: Guardrails middleware provides real-time content filtering and policy enforcement for AI model outputs, blocking profanity, PII, unsafe content, and custom-defined terms.\n\nWhy use it: Protect your application from generating harmful, inappropriate, or non-compliant content. Ensures AI responses meet safety standards and regulatory requirements.\n\nCommon use cases:\nContent moderation for user-facing applications\nPII (Personally Identifiable Information) redaction\nProfanity filtering for family-friendly apps\nCompliance with industry regulations (COPPA, GDPR, etc.)\nBrand safety and reputation management\n\nQuick Start\n\nGuardrails work out of the box with the security preset. No custom configuration required for basic content filtering.\n\nSDK Example with Security Preset\nEnables guardrails middleware with default configuration\nPass middleware on every call that should be filtered; the NeuroLink constructor does not take this option\nContent is already filtered - safe to display to users\n\nCustom Guardrails Configuration\nMaster switch for guardrails middleware\nEnable keyword-based filtering (fast, regex-based)\nCustom terms to filter/redact from outputs\nEnable AI-powered content safety check (slower, more accurate)\nUse fast, cheap model for safety evaluation\n\nCLI Usage\n\nConfiguration\n\n| Option | Type | Default | Required | Description |\n| ------------------------- | ---------- | ------- | -------- | ------------------------------------ |\n| enabled | boolean | true | No | Enable/disable guardrails middleware |\n| badWords.enabled | boolean | false | No | Enable keyword-based filtering |\n| badWords.list | string[] | [] | No | List of terms to filter/redact |\n| badWords.regexPatterns | string[] | [] | No | Regular expressions to redact |\n| modelFilter.enabled | boolean | false | No | Enable AI-based content safety check |\n| modelFilter.filterModel | string | - | No | Model to use for safety evaluation |\n\nEnvironment Variables\n\nConfig File\n\nHow It Works\n\nFiltering Pipeline\nUser prompt β†’ Sent to AI model\nAI generates response β†’ Initial content created\nGuardrails middleware intercepts:\nBad word filtering: Regex-based term replacement\nModel-based filtering: AI evaluates content safety\nFiltered response β†’ Delivered to user\n\nBad Word Filtering\n\nSimple regex-based replacement:\nCase-insensitive matching\nReplaces each match with a fixed string, [REDACTED] by default (not length-preserving asterisks) β€” override it with badWords.replacementText\nWorks in both generate and stream modes\n\nRegex Patterns\n\nbadWords.regexPatterns takes regular expressions, each applied with the gi flags. When it is set it takes priority over list:\n\nPatterns run synchronously against the whole response, so one that backtracks catastrophically would stall every request in the process. The cost comes from input that can be split between the parts of a pattern in many ways: a variable-length part (+, *, ?, {n,m}) that can match the same text as whatever follows it. A pattern is refused when it:\nis longer than 1000 characters;\nrepeats a group in which such a part can match the same text as what follows it, including the next iteration of the group: (a+)+, (\\w+\\s*)*, (.*a){10}, (a?a?)+, (a{1,30}){1,30};\nrepeats a group whose alternatives may overlap, such as (a|aa)+ or (\\w|\\d)+;\nchains too many overlapping variable-length parts: more than 8 optional parts in a row (a?a?a?a?a?a?a?a?a?), or more than 4 open-ended ones (.*a.*b.*c.*d.*e.*f);\nuses a repetition bound above 500, such as a{1,1000}.\n\nA repeated group is fine when each variable-length part is followed by something it cannot match. These all run: (\\d{1,3}\\.){3}, ([a-z0-9-]+\\.)+[a-z]{2,}, (?:\\d{4}[- ]?)+, \\b(?:\\d[ -]*?){13,16}\\b, (?:\\w+\\s+)+.\n\nA refused pattern is skipped and logged as an error (Refusing regex pattern ...), the same way an invalid regex is. It is never thrown at the caller, and the other patterns in the list still run. Fail-open is the trade: a skipped pattern filters nothing, so check the logs after you change a pattern. The same limits apply to precallEvaluation.sanitizationPatterns (Refusing sanitization pattern ...).\n\nThe check reads the pattern; it does not run it, so it is conservative and not a proof:\nIt refuses some safe patterns, such as a small fixed count of an ambiguous part ((a{1,3}){3}). Flatten it (a{1,9}) or split it.\nIt compares character classes on a fixed sample of characters (Latin text plus a few other scripts), so a class that only overlaps outside the sample can look disjoint. A back-reference is assumed to overlap with everything.\nExponential shapes built from optional parts are only partly covered: loops and long chains are refused, but the check is a model of the engine, not the engine. Open-ende","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Middleware","lvl2":"","lvl3":""}},
3508
3510
  {"objectID":"ad4c8c0e011c259d8f444afec90c94a3c939d9f14e65491e8044a8417430b54c","title":"Guardrails Middleware","url":"/docs/features/guardrails#guardrails-middleware","content":"Since: v7.42.0 | Status: Stable | Availability: SDK (CLI + SDK)","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Middleware","lvl2":"Guardrails Middleware","lvl3":""}},
3509
3511
  {"objectID":"1ecba9f0cdb3586cf8ad53bba31fb80cabab7aed2aba88050b4f98078dd2bec9","title":"Overview","url":"/docs/features/guardrails#overview","content":"What it does: Guardrails middleware provides real-time content filtering and policy enforcement for AI model outputs, blocking profanity, PII, unsafe content, and custom-defined terms.\n\nWhy use it: Protect your application from generating harmful, inappropriate, or non-compliant content. Ensures AI responses meet safety standards and regulatory requirements.\n\nCommon use cases:\nContent moderation for user-facing applications\nPII (Personally Identifiable Information) redaction\nProfanity filtering for family-friendly apps\nCompliance with industry regulations (COPPA, GDPR, etc.)\nBrand safety and reputation management","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Middleware","lvl2":"Overview","lvl3":""}},
3510
3512
  {"objectID":"064824951ceeb2f827852673ce43e1d5b0a4776cda59dec766413ea3ea1a41ae","title":"Quick Start","url":"/docs/features/guardrails#quick-start","content":"Guardrails work out of the box with the security preset. No custom configuration required for basic content filtering.","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Middleware","lvl2":"Quick Start","lvl3":""}},
@@ -3513,15 +3515,17 @@
3513
3515
  {"objectID":"c8521792297f968b1ed06d4d84924590f9453bb688d0511d82b24e8cb807d1d4","title":"CLI Usage","url":"/docs/features/guardrails#cli-usage","content":"`bash","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Middleware","lvl2":"CLI Usage","lvl3":""}},
3514
3516
  {"objectID":"db6d627e8bf12acc503a42180b82237d38b98a34bf4b5c6427110388ba783598","title":"Enable guardrails via environment variable","url":"/docs/features/guardrails#enable-guardrails-via-environment-variable","content":"npx @juspay/neurolink generate \"Write a product description\" --enable-analytics","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Middleware","lvl2":"Enable guardrails via environment variable","lvl3":""}},
3515
3517
  {"objectID":"0968c358bc16ec092d8eafc1875703e50dd25b900e6a64d8f9a1356ac3e143f8","title":"Guardrails are automatically applied to all generations","url":"/docs/features/guardrails#guardrails-are-automatically-applied-to-all-generations","content":"`","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Middleware","lvl2":"Guardrails are automatically applied to all generations","lvl3":""}},
3516
- {"objectID":"5b562e23dda525ed54a3fbcd8d86fd0b6b8aba8bc84bb34bc52b2cd028cf0178","title":"Configuration","url":"/docs/features/guardrails#configuration","content":"| Option | Type | Default | Required | Description |\n| ------------------------- | ---------- | ------- | -------- | ------------------------------------ |\n| enabled | boolean | true | No | Enable/disable guardrails middleware |\n| badWords.enabled | boolean | false | No | Enable keyword-based filtering |\n| badWords.list | string[] | [] | No | List of terms to filter/redact |\n| modelFilter.enabled | boolean | false | No | Enable AI-based content safety check |\n| modelFilter.filterModel | string | - | No | Model to use for safety evaluation |","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Middleware","lvl2":"Configuration","lvl3":""}},
3518
+ {"objectID":"5b562e23dda525ed54a3fbcd8d86fd0b6b8aba8bc84bb34bc52b2cd028cf0178","title":"Configuration","url":"/docs/features/guardrails#configuration","content":"| Option | Type | Default | Required | Description |\n| ------------------------- | ---------- | ------- | -------- | ------------------------------------ |\n| enabled | boolean | true | No | Enable/disable guardrails middleware |\n| badWords.enabled | boolean | false | No | Enable keyword-based filtering |\n| badWords.list | string[] | [] | No | List of terms to filter/redact |\n| badWords.regexPatterns | string[] | [] | No | Regular expressions to redact |\n| modelFilter.enabled | boolean | false | No | Enable AI-based content safety check |\n| modelFilter.filterModel | string | - | No | Model to use for safety evaluation |","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Middleware","lvl2":"Configuration","lvl3":""}},
3517
3519
  {"objectID":"2406e4412d40d6ab610c334f551ae73529304f50a559b6fdf180d616d7536174","title":"Environment Variables","url":"/docs/features/guardrails#environment-variables","content":"`bash","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Middleware","lvl2":"Environment Variables","lvl3":""}},
3518
3520
  {"objectID":"946b41af2f888ce1a40149ea8123d2c4584292d7a22fe88549f0b7c23671f951","title":"Or enable all middleware (includes guardrails + analytics)","url":"/docs/features/guardrails#or-enable-all-middleware-includes-guardrails-analytics","content":"`","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Middleware","lvl2":"Or enable all middleware (includes guardrails + analytics)","lvl3":""}},
3519
3521
  {"objectID":"70cbcd4ca56befe769c6ddb6128a5ab280c75a48edc8e9b4141dfce607bc2c1e","title":"Filtering Pipeline","url":"/docs/features/guardrails#filtering-pipeline","content":"User prompt β†’ Sent to AI model\nAI generates response β†’ Initial content created\nGuardrails middleware intercepts:\nBad word filtering: Regex-based term replacement\nModel-based filtering: AI evaluates content safety\nFiltered response β†’ Delivered to user","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Middleware","lvl2":"Filtering Pipeline","lvl3":""}},
3520
3522
  {"objectID":"3af7a22581a93723a5045560d7c0026a6fc3f1bca903dd47c28e0dfa5707e350","title":"Bad Word Filtering","url":"/docs/features/guardrails#bad-word-filtering","content":"Simple regex-based replacement:\nCase-insensitive matching\nReplaces each match with a fixed string, [REDACTED] by default (not length-preserving asterisks) β€” override it with badWords.replacementText\nWorks in both generate and stream modes","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Middleware","lvl2":"Bad Word Filtering","lvl3":""}},
3523
+ {"objectID":"4be9b0134609c0a5ccba707be47bfc7c5708940e325c69550c196de6060f48a0","title":"Regex Patterns","url":"/docs/features/guardrails#regex-patterns","content":"badWords.regexPatterns takes regular expressions, each applied with the gi flags. When it is set it takes priority over list:\n\nPatterns run synchronously against the whole response, so one that backtracks catastrophically would stall every request in the process. The cost comes from input that can be split between the parts of a pattern in many ways: a variable-length part (+, *, ?, {n,m}) that can match the same text as whatever follows it. A pattern is refused when it:\nis longer than 1000 characters;\nrepeats a group in which such a part can match the same text as what follows it, including the next iteration of the group: (a+)+, (\\w+\\s*)*, (.*a){10}, (a?a?)+, (a{1,30}){1,30};\nrepeats a group whose alternatives may overlap, such as (a|aa)+ or (\\w|\\d)+;\nchains too many overlapping variable-length parts: more than 8 optional parts in a row (a?a?a?a?a?a?a?a?a?), or more than 4 open-ended ones (.*a.*b.*c.*d.*e.*f);\nuses a repetition bound above 500, such as a{1,1000}.\n\nA repeated group is fine when each variable-length part is followed by something it cannot match. These all run: (\\d{1,3}\\.){3}, ([a-z0-9-]+\\.)+[a-z]{2,}, (?:\\d{4}[- ]?)+, \\b(?:\\d[ -]*?){13,16}\\b, (?:\\w+\\s+)+.\n\nA refused pattern is skipped and logged as an error (Refusing regex pattern ...), the same way an invalid regex is. It is never thrown at the caller, and the other patterns in the list still run. Fail-open is the trade: a skipped pattern filters nothing, so check the logs after you change a pattern. The same limits apply to precallEvaluation.sanitizationPatterns (Refusing sanitization pattern ...).\n\nThe check reads the pattern; it does not run it, so it is conservative and not a proof:\nIt refuses some safe patterns, such as a small fixed count of an ambiguous part ((a{1,3}){3}). Flatten it (a{1,9}) or split it.\nIt compares character classes on a fixed sample of characters (Latin text plus a few other scripts), so a class that only overlaps outside the sample can look disjoint.","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Middleware","lvl2":"Regex Patterns","lvl3":""}},
3521
3524
  {"objectID":"5c5b50314493905262b204dbb73bacc7c6ab8a60fa3124469df9e6c1706e47a5","title":"Model-Based Filtering","url":"/docs/features/guardrails#model-based-filtering","content":"While guardrails filter common PII patterns, always review critical outputs manually. False negatives can occur with obfuscated data or uncommon PII formats. For high-stakes compliance, combine with dedicated PII detection services.\n\nAI-powered safety check:\nUses separate, lightweight model (e.g., gpt-4o-mini)\nBinary safe/unsafe classification\nFull redaction on unsafe detection","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Middleware","lvl2":"Model-Based Filtering","lvl3":""}},
3522
3525
  {"objectID":"dbfe7ff9f27039591c8f98fc3b03c705f22f7b36b689e5f0de95241ae3fb71ee","title":"Middleware Configuration","url":"/docs/features/guardrails#middleware-configuration","content":"preset: \"security\" β†’ Enables guardrails with defaults\npreset: \"all\" β†’ Enables guardrails + all other middleware\nmiddlewareConfig.guardrails β†’ Custom guardrails configuration\n\nSee guardrails-ai-integration.md for complete integration guide.","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Middleware","lvl2":"Middleware Configuration","lvl3":""}},
3523
3526
  {"objectID":"85995a92035eb64e3e92878f16c818aa6b02432dfcdf8a2c1b7d0ec93efb0ceb","title":"Problem: Guardrails not filtering content","url":"/docs/features/guardrails#problem-guardrails-not-filtering-content","content":"Cause: Middleware not enabled or preset not configured\nSolution:","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Middleware","lvl2":"Problem: Guardrails not filtering content","lvl3":""}},
3524
3527
  {"objectID":"69697f2c3191cc2ac3f2d5a0a1e9295a7c6df79603d7a54068a65420afd69858","title":"Problem: Too many false positives (legitimate content filtered)","url":"/docs/features/guardrails#problem-too-many-false-positives-legitimate-content-filtered","content":"Cause: Overly aggressive bad word list\nSolution:","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Middleware","lvl2":"Problem: Too many false positives (legitimate content filtered)","lvl3":""}},
3528
+ {"objectID":"eee2fe44ae3284cb63eec8fb3919e61415d44d01645db00a942193e14955f189","title":"Problem: A regex pattern is not filtering anything","url":"/docs/features/guardrails#problem-a-regex-pattern-is-not-filtering-anything","content":"Cause: The pattern was refused for its length or its shape, or it is not valid regex. Both are skipped, and the log says which\nSolution: Look for Refusing regex pattern (or Invalid regex pattern) in the error log. A refusal names the reason, for example a repeated group whose variable-length part can match the same text as what follows it. Separate the parts with a character they cannot match (([\\w-]+\\.)+ instead of ([\\w-]+)+), split a long pattern into several, or move plain terms to badWords.list","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Middleware","lvl2":"Problem: A regex pattern is not filtering anything","lvl3":""}},
3525
3529
  {"objectID":"203e91cc171e445ffc3872091866a6a6da27809cb879259d7c595e54cf02b29f","title":"Problem: Model-based filter is slow","url":"/docs/features/guardrails#problem-model-based-filter-is-slow","content":"Cause: Using large/expensive model for filtering\nSolution:","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Middleware","lvl2":"Problem: Model-based filter is slow","lvl3":""}},
3526
3530
  {"objectID":"3d6cce90a89ac6dc76fe42611ab3d172032a8879982db277948a0f6982c57923","title":"Problem: Guardrails not working in streaming mode","url":"/docs/features/guardrails#problem-guardrails-not-working-in-streaming-mode","content":"Cause: Streaming guardrails only support bad word filtering (not model-based)\nSolution:","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Middleware","lvl2":"Problem: Guardrails not working in streaming mode","lvl3":""}},
3527
3531
  {"objectID":"95ef73f0ed68f3ce81ba9c25d863438aae71096384fc37cf1d5b3ee3e6219c69","title":"Content Filtering Strategy","url":"/docs/features/guardrails#content-filtering-strategy","content":"Start with presets - Use preset: \"security\" as baseline\nLayer protections - Combine bad words + model filtering\nUse lightweight filter models - gpt-4o-mini for speed\nTest thoroughly - Verify filtering doesn't break legitimate content\nMonitor and iterate - Track false positives/negatives","hierarchy":{"lvl0":"Features","lvl1":"Guardrails Middleware","lvl2":"Content Filtering Strategy","lvl3":""}},
@@ -3743,8 +3747,9 @@
3743
3747
  {"objectID":"d2bc56f680ee79ff976a89a240129d887e7d55b99a498c33d265efd9db1580de","title":"Additional Methods (ServerCapabilitiesManager)","url":"/docs/features/mcp-enhancements#additional-methods-servercapabilitiesmanager","content":"| Method | Description |\n| --------------------------------------------- | --------------------------------------------------------- |\n| registerResource(resource) | Register a static or dynamic resource |\n| registerResourceTemplate(pattern, template) | Register a URI-template resource for pattern matching |\n| readResource(uri) | Read a resource by URI (resolves templates) |\n| listResources() | List all registered resources as MCPResource[] |\n| getResource(uri) | Get a registered resource by URI |\n| subscribeToResource(uri, callback) | Subscribe to resource changes; returns unsubscribe fn |\n| notifyResourceChanged(uri) | Notify all subscribers that a resource has changed |\n| registerPrompt(prompt) | Register a prompt with static template or async generator |\n| getPrompt(name, args?) | Generate a prompt result with provided arguments |\n| listPrompts() | List all registered prompts as MCPPrompt[] |\n| getCapabilities() | Get MCP capabilities object for protocol negotiation |","hierarchy":{"lvl0":"Features","lvl1":"MCP Enhancements","lvl2":"Additional Methods (ServerCapabilitiesManager)","lvl3":""}},
3744
3748
  {"objectID":"d14031ea1ed6ebeb76b630965f3e8caa7e289e68f3d154cc6773f638bd503527","title":"Events","url":"/docs/features/mcp-enhancements#events-7","content":"ServerCapabilitiesManager extends EventEmitter and emits the following events:\n\n| Event | Payload | Fired When |\n| ---------------------------- | -------------------------------------------------------------------------------------------------------------- | -------------------------------------------- |\n| resourceRegistered | { uri: string, name: string, timestamp: Date } | A resource is registered |\n| resourceTemplateRegistered | { pattern: string, timestamp: Date } | A resource template is registered |\n| resourceUnregistered | { uri: string, timestamp: Date } | A resource is unregistered |\n| resourceRead | { uri: string, duration: number, success: boolean, timestamp: Date, error?: string } | A resource is read (success or failure) |\n| resourceSubscribed | { uri: string, timestamp: Date } | A subscription is added to a resource |\n| resourceUnsubscribed | { uri: string, timestamp: Date } | A subscription is removed from a resource |\n| resourceChanged | { uri: string, subscriberCount: number, timestamp: Date } | A resource change is notified to subscribers |\n| promptRegistered | { name: string, timestamp: Date } | A prompt is registered |\n| promptUnregistered","hierarchy":{"lvl0":"Features","lvl1":"MCP Enhancements","lvl2":"Events","lvl3":""}},
3745
3749
  {"objectID":"4a1991e2b792637d2ef189757e16ad54e2e0fc8a6a0515f7fd33f3ce405773d6","title":"Additional Methods","url":"/docs/features/mcp-enhancements#additional-methods-6","content":"| Method | Description |\n| --------------------------------------------- | ----------------------------------------------------------- |\n| registerResource(resource) | Register a resource with a reader function |\n| registerResourceTemplate(pattern, template) | Register a URI-pattern-based resource template |\n| unregisterResource(uri) | Remove a resource and its subscriptions |\n| listResources() | List all registered resources |\n| readResource(uri, context?) | Read a resource by URI (checks templates on miss) |\n| getResource(uri) | Get resource definition by URI |\n| subscribeToResource(uri, callback) | Subscribe to resource changes; returns unsubscribe function |\n| notifyResourceChanged(uri) | Read resource and notify all subscribers |\n| registerPrompt(prompt) | Register a prompt with a generator function |\n| unregisterPrompt(name) | Remove a prompt |\n| listPrompts() | List all registered prompts |\n| getPrompt(name, args?, context?) | Generate a prompt with arguments |\n| getPromptDefinition(name) | Get prompt definition without generating |\n| getCapabilities() | Get MCP capabilities object for protocol negotiation |\n| getStatistics() | Get counts of resources, templates, prompts, subscriptions |\n| clear() | Clear all resources, templates, prompts, and subscriptions |","hierarchy":{"lvl0":"Features","lvl1":"MCP Enhancements","lvl2":"Additional Methods","lvl3":""}},
3746
- {"objectID":"516493ee3c698891a2347410f8334c9b75f5aed4ee7aff7d926824f114525f12","title":"MCP Registry Client","url":"/docs/features/mcp-enhancements#mcp-registry-client","content":"Discover MCP servers from registries, including a built-in catalog of well-known servers. Search by category, tags, transport type, and verification status.","hierarchy":{"lvl0":"Features","lvl1":"MCP Enhancements","lvl2":"MCP Registry Client","lvl3":""}},
3747
- {"objectID":"5b3d6019b7b02e98705f573ca40f35717ada3a4dc46fbfd54a20df21984f6f5f","title":"Methods","url":"/docs/features/mcp-enhancements#methods-1","content":"| Method | Description |\n| ----------------------------- | ----------------------------------- |\n| search(options) | Search for servers with filters |\n| getByCategory(category) | Browse servers by category |\n| getByTag(tag) | Filter entries by tag |\n| getCategories() | Get all available categories |\n| getTags() | Get all available tags |\n| getEntry(id) | Get a specific registry entry |\n| getAllEntries() | Get all entries from all registries |\n| addCustomEntry(entry) | Add a custom registry entry |\n| removeCustomEntry(id) | Remove a custom entry |\n| addRegistry(config) | Add a custom registry source |\n| getPopularServers(limit?) | Get popular servers |\n| getVerifiedServers() | Get verified servers |\n| getStatistics() | Get registry statistics |\n| toServerInfo(entry) | Convert entry to MCPServerInfo |\n| getInstallCommand(entry) | Get install command for an entry |\n| checkRequiredEnvVars(entry) | Check if required env vars are set |","hierarchy":{"lvl0":"Features","lvl1":"MCP Enhancements","lvl2":"Methods","lvl3":""}},
3750
+ {"objectID":"516493ee3c698891a2347410f8334c9b75f5aed4ee7aff7d926824f114525f12","title":"MCP Registry Client","url":"/docs/features/mcp-enhancements#mcp-registry-client","content":"Discover MCP servers from a built-in catalog of well-known servers and, when you opt in, from the official MCP Registry or a registry of your own. Search by category, tags, transport type, and verification status.\n\nBy default the client reads only the built-in catalog and the custom entries you add, and it never makes a network request. Remote lookup is off until you turn it on.","hierarchy":{"lvl0":"Features","lvl1":"MCP Enhancements","lvl2":"MCP Registry Client","lvl3":""}},
3751
+ {"objectID":"218137891a5c9dc10b8eadd26a2d9b7501b472b1c6745e54dfa8f77e2bbba11c","title":"Remote lookup (opt-in)","url":"/docs/features/mcp-enhancements#remote-lookup-opt-in","content":"Set remoteLookup: true to let the client consult the registries in registries. The default list is the official MCP Registry at https://registry.modelcontextprotocol.io; add your own with { type: \"custom\", url } or addRegistry(). A custom registry must serve the same /v0.1 API as the official one (GET /v0.1/servers and GET /v0.1/servers/{name}/versions/latest, see the registry API reference); url is its base URL.\n\nWhat to expect:\nOpt-in. With remoteLookup unset or false, no registry is contacted, whatever registries contains. A client you did not construct, such as the one from neurolink.getMCPRegistryClient(), can be switched with client.setRemoteLookup(true).\nWhen a registry is queried. getEntry(id) asks the registries only after the custom entries and the built-in catalog miss. search() and getAllEntries() merge each registry's servers after the local ones; an id that exists locally is never replaced by a remote entry. search({ query }) passes the query to the registry, which matches it against the server name (a substring match), so a word that appears only in a remote server's description is not found.\nRemote entries are unverified. They carry verified: false, so verifiedOnly never returns them. The registry publishes whatever its authors submit; review a server before running its command and args.\nIds differ from the built-in slugs. The official registry names servers in reverse-DNS form, such as io.github.example/my-server. Built-in slugs like filesystem are not aliased to them.\nWhat is mapped. An npm package becomes npmPackage, command: \"npx\" and args: [\"-y\", \"<package>@<version>\"], with its required environment variables in requiredEnvVars. Other package types (for example pypi or oci) and remote URLs are listed under entry.metadata.packages and entry.metadata.remotes; no command is set for them.\nPackage names are validated, not just typed.","hierarchy":{"lvl0":"Features","lvl1":"MCP Enhancements","lvl2":"Remote lookup (opt-in)","lvl3":""}},
3752
+ {"objectID":"5b3d6019b7b02e98705f573ca40f35717ada3a4dc46fbfd54a20df21984f6f5f","title":"Methods","url":"/docs/features/mcp-enhancements#methods-1","content":"| Method | Description |\n| ----------------------------- | ------------------------------------------------------------------------------------------- |\n| search(options) | Search for servers with filters; includes remote servers when remote lookup is on |\n| getByCategory(category) | Browse servers by category |\n| getByTag(tag) | Filter entries by tag |\n| getCategories() | Get all available categories |\n| getTags() | Get all available tags |\n| getEntry(id) | Get a specific registry entry; asks the registries on a local miss when remote lookup is on |\n| getAllEntries() | Get local entries, plus every configured registry's servers when remote lookup is on |\n| addCustomEntry(entry) | Add a custom registry entry |\n| removeCustomEntry(id) | Remove a custom entry |\n| addRegistry(config) | Add a registry source (queried only when remote lookup is on) |\n| setRemoteLookup(enabled) | Turn remote lookup on or off at runtime |\n| getPopularServers(limit?)","hierarchy":{"lvl0":"Features","lvl1":"MCP Enhancements","lvl2":"Methods","lvl3":""}},
3748
3753
  {"objectID":"c9b947029152d8f4bb0d1aed82467f27f4a1d8f8bbead8f54e660c0e4696f13f","title":"Well-Known Servers","url":"/docs/features/mcp-enhancements#well-known-servers","content":"The registry includes these verified servers out of the box:\n\n| ID | Name | Categories | Key Tools |\n| -------------- | ------------ | -------------------- | ------------------------------- |\n| filesystem | Filesystem | file-system | readfile, writefile, list_dir |\n| github | GitHub | version-control, api | createrepo, listcommits |\n| postgres | PostgreSQL | database | query, list_tables |\n| sqlite | SQLite | database | query, list_tables |\n| brave-search | Brave Search | search, api | websearch, localsearch |\n| puppeteer | Puppeteer | automation, web | navigate, screenshot, click |\n| git | Git | version-control | gitstatus, gitlog, git_diff |\n| memory | Memory | memory, storage | store, retrieve, search |\n| slack | Slack | communication, api | sendmessage, listchannels |\n| google-drive | Google Drive | file-system, api | listfiles, readfile |","hierarchy":{"lvl0":"Features","lvl1":"MCP Enhancements","lvl2":"Well-Known Servers","lvl3":""}},
3749
3754
  {"objectID":"e05f50888fa69abd7742f6aaff003d55366c2353c7a67eeeed6679d88899c3a6","title":"Architecture","url":"/docs/features/mcp-enhancements#architecture","content":"For detailed per-module flow diagrams (Tool Router decision flow, Tool Cache eviction, Request Batcher sequencing, Elicitation Protocol handshake, and Multi-Server topology), see MCP Enhancement Architecture Diagrams.\n\nThe MCP enhancement modules are layered on top of NeuroLink's existing MCP infrastructure:","hierarchy":{"lvl0":"Features","lvl1":"MCP Enhancements","lvl2":"Architecture","lvl3":""}},
3750
3755
  {"objectID":"15557df8424972e1543abb16d52b1a30d2045fd2e9618c5f2be950eb76066de5","title":"End-to-End Integration Example","url":"/docs/features/mcp-enhancements#end-to-end-integration-example","content":"This example shows how ToolCache, Tool Annotations, ToolIntegration middleware, and MCPServerBase compose together in a realistic scenario: a custom MCP server whose tools are executed through a middleware pipeline with caching, retry, timeout, and confirmation for destructive operations.\n\nWhat this demonstrates:\nMCPServerBase provides a structured way to define and register tools with lifecycle hooks (\\init\\, \\start\\, \\stop\\).\nTool Annotations are inferred automatically from tool names and descriptions -- \\getProduct\\ is read-only, \\deleteProduct\\ is destructive.\nToolIntegrationManager chains middleware so every tool call passes through logging, confirmation (for destructive tools), timeout, and retry (for idempotent/read-only tools).\nToolCache wraps read-only calls with \\getOrSet\\ to avoid redundant execution, and \\invalidate\\ clears stale entries after mutations.\n\nSee the Architecture Diagrams for visual flows of how these components interact.","hierarchy":{"lvl0":"Features","lvl1":"MCP Enhancements","lvl2":"End-to-End Integration Example","lvl3":""}},
@@ -4476,7 +4481,7 @@
4476
4481
  {"objectID":"74157a50c681176730f3b27c3e830a008684c85e311c55800613565f57c35c9a","title":"Environment Variable Overrides","url":"/docs/features/task-manager#environment-variable-overrides","content":"Note: The following environment variables are planned but not yet implemented. They are not currently read by any code. Configuration should be done programmatically via the NeuroLink constructor options until these are wired up.\n\n| Variable | Purpose | Default |\n| -------------------------------- | ---------------------------------- | ----------------------------- |\n| NEUROLINK_TASKS_ENABLED | Enable/disable TaskManager | true |\n| NEUROLINK_TASKS_BACKEND | Backend selection | bullmq |\n| NEUROLINK_TASKS_REDIS_URL | Redis connection URL (BullMQ) | redis://localhost:6379 |\n| NEUROLINK_TASKS_STORE_PATH | File store path (NodeTimeout only) | .neurolink/tasks/tasks.json |\n| NEUROLINK_TASKS_MAX_CONCURRENT | Max concurrent task runs | 5 |","hierarchy":{"lvl0":"Features","lvl1":"TaskManager - Scheduled & Self-Running Tasks","lvl2":"Environment Variable Overrides","lvl3":""}},
4477
4482
  {"objectID":"77ae3c208bde91c496d4387894a724101b09e84f320fb0cb958b8926aee9b6e2","title":"Retry Policy","url":"/docs/features/task-manager#retry-policy","content":"Transient errors (rate limits, network timeouts, 5xx): Auto-retry with exponential backoff\nPermanent errors (auth failures, invalid config): Task marked as failed immediately\nDefault: 3 attempts with backoff at 30s, 60s, 5min","hierarchy":{"lvl0":"Features","lvl1":"TaskManager - Scheduled & Self-Running Tasks","lvl2":"Retry Policy","lvl3":""}},
4478
4483
  {"objectID":"29e444e0a6967995041692f0569002ad4bc9e5735327d7b1a8b77928a0fb7750","title":"One-shot vs Recurring Error Behavior","url":"/docs/features/task-manager#one-shot-vs-recurring-error-behavior","content":"| Task Type | On Transient Error | On Permanent Error |\n| ----------------------------- | -------------------------------------- | ------------------ |\n| One-shot (once) | Retry up to maxAttempts | Mark as failed |\n| Recurring (cron/interval) | Retry, then skip to next scheduled run | Mark as failed |","hierarchy":{"lvl0":"Features","lvl1":"TaskManager - Scheduled & Self-Running Tasks","lvl2":"One-shot vs Recurring Error Behavior","lvl3":""}},
4479
- {"objectID":"0fc2f7460a56b3d81f4a59e9e2975765a521b62861f124e831f3c59d0d6e8a67","title":"Events","url":"/docs/features/task-manager#events","content":"TaskManager emits events via NeuroLink's existing TypedEventEmitter:","hierarchy":{"lvl0":"Features","lvl1":"TaskManager - Scheduled & Self-Running Tasks","lvl2":"Events","lvl3":""}},
4484
+ {"objectID":"0fc2f7460a56b3d81f4a59e9e2975765a521b62861f124e831f3c59d0d6e8a67","title":"Events","url":"/docs/features/task-manager#events","content":"TaskManager emits events via NeuroLink's existing TypedEventEmitter, which you reach with getEventEmitter() (NeuroLink itself has no on()):","hierarchy":{"lvl0":"Features","lvl1":"TaskManager - Scheduled & Self-Running Tasks","lvl2":"Events","lvl3":""}},
4480
4485
  {"objectID":"dc77fa796ab3fb50c605f737163d0caab113900f9f29e5536fa2b84d40ffe94e","title":"Phase 1: Core Infrastructure","url":"/docs/features/task-manager#phase-1-core-infrastructure","content":"Type definitions (src/lib/tasks/types.ts)\nTaskBackend interface (src/lib/tasks/backends/taskBackend.ts)\nTaskBackendFactory + Registry (src/lib/tasks/backends/taskBackendFactory.ts, taskBackendRegistry.ts)\nTaskStore interface (src/lib/tasks/store/taskStore.ts)\nRedisTaskStore (src/lib/tasks/store/redisTaskStore.ts)\nFileTaskStore (src/lib/tasks/store/fileTaskStore.ts)","hierarchy":{"lvl0":"Features","lvl1":"TaskManager - Scheduled & Self-Running Tasks","lvl2":"Phase 1: Core Infrastructure","lvl3":""}},
4481
4486
  {"objectID":"f9b16fc39cf5e28674e54775f739edfab4f4a3dae008688df4b44ae133475f72","title":"Phase 2: Backends","url":"/docs/features/task-manager#phase-2-backends","content":"NodeTimeout backend (src/lib/tasks/backends/nodeTimeoutBackend.ts)\nBullMQ backend (src/lib/tasks/backends/bullmqBackend.ts)","hierarchy":{"lvl0":"Features","lvl1":"TaskManager - Scheduled & Self-Running Tasks","lvl2":"Phase 2: Backends","lvl3":""}},
4482
4487
  {"objectID":"cb8b756ebd09cc1eea9088d201f866c88468abc63a52bb68791b9bf747b98636","title":"Phase 3: Orchestration","url":"/docs/features/task-manager#phase-3-orchestration","content":"TaskExecutor - run engine (src/lib/tasks/taskExecutor.ts)\nTaskManager - main orchestrator (src/lib/tasks/taskManager.ts)\nIntegration into NeuroLink class (src/lib/neurolink.ts)","hierarchy":{"lvl0":"Features","lvl1":"TaskManager - Scheduled & Self-Running Tasks","lvl2":"Phase 3: Orchestration","lvl3":""}},
@@ -4513,11 +4518,11 @@
4513
4518
  {"objectID":"5594cc075cbacf6979c75d68f20b45ccff0513a1e4c7087d756491900cbb1c4d","title":"Model Detection Utilities","url":"/docs/features/thinking-configuration#model-detection-utilities","content":"NeuroLink provides utilities to check thinking support:","hierarchy":{"lvl0":"Features","lvl1":"Extended Thinking Configuration","lvl2":"Model Detection Utilities","lvl3":""}},
4514
4519
  {"objectID":"559dd274be4e9bdfeabf680692f3830f92a5c13caefc42acfb819d9635f2dad7","title":"Important Notes","url":"/docs/features/thinking-configuration#important-notes","content":"Provider compatibility: Thinking configuration is provider-specific. Gemini uses thinkingLevel, Claude uses budgetTokens\nToken consumption: Extended thinking uses additional tokens beyond the response\nLatency impact: Higher thinking levels increase response time\nNot all models support thinking: Check supportsThinkingConfig() before enabling\nStreaming support: Thinking configuration works with both generate() and stream()","hierarchy":{"lvl0":"Features","lvl1":"Extended Thinking Configuration","lvl2":"Important Notes","lvl3":""}},
4515
4520
  {"objectID":"4bd3d62cf46ca16e0b9a52768c51ca4bced1f07f6c32f9a141c0cbfc599bcefb","title":"See Also","url":"/docs/features/thinking-configuration#see-also","content":"API Reference\nProvider Configuration\nStreaming","hierarchy":{"lvl0":"Features","lvl1":"Extended Thinking Configuration","lvl2":"See Also","lvl3":""}},
4516
- {"objectID":"ffa6f024a99609da8db45d9a02bc76178d7fac894f00af93b830f9b356e86f3c","title":"Tool / MCP routing by decision model","url":"/docs/features/tool-routing-decision-model","content":"Tool / MCP routing by decision model\n\nThe shipped tool router asks a generative model for {servers: string[]} on\na 15-second budget. That shape cannot express uncertainty β€” a server is in\nthe list or it is not, and the only recourse for a model that is unsure is to\ninclude it. A decision model instead\nasks one calibrated yes/no question per server, in a single round trip of\nabout 400ms and $0.00002 on TypeSafe (on Perplexity each further question adds\nabout 65 ms, up to 128 in a request; see\nits guide; on\nCloudflare Clef a request takes up to 64 questions, and tryDecide() splits a\nlarger set into batches of 64; see\nits guide; OpenAI Decisions\ndeclares no question cap, so a set goes whole and what the endpoint accepts is\nnot established, see\nits guide), and each\nanswer comes back with a real probability rather than a name that either did or\ndidn't make a list.\n\nThe degradation contract. selectServersByDecision() is used only when a\ndecision provider is configured; hosts never wire decideFn by hand β€” it is\nbound automatically wherever tool routing resolves, using the same\ntryDecide() that returns null on any failure or absent configuration. No\ndecision provider, a failed call, fewer than two candidate servers, or an\nanswer set that would drop nothing β€” any of these fall straight through to\nthe existing generative router, unchanged.\n\nOne question per server\n\nEach routable server gets its own boolean question, built from its\ndescription (or, absent one, its tool names):\n\nA server is excluded only on a confident false β€” minDropConfidence\ndefaults to 0.6. undefined (unanswered, malformed, or too close to a\ncoin flip) and a confident true both keep the server. This is the same\nasymmetry as the classifier's upgrade/downgrade bars: keeping an unneeded\nserver costs a few hundred tokens of tool definitions; dropping a needed one\nbreaks the turn outright, because the model can never call a tool it was\nnever shown and has no way to ask for it back.\n\nTwo size guards bound the request: at most 200 servers are asked about\nin one batch (MAX_SERVERS), and the query text sent as state is capped at\n10,000 characters. Servers past the cap are never asked about and are\ntherefore always kept β€” a server that was not offered to the model must\nnever be silently dropped by its own absence from the question set.\n\nNeuroLink refuses a state it estimates at more than 16,000 tokens with\nmax_tokens_exceeded. A query long enough to be estimated above that is refused,\nand routing falls through to the generative router, as it does on any failure.\n\nThe wording that made this work: a measured A/B result\n\nThe first phrasing tried was the obvious one: \"answering this request will\nrequire calling at least one tool from this server,\" with false meaning\n\"this server is unrelated, OR the request needs no tool at all.\" Measured\nagainst a 10-request Γ— 5-server labelled set, it separated correctly but\nweakly β€” unrelated servers averaged p = 0.31 and reached as high as\n0.80, so at the 0.6 drop bar only 12 of 39 unneeded servers were\nactually dropped.\n\nThree changes fixed it: naming the server explicitly, asking in the present\ntense about what carrying out the request involves rather than what\n\"will require,\" and splitting the bundled false criterion (which was\nreally two separate claims joined by \"or\") into one single claim. That\nmoved unrelated servers to a mean of p = 0.03 with a maximum of 0.35\nβ€” 37 of 39 dropped at the same 0.6 bar, still with zero wrong drops.\n\nThe lesson generalises past this one question: a decision model reads\nliterally, and an \"or\" in a criterion is two questions wearing one coat. Each\nhalf of a compound criterion pulls the answer toward the middle whenever\nonly one half is true, which is exactly the muddy, hard-to-gate signal the\nfirst version produced.\n\nWhat this is bad at\nIt reasons about servers, not individual tools. The unit of decision is\n a whole MCP server; a server with twenty tools where the request needs one\n is kept or dropped as a unit, not tool-by-tool.\nThe description quality bounds the question quality. A server with no\n declared description falls back to a comma-joined list of its own tool\n names, which carries much less signal than a well-written one-line\n description β€” the wording fix above only helps once the server's own text\n is legible to a literal reader.\nA close call still resolves to \"keep.\" There is no partial exclusion;\n anything from a coin flip up to just under 0.6 confidence is treated\n identically to a confident true.\nIt shares the base model's general limits β€” literal reading, no\n arithmetic, accuracy sensitive to a noisy or oversized state β€” all\n described in\n what decide is bad at.\nThe query is untrusted input sent as state, and this module does not\n sanitize it. The blast radius is deliberately bounded instead: server ids\n are never read back off the wire (answers are matched by position, not by\n name), so the worst a crafted query can do is keep more already-registered\n server","hierarchy":{"lvl0":"Features","lvl1":"Tool / MCP routing by decision model","lvl2":"","lvl3":""}},
4521
+ {"objectID":"ffa6f024a99609da8db45d9a02bc76178d7fac894f00af93b830f9b356e86f3c","title":"Tool / MCP routing by decision model","url":"/docs/features/tool-routing-decision-model","content":"Tool / MCP routing by decision model\n\nThe shipped tool router asks a generative model for {servers: string[]} on\na 15-second budget. That shape cannot express uncertainty β€” a server is in\nthe list or it is not, and the only recourse for a model that is unsure is to\ninclude it. A decision model instead\nasks one calibrated yes/no question per server, in a single round trip of\nabout 400ms and $0.00002 on TypeSafe (on Perplexity each further question adds\nabout 65 ms, up to 128 in a request; see\nits guide; on\nCloudflare Clef a request takes up to 64 questions, and tryDecide() splits a\nlarger set into batches of 64; see\nits guide; OpenAI Decisions\ndeclares no question cap, so a set goes whole and what the endpoint accepts is\nnot established, see\nits guide), and each\nanswer comes back with a real probability rather than a name that either did or\ndidn't make a list.\n\nThe degradation contract. selectServersByDecision() is used only when a\ndecision provider is configured; hosts never wire decideFn by hand β€” it is\nbound automatically wherever tool routing resolves, using the same\ntryDecide() that returns null on any failure or absent configuration. No\ndecision provider, a failed call, fewer than two candidate servers, or an\nanswer set that would drop nothing β€” any of these fall straight through to\nthe existing generative router, unchanged.\n\nOne question per server\n\nEach routable server gets its own boolean question, built from its\ndescription (or, absent one, its tool names):\n\nA server is excluded only on a confident false β€” minDropConfidence\ndefaults to 0.6. undefined (unanswered, malformed, or too close to a\ncoin flip) and a confident true both keep the server. This is the same\nasymmetry as the classifier's upgrade/downgrade bars: keeping an unneeded\nserver costs a few hundred tokens of tool definitions; dropping a needed one\nbreaks the turn outright, because the model can never call a tool it was\nnever shown and has no way to ask for it back.\n\nTwo size guards bound the request: at most 200 servers are asked about\nin one batch (MAX_SERVERS), and the query text sent as state is capped at\n10,000 characters. Servers past the cap are never asked about and are\ntherefore always kept β€” a server that was not offered to the model must\nnever be silently dropped by its own absence from the question set.\n\nNeuroLink refuses a state it estimates at more than 16,000 tokens with\nmax_tokens_exceeded. A query long enough to be estimated above that is refused,\nand routing falls through to the generative router, as it does on any failure.\n\nThe wording that made this work: a measured A/B result\n\nThe first phrasing tried was the obvious one: \"answering this request will\nrequire calling at least one tool from this server,\" with false meaning\n\"this server is unrelated, OR the request needs no tool at all.\" Measured\nagainst a 10-request Γ— 5-server labelled set, it separated correctly but\nweakly β€” unrelated servers averaged p = 0.31 and reached as high as\n0.80, so at the 0.6 drop bar only 12 of 39 unneeded servers were\nactually dropped.\n\nThree changes fixed it: naming the server explicitly, asking in the present\ntense about what carrying out the request involves rather than what\n\"will require,\" and splitting the bundled false criterion (which was\nreally two separate claims joined by \"or\") into one single claim. That\nmoved unrelated servers to a mean of p = 0.03 with a maximum of 0.35\nβ€” 37 of 39 dropped at the same 0.6 bar, still with zero wrong drops.\n\nThe lesson generalises past this one question: a decision model reads\nliterally, and an \"or\" in a criterion is two questions wearing one coat. Each\nhalf of a compound criterion pulls the answer toward the middle whenever\nonly one half is true, which is exactly the muddy, hard-to-gate signal the\nfirst version produced.\n\nWhat this is bad at\nIt reasons about servers, not individual tools. The unit of decision is\n a whole MCP server; a server with twenty tools where the request needs one\n is kept or dropped as a unit, not tool-by-tool.\nThe description quality bounds the question quality. A server with no\n declared description falls back to a comma-joined list of its own tool\n names, which carries much less signal than a well-written one-line\n description β€” the wording fix above only helps once the server's own text\n is legible to a literal reader.\nA close call still resolves to \"keep.\" There is no partial exclusion;\n anything from a coin flip up to just under 0.6 confidence is treated\n identically to a confident true.\nIt shares the base model's general limits β€” literal reading, no\n arithmetic, accuracy sensitive to a noisy or oversized state β€” all\n described in\n what decide is bad at.\nThe query is untrusted input sent as state, and this module does not\n sanitize it. The reach is deliberately bounded, not zero. Server ids are\n never read back off the wire (answers are matched by position, not by name),\n so a crafted query cannot name a tool that was not already registered, and\n the ","hierarchy":{"lvl0":"Features","lvl1":"Tool / MCP routing by decision model","lvl2":"","lvl3":""}},
4517
4522
  {"objectID":"4b84d2a2ea7a8b34624599647a02792ace2fc30650e5bb5d3da1ea68e46fdad8","title":"Tool / MCP routing by decision model","url":"/docs/features/tool-routing-decision-model#tool-mcp-routing-by-decision-model","content":"The shipped tool router asks a generative model for {servers: string[]} on\na 15-second budget. That shape cannot express uncertainty β€” a server is in\nthe list or it is not, and the only recourse for a model that is unsure is to\ninclude it. A decision model instead\nasks one calibrated yes/no question per server, in a single round trip of\nabout 400ms and $0.00002 on TypeSafe (on Perplexity each further question adds\nabout 65 ms, up to 128 in a request; see\nits guide; on\nCloudflare Clef a request takes up to 64 questions, and tryDecide() splits a\nlarger set into batches of 64; see\nits guide; OpenAI Decisions\ndeclares no question cap, so a set goes whole and what the endpoint accepts is\nnot established, see\nits guide), and each\nanswer comes back with a real probability rather than a name that either did or\ndidn't make a list.\n\nThe degradation contract. selectServersByDecision() is used only when a\ndecision provider is configured; hosts never wire decideFn by hand β€” it is\nbound automatically wherever tool routing resolves, using the same\ntryDecide() that returns null on any failure or absent configuration. No\ndecision provider, a failed call, fewer than two candidate servers, or an\nanswer set that would drop nothing β€” any of these fall straight through to\nthe existing generative router, unchanged.","hierarchy":{"lvl0":"Features","lvl1":"Tool / MCP routing by decision model","lvl2":"Tool / MCP routing by decision model","lvl3":""}},
4518
4523
  {"objectID":"0b9203bc3ddca1d61b578f4bea25de508f6a241da96f270ca4742163bd99884a","title":"One question per server","url":"/docs/features/tool-routing-decision-model#one-question-per-server","content":"Each routable server gets its own boolean question, built from its\ndescription (or, absent one, its tool names):\n\nA server is excluded only on a confident false β€” minDropConfidence\ndefaults to 0.6. undefined (unanswered, malformed, or too close to a\ncoin flip) and a confident true both keep the server. This is the same\nasymmetry as the classifier's upgrade/downgrade bars: keeping an unneeded\nserver costs a few hundred tokens of tool definitions; dropping a needed one\nbreaks the turn outright, because the model can never call a tool it was\nnever shown and has no way to ask for it back.\n\nTwo size guards bound the request: at most 200 servers are asked about\nin one batch (MAX_SERVERS), and the query text sent as state is capped at\n10,000 characters. Servers past the cap are never asked about and are\ntherefore always kept β€” a server that was not offered to the model must\nnever be silently dropped by its own absence from the question set.\n\nNeuroLink refuses a state it estimates at more than 16,000 tokens with\nmax_tokens_exceeded. A query long enough to be estimated above that is refused,\nand routing falls through to the generative router, as it does on any failure.","hierarchy":{"lvl0":"Features","lvl1":"Tool / MCP routing by decision model","lvl2":"One question per server","lvl3":""}},
4519
4524
  {"objectID":"19352c9bf82d208bbd76e4303e3e35ac7d4f7497562a4f1ee006d8cf1fae5f6b","title":"The wording that made this work: a measured A/B result","url":"/docs/features/tool-routing-decision-model#the-wording-that-made-this-work-a-measured-ab-result","content":"The first phrasing tried was the obvious one: \"answering this request will\nrequire calling at least one tool from this server,\" with false meaning\n\"this server is unrelated, OR the request needs no tool at all.\" Measured\nagainst a 10-request Γ— 5-server labelled set, it separated correctly but\nweakly β€” unrelated servers averaged p = 0.31 and reached as high as\n0.80, so at the 0.6 drop bar only 12 of 39 unneeded servers were\nactually dropped.\n\nThree changes fixed it: naming the server explicitly, asking in the present\ntense about what carrying out the request involves rather than what\n\"will require,\" and splitting the bundled false criterion (which was\nreally two separate claims joined by \"or\") into one single claim. That\nmoved unrelated servers to a mean of p = 0.03 with a maximum of 0.35\nβ€” 37 of 39 dropped at the same 0.6 bar, still with zero wrong drops.\n\nThe lesson generalises past this one question: a decision model reads\nliterally, and an \"or\" in a criterion is two questions wearing one coat. Each\nhalf of a compound criterion pulls the answer toward the middle whenever\nonly one half is true, which is exactly the muddy, hard-to-gate signal the\nfirst version produced.","hierarchy":{"lvl0":"Features","lvl1":"Tool / MCP routing by decision model","lvl2":"The wording that made this work: a measured A/B result","lvl3":""}},
4520
- {"objectID":"9c9af1c1ff58051674501cb10c371fdcf50758c935a2dfa168df9719969bb7af","title":"What this is bad at","url":"/docs/features/tool-routing-decision-model#what-this-is-bad-at","content":"It reasons about servers, not individual tools. The unit of decision is\n a whole MCP server; a server with twenty tools where the request needs one\n is kept or dropped as a unit, not tool-by-tool.\nThe description quality bounds the question quality. A server with no\n declared description falls back to a comma-joined list of its own tool\n names, which carries much less signal than a well-written one-line\n description β€” the wording fix above only helps once the server's own text\n is legible to a literal reader.\nA close call still resolves to \"keep.\" There is no partial exclusion;\n anything from a coin flip up to just under 0.6 confidence is treated\n identically to a confident true.\nIt shares the base model's general limits β€” literal reading, no\n arithmetic, accuracy sensitive to a noisy or oversized state β€” all\n described in\n what decide is bad at.\nThe query is untrusted input sent as state, and this module does not\n sanitize it. The blast radius is deliberately bounded instead: server ids\n are never read back off the wire (answers are matched by position, not by\n name), so the worst a crafted query can do is keep more already-registered\n servers than necessary β€” it cannot register a server that wasn't already\n configured.","hierarchy":{"lvl0":"Features","lvl1":"Tool / MCP routing by decision model","lvl2":"What this is bad at","lvl3":""}},
4525
+ {"objectID":"9c9af1c1ff58051674501cb10c371fdcf50758c935a2dfa168df9719969bb7af","title":"What this is bad at","url":"/docs/features/tool-routing-decision-model#what-this-is-bad-at","content":"It reasons about servers, not individual tools. The unit of decision is\n a whole MCP server; a server with twenty tools where the request needs one\n is kept or dropped as a unit, not tool-by-tool.\nThe description quality bounds the question quality. A server with no\n declared description falls back to a comma-joined list of its own tool\n names, which carries much less signal than a well-written one-line\n description β€” the wording fix above only helps once the server's own text\n is legible to a literal reader.\nA close call still resolves to \"keep.\" There is no partial exclusion;\n anything from a coin flip up to just under 0.6 confidence is treated\n identically to a confident true.\nIt shares the base model's general limits β€” literal reading, no\n arithmetic, accuracy sensitive to a noisy or oversized state β€” all\n described in\n what decide is bad at.\nThe query is untrusted input sent as state, and this module does not\n sanitize it. The reach is deliberately bounded, not zero. Server ids are\n never read back off the wire (answers are matched by position, not by name),\n so a crafted query cannot name a tool that was not already registered, and\n the result is only a denylist appended to excludeTools. It can still steer\n a verdict: a confident false (0.6 by default) withholds that server's\n tools for the turn. Do not rely on this router as a security control; see\n the Untrusted input bullet under\n what decide is bad at.","hierarchy":{"lvl0":"Features","lvl1":"Tool / MCP routing by decision model","lvl2":"What this is bad at","lvl3":""}},
4521
4526
  {"objectID":"b55a36dccb54a184ce24fa850942a8f5455cbe7f4391a23fc94f326aebeae19e","title":"See also","url":"/docs/features/tool-routing-decision-model#see-also","content":"The decide inference type\nModel routing with a decision model\nRelevance-driven compaction","hierarchy":{"lvl0":"Features","lvl1":"Tool / MCP routing by decision model","lvl2":"See also","lvl3":""}},
4522
4527
  {"objectID":"868aff1102e3175cc67c89cc4d5bc4a20b86b1666dcd8d010b976d4b16364ece","title":"The transcribe inference type","url":"/docs/features/transcribe","content":"The transcribe inference type\n\nNeuroLink has four inference types. transcribe is the one that starts from audio:\n\n| Type | Call | Produces |\n| ---------------- | --------------------------------------------------- | -------------------------------- |\n| generate | neurolink.generate() | text |\n| stream | neurolink.stream() | text, incrementally |\n| decide | neurolink.decide() | typed judgements |\n| transcribe | neurolink.transcribe() / transcribeStream() | text from audio, with timing |\n\nIt runs through any registered speech-to-text (STT) engine and adds the layers\nthat make an engine usable on real speech: a dictionary of names and\njargon, a correction pass guarded by the decision model and finished by an\nLLM rewrite, a second-opinion engine, a fallback engine for audio the\nfirst one cannot read, and client-side streaming for engines that only\ntake whole files.\n\nZero configuration. With no STT provider configured, transcribe() uses\nWhistle, the built-in local engine: it runs on this machine, needs no key\nand no network; its model files (about 18 MB) ship inside the package.\nWhistle reads English, German, French, Spanish, Italian, Dutch and Polish; for\nother languages, accents, noisy rooms or heavy jargon, configure a cloud or\nself-hosted engine, or add a dictionary and correction.\n\nSDK\n\naudio accepts bytes (Buffer, ArrayBuffer, Uint8Array), a path, a\nfile:// URL or an http(s):// URL. The container is inferred from the path\nor the bytes; pass format (\"wav\", \"mp3\", \"m4a\", \"ogg\", \"opus\",\n\"webm\", \"flac\", \"mp4\", \"pcm16\" …) for a buffer it cannot be read from.\n\nOptions\n\n| Option | Meaning |\n| ---------------- | --------------------------------------------------------------------------------------------------------------------------------- |\n| provider | STT provider name or alias. Default: NEUROLINK_STT_PROVIDER, then the first configured provider, then Whistle. |\n| model | Model of that provider. Default: NEUROLINK_STT_MODEL, only when the provider also came from the environment. |\n| language | Language code or locale, or \"auto\". Default: NEUROLINK_STT_LANGUAGE, else the engine detects it. |\n| prompt | Context prompt for engines that bias on one; dictionary terms are appended to it. |\n| diarization | Label speakers, on engines that diarize. |\n| wordTimestamps | Ask for word-level timings. |\n| dictionary | Names and jargon, see Dictionary. |\n| correction | The correction layer, see Correction. |\n| fallback | { provider, model?, when? }, see Fallback. |\n| streaming | Tuning for transcribeStream(), see Streaming. |\n| timeoutMs | Whole-call timeout. |\n| credentials | Per-call credentials; the stt slice (credentials.stt.whisper.apiKey, credentials.stt.deepgram.apiKey …) beats the env vars. |\n\nResult\n\nTranscribeResult is the engine's STTResult (text, confidence,\nlanguage, duration, words, segments, speakers, metadata) plus what\nthe layers did:\n\n| Field | Meaning |\n| ------------------ | -------------------------------------------------------------------------------------------------------- |\n| raw | The engine's text before any correction. |\n| text | The final text β€” the corrected text when correction changed it, else raw. |\n| corrected | Present only when correction changed the text. |\n| languageDetected | false when the engine reported a low language-detection score. |\n| languageScores | Candidate languages with the engine's own scores, where it reports them. |\n| decisions | One record per dictionary candidate: what was heard, the ter","hierarchy":{"lvl0":"Features","lvl1":"The transcribe inference type","lvl2":"","lvl3":""}},
4523
4528
  {"objectID":"022bf9f0cc0df8253fa229c043dc4762f656ee2c7d69e782484cb8425973befb","title":"The transcribe inference type","url":"/docs/features/transcribe#the-transcribe-inference-type","content":"NeuroLink has four inference types. transcribe is the one that starts from audio:\n\n| Type | Call | Produces |\n| ---------------- | --------------------------------------------------- | -------------------------------- |\n| generate | neurolink.generate() | text |\n| stream | neurolink.stream() | text, incrementally |\n| decide | neurolink.decide() | typed judgements |\n| transcribe | neurolink.transcribe() / transcribeStream() | text from audio, with timing |\n\nIt runs through any registered speech-to-text (STT) engine and adds the layers\nthat make an engine usable on real speech: a dictionary of names and\njargon, a correction pass guarded by the decision model and finished by an\nLLM rewrite, a second-opinion engine, a fallback engine for audio the\nfirst one cannot read, and client-side streaming for engines that only\ntake whole files.\n\nZero configuration. With no STT provider configured, transcribe() uses\nWhistle, the built-in local engine: it runs on this machine, needs no key\nand no network; its model files (about 18 MB) ship inside the package.\nWhistle reads English, German, French, Spanish, Italian, Dutch and Polish; for\nother languages, accents, noisy rooms or heavy jargon, configure a cloud or\nself-hosted engine, or add a dictionary and correction.","hierarchy":{"lvl0":"Features","lvl1":"The transcribe inference type","lvl2":"The transcribe inference type","lvl3":""}},
@@ -5650,7 +5655,7 @@
5650
5655
  {"objectID":"5862cb134695d7821bb2656e8d0c7c1ffee1ff3f295c36858f60fa939ba2facd","title":"Verification status","url":"/docs/getting-started/providers/chutes#verification-status","content":"Tier-2 onboarding normally requires a live-key capability sweep\n(docs/provider-integration/tiers/tier-2-catalog-entry.md,\n\"Live verification\"), gated by pnpm run verify:provider-onboarding. This\nentry was added under a credential-free onboarding pass instead: no\nChutes API key was ever created or used, and no authenticated or POST\nrequest was sent to any Chutes endpoint. Everything below is either a public\ndocument or a single unauthenticated GET.\n\n| Probe | Result |\n| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| Roster | Unauthenticated GET https://llm.chutes.ai/v1/models, HTTP 200, 14 models, re-run 2026-09-28. /v1/models is itself documented by Chutes as a \"public catalog (no key required).\" |\n| Wire shape | Chutes' own homepage Python sample posts to https://llm.chutes.ai/v1/chat/completions with model + messages + Authorization: Bearer $CHUTES_API_KEY + stream: true β€” never executed here, only read. |\n| Tools / structured output | Confirmed from docs only: the \"Function Calling, Agents, and Tool Use\" guide shows OpenAI-shaped tools/tool_choice/tool_call_id, and the same guide shows a separate response_format: {\"type\": \"json_object\"} JSON-mode example.","hierarchy":{"lvl0":"Getting Started","lvl1":"Chutes Provider Guide","lvl2":"Verification status","lvl3":""}},
5651
5656
  {"objectID":"34c0be7e44128ded319ab20090fe5bfecd98725996a4350660f6dad0932a5601","title":"Troubleshooting","url":"/docs/getting-started/providers/chutes#troubleshooting","content":"| Symptom | Cause | Fix |\n| ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Requests hit an anonymous rate limit (HTTP 429) | No token, or an invalid token, was sent | Set CHUTES_API_KEY, and send it as Authorization: Bearer <key> β€” X-API-Key is documented as unsupported for inference calls |\n| Model not found | The roster changed since 2026-09-28 | Pick a current id from the unauthenticated GET /v1/models roster |\n| Structured output silently dropped when tools are used | structuredOutputWithTools is false β€” no combined probe was possible | This is intentional pending a live-key check, not a bug; NeuroLink's runtime conflict retry drops structured output and retries rather than losing the turn |\n| Unsure whether a specific model supports tools / JSON mode | capabilities.tools is \"model-dependent\" β€” two roster ids ship no supported_features at all | Check the model's entry in GET /v1/models, or consult the Models table above |","hierarchy":{"lvl0":"Getting Started","lvl1":"Chutes Provider Guide","lvl2":"Troubleshooting","lvl3":""}},
5652
5657
  {"objectID":"f743dd0fbfd3517546cecc2240a8513ad5a47938ceae45eec2ad4fe45aa06d9f","title":"See also","url":"/docs/getting-started/providers/chutes#see-also","content":"Provider setup overview\nAll providers\nTier-2 onboarding β€” how this provider's JSON becomes a working integration, and what live verification still needs to happen\nProvider feature compatibility","hierarchy":{"lvl0":"Getting Started","lvl1":"Chutes Provider Guide","lvl2":"See also","lvl3":""}},
5653
- {"objectID":"1fb3d0f4a1510905b14436d78a4928a8e825b3dbdb324b6cb7c9a340e088d0f6","title":"Cloudflare Clef Provider Guide","url":"/docs/getting-started/providers/cloudflare-clef","content":"Cloudflare Clef Provider Guide\n\nA provider of decide β€” the same typed boolean / choice / score\nanswers as TypeSafe's Jev, Laya, XOR,\nPerplexity and OpenAI Decisions,\nfrom Cloudflare's Clef models on Workers AI, and it also reads images. It emits\nno text at all.\n\nThis is not the Cloudflare Workers AI text provider\n(cloudflare, which runs chat models). The two are separate providers that\nread the same CLOUDFLARE_API_KEY and CLOUDFLARE_ACCOUNT_ID; see\nOne token, two providers.\n\nRead Limits before you rely on it. Workers AI's state window\nchanged in October 2026 (hosted service or model: unknown). Until 2026-10-04 it\nread only about the first 2,048 tokens of the state, far less than the 64K\ncontext Cloudflare documents, and ignored the rest without an error; on\n2026-10-07 it read states of at least 190,153 tokens (clef-flash) and 52,154\n(clef). NeuroLink refuses a state it estimates at more than 16,000 tokens,\ninside what was read in full, and a longer wait than a fail-open feature can\nafford.\n\nOverview\n\nClef is a decision model: it reads a state and a set of typed questions and\nreturns a probability for every allowed answer, with no free-form text and no\nreasoning tokens to wait for. Cloudflare publishes two sizes, clef (27B) and\nclef-flash (9B), and says it is releasing their weights under the Apache 2.0\nlicense. Both answered in about a second from a developer machine. Cloudflare's\npages call them available, and do not say whether they are generally available\nor in beta.\n\nKey Facts\n\n| | |\n| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Provider id | cloudflare-clef |\n| Models | clef (27B, the default) and clef-flash (9B). @cf/cloudflare/clef and @cf/cloudflare/clef-flash are accepted too |\n| Question types | boolean (sent as noul), choice (2 to 255 options), score (2 to 10 levels) |\n| Questions per request | 64 |\n| Images | up to 4 per request: PNG, JPEG or WebP. No video |\n| State | read in full up to at least 190,153 tokens (clef-flash) and 52,154 (clef) on 2026-10-07; about 2,048 until 2026-10-04. NeuroLink refuses a state it estimates at more than 16,000 |\n| Request size | 256,000 bytes in NeuroLink, base64 image data included |\n| Endpoint | https://api.cloudflare.com/client/v4/accounts/<account id>/ai/run/@cf/cloudflare/<model> |\n| Credentials | an API token with Workers AI permission, and the account id |\n| Price | $0.24 per million input tokens for clef, $0.09 for clef-flash; no output price is listed (Cloudflare's Workers AI pricing page) |\n| Measured latency | 2026-10-03: 0.3 to 1.0 s for a small request; 64 questions: 1.1 s (clef-flash), 1.3 s (clef); 2026-10-04: 1.5 s / 2.3 s |\n| Default decide provider | second to last: after TypeSafe, Laya, XOR, SubQ and Perplexity, before OpenAI Decisions |\n| Verified live | 2026-10-03 and 2026-10-04, with a real account (see Limits) |\n\nQuick Start\nGet a token and your account id\n\nCreate an API token with the Workers AI: Read + Write permission at\ndash.cloudflare.com/profile/api-tokens, and copy your account id from\nthe dashboard URL or the \"Account ID\" panel.\nConfigure\n\nOr pass them in code, which wins over the environment:\n\nBoth the token and the account id are needed: the account id","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Clef Provider Guide","lvl2":"","lvl3":""}},
5658
+ {"objectID":"1fb3d0f4a1510905b14436d78a4928a8e825b3dbdb324b6cb7c9a340e088d0f6","title":"Cloudflare Clef Provider Guide","url":"/docs/getting-started/providers/cloudflare-clef","content":"Cloudflare Clef Provider Guide\n\nA provider of decide β€” the same typed boolean / choice / score\nanswers as TypeSafe's Jev, Laya, XOR,\nPerplexity and OpenAI Decisions,\nfrom Cloudflare's Clef models on Workers AI, and it also reads images. It emits\nno text at all.\n\nThis is not the Cloudflare Workers AI text provider\n(cloudflare, which runs chat models). The two are separate providers that\nread the same CLOUDFLARE_API_KEY and CLOUDFLARE_ACCOUNT_ID; see\nOne token, two providers.\n\nRead Limits before you rely on it. Workers AI's state window\nchanged in October 2026 (hosted service or model: unknown). Until 2026-10-04 it\nread only about the first 2,048 tokens of the state, far less than the 64K\ncontext Cloudflare documents, and ignored the rest without an error; on\n2026-10-07 it read states of at least 190,153 tokens (clef-flash) and 52,154\n(clef). NeuroLink refuses a state it estimates at more than 16,000 tokens,\ninside what was read in full, and a longer wait than a fail-open feature can\nafford.\n\nOverview\n\nClef is a decision model: it reads a state and a set of typed questions and\nreturns a probability for every allowed answer, with no free-form text and no\nreasoning tokens to wait for. Cloudflare publishes two sizes, clef (27B) and\nclef-flash (9B), and says it is releasing their weights under the Apache 2.0\nlicense. Both answered in about a second from a developer machine. Cloudflare's\npages call them available, and do not say whether they are generally available\nor in beta.\n\nKey Facts\n\n| | |\n| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Provider id | cloudflare-clef |\n| Models | clef (27B, the default) and clef-flash (9B). @cf/cloudflare/clef and @cf/cloudflare/clef-flash are accepted too |\n| Question types | boolean (sent as noul), choice (2 to 255 options), score (2 to 10 levels) |\n| Questions per request | 64 |\n| Images | up to 4 per request: PNG, JPEG or WebP. No video |\n| State | read in full up to at least 190,153 tokens (clef-flash) and 52,154 (clef) on 2026-10-07; about 2,048 until 2026-10-04. NeuroLink refuses a state it estimates at more than 16,000 |\n| Request size | 256,000 bytes in NeuroLink, base64 image data included |\n| Endpoint | https://api.cloudflare.com/client/v4/accounts/<account id>/ai/run/@cf/cloudflare/<model> |\n| Credentials | an API token with Workers AI permission, and the account id |\n| Price | $0.24 per million input tokens for clef, $0.09 for clef-flash; no output price is listed (Cloudflare's Workers AI pricing page) |\n| Measured latency | 2026-10-03: 0.3 to 1.0 s for a small request; 64 questions: 1.1 s (clef-flash), 1.3 s (clef); 2026-10-04: 1.5 s / 2.3 s |\n| Default decide provider | second to last: after TypeSafe, Laya, XOR, SubQ and Perplexity, before OpenAI Decisions |\n| Verified live | 2026-10-03 and 2026-10-04, with a real account (see Limits) |\n\nQuick Start\nGet a token and your account id\n\nCreate an API token with the Workers AI: Read + Write permission at\ndash.cloudflare.com/profile/api-tokens, and copy your account id from\nthe dashboard URL or the \"Account ID\" panel.\nConfigure\n\nThe base URL must be https://; http:// is accepted only for localhost,\n127.0.0.1 and [::1], because every request ca","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Clef Provider Guide","lvl2":"","lvl3":""}},
5654
5659
  {"objectID":"eebb9363ccd61130d0be9464df57f02fd61d00b6ff81821dd3162c030c0bc0db","title":"Cloudflare Clef Provider Guide","url":"/docs/getting-started/providers/cloudflare-clef#cloudflare-clef-provider-guide","content":"A provider of decide β€” the same typed boolean / choice / score\nanswers as TypeSafe's Jev, Laya, XOR,\nPerplexity and OpenAI Decisions,\nfrom Cloudflare's Clef models on Workers AI, and it also reads images. It emits\nno text at all.\n\nThis is not the Cloudflare Workers AI text provider\n(cloudflare, which runs chat models). The two are separate providers that\nread the same CLOUDFLARE_API_KEY and CLOUDFLARE_ACCOUNT_ID; see\nOne token, two providers.\n\nRead Limits before you rely on it. Workers AI's state window\nchanged in October 2026 (hosted service or model: unknown). Until 2026-10-04 it\nread only about the first 2,048 tokens of the state, far less than the 64K\ncontext Cloudflare documents, and ignored the rest without an error; on\n2026-10-07 it read states of at least 190,153 tokens (clef-flash) and 52,154\n(clef). NeuroLink refuses a state it estimates at more than 16,000 tokens,\ninside what was read in full, and a longer wait than a fail-open feature can\nafford.","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Clef Provider Guide","lvl2":"Cloudflare Clef Provider Guide","lvl3":""}},
5655
5660
  {"objectID":"d3aa34515e7690cc133be051b57b7fda1e8fdd225ef0dd7a162d91ee2ffa91d8","title":"Overview","url":"/docs/getting-started/providers/cloudflare-clef#overview","content":"Clef is a decision model: it reads a state and a set of typed questions and\nreturns a probability for every allowed answer, with no free-form text and no\nreasoning tokens to wait for. Cloudflare publishes two sizes, clef (27B) and\nclef-flash (9B), and says it is releasing their weights under the Apache 2.0\nlicense. Both answered in about a second from a developer machine. Cloudflare's\npages call them available, and do not say whether they are generally available\nor in beta.","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Clef Provider Guide","lvl2":"Overview","lvl3":""}},
5656
5661
  {"objectID":"babb1678dd2f0f63c1db8cf3e5216f3ac6b22a00331fe49058519957948ca5fb","title":"Key Facts","url":"/docs/getting-started/providers/cloudflare-clef#key-facts","content":"| | |\n| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Provider id | cloudflare-clef |\n| Models | clef (27B, the default) and clef-flash (9B). @cf/cloudflare/clef and @cf/cloudflare/clef-flash are accepted too |\n| Question types | boolean (sent as noul), choice (2 to 255 options), score (2 to 10 levels) |\n| Questions per request | 64 |\n| Images | up to 4 per request: PNG, JPEG or WebP. No video |\n| State | read in full up to at least 190,153 tokens (clef-flash) and 52,154 (clef) on 2026-10-07; about 2,048 until 2026-10-04.","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Clef Provider Guide","lvl2":"Key Facts","lvl3":""}},
@@ -5668,7 +5673,7 @@
5668
5673
  {"objectID":"bb0d1df2801529da652fbd15360879d9b2ccce53dfdf4d825a7a00f4e19d8d15","title":"What is not verified","url":"/docs/getting-started/providers/cloudflare-clef#what-is-not-verified","content":"The status Cloudflare returns for a token without Workers AI permission. No\n such token was available. A 403 is treated as an ordinary invalid_request,\n not authentication, so that if it does mean a missing permission, fixing it\n in the dashboard works at once, without restarting the process.\nAny 5xx other than one 529. Cloudflare answered a single server error, HTTP 529\n with code 5012 (\"Clef inference failed\"), to a 190,153-token state on clef on\n 2026-10-07; the retry and classification of 500, 502, 503 and 504 rest on\n ordinary HTTP conventions.\nWhat a Workers Paid account that has run out of credit gets. Only the Free plan's\n daily allocation running out was seen (HTTP 429, code 4006, 2026-10-05); it is\n not retried. Cloudflare documents a reset at 00:00 UTC, but this account was\n still refused at 02:38 and 04:12 UTC on 2026-10-06 and answered again at\n 07:24 UTC on 2026-10-07, so when the allowance returns here is not verified.\nThe 27B TypeScript, minified-JSON and synthetic Devanagari/emoji cuts; see the\n model coverage above.\nThe rate limit. Only a burst of 60 was tried.\nWhether Cloudflare's service is generally available or in beta.\nWhether the state window (about 2,048 tokens until 2026-10-04, none found by\n 2026-10-07) and the changing request-size limit belong to the hosted service or\n to the model itself. The open weights on Hugging Face\n were not run.\nWhether either limit changes again. The live decide suite carries three canary\n cases that fail with an instruction to re-measure: 19.10 and 19.10b send a\n prose state and a digit array just under NeuroLink's own limit, with a fact at\n the very end, to both models, and fail if the service stops reading below that\n limit; 19.11 checks both sides of the text-only request ceiling on clef-flash.\n None of them notices a service that reads more than the limit allows.","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Clef Provider Guide","lvl2":"What is not verified","lvl3":""}},
5669
5674
  {"objectID":"4214184c06ad6cee88e38838f55c38c5a554a78434494b5d765a1c120eb0e339","title":"Latency and the timeout","url":"/docs/getting-started/providers/cloudflare-clef#latency-and-the-timeout","content":"On 2026-10-03, a small request answered in 0.3 to 1.0 s from a developer\nmachine; 64 questions took 1.1 s on clef-flash and 1.3 s on clef; the\nslowest of 60 requests sent at once took 2.2 s. On 2026-10-04, a\n64-question request with the same questions and a shorter state took 1.5 s on clef-flash and 2.3 s on clef. The default timeout is 5 s plus 250 ms for each full 1,000 estimated state tokens\n(5 s for a short state, 9 s at the 16,000-token limit); on 2026-10-07 large states took about 0.2 s per\n1,000 input tokens (1.7 to 1.9 s for 20,954 tokens on clef-flash; 11.8 s for 52,154 on clef). Pass\ntimeoutMs to change it for one call.","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Clef Provider Guide","lvl2":"Latency and the timeout","lvl3":""}},
5670
5675
  {"objectID":"c2d0b99e3c2760e14d8be1f81ba92c025ad96523cdeaa34dd002a748ae9658de","title":"Errors","url":"/docs/getting-started/providers/cloudflare-clef#errors","content":"Cloudflare answers with its own envelope, { \"success\": false, \"errors\": [{ \"code\",\n\"message\" }] }, and a refusal from the model nests a second envelope, with a\ntrailing request id, inside message. NeuroLink flattens both to one line and\ntakes the request id out of the text.\n\n| Status | Code | Seen for | Kind | Retried |\n| ------ | ----- | ----------------------------------------------------------------------------------------- | ----------------------------------- | ------------------------------ |\n| 401 | 10000 | a token Cloudflare does not know | authentication | no; trips the breaker |\n| 403 | | never seen; a token without Workers AI permission may draw it | invalid_request | no; does not trip the breaker |\n| 400 | 5006 | no questions; an unknown question type | invalid_request | no |\n| 400 | 7000 | a model path that does not exist (\"No route for that URI\") | invalid_request | no |\n| 400 | 6003 | a body that is not JSON | invalid_request | no |\n| 422 | 5012 | a validation failure: 65 questions, a fifth image, an unknown field, an empty instruction | invalid_request | no |\n| 413 | 5021 | a request past the estimate above | max_tokens_exceeded | no |\n| 429 | 3040 | \"Capacity temporarily exceeded\"; no Retry-After","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Clef Provider Guide","lvl2":"Errors","lvl3":""}},
5671
- {"objectID":"ce05a3d9d2ab15b8867c8e721fbfa0f8e1248520e2413765fa7d70bd835e3f85","title":"Troubleshooting","url":"/docs/getting-started/providers/cloudflare-clef#troubleshooting","content":"\"requires the account id\" β€” set CLOUDFLARE_ACCOUNT_ID or\n credentials.cloudflareClef.accountId.\n\"The state is ~N tokens; Cloudflare's … model reads at most 1500\" β€” shorten\n the state, or send only the part the question is about. Cloudflare would have\n cut the rest without telling you.\n\"No route for that URI\" β€” the model name or the base URL is wrong. Clef is\n served as clef and clef-flash, and the base URL must end in /client/v4.\nA 429 \"Capacity temporarily exceeded\" β€” retried for you; if it keeps\n happening, send fewer requests at once.\nA 429 \"you have used up your daily free allocation of 10,000 neurons\" β€” the\n Free plan's allowance for the day is gone. It is not retried, because nothing\n changes until the allowance returns (Cloudflare documents a reset at 00:00 UTC; on\n this account it came back later, see \"What is not verified\"); upgrade to Workers Paid or wait.\n Built-in features that use Clef as their default fall back as on any failure.\nAn image is refused as \"The request is N bytes; Cloudflare accepts at most\n 256000\" β€” Cloudflare counts the base64 text of the image, so NeuroLink\n refuses it locally under the retained conservative cap. Resize or compress it\n to well under 190 KB; a 195 KB PNG, which Cloudflare accepted, is about 260,000\n characters in base64 and is refused here.\ndecide() uses Clef although you never chose it β€” you have the Workers AI\n token and account id set and no other decision provider; see\n When NeuroLink uses it.","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Clef Provider Guide","lvl2":"Troubleshooting","lvl3":""}},
5676
+ {"objectID":"ce05a3d9d2ab15b8867c8e721fbfa0f8e1248520e2413765fa7d70bd835e3f85","title":"Troubleshooting","url":"/docs/getting-started/providers/cloudflare-clef#troubleshooting","content":"\"requires the account id\" β€” set CLOUDFLARE_ACCOUNT_ID or\n credentials.cloudflareClef.accountId.\n\"The state is ~N tokens; Cloudflare's … model reads at most 1500\" β€” shorten\n the state, or send only the part the question is about. Cloudflare would have\n cut the rest without telling you.\n\"No route for that URI\" β€” the model name or the base URL is wrong. Clef is\n served as clef and clef-flash, and the base URL must end in /client/v4.\n\"The Cloudflare base URL must use https:// unless it points at this machine\" β€”\n the override is an http:// URL whose host is not localhost, 127.0.0.1 or\n [::1]. A plain-http request would send the token unencrypted. Use https://,\n or reach the server through a port-forward to localhost.\n\"Cloudflare answered with a redirect\" β€” the endpoint replied 301, 302, 307 or 308. The provider does not follow it and does not retry. Set the base URL to the\n address the redirect leads to.\nA 429 \"Capacity temporarily exceeded\" β€” retried for you; if it keeps\n happening, send fewer requests at once.\nA 429 \"you have used up your daily free allocation of 10,000 neurons\" β€” the\n Free plan's allowance for the day is gone. It is not retried, because nothing\n changes until the allowance returns (Cloudflare documents a reset at 00:00 UTC; on\n this account it came back later, see \"What is not verified\"); upgrade to Workers Paid or wait.\n Built-in features that use Clef as their default fall back as on any failure.\nAn image is refused as \"The request is N bytes; Cloudflare accepts at most\n 256000\" β€” Cloudflare counts the base64 text of the image, so NeuroLink\n refuses it locally under the retained conservative cap. Resize or compress it\n to well under 190 KB; a 195 KB PNG, which Cloudflare accepted, is about 260,000\n characters in base64 and is refused here.\ndecide() uses Clef although you never chose it β€” you have the Workers AI\n token and account id set and no other decision provider; see\n When NeuroLink uses it.","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Clef Provider Guide","lvl2":"Troubleshooting","lvl3":""}},
5672
5677
  {"objectID":"64d2af754e23d6f77f9ba5991174048f9dc4e8434d0f9a633527785feff8158e","title":"See also","url":"/docs/getting-started/providers/cloudflare-clef#see-also","content":"The decide inference type\nTypeSafe (Jev) Provider Guide\nLaya Provider Guide\nXOR Provider Guide\nPerplexity Decisions Provider Guide\nSubQ Provider Guide\nOpenAI Decisions Provider Guide\nCloudflare Workers AI text provider\nClef on Workers AI\nIntroducing Clef: our open-source decision models, and new RL fine-tuning platform (Cloudflare Blog)","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Clef Provider Guide","lvl2":"See also","lvl3":""}},
5673
5678
  {"objectID":"3803b4ecde578f946b8a4fe5139e3ee640d53281541c50578e8a5d47847d5157","title":"Cloudflare Workers AI Provider Guide","url":"/docs/getting-started/providers/cloudflare","content":"Cloudflare Workers AI Provider Guide\n\nOpen-model inference at the edge via Cloudflare Workers AI\n\nOverview\n\nCloudflare Workers AI\nserves Meta Llama, Mistral, and other open models from Cloudflare's\nglobal GPU cluster. NeuroLink talks to the OpenAI-compatible endpoint.\n\nKey Facts\nProtocol: OpenAI-compatible (/v1/chat/completions)\nDefault base URL: https://api.cloudflare.com/client/v4/accounts/{accountId}/ai/v1\nDefault model: @cf/meta/llama-3.3-70b-instruct-fp8-fast\nStreaming: Yes\nTool calling: Limited (model-dependent)\n\nQuick Start\nGet Credentials\n\nYou need both:\nA Cloudflare Account ID (Cloudflare dashboard β†’ right sidebar)\nA Workers AI API token with the Workers AI Read & Write\n permission (Profile β†’ API Tokens β†’ Create Token)\nConfigure\nGenerate\n\nSupported Models (sample)\n\n| Model ID | Notes |\n| ------------------------------------------ | -------------- |\n| @cf/meta/llama-3.3-70b-instruct-fp8-fast | Default |\n| @cf/meta/llama-3.1-70b-instruct | Llama 3.1 70B |\n| @cf/meta/llama-3.1-8b-instruct | Fast tier |\n| @cf/meta/llama-3.2-11b-vision-instruct | Vision-capable |\n\nBrowse: https://developers.cloudflare.com/workers-ai/models\n\nCLI Usage\n\nProvider Aliases\n\n| Alias | Example |\n| ------------ | ----------------------- |\n| cloudflare | --provider cloudflare |\n| cf | --provider cf |\n\nConfiguration Reference\n\n| Environment Variable | Required | Default |\n| ----------------------- | -------- | ------------------------------------------ |\n| CLOUDFLARE_ACCOUNT_ID | Yes | β€” |\n| CLOUDFLARE_API_KEY | Yes | β€” |\n| CLOUDFLARE_MODEL | No | @cf/meta/llama-3.3-70b-instruct-fp8-fast |\n\nAlso configures decisions\n\nCLOUDFLARE_API_KEY and CLOUDFLARE_ACCOUNT_ID also configure a separate\nprovider, the Cloudflare Clef provider (cloudflare-clef),\nwhich serves decide() and emits no text. It is the second-to-last decision\nprovider NeuroLink falls back to: built-in features that call decide() use the\nfirst one configured, in the order TypeSafe, Laya, XOR, SubQ, Perplexity, Clef, then\nOpenAI Decisions. So a host\nthat set these two variables only for this text provider, and has no other\ndecision provider configured, has Clef as its default decision provider, and no\nswitch turns that off while they are set.\n\ncredentials.cloudflare does not configure decide; Clef reads its own\nslice, credentials.cloudflareClef. The text provider itself is unchanged: it\nstill serves generate() and stream() with the same variables, models and base\nURL. See\nOne token, two providers.\n\nSee Also\nCloudflare Clef Provider β€” typed decide() judgments on the same token and account id\nTogether AI Provider\nFireworks Provider","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Workers AI Provider Guide","lvl2":"","lvl3":""}},
5674
5679
  {"objectID":"aafa1a6f2adf2bacc5661cf9ccb309d1e32e300645f037c35a98217b31eb15df","title":"Cloudflare Workers AI Provider Guide","url":"/docs/getting-started/providers/cloudflare#cloudflare-workers-ai-provider-guide","content":"Open-model inference at the edge via Cloudflare Workers AI","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Workers AI Provider Guide","lvl2":"Cloudflare Workers AI Provider Guide","lvl3":""}},
@@ -6526,7 +6531,7 @@
6526
6531
  {"objectID":"ea8a27a2ad19397f67e1da30b6d09cd934e2032a3b4e9b2c23cee112d5aa1761","title":"Verification status","url":"/docs/getting-started/providers/minimax#verification-status","content":"Tier-2 onboarding requires evidence before a provider is accepted, and\npnpm run verify:provider-onboarding gates it in CI. This is what the\ncatalog currently records for MiniMax β€” docs-verified only, not\nlive-verified:\n\n| Probe | Result |\n| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Roster | unauthenticated GET https://api.minimax.io/v1/models answers HTTP 401 without a key (2026-09-29), so model ids are taken from the OpenAI SDK page (retrieved 2026-09-29); roster not verified |\n| Auth-failure shape | unauthenticated GET","hierarchy":{"lvl0":"Getting Started","lvl1":"MiniMax Provider Guide","lvl2":"Verification status","lvl3":""}},
6527
6532
  {"objectID":"53b6d682f1044041732dc0189793fbf9327db08dfa55648ac435cb728ff43b7e","title":"Troubleshooting","url":"/docs/getting-started/providers/minimax#troubleshooting","content":"Causes and fixes in quotation marks are MiniMax's wording, with the page named.\n\n| Symptom | Cause | Fix |\n| --------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |\n| HTTP 401 with login fail: Please carry the API secret key in the 'Authorization' field of the request header (1004) | The error-code table lists 1004 as \"not authorized / token not match group / cookie is missing, log in again\" (errorcode page) | \"please check your API Key and make sure it is correct and active.\" (https://platform.minimax.io/docs/api-reference/errorcode) |\n| Error 1008 \"insufficient balance\" | Listed in the error-code table | \"Please check your account balance.\" (https://platform.minimax.io/docs/api-reference/errorcode) |\n| Error 1002 \"rate limit\" | Listed in the error-code table | \"Please retry your requests later.\"","hierarchy":{"lvl0":"Getting Started","lvl1":"MiniMax Provider Guide","lvl2":"Troubleshooting","lvl3":""}},
6528
6533
  {"objectID":"e907030d03048f98452b61d0255663abd19f149d91f8ad9670b837ca0a8b7e35","title":"See also","url":"/docs/getting-started/providers/minimax#see-also","content":"Provider setup overview\nAll providers\nTier-2 onboarding β€” how this provider's JSON becomes a working integration\nProvider feature compatibility\nMiniMax pages this entry was built from:\n OpenAI SDK,\n Chat Completions,\n Anthropic API,\n Models,\n Model Invocation,\n Pay as You Go,\n Rate Limits,\n Error Codes,\n Prerequisites,\n Token Plan Overview","hierarchy":{"lvl0":"Getting Started","lvl1":"MiniMax Provider Guide","lvl2":"See also","lvl3":""}},
6529
- {"objectID":"6748f6472fbf23ce7e62b6548376cf240e9764bce6f2ed06ee81c3628d066127","title":"Mistral AI Provider Guide","url":"/docs/getting-started/providers/mistral","content":"Mistral AI Provider Guide\n\nEuropean AI excellence with GDPR compliance and competitive free tier\n\nOverview\n\nMistral AI is a European AI company offering powerful open-source and proprietary models with built-in GDPR compliance, European data residency, and competitive pricing. Perfect for EU-based companies and privacy-conscious applications.\n\nMistral AI is EU-based with European data residency by default. Ideal for GDPR-compliant applications without additional configuration required.\n\nKey Benefits\nπŸ‡ͺπŸ‡Ί European Company: GDPR-compliant by design\nπŸ†“ Free Tier: Generous free tier for experimentation\nπŸš€ High Performance: Competitive with GPT-4 and Claude\nπŸ’° Cost-Effective: Lower pricing than major US providers\nπŸ”“ Open Source: Mistral 7B model fully open-source\n⚑ Fast Inference: Optimized for low latency\n\nUse Cases\nEU Compliance: GDPR-compliant AI for European companies\nCost Optimization: Lower costs than OpenAI/Anthropic\nCode Generation: Excellent coding capabilities (Codestral)\nEnterprise: Production-ready with EU data residency\nResearch: Open-source models for experimentation\n\nQuick Start\nGet Your API Key\nVisit Mistral AI Console\nCreate a free account\nGo to \"API Keys\" section\nClick \"Create new key\"\nCopy the key (format: xxx...)\nConfigure NeuroLink\n\nAdd to your .env file:\nTest the Setup\n\nModel Selection Guide\n\nAvailable Models\n\n| Model | Model ID | Context | Vision | Use Case |\n| ---------------------- | ------------------------- | ------- | ------ | -------------------------------------------------------- |\n| Mistral Large 3 | mistral-large-latest | 256K | Yes | Flagship, agentic β€” native vision replaces Pixtral Large |\n| Mistral Medium 3.1 | mistral-medium-latest | 128K | Yes | Balanced performance/cost |\n| Mistral Small 4 | mistral-small-latest | 128K | Yes | MoE architecture, strong reasoning at low cost |\n| Magistral Medium | magistral-medium-latest | 128K | Yes | Reasoning-focused |\n| Magistral Small | magistral-small-latest | 128K | Yes | Reasoning (Apache 2.0 license) |\n| Codestral | codestral-latest | 256K | No | Code generation and review |\n| Devstral 2 | devstral-2512 | 256K | No | Agentic coding workflows |\n| Pixtral Large | pixtral-large | 128K | Yes | Vision (deprecated β€” use Mistral Large 3) |\n| Mistral Embed | mistral-embed | β€” | β€” | Embeddings (1024 dimensions) |\n| Codestral Embed | codestral-embed | β€” | β€” | Code embeddings |\n\nPixtral Large has been superseded by Mistral Large 3, which includes native vision capabilities alongside its flagship text performance. New projects should use mistral-large-latest for both text and vision tasks. The pixtral-large model ID remains available but is considered deprecated.\n\nFree Tier Details\n\nβœ… What's Included:\n$5 free credits for new users\nNo time limit on free credits\nAll models available on free tier\nNo credit card required for signup\n\nπŸ’‘ Free Tier Estimate:\n~2.5M tokens with mistral-small\n~625K tokens with mistral-large\n~5M tokens with codestral\n\nModel Selection by Use Case\n\nGDPR Compliance & European Deployment\n\nWhy Mistral for EU Companies\n\nBuilt-in GDPR Compliance:\nβœ… European company (France-based)\nβœ… EU data centers\nβœ… GDPR-compliant by design\nβœ… No data sent to US servers\nβœ… Data residency in Europe\n\nData Residency Configuration\n\nGDPR Compliance Checklist\n\nCompliance Features\n\n| Feature | Mistral AI | Other Providers |\n| -------------------- | ----------------- | --------------- |\n| EU Data Centers | βœ… Yes | ⚠️ Limited |\n| GDPR Compliance | βœ… Built-in | ⚠️ Varies |\n| Data Residency | βœ… EU-only option | ⚠️ Often US |\n| Privacy Controls | βœ… Granular | ⚠️ Limited |\n| Audit Logs | βœ… Available | ⚠️ Varies |\n\nSDK Integration\n\nBasic Usage\n\nWith Specific Model\n\nStreaming Responses\n\nMulti-Language Support\n\nCost Tracking\n\nCLI Usage\n\nBasic Commands\n\nAdvanced Usage\n\nCost-Effective Workflows\n\nConfiguration Options\n\nEnvironment Variables\n\nProgrammatic Configuration\n\nEnterprise Deployment\n\nProduction Setup\n\nMulti-Region Deployment\n\nCost Optimization\n\nTroubleshooting\n\nCommon Issues\n\"Invalid API Key\"\n\nProblem: API key is incorrect or expired.\n\nSolution:\n\"Rate Limit Exceeded\"\n\nProblem: Exceeded free tier or paid tier limits.\n\nSolution:\n\"Insufficient Credits\"\n\nProblem: Free tier exhausted.\n\nSolution:\nAdd payment method in Mistral console\nUse fallback provider\nMonitor usage:\nSlow Response Times\n\nProblem: Model or network latency.\n\nSolution:\n\nBest Practices\nGDPR-Compliant Usage\nCost Optimization\n","hierarchy":{"lvl0":"Getting Started","lvl1":"Mistral AI Provider Guide","lvl2":"","lvl3":""}},
6534
+ {"objectID":"6748f6472fbf23ce7e62b6548376cf240e9764bce6f2ed06ee81c3628d066127","title":"Mistral AI Provider Guide","url":"/docs/getting-started/providers/mistral","content":"Mistral AI Provider Guide\n\nEuropean AI excellence with GDPR compliance and competitive free tier\n\nOverview\n\nMistral AI is a European AI company offering powerful open-source and proprietary models with built-in GDPR compliance, European data residency, and competitive pricing. Perfect for EU-based companies and privacy-conscious applications.\n\nMistral AI is EU-based with European data residency by default. Ideal for GDPR-compliant applications without additional configuration required.\n\nKey Benefits\nπŸ‡ͺπŸ‡Ί European Company: GDPR-compliant by design\nπŸ†“ Free Tier: Generous free tier for experimentation\nπŸš€ High Performance: Competitive with GPT-4 and Claude\nπŸ’° Cost-Effective: Lower pricing than major US providers\nπŸ”“ Open Source: Mistral 7B model fully open-source\n⚑ Fast Inference: Optimized for low latency\n\nUse Cases\nEU Compliance: GDPR-compliant AI for European companies\nCost Optimization: Lower costs than OpenAI/Anthropic\nCode Generation: Excellent coding capabilities (Codestral)\nEnterprise: Production-ready with EU data residency\nResearch: Open-source models for experimentation\n\nQuick Start\nGet Your API Key\nVisit Mistral AI Console\nCreate a free account\nGo to \"API Keys\" section\nClick \"Create new key\"\nCopy the key (format: xxx...)\nConfigure NeuroLink\n\nAdd to your .env file:\nTest the Setup\n\nModel Selection Guide\n\nAvailable Models\n\n| Model | Model ID | Context | Vision | Use Case |\n| ---------------------- | ------------------------- | ------- | ------ | -------------------------------------------------------- |\n| Mistral Large 3 | mistral-large-latest | 256K | Yes | Flagship, agentic β€” native vision replaces Pixtral Large |\n| Mistral Medium 3.1 | mistral-medium-latest | 128K | Yes | Balanced performance/cost |\n| Mistral Small 4 | mistral-small-latest | 128K | Yes | MoE architecture, strong reasoning at low cost |\n| Magistral Medium | magistral-medium-latest | 128K | Yes | Reasoning-focused |\n| Magistral Small | magistral-small-latest | 128K | Yes | Reasoning (Apache 2.0 license) |\n| Codestral | codestral-latest | 256K | No | Code generation and review |\n| Devstral 2 | devstral-2512 | 256K | No | Agentic coding workflows |\n| Pixtral Large | pixtral-large | 128K | Yes | Vision (deprecated β€” use Mistral Large 3) |\n| Mistral Embed | mistral-embed | β€” | β€” | Embeddings (1024 dimensions) |\n| Codestral Embed | codestral-embed | β€” | β€” | Code embeddings |\n\nPixtral Large has been superseded by Mistral Large 3, which includes native vision capabilities alongside its flagship text performance. New projects should use mistral-large-latest for both text and vision tasks. The pixtral-large model ID remains available but is considered deprecated.\n\nFree Tier Details\n\nβœ… What's Included:\n$5 free credits for new users\nNo time limit on free credits\nAll models available on free tier\nNo credit card required for signup\n\nπŸ’‘ Free Tier Estimate:\n~2.5M tokens with mistral-small\n~625K tokens with mistral-large\n~5M tokens with codestral\n\nModel Selection by Use Case\n\nNeuroLink does not serve embeddings through Mistral. For RAG, pair Mistral for generation with a provider that supports embeddings.\n\nGDPR Compliance & European Deployment\n\nWhy Mistral for EU Companies\n\nBuilt-in GDPR Compliance:\nβœ… European company (France-based)\nβœ… EU data centers\nβœ… GDPR-compliant by design\nβœ… No data sent to US servers\nβœ… Data residency in Europe\n\nData Residency Configuration\n\nGDPR Compliance Checklist\n\nCompliance Features\n\n| Feature | Mistral AI | Other Providers |\n| -------------------- | ----------------- | --------------- |\n| EU Data Centers | βœ… Yes | ⚠️ Limited |\n| GDPR Compliance | βœ… Built-in | ⚠️ Varies |\n| Data Residency | βœ… EU-only option | ⚠️ Often US |\n| Privacy Controls | βœ… Granular | ⚠️ Limited |\n| Audit Logs | βœ… Available | ⚠️ Varies |\n\nSDK Integration\n\nBasic Usage\n\nWith Specific Model\n\nStreaming Responses\n\nMulti-Language Support\n\nCost Tracking\n\nCLI Usage\n\nBasic Commands\n\nAdvanced Usage\n\nCost-Effective Workflows\n\nConfiguration Options\n\nEnvironment Variables\n\nProgrammatic Configuration\n\nEnterprise Deployment\n\nProduction Setup\n\nMulti-Region Deployment\n\nCost Optimization\n\nTroubleshooting\n\nCommon Issues\n\"Invalid API Key\"\n\nProblem: API key is incorrect or expired.\n\nSolution:\n\"Rate Limit Exceeded\"\n\nProblem: Exceeded free tier or paid tier limits.\n\nSolution:\n\"Insufficient Credits\"\n\nProblem: Free tier exhausted.\n\nSolution:\nAdd payment method in Mistral console\nUse fallback provider\nMoni","hierarchy":{"lvl0":"Getting Started","lvl1":"Mistral AI Provider Guide","lvl2":"","lvl3":""}},
6530
6535
  {"objectID":"0ce7b52929014d0ecaddc797a9d0dcdb7977f696c76a71ab2114290e61fd0ed7","title":"Mistral AI Provider Guide","url":"/docs/getting-started/providers/mistral#mistral-ai-provider-guide","content":"European AI excellence with GDPR compliance and competitive free tier","hierarchy":{"lvl0":"Getting Started","lvl1":"Mistral AI Provider Guide","lvl2":"Mistral AI Provider Guide","lvl3":""}},
6531
6536
  {"objectID":"065784e2ef6ad614a2508b05360fcd65d3501b5f4807a64becbf0a3c8a188475","title":"Overview","url":"/docs/getting-started/providers/mistral#overview","content":"Mistral AI is a European AI company offering powerful open-source and proprietary models with built-in GDPR compliance, European data residency, and competitive pricing. Perfect for EU-based companies and privacy-conscious applications.\n\nMistral AI is EU-based with European data residency by default. Ideal for GDPR-compliant applications without additional configuration required.","hierarchy":{"lvl0":"Getting Started","lvl1":"Mistral AI Provider Guide","lvl2":"Overview","lvl3":""}},
6532
6537
  {"objectID":"fdddd6025681658ce2b22cc29064e0d25b32199167eb2855c8db0c7110e1a0a0","title":"Key Benefits","url":"/docs/getting-started/providers/mistral#key-benefits","content":"πŸ‡ͺπŸ‡Ί European Company: GDPR-compliant by design\nπŸ†“ Free Tier: Generous free tier for experimentation\nπŸš€ High Performance: Competitive with GPT-4 and Claude\nπŸ’° Cost-Effective: Lower pricing than major US providers\nπŸ”“ Open Source: Mistral 7B model fully open-source\n⚑ Fast Inference: Optimized for low latency","hierarchy":{"lvl0":"Getting Started","lvl1":"Mistral AI Provider Guide","lvl2":"Key Benefits","lvl3":""}},
@@ -6539,6 +6544,7 @@
6539
6544
  {"objectID":"81c6bb84148096ad2b53a1a2e434a17898acde187cd655c8aebb32999d1dffeb","title":"SDK","url":"/docs/getting-started/providers/mistral#sdk","content":"node -e \"\nconst { NeuroLink } = require('@juspay/neurolink');\n(async () => {\n const ai = new NeuroLink();\n const result = await ai.generate({\n input: { text: 'Hello from Mistral AI!' },\n provider: 'mistral'\n });\n console.log(result.content);\n})();\n\"\n`","hierarchy":{"lvl0":"Getting Started","lvl1":"Mistral AI Provider Guide","lvl2":"SDK","lvl3":""}},
6540
6545
  {"objectID":"63047efb34cad7a58b2a478140c72b0bd1cded0982ec5d7b0540f37209af1e0c","title":"Available Models","url":"/docs/getting-started/providers/mistral#available-models","content":"| Model | Model ID | Context | Vision | Use Case |\n| ---------------------- | ------------------------- | ------- | ------ | -------------------------------------------------------- |\n| Mistral Large 3 | mistral-large-latest | 256K | Yes | Flagship, agentic β€” native vision replaces Pixtral Large |\n| Mistral Medium 3.1 | mistral-medium-latest | 128K | Yes | Balanced performance/cost |\n| Mistral Small 4 | mistral-small-latest | 128K | Yes | MoE architecture, strong reasoning at low cost |\n| Magistral Medium | magistral-medium-latest | 128K | Yes | Reasoning-focused |\n| Magistral Small | magistral-small-latest | 128K | Yes | Reasoning (Apache 2.0 license) |\n| Codestral | codestral-latest | 256K | No | Code generation and review |\n| Devstral 2 | devstral-2512 | 256K | No | Agentic coding workflows |\n| Pixtral Large | pixtral-large | 128K | Yes | Vision (deprecated β€” use Mistral Large 3) |\n| Mistral Embed | mistral-embed | β€” | β€” | Embeddings (1024 dimensions) |\n| Codestral Embed | codestral-embed | β€” | β€” | Code embeddings |\n\nPixtral Large has been superseded by Mistral Large 3, which includes native vision capabilities alongside its flagship text performance. New projects should use mistral-large-latest for both text and vision tasks. The pixtral-large model ID remains available but is considered deprecated.","hierarchy":{"lvl0":"Getting Started","lvl1":"Mistral AI Provider Guide","lvl2":"Available Models","lvl3":""}},
6541
6546
  {"objectID":"f46d3185581434aeb5a6a253ea86c62ffdd47d6dd7573b008a28cca3c63e9fce","title":"Free Tier Details","url":"/docs/getting-started/providers/mistral#free-tier-details","content":"βœ… What's Included:\n$5 free credits for new users\nNo time limit on free credits\nAll models available on free tier\nNo credit card required for signup\n\nπŸ’‘ Free Tier Estimate:\n~2.5M tokens with mistral-small\n~625K tokens with mistral-large\n~5M tokens with codestral","hierarchy":{"lvl0":"Getting Started","lvl1":"Mistral AI Provider Guide","lvl2":"Free Tier Details","lvl3":""}},
6547
+ {"objectID":"06e2c56add228976d6d818a39519e46cb7db0f622f6fb57867bba4a28300b396","title":"Model Selection by Use Case","url":"/docs/getting-started/providers/mistral#model-selection-by-use-case","content":"NeuroLink does not serve embeddings through Mistral. For RAG, pair Mistral for generation with a provider that supports embeddings.","hierarchy":{"lvl0":"Getting Started","lvl1":"Mistral AI Provider Guide","lvl2":"Model Selection by Use Case","lvl3":""}},
6542
6548
  {"objectID":"8594abf964e2f7d68d1b695e3705e3c9cd1c8ed40a683bf2686f64df4d61c4b2","title":"Why Mistral for EU Companies","url":"/docs/getting-started/providers/mistral#why-mistral-for-eu-companies","content":"Built-in GDPR Compliance:\nβœ… European company (France-based)\nβœ… EU data centers\nβœ… GDPR-compliant by design\nβœ… No data sent to US servers\nβœ… Data residency in Europe","hierarchy":{"lvl0":"Getting Started","lvl1":"Mistral AI Provider Guide","lvl2":"Why Mistral for EU Companies","lvl3":""}},
6543
6549
  {"objectID":"ec568746de63bf30df140a9c6a27facd4e816dd058ec01a7bfb0060c49486af3","title":"Compliance Features","url":"/docs/getting-started/providers/mistral#compliance-features","content":"| Feature | Mistral AI | Other Providers |\n| -------------------- | ----------------- | --------------- |\n| EU Data Centers | βœ… Yes | ⚠️ Limited |\n| GDPR Compliance | βœ… Built-in | ⚠️ Varies |\n| Data Residency | βœ… EU-only option | ⚠️ Often US |\n| Privacy Controls | βœ… Granular | ⚠️ Limited |\n| Audit Logs | βœ… Available | ⚠️ Varies |","hierarchy":{"lvl0":"Getting Started","lvl1":"Mistral AI Provider Guide","lvl2":"Compliance Features","lvl3":""}},
6544
6550
  {"objectID":"8310b1c2246240c792596e8dbb19f44e7f12dcda2049719e9d460ae004348b74","title":"Basic Commands","url":"/docs/getting-started/providers/mistral#basic-commands","content":"`bash","hierarchy":{"lvl0":"Getting Started","lvl1":"Mistral AI Provider Guide","lvl2":"Basic Commands","lvl3":""}},
@@ -6820,8 +6826,8 @@
6820
6826
  {"objectID":"4578834b017bbed1b8de1a71d677386e28437557be3814e141fa7becf3e36be2","title":"What is not established","url":"/docs/getting-started/providers/openai-decisions#what-is-not-established","content":"Each item below is not measured: nothing NeuroLink was built or tested from\nsays what the endpoint does, and no live request was made. Where NeuroLink had\nto choose, it chose to send only documented fields, to refuse nothing locally on\nOpenAI's behalf, and to drop a bad answer rather than guess.\nWhether /v1/decisions uses OpenAI's general error envelope, and the status\n and text of a refusal for an over-length input. NeuroLink reads an error's\n error.message when there is one, and classifies by HTTP status.\nThe maximum number of questions per request, of choices per question (the\n benchmarks NeuroLink has in mind need 77 and 151), and of levels per score,\n and what a question name may contain.\nThe endpoint's input ceiling (the model page gives 922,000 input tokens for the\n model in general), the number of images per request, the request body cap and\n the accepted image formats.\nWhether probabilities always covers every supplied option, in what order, and\n how the numbers are rounded. NeuroLink reads each distribution by key, not by\n position, and requires each asked option exactly once.\nThe endpoint's rate limits. The model page lists limits for the model, not for\n this endpoint.\nHow long a request takes, for any size. The 10-second default timeout is a\n starting point.\nWhether a regional host such as https://eu.api.openai.com serves this\n endpoint with the same request. The base URL can be changed to try one.","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Decisions Provider Guide","lvl2":"What is not established","lvl3":""}},
6821
6827
  {"objectID":"155654a19ca65d0e67082bb342d58723138287406b9783055a27d57d44812646","title":"Cost","url":"/docs/getting-started/providers/openai-decisions#cost","content":"$0.10 per 1M input tokens, input only, from\nOpenAI's Decisions guide\nas read on 2026-10-07. Regional and long-context multipliers are not modelled.\nNeuroLink prices a decision from the input tokens the reply reports and counts\noutput tokens at nothing, so result.usage and the CLI's Cost: line are an\nestimate from that one rate, not a bill. A reply that reports no usage is priced\nat zero.","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Decisions Provider Guide","lvl2":"Cost","lvl3":""}},
6822
6828
  {"objectID":"f61611df66cdbcf4e2fb52b5095b4ec859a6a96289fc4e4be0a383f8484f3c9f","title":"Errors","url":"/docs/getting-started/providers/openai-decisions#errors","content":"| Reply | Kind | Retried |\n| -------------------------------------------------------------------- | ------------------------------------------------------- | ---------------------------------------- |\n| 401 | authentication β€” the provider instance stops retrying | no |\n| 429 (every one) | rate_limit | no |\n| 503 | overloaded | yes, once (after Retry-After, if sent) |\n| other 5xx (500, 502, 504) | server | yes, once |\n| any other status, including 400, 402, 403 and 404 | invalid_request, with the reply's own message | no |\n| a 200 whose answers is not an array | server | no |\n| no response within the timeout | timeout | yes, once |\n| the request fails before any reply (connection refused, DNS failure) | network | yes, once |\n| the caller's own signal aborts the request | network | no |\n| more than 8 images, a video, or an unusable image (local) | invalid_request, with no network call","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Decisions Provider Guide","lvl2":"Errors","lvl3":""}},
6823
- {"objectID":"7cdf00f2dd7ac7f9cfae6a1b387567d1cf0c7de8a98f5c47210a6ff8221db4d6","title":"Base URL","url":"/docs/getting-started/providers/openai-decisions#base-url","content":"OPENAI_DECISIONS_BASE_URL, or credentials.openaiDecisions.baseURL, replaces\nhttps://api.openai.com. It is an origin:\ntrailing slashes and one trailing /v1 are stripped, so\n https://api.openai.com/v1/ and https://api.openai.com are the same;\na user name or password, a query string, a fragment, a scheme other than\n http or https, or a value that is not an absolute URL is refused before any\n request, with a message that never repeats the value;\nthe request goes to <origin>/v1/decisions.","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Decisions Provider Guide","lvl2":"Base URL","lvl3":""}},
6824
- {"objectID":"c6c6f00939ee73c7416d6eed5fcb54dfca58a77c31a358c0e1b630c25fdf9e71","title":"Troubleshooting","url":"/docs/getting-started/providers/openai-decisions#troubleshooting","content":"No decision provider is configured although OPENAI_API_KEY is set β€”\n OPENAI_BASE_URL, OPENAI_API_BASE or credentials.openai.baseURL names a host other than\n https://api.openai.com, so the key is taken to be a gateway's. See\n A gateway's key: set\n OPENAI_DECISIONS_BASE_URL or pass credentials.openaiDecisions to route this\n provider on purpose. Naming the provider in a call is not a way out when the key\n is a gateway's: a named call sends the environment key to api.openai.com.\nOpenAI Decisions requires an API key β€” set OPENAI_API_KEY, or pass\n credentials.openaiDecisions.apiKey. A key passed as credentials.openai does\n not count.\nA 401 β€” OpenAI rejected the key. The provider instance stops retrying after\n a rejection, so fix the key and construct a new one.\nA 403 β€” OpenAI's general error documentation lists a 403 for an unsupported\n country; what this endpoint's own 403s mean is not established. It does not latch\n the instance, so a change on the account side works at once.\nA 400 naming the model β€” OPENAI_DECISIONS_MODEL, or a per-call model,\n names something other than a model the endpoint supports.\nThe OpenAI Decisions base URL must not carry credentials… β€” the override\n has a user name, a password, a query string or a fragment. Set it to the origin\n only, or leave it unset for https://api.openai.com.\nThe OpenAI Decisions base URL must start with https:// or http:// β€” the\n value parses as a URL with another scheme, or is a host name and port with no\n scheme, such as localhost:8080, which reads as the scheme localhost:. Put\n https:// or http:// in front.\nThe OpenAI Decisions base URL is not a valid absolute URL β€” the value does\n not parse as a URL at all, for example a bare host name. Write the origin with\n its scheme.\nOpenAI Decisions accepts at most 8 images per request β€” NeuroLink's own\n allowance. Send fewer, or use a decision provider with a higher one.\nOpenAI Decisions does not accept video β€” the endpoint has no video part.","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Decisions Provider Guide","lvl2":"Troubleshooting","lvl3":""}},
6829
+ {"objectID":"7cdf00f2dd7ac7f9cfae6a1b387567d1cf0c7de8a98f5c47210a6ff8221db4d6","title":"Base URL","url":"/docs/getting-started/providers/openai-decisions#base-url","content":"OPENAI_DECISIONS_BASE_URL, or credentials.openaiDecisions.baseURL, replaces\nhttps://api.openai.com. It is an origin:\ntrailing slashes and one trailing /v1 are stripped, so\n https://api.openai.com/v1/ and https://api.openai.com are the same;\nhttp:// is accepted only for localhost, 127.0.0.1 and [::1], because the\n request carries the key and the state. Any other host needs https://; 0.0.0.0\n and the rest of 127.0.0.0/8 do not count as this machine;\na user name or password, a query string, a fragment, a scheme other than\n http or https, http:// to a host other than those three, or a value that\n is not an absolute URL is refused before any request, with a message that never\n repeats the value;\na redirect from the endpoint is refused rather than followed, so the decision is\n never replayed at an address the server chooses;\nthe request goes to <origin>/v1/decisions.","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Decisions Provider Guide","lvl2":"Base URL","lvl3":""}},
6830
+ {"objectID":"c6c6f00939ee73c7416d6eed5fcb54dfca58a77c31a358c0e1b630c25fdf9e71","title":"Troubleshooting","url":"/docs/getting-started/providers/openai-decisions#troubleshooting","content":"No decision provider is configured although OPENAI_API_KEY is set β€”\n OPENAI_BASE_URL, OPENAI_API_BASE or credentials.openai.baseURL names a host other than\n https://api.openai.com, so the key is taken to be a gateway's. See\n A gateway's key: set\n OPENAI_DECISIONS_BASE_URL or pass credentials.openaiDecisions to route this\n provider on purpose. Naming the provider in a call is not a way out when the key\n is a gateway's: a named call sends the environment key to api.openai.com.\nOpenAI Decisions requires an API key β€” set OPENAI_API_KEY, or pass\n credentials.openaiDecisions.apiKey. A key passed as credentials.openai does\n not count.\nA 401 β€” OpenAI rejected the key. The provider instance stops retrying after\n a rejection, so fix the key and construct a new one.\nA 403 β€” OpenAI's general error documentation lists a 403 for an unsupported\n country; what this endpoint's own 403s mean is not established. It does not latch\n the instance, so a change on the account side works at once.\nA 400 naming the model β€” OPENAI_DECISIONS_MODEL, or a per-call model,\n names something other than a model the endpoint supports.\nThe OpenAI Decisions base URL must not carry credentials… β€” the override\n has a user name, a password, a query string or a fragment. Set it to the origin\n only, or leave it unset for https://api.openai.com.\nThe OpenAI Decisions base URL must start with https:// or http:// β€” the\n value parses as a URL with another scheme, or is a host name and port with no\n scheme, such as localhost:8080, which reads as the scheme localhost:. Put\n https:// in front, or http:// for a server on this machine.\nThe OpenAI Decisions base URL must use https:// unless it points at this machine β€”\n the override is an http:// URL whose host is not localhost, 127.0.0.1 or\n [::1]. A plain-http request would send the key and the state unencrypted. Use\n https://, or reach the server through a port-forward to localhost.","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Decisions Provider Guide","lvl2":"Troubleshooting","lvl3":""}},
6825
6831
  {"objectID":"b7b92543296a3f4ebd2f58c8d0c68da7750bb2a51df7eb7abaca356794a4681b","title":"See also","url":"/docs/getting-started/providers/openai-decisions#see-also","content":"The decide inference type\nTypeSafe (Jev) Provider Guide\nLaya Provider Guide\nXOR Provider Guide\nPerplexity Decisions Provider Guide\nCloudflare Clef Provider Guide\nOpenAI chat provider\nOpenAI's Decisions guide","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Decisions Provider Guide","lvl2":"See also","lvl3":""}},
6826
6832
  {"objectID":"d6669edf9f3a9ed44443cdbca83140ef76b3dffb6c23994cb07ca53b8661aece","title":"OpenAI TTS Provider Guide","url":"/docs/getting-started/providers/openai-tts","content":"OpenAI TTS Provider Guide\n\nHigh-quality neural text-to-speech with six distinct voices and HD quality option\n\nOverview\n\nNeuroLink integrates OpenAI's Text-to-Speech API, giving you access to six expressive neural voices across two model tiers. The standard model (tts-1) optimises for low latency, while the HD model (tts-1-hd) delivers higher audio fidelity for production use cases such as podcasts, voice assistants, and narration.\n\nOpenAI TTS works with any NeuroLink text generation call β€” you can synthesise the raw prompt directly or synthesise the AI-generated response, controlled by the useAiResponse flag.\n\nKey Facts\n\n| Property | Value |\n| ---------------- | --------------------------------------------- |\n| Provider ID | openai-tts |\n| API endpoint | https://api.openai.com/v1/audio/speech |\n| Models | tts-1 (standard), tts-1-hd (high quality) |\n| Voices | alloy, echo, fable, onyx, nova, shimmer |\n| Formats | mp3, wav, ogg (opus), opus |\n| Max input | 4,096 characters per request |\n| Languages | Follows input text language automatically |\n| Streaming | Not supported (batch synthesis only) |\n\nQuick Start\nGet an API Key\n\nSign up or log in at https://platform.openai.com and create a new secret key under API keys.\nConfigure Environment\n\nAdd to your .env file:\n\nDefault model (tts-1) and voice (alloy) are set in code; override per call\nvia tts.model / tts.voice in the SDK or --tts-model / --tts-voice on\nthe CLI. There is no OPENAI_TTS_MODEL / OPENAI_TTS_VOICE env var.\nInstall NeuroLink\nSynthesise Your First Audio\n\nSupported Models\n\n| Model ID | Quality | Latency | Use Case |\n| ---------- | -------- | ------- | ---------------------------------------------- |\n| tts-1 | Standard | Lower | Default; real-time apps, interactive voice UIs |\n| tts-1-hd | HD | Higher | Podcasts, narration, production audio assets |\n\nSelect the HD model by passing quality: \"hd\" in TTS options β€” NeuroLink maps this automatically to tts-1-hd.\n\nSDK Usage\n\nDirect Text Synthesis\n\nSynthesise the input text directly without calling an AI model:\n\nAI Response Synthesis\n\nGenerate a response with an AI model and then synthesise it:\n\nHD Quality Audio\n\nAdjusting Playback Speed\n\nSave to File\n\nPer-Call Credential Override\n\nCLI Usage\n\nBasic TTS\n\nHD Quality\n\nSynthesise AI Response\n\nSpeed Adjustment\n\nAvailable Voices\n\n| Voice ID | Gender | Character | Best For |\n| --------- | ------- | -------------------------------- | --------------------------------- |\n| alloy | Neutral | Balanced, clear, versatile | General purpose, default |\n| echo | Male | Crisp, authoritative | Announcements, business content |\n| fable | Neutral | Warm, expressive, storytelling | Narration, audiobooks |\n| onyx | Male | Deep, confident, professional | Voiceovers, documentary |\n| nova | Female | Bright, friendly, conversational | Voice assistants, customer-facing |\n| shimmer | Female | Soft, gentle, calm | Wellness apps, guided meditation |\n\nOpenAI voices are language-agnostic β€” they follow the language of the input text automatically, supporting English, Spanish, French, German, Japanese, and many more.\n\nAudio Formats\n\n| Format | Extension | Use Case | Notes |\n| ------ | --------- | --------------------------------------- | -------------------- |\n| mp3 | .mp3 | Default; web, mobile, general storage | 24 kHz sample rate |\n| wav | .wav | Uncompressed; audio editors, processing | 24 kHz sample rate |\n| ogg | .ogg | Browser streaming, web apps | Opus codec at 48 kHz |\n| opus | .opus | Low-bandwidth streaming | Opus codec at 48 kHz |\n\nConfiguration Reference\n\n| Environment Variable | Required | Default | Description |\n| -------------------- | -------- | ------- | ---------------------------------- |\n| OPENAI_API_KEY | Yes | β€” | OpenAI API key (starts with sk-) |\n\nDefaults for model (tts-1) and voice (alloy) are set in code; override per\ncall via tts.model / tts.voice in the SDK or --tts-model / --tts-voice\non the CLI. There are no OPENAI_TTS_MODEL / OPENAI_TTS_VOICE env vars.\n\nFeature Support Matrix\n\n| Feature | Supported | Notes |\n| ---------------------- | --------- | ---------------------------------- |\n| Text synthesis | Yes | |\n| AI response synthesis | Yes | Set useAiResponse: true |\n| HD quality | Yes | quality: \"hd\" maps to tts-1-hd |\n| Speed control | Yes | 0.25 – 4.0 |\n| Voice selection | Yes | 6 neural voices ","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI TTS Provider Guide","lvl2":"","lvl3":""}},
6827
6833
  {"objectID":"3124582a399e5bb98ce8924efecb3558d0161c1f16faae7fdedbfc2e182e34a0","title":"OpenAI TTS Provider Guide","url":"/docs/getting-started/providers/openai-tts#openai-tts-provider-guide","content":"High-quality neural text-to-speech with six distinct voices and HD quality option","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI TTS Provider Guide","lvl2":"OpenAI TTS Provider Guide","lvl3":""}},
@@ -6974,12 +6980,12 @@
6974
6980
  {"objectID":"106d04b8baec018f872ce608c3b0dd33f8b3d43ada85072831a2e9ab9c64c46b","title":"Verification status","url":"/docs/getting-started/providers/pareto-inference#verification-status","content":"Tier-2 onboarding requires evidence before a provider is accepted, and\npnpm run verify:provider-onboarding gates it in CI. This is what the\ncatalog records for Pareto Inference β€” and, just as importantly, what it\ndoes not yet record:\n\n| Probe | Result |\n| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Roster | unauthenticated GET /v1/models, HTTP 200, 1 model (z-ai/glm-5.3-flash), 2026-09-28. No API key was used or required for this call. |\n| Auth rejection | Not probed. Would require a POST with an invalid key, which this credential-free onboarding pass does not send. Pareto's docs describe 401 as \"the chat API key is missing, invalid, or no longer active,\" with no example error body. |\n| Live capability sweep | Not run. evidence.liveMatrix is null.","hierarchy":{"lvl0":"Getting Started","lvl1":"Pareto Inference Provider Guide","lvl2":"Verification status","lvl3":""}},
6975
6981
  {"objectID":"b844edaf09c93fb3089bbf0a71254c5039dedf111e2b59563321484496862aa4","title":"Troubleshooting","url":"/docs/getting-started/providers/pareto-inference#troubleshooting","content":"| Symptom | Cause | Fix |\n| --------------------------------------- | -------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |\n| Invalid Pareto Inference API key | PARETO_INFERENCE_API_KEY unset, wrong, or expired | Pareto documents 401 as \"the chat API key is missing, invalid, or no longer active\" β€” check or replace the key in the dashboard |\n| 429 with credit_exhausted | Prepaid balance is empty | Buy more prepaid credits |\n| 429 with credit_insufficient | Held credits (reserved for max_tokens) are below what's needed | Lower max_tokens, or buy more credits |\n| 429 with model_capacity | The model itself is at capacity β€” not an account-level limit | Honor the Retry-After header and retry |\n| 502 mid-stream | The model request failed after the stream started | Retry the request; check whether a tool call already ran before retrying |\n| 503 | Temporary Pareto-side failure (e.g. maintenance, GPU outage) | Wait and retry; Retry-After gives the delay in seconds","hierarchy":{"lvl0":"Getting Started","lvl1":"Pareto Inference Provider Guide","lvl2":"Troubleshooting","lvl3":""}},
6976
6982
  {"objectID":"57b8457eff592f229d3c0f0fb7c73148341ecffd72bb29c15d73f1471b1fd886","title":"See also","url":"/docs/getting-started/providers/pareto-inference#see-also","content":"Provider setup overview\nAll providers\nTier-2 onboarding β€” how this provider's JSON becomes a working integration\nProvider feature compatibility","hierarchy":{"lvl0":"Getting Started","lvl1":"Pareto Inference Provider Guide","lvl2":"See also","lvl3":""}},
6977
- {"objectID":"daf00919862e4bbed4b3fc1082bea17843a987e5e3970cefed2c95537b22cceb","title":"Perplexity Decisions Provider Guide","url":"/docs/getting-started/providers/perplexity-decider","content":"Perplexity Decisions Provider Guide\n\nA provider of decide β€” the same typed boolean / choice / score\nanswers as TypeSafe's Jev, Laya, XOR,\nCloudflare Clef and OpenAI Decisions,\nfrom Perplexity's hosted Decisions API, and it also reads images. It emits no\ntext at all.\n\nThis is not the Perplexity text provider (perplexity, the\nSonar models), which serves generate() and stream(). The two share one API\nkey, which has a consequence worth reading before you set it. See\nWhat is sent to Perplexity and\nOne key, two providers.\n\nOverview\n\npplx-decider-v1-27b is Perplexity's decision model. You send one state\nplus named, typed questions, and optionally images. The model answers every\nquestion in a single batched pass and returns a typed answer for each, with a\nprobability instead of a sentence. NeuroLink calls Perplexity's public endpoint,\nso a key alone configures it: there is no base URL to set.\n\nKey Facts\n\n| | |\n| ------------------------ | ----------------------------------------------------------------------------------------------------------------- |\n| Provider id | perplexity-decider (no aliases) β€” distinct from perplexity, the Sonar text provider |\n| Inference type | decide only |\n| Model | pplx-decider-v1-27b; the API answers 400 to a missing or unknown model. PERPLEXITY_DECIDER_MODEL sets it |\n| Key | PERPLEXITY_API_KEY, shared with the Perplexity text provider, or credentials.perplexityDecider.apiKey |\n| Endpoint | https://api.perplexity.ai/v1/decisions; PERPLEXITY_DECIDER_BASE_URL can name another origin |\n| Media | images (PNG, JPEG or WebP), up to 8 per request; no video |\n| Questions per request | up to 128 |\n| Server input ceiling | under 262,144 tokens (state, questions and images); more is refused with an explicit 400, never cut off silently |\n| Images and that ceiling | billed as input tokens, and counted toward the ceiling at one token per 32 Γ— 32 tile (measured) |\n| NeuroLink's state window | 100,000 estimated tokens: a deliberate local limit, not the server's |\n| Cost | $0.04 per million input tokens (image tokens included); output tokens are free. Perplexity's documented price |\n| Default timeout | 10 seconds plus 100 ms for each question (10.1 s for one, 22.8 s for 128); timeoutMs or --timeout replaces it |\n| Precedence | used automatically when TypeSafe, Laya, XOR and SubQ are not configured |\n\nEach limit, token rate and latency in this guide is either measured on a real\naccount in October 2026 or taken from Perplexity's documentation, and says\nwhich where it appears. Measured: the 128-question and 8-image caps, the\n262,144-token input ceiling for the state, the questions and the images (nothing\nis cut off silently), characters per token for each kind of text, latency by\ninput size and by question count, what an image costs, which image sizes stall\n(the 2,048-tile rule, checked at its edge: see Images), and how the\nAPI answers a burst of requests. Documented and not tested: the 32 MiB request\nbody, the price, and the option and level counts. Perplexity documents a limit of\n10 requests per second for the account's tier (every organization, on every\nplan, with a token limit on large bursts), and a burst test on the one account\ntested saw the request limit act.\n\nQuick Start\nGet a key\n\nCreate one in the Perplexity console. Any\nPerplexity API key works.\nConfigure\n\nSet the key in the environment:\n\nor in the config passed to the SDK, exactly as for any other provider. Values\npassed per call override the constructor's, which override the environment:\n\ncredentials.perplexityDecider is its own slice. A key passed as\ncredentials.perplexity belongs to the text provider and does not configure\nthis one. PERPLEXITY_BASE_URL, which moves the text provider, is not read here;\nthe override for this provider is PERPLEXITY_DECIDER_BASE_URL, and a trailing\n/v1 on it is accepted.\nUse it\n\nNeuroLink's boolean question is sent to the API as its noul type, and the\nanswer is read back as a boolean. A boolean answer carries a probability and\nno confidence of its own; a choice or score answer carries the confidence the\nAPI reports, which Perplexity describes as the model's own certainty estimate,\nnot the top probability. Perplexity's API reference and quickstart do not call\nthat confidence calibrated, and NeuroLink did not","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"","lvl3":""}},
6983
+ {"objectID":"daf00919862e4bbed4b3fc1082bea17843a987e5e3970cefed2c95537b22cceb","title":"Perplexity Decisions Provider Guide","url":"/docs/getting-started/providers/perplexity-decider","content":"Perplexity Decisions Provider Guide\n\nA provider of decide β€” the same typed boolean / choice / score\nanswers as TypeSafe's Jev, Laya, XOR,\nCloudflare Clef and OpenAI Decisions,\nfrom Perplexity's hosted Decisions API, and it also reads images. It emits no\ntext at all.\n\nThis is not the Perplexity text provider (perplexity, the\nSonar models), which serves generate() and stream(). The two share one API\nkey, which has a consequence worth reading before you set it. See\nWhat is sent to Perplexity and\nOne key, two providers.\n\nOverview\n\npplx-decider-v1-27b is Perplexity's decision model. You send one state\nplus named, typed questions, and optionally images. The model answers every\nquestion in a single batched pass and returns a typed answer for each, with a\nprobability instead of a sentence. NeuroLink calls Perplexity's public endpoint,\nso a key alone configures it: there is no base URL to set.\n\nKey Facts\n\n| | |\n| ------------------------ | ----------------------------------------------------------------------------------------------------------------- |\n| Provider id | perplexity-decider (no aliases) β€” distinct from perplexity, the Sonar text provider |\n| Inference type | decide only |\n| Model | pplx-decider-v1-27b; the API answers 400 to a missing or unknown model. PERPLEXITY_DECIDER_MODEL sets it |\n| Key | PERPLEXITY_API_KEY, shared with the Perplexity text provider, or credentials.perplexityDecider.apiKey |\n| Endpoint | https://api.perplexity.ai/v1/decisions; PERPLEXITY_DECIDER_BASE_URL can name another origin |\n| Media | images (PNG, JPEG or WebP), up to 8 per request; no video |\n| Questions per request | up to 128 |\n| Server input ceiling | under 262,144 tokens (state, questions and images); more is refused with an explicit 400, never cut off silently |\n| Images and that ceiling | billed as input tokens, and counted toward the ceiling at one token per 32 Γ— 32 tile (measured) |\n| NeuroLink's state window | 100,000 estimated tokens: a deliberate local limit, not the server's |\n| Cost | $0.04 per million input tokens (image tokens included); output tokens are free. Perplexity's documented price |\n| Default timeout | 10 seconds plus 100 ms for each question (10.1 s for one, 22.8 s for 128); timeoutMs or --timeout replaces it |\n| Precedence | used automatically when TypeSafe, Laya, XOR and SubQ are not configured |\n\nEach limit, token rate and latency in this guide is either measured on a real\naccount in October 2026 or taken from Perplexity's documentation, and says\nwhich where it appears. Measured: the 128-question and 8-image caps, the\n262,144-token input ceiling for the state, the questions and the images (nothing\nis cut off silently), characters per token for each kind of text, latency by\ninput size and by question count, what an image costs, which image sizes stall\n(the 2,048-tile rule, checked at its edge: see Images), and how the\nAPI answers a burst of requests. Documented and not tested: the 32 MiB request\nbody, the price, and the option and level counts. Perplexity documents a limit of\n10 requests per second for the account's tier (every organization, on every\nplan, with a token limit on large bursts), and a burst test on the one account\ntested saw the request limit act.\n\nQuick Start\nGet a key\n\nCreate one in the Perplexity console. Any\nPerplexity API key works.\nConfigure\n\nSet the key in the environment:\n\nor in the config passed to the SDK, exactly as for any other provider. Values\npassed per call override the constructor's, which override the environment:\n\ncredentials.perplexityDecider is its own slice. A key passed as\ncredentials.perplexity belongs to the text provider and does not configure\nthis one. PERPLEXITY_BASE_URL, which moves the text provider, is not read here;\nthe override for this provider is PERPLEXITY_DECIDER_BASE_URL, and a trailing\n/v1 on it is accepted. It must be https://; http:// is accepted only for\nlocalhost, 127.0.0.1 and [::1], because every request carries the key.\nUse it\n\nNeuroLink's boolean question is sent to the API as its noul type, and the\nanswer is read back as a boolean. A boolean answer carries a probability and\nno confidence of its own; a choice or score answer carries the confidence the\nAPI reports, which Perplexity describes as the model's own certainty estimate,\nnot the","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"","lvl3":""}},
6978
6984
  {"objectID":"cd579839c9ecb7a84dee24ccd591e76f90eb1f05b384a35488c7603f72178d38","title":"Perplexity Decisions Provider Guide","url":"/docs/getting-started/providers/perplexity-decider#perplexity-decisions-provider-guide","content":"A provider of decide β€” the same typed boolean / choice / score\nanswers as TypeSafe's Jev, Laya, XOR,\nCloudflare Clef and OpenAI Decisions,\nfrom Perplexity's hosted Decisions API, and it also reads images. It emits no\ntext at all.\n\nThis is not the Perplexity text provider (perplexity, the\nSonar models), which serves generate() and stream(). The two share one API\nkey, which has a consequence worth reading before you set it. See\nWhat is sent to Perplexity and\nOne key, two providers.","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"Perplexity Decisions Provider Guide","lvl3":""}},
6979
6985
  {"objectID":"0d2eec9390e1cc5078e5419138c190cc8dc524c5ebd8972a9c7afa9625dae43a","title":"Overview","url":"/docs/getting-started/providers/perplexity-decider#overview","content":"pplx-decider-v1-27b is Perplexity's decision model. You send one state\nplus named, typed questions, and optionally images. The model answers every\nquestion in a single batched pass and returns a typed answer for each, with a\nprobability instead of a sentence. NeuroLink calls Perplexity's public endpoint,\nso a key alone configures it: there is no base URL to set.","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"Overview","lvl3":""}},
6980
6986
  {"objectID":"c9690ba724ce4205d66ac4d75981884b735170b152767047afcc0d406d5e7c8d","title":"Key Facts","url":"/docs/getting-started/providers/perplexity-decider#key-facts","content":"| | |\n| ------------------------ | ----------------------------------------------------------------------------------------------------------------- |\n| Provider id | perplexity-decider (no aliases) β€” distinct from perplexity, the Sonar text provider |\n| Inference type | decide only |\n| Model | pplx-decider-v1-27b; the API answers 400 to a missing or unknown model. PERPLEXITY_DECIDER_MODEL sets it |\n| Key | PERPLEXITY_API_KEY, shared with the Perplexity text provider, or credentials.perplexityDecider.apiKey |\n| Endpoint | https://api.perplexity.ai/v1/decisions; PERPLEXITY_DECIDER_BASE_URL can name another origin |\n| Media | images (PNG, JPEG or WebP), up to 8 per request; no video |\n| Questions per request | up to 128 |\n| Server input ceiling | under 262,144 tokens (state, questions and images); more is refused with an explicit 400, never cut off silently |\n| Images and that ceiling | billed as input tokens, and counted toward the ceiling at one token per 32 Γ— 32 tile (measured) |\n| NeuroLink's state window | 100,000 estimated tokens: a deliberate local limit, not the server's |\n| Cost | $0.04 per million input tokens (image tokens included); output tokens are free.","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"Key Facts","lvl3":""}},
6981
6987
  {"objectID":"467fb7efd250abc71afba6a9535ee164e671526dc06ff59407a827bda872b268","title":"1. Get a key","url":"/docs/getting-started/providers/perplexity-decider#1-get-a-key","content":"Create one in the Perplexity console. Any\nPerplexity API key works.","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"1. Get a key","lvl3":""}},
6982
- {"objectID":"bd7509f708e016023be201690ca4cc963bc77551d7152b34c636ae628ea5e497","title":"2. Configure","url":"/docs/getting-started/providers/perplexity-decider#2-configure","content":"Set the key in the environment:\n\nor in the config passed to the SDK, exactly as for any other provider. Values\npassed per call override the constructor's, which override the environment:\n\ncredentials.perplexityDecider is its own slice. A key passed as\ncredentials.perplexity belongs to the text provider and does not configure\nthis one. PERPLEXITY_BASE_URL, which moves the text provider, is not read here;\nthe override for this provider is PERPLEXITY_DECIDER_BASE_URL, and a trailing\n/v1 on it is accepted.","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"2. Configure","lvl3":""}},
6988
+ {"objectID":"bd7509f708e016023be201690ca4cc963bc77551d7152b34c636ae628ea5e497","title":"2. Configure","url":"/docs/getting-started/providers/perplexity-decider#2-configure","content":"Set the key in the environment:\n\nor in the config passed to the SDK, exactly as for any other provider. Values\npassed per call override the constructor's, which override the environment:\n\ncredentials.perplexityDecider is its own slice. A key passed as\ncredentials.perplexity belongs to the text provider and does not configure\nthis one. PERPLEXITY_BASE_URL, which moves the text provider, is not read here;\nthe override for this provider is PERPLEXITY_DECIDER_BASE_URL, and a trailing\n/v1 on it is accepted. It must be https://; http:// is accepted only for\nlocalhost, 127.0.0.1 and [::1], because every request carries the key.","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"2. Configure","lvl3":""}},
6983
6989
  {"objectID":"c3dbe3c712926dfb07b0d907370532df8bc3c98a5e81f4b46784a037ac0f1e0b","title":"3. Use it","url":"/docs/getting-started/providers/perplexity-decider#3-use-it","content":"NeuroLink's boolean question is sent to the API as its noul type, and the\nanswer is read back as a boolean. A boolean answer carries a probability and\nno confidence of its own; a choice or score answer carries the confidence the\nAPI reports, which Perplexity describes as the model's own certainty estimate,\nnot the top probability. Perplexity's API reference and quickstart do not call\nthat confidence calibrated, and NeuroLink did not measure whether it is, so tune\na threshold on it against your own labelled data. (The Hugging Face model card\nfor the open-weights model describes its output as calibrated probabilities.)\nPerplexity also notes that identical requests occasionally differ in the second\ndecimal place. Repeating a request returned the same numbers in NeuroLink's\nprobe, but leave some margin when you set a threshold anyway.","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"3. Use it","lvl3":""}},
6984
6990
  {"objectID":"6f3f0a67d6c85ce65d1d7d95a7016987ad0423b545c9f849bcde853edd0dd20f","title":"From the CLI","url":"/docs/getting-started/providers/perplexity-decider#from-the-cli","content":"The CLI reads the same environment variables:\n\nThe text output ends with a Cost: line, priced from the input tokens the API\nreports.","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"From the CLI","lvl3":""}},
6985
6991
  {"objectID":"e1b9161659de68a10277e69ce53077f2aed241892d783054f01471fb793024bd","title":"Images","url":"/docs/getting-started/providers/perplexity-decider#images","content":"Perplexity reads images alongside the state. TypeSafe and Laya do not read\nmedia. XOR reads images and a video; Perplexity reads images only, and so do\nCloudflare Clef, up to 4 of them, and\nOpenAI Decisions. In the probe of\nPerplexity's model it did read an image: asked red versus blue about one, it\nanswered correctly at about 0.98 confidence.\n\nFrom the CLI, pass --image <path>, repeated for several:\n\nOn the wire the images go inside state: NeuroLink sends state as an array,\nyour state first and then one OpenAI-style image_url part per image, each a\nbase64 data URL. The API has no separate images field and rejects unknown\nfields. An image can also be the whole input (an image-only state was\naccepted in the probe); from the SDK, pass an empty string as state with\nimages. The CLI always needs a state.\n\nThe rules:\nUp to 8 images per request. Measured: 8 images with three questions were\n accepted, and 9 images with one question were refused with a 400 whose message\n words the cap as \"per question\". NeuroLink applies the 8 to the request as a\n whole.\nPNG, JPEG or WebP only. The type comes from the bytes, not the file\n extension. A GIF, or a data: URL of another type, is refused before any\n request, as a non-retryable invalid_request. The API refuses a GIF with a 400\n too.\nEach is a Buffer, a local file path or a data: URL. An http(s) URL is\n refused locally and never fetched. The API does not fetch URLs either: an\n https image URL returned a 400 in the probe.\nEach image may be at most 2,048 tiles of 32 Γ— 32 pixels. Round the width\n and the height to the nearest multiple of 32 and keep (width / 32) Γ—\n (height / 32) at or under 2,048: by that count 1440 Γ— 1440 (2,025 tiles) and\n 2048 Γ— 1024 (2,048) fit, and 1600 Γ— 1310 (2,050) does not. Perplexity documents\n this rule, and it was checked at its edge. Fitting sizes were answered in\n about a second: 1920 Γ— 1080 (2,040 tiles) in 1.1 seconds, 2048 Γ— 1024 (2,048,\n exactly the cap) in 1.3 and 1450 Γ— 1450 in 1.1.","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"Images","lvl3":""}},
@@ -6992,7 +6998,7 @@
6992
6998
  {"objectID":"8e97b6f8092812014ba072ae65457308bc11e5c8b5349d31ff466c7db1f9cb39","title":"Latency and the timeout","url":"/docs/getting-started/providers/perplexity-decider#latency-and-the-timeout","content":"The default timeout is 10 seconds plus 100 ms for each question: 10.1\nseconds for one question and 22.8 seconds for the 128-question maximum. A\ntimeoutMs you pass, or --timeout on the CLI, is used exactly as given, with\nnothing added. The 10 seconds are the allowance for reading the input. Latency\ngrows faster than linearly with input (3.9 s at 65,000 tokens, 10 s at 146,000\nand 22.9 s at 251,000), so a state of 100,000 tokens takes about 7 s, an\ninterpolation between the 65,000- and 146,000-token measurements, and a larger\none needs a larger timeoutMs. The 100 ms follows what a question costs: each\none after the first added about 65 ms, and 128 minimal questions took 8.9 s on\n11,904 input tokens, so a flat 10 seconds would have been nearly spent on the\nquestions alone. Images count as input tokens too (see Images).\n\nA timeout is retried once, so a request that stalls can take about twice the\ntimeout plus a quarter to half a second before it fails: about 20 seconds at the\ndefault for one question. Pass a larger timeoutMs for a state of more than\nabout 100,000 real tokens, which log lines and arrays of numbers reach well\ninside the window (see\nWhat NeuroLink refuses). A model\nthat does not answer in time returns an HTML 504 after about a minute;\nNeuroLink's shorter timeout fires first, so it arrives as timeout, retried\nonce.\n\nEach built-in consumer takes its timeout from where it is configured:\nModel routing (with the model catalogue and the context budget, which share\n its request): classifierRouter.timeoutMs in the NeuroLink config, passed to\n the decision request when set.\nRelevance compaction: contextRelevance.timeoutMs in the NeuroLink\n config.\nSummary-quality gate: no setting. The NeuroLink config has none for it.\nTool / MCP routing: no setting for the decision request.\n toolRouting.timeoutMs bounds the generative router only.\nRAG planning: no setting in the pipeline config.","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"Latency and the timeout","lvl3":""}},
6993
6999
  {"objectID":"e0c0e895220d617b9c97e379206986672c638c01de25fb9e0b52fa7c04bf0ca1","title":"Rate limits","url":"/docs/getting-started/providers/perplexity-decider#rate-limits","content":"The account measured allows 10 requests per second. A 429 is retried once, after\nthe wait its Retry-After header asks for. NeuroLink honours that header on any\nretried reply that carries it, and only as a whole number of seconds above zero\nor as an HTTP date in the future; anything else (zero, a negative number, a hex\nor exponent spelling, a fraction, a date already past) is ignored, and the\ndefault backoff of a quarter to half a second is used instead. A wait longer\nthan what is left of the attempt's timeout is not taken: the error is thrown at\nonce so a fail-open consumer is not held for the length of a cooldown, and a\ncaller's abort signal ends a wait immediately.","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"Rate limits","lvl3":""}},
6994
7000
  {"objectID":"f40b2da5feaf02bc4eaf5102d75c33ce6fc9f979f7106853002b142aad4fd67f","title":"Errors","url":"/docs/getting-started/providers/perplexity-decider#errors","content":"| Reply | Kind | Retried |\n| -------------------------------------------------------------------- | ------------------------------------------------------- | ------------------------------ |\n| 401 | authentication β€” the provider instance stops retrying | no |\n| 413 | max_tokens_exceeded (the body is over 32 MiB) | no |\n| 400 saying the input exceeds the model's maximum context length | max_tokens_exceeded | no |\n| any other 4xx (for example another 400, 403, 404) | invalid_request, with Perplexity's own message | no |\n| 429 | rate_limit | yes, once, after Retry-After |\n| 503 | overloaded | yes, once |\n| other 5xx (500, 502, 504) | server | yes, once |\n| no response within the timeout | timeout | yes, once |\n| the request fails before any reply (connection refused, DNS failure) | network | yes, once |\n| the caller's own signal aborts the request | network | no |\n| state or questions over the limit (local)","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"Errors","lvl3":""}},
6995
- {"objectID":"a812289efc882316bb62c31aea533cd0a0e8e219eeea12289b4503450b4dd9a5","title":"Troubleshooting","url":"/docs/getting-started/providers/perplexity-decider#troubleshooting","content":"Perplexity requires an API key β€” set PERPLEXITY_API_KEY, or pass\n credentials.perplexityDecider.apiKey. A key passed as\n credentials.perplexity does not count.\nA 401, Invalid API key provided β€” Perplexity rejected the key, and it\n checks the key before anything else. The provider instance stops retrying\n after a rejection, so fix the key and construct a new one.\nA 400 naming the model β€” PERPLEXITY_DECIDER_MODEL, or a per-call\n model, names something other than pplx-decider-v1-27b.\nThe Perplexity base URL must not carry credentials… β€” the override has a\n user name, a password, a query string or a fragment. Set it to the origin only,\n or leave it unset for https://api.perplexity.ai.\nThe Perplexity base URL must start with https:// or http:// β€” the value\n parses as a URL with another scheme: an explicit one such as ftp://, or a host\n name and port with no scheme, such as localhost:8080, which reads as the\n scheme localhost:. Put https:// or http:// in front.\nThe Perplexity base URL is not a valid absolute URL β€” the value does not\n parse as a URL at all: a bare host name such as api.perplexity.ai (the likely\n mistake), an IP address and port such as 127.0.0.1:8080, a path, or a scheme\n with no host. Write the origin with its scheme.\nA refused base URL in the debug log β€” it is not there. A base URL that\n NeuroLink refuses (credentials, a query string, a fragment, a scheme other than\n http or https, or not a URL at all) is never written to the debug log: the line\n shows (invalid) in its place, because such a value can carry a secret.\nImage N is not a PNG, JPEG or WebP image β€” Perplexity reads only those\n three. Convert the image first.\nImage N is … pixels; Perplexity reads at most 2048 tiles β€” resize the\n image to fit, for example 1440 Γ— 1440 or 2048 Γ— 1024.\nA request with an image stalls until it times out, or fails as server with\n HTTP 504 when the timeout is longer than a minute β€” an image over the tile\n cap does this.","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"Troubleshooting","lvl3":""}},
7001
+ {"objectID":"a812289efc882316bb62c31aea533cd0a0e8e219eeea12289b4503450b4dd9a5","title":"Troubleshooting","url":"/docs/getting-started/providers/perplexity-decider#troubleshooting","content":"Perplexity requires an API key β€” set PERPLEXITY_API_KEY, or pass\n credentials.perplexityDecider.apiKey. A key passed as\n credentials.perplexity does not count.\nA 401, Invalid API key provided β€” Perplexity rejected the key, and it\n checks the key before anything else. The provider instance stops retrying\n after a rejection, so fix the key and construct a new one.\nA 400 naming the model β€” PERPLEXITY_DECIDER_MODEL, or a per-call\n model, names something other than pplx-decider-v1-27b.\nThe Perplexity base URL must not carry credentials… β€” the override has a\n user name, a password, a query string or a fragment. Set it to the origin only,\n or leave it unset for https://api.perplexity.ai.\nThe Perplexity base URL must start with https:// or http:// β€” the value\n parses as a URL with another scheme: an explicit one such as ftp://, or a host\n name and port with no scheme, such as localhost:8080, which reads as the\n scheme localhost:. Put https:// in front, or http:// for a server on this\n machine.\nThe Perplexity base URL must use https:// unless it points at this machine β€”\n the override is an http:// URL whose host is not localhost, 127.0.0.1 or\n [::1]. A plain-http request would send the key unencrypted. Use https://, or\n reach the server through a port-forward to localhost.\nPerplexity answered with a redirect β€” the endpoint replied 301, 302, 307 or 308. The provider does not follow it and does not retry. Set the base URL to the\n address the redirect leads to.\nThe Perplexity base URL is not a valid absolute URL β€” the value does not\n parse as a URL at all: a bare host name such as api.perplexity.ai (the likely\n mistake), an IP address and port such as 127.0.0.1:8080, a path, or a scheme\n with no host. Write the origin with its scheme.\nA refused base URL in the debug log β€” it is not there.","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"Troubleshooting","lvl3":""}},
6996
7002
  {"objectID":"6d580e7ffb3867905a72879cdccbab76b5df280677e9d18b0029fd5bc5092025","title":"See also","url":"/docs/getting-started/providers/perplexity-decider#see-also","content":"The decide inference type\nTypeSafe (Jev) Provider Guide\nLaya Provider Guide\nXOR Provider Guide\nCloudflare Clef Provider Guide\nSubQ Provider Guide\nOpenAI Decisions Provider Guide\nPerplexity text provider\nPerplexity Decisions API reference","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"See also","lvl3":""}},
6997
7003
  {"objectID":"6d55ee7ec0f21369a70b421eaeaddf6b44fe88746beb28c252588d42d97048b7","title":"Perplexity Provider Guide","url":"/docs/getting-started/providers/perplexity","content":"Perplexity Provider Guide\n\nWeb-search-augmented generation via Perplexity's Sonar models\n\nOverview\n\nPerplexity hosts a family of LLMs (Sonar,\nSonar Pro, Sonar Reasoning) that pair the model with a live web search\nbackend; responses include citations to the documents the model relied on.\n\nKey Facts\nProtocol: OpenAI-compatible (/chat/completions)\nDefault base URL: https://api.perplexity.ai\nDefault model: sonar\nCitations: Returned via citations field on the response\nStreaming: Yes\nTool calling: No\n\nQuick Start\nGet an API Key\n\nhttps://www.perplexity.ai/settings/api\nConfigure\n\nPERPLEXITY_API_KEY also configures decisions. The same variable configures\nthe Perplexity Decisions provider (perplexity-decider,\nwhich serves decide()). So setting it for Sonar also lets NeuroLink's built-in\nfeatures send decision requests to Perplexity when no TypeSafe, Laya, XOR or SubQ\nprovider is configured, and context compaction needs no other opt-in to do so.\nTo avoid that, pass the key through the SDK as credentials.perplexity.apiKey\ninstead of the environment, and keep it out of .env too: the SDK and the CLI\nload that file into the environment, so a PERPLEXITY_API_KEY line like the one\nabove would still configure decisions. (That the text provider reads this slice\nis taken from the code and has not been run against the live API.) See\nWhat is sent to Perplexity\nand One key, two providers.\nGenerate\n\nSupported Models\n\n| Model ID | Notes |\n| ----------------- | ----------------------------------- |\n| sonar | Default; fast search-augmented chat |\n| sonar-pro | Larger context, deeper search |\n| sonar-reasoning | Chain-of-thought reasoning |\n\nCLI Usage\n\nProvider Aliases\n\n| Alias | Example |\n| ------------ | ----------------------- |\n| perplexity | --provider perplexity |\n\nConfiguration Reference\n\n| Environment Variable | Required | Default |\n| --------------------- | -------- | --------------------------- |\n| PERPLEXITY_API_KEY | Yes | β€” |\n| PERPLEXITY_MODEL | No | sonar |\n| PERPLEXITY_BASE_URL | No | https://api.perplexity.ai |\n\nFeature Support Matrix\n\n| Feature | Support |\n| ----------------- | ------------ |\n| Text generation | Yes |\n| Streaming | Yes |\n| Tool calling | No |\n| Structured output | Limited |\n| Web search | Yes (native) |\n| Citations | Yes |\n\nSee Also\nPerplexity Decisions Provider β€” typed, calibrated decide() judgments on the same key\nAnthropic Provider β€” web-search via the web_search tool\nVertex Provider β€” Google search grounding","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Provider Guide","lvl2":"","lvl3":""}},
6998
7004
  {"objectID":"59d597c2561bea4977d9a4ae9a111235c2a042b1573e0fad7cf2147851b79e13","title":"Perplexity Provider Guide","url":"/docs/getting-started/providers/perplexity#perplexity-provider-guide","content":"Web-search-augmented generation via Perplexity's Sonar models","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Provider Guide","lvl2":"Perplexity Provider Guide","lvl3":""}},
@@ -7034,14 +7040,14 @@
7034
7040
  {"objectID":"b542e878ae561e1cd9d7ea83a1a95d493712f64171d7fbd98a2819ce32ab3cbb","title":"Supported Models","url":"/docs/getting-started/providers/recraft#supported-models","content":"| Model ID | Output | Notes |\n| --------------- | ------ | ------------------------- |\n| recraftv3 | Raster | Default; current flagship |\n| recraftv3-svg | SVG | Native vector output |\n| recraftv2 | Raster | Previous generation |","hierarchy":{"lvl0":"Getting Started","lvl1":"Recraft Provider Guide (image-gen)","lvl2":"Supported Models","lvl3":""}},
7035
7041
  {"objectID":"8b6c0c2cc6eda6858431c784ce846bac4040fca7b7fb7e1d8b78994d71dbd2c9","title":"Configuration Reference","url":"/docs/getting-started/providers/recraft#configuration-reference","content":"| Environment Variable | Required | Default |\n| -------------------- | -------- | ----------- |\n| RECRAFT_API_KEY | Yes | β€” |\n| RECRAFT_MODEL | No | recraftv3 |","hierarchy":{"lvl0":"Getting Started","lvl1":"Recraft Provider Guide (image-gen)","lvl2":"Configuration Reference","lvl3":""}},
7036
7042
  {"objectID":"a486a24ebd4845bec154166c9db68f9d2a4ef200eab97990b9384f23ab7a3ae5","title":"See Also","url":"/docs/getting-started/providers/recraft#see-also","content":"Stability AI Provider\nIdeogram Provider","hierarchy":{"lvl0":"Getting Started","lvl1":"Recraft Provider Guide (image-gen)","lvl2":"See Also","lvl3":""}},
7037
- {"objectID":"253e96d7ea40ad1aea03bc5cb594922747b4cfc6eafdf54b8b1a8711a513a431","title":"Reka AI Provider Guide","url":"/docs/getting-started/providers/reka","content":"Reka AI Provider Guide\n\nReka AI is a Tier-2 catalog provider: its entire integration is one JSON\nfile (src/lib/providers/catalog/reka.json) rather than hand-written code.\nThat file is the source of truth for everything on this page.\n\nVerification status: this entry is docs-verified only, not yet\nlive-verified. Reka's GET https://api.reka.ai/v1/models needs a key (it\nanswers HTTP 401 without one), so the three model ids come from Reka's public\ndocs (Models page, retrieved\n2026-09-29) and the roster has not been checked. No account was created, no\nAPI key was used and no POST request was sent to build it.\nevidence.liveMatrix is null until someone runs the live capability matrix\nwith a real key (see Verification status below).\n\nKey Facts\nProvider id: reka\nEndpoint: /chat/completions β€” the\n Quickstart says \"our API is fully\n OpenAI-compatible\"\nBase URL: https://api.reka.ai/v1\nDefault model: reka-flash\nModels in catalog: 3 β€” the ids on the Models page (reka-flash,\n reka-edge, reka-edge-2603)\nStreaming: supported β€” the\n Chat overview says \"The Chat API\n supports streaming\"\nTool calling: model-dependent β€” the\n Function Calling page\n documents the tools parameter and tool_calls, and says \"Currently, only\n Reka Flash supports function calling.\"\nTools while streaming: not declared (false) β€” no request combining them\n was sent\nStructured output: not declared (false) β€” the ChatRequest on the\n Chat API reference lists\n messages, model, frequency_penalty, max_tokens, presence_penalty,\n seed, stop, stream, temperature, tool_choice, tools, top_k and\n top_p\nStructured output + tools together: not declared (false) β€” no combined\n probe was run without credentials\nEmbeddings: not declared\nThinking: not declared\nVision: reka-flash, reka-edge and reka-edge-2603 are marked\n vision: true from the vendor's image examples (see Models)\nBilling: billingPolicy holds free-tier, one of the three values the\n catalog schema allows β€” the vendor wording is quoted in\n Billing below\nKey format: none declared\n\nQuick Start\nGet an API key\nVisit: https://platform.reka.ai/sign-up (the \"Start for free\" and \"Get started\" links on https://platform.reka.ai/pricing point to /sign-up). The Quickstart (https://docs.reka.ai/quickstart.md) says \"Create a free account on the Reka Platform to access your API key.\" and the FAQ (https://docs.reka.ai/resources/faqs.md) answers \"How do I get an API key?\" with \"Go to Platform, > API Keys to generate or copy your key.\"\nBilling as the vendor states it: https://docs.reka.ai/pricing.md says \"Get started with no upfront costs.\"; the FAQ (https://docs.reka.ai/resources/faqs.md) answers \"Do I need to pre-pay?\" with \"Yes. Add credits to your account before making requests.\" and says the balance error reads \"P001: Insufficient Balance\" when the balance hits $0\nAuthentication: the vendor's REST examples send the header X-Api-Key (https://docs.reka.ai/chat/overview.md) and the OpenAPI file https://docs.reka.ai/openapi/api-reference.yaml declares one security scheme, an apiKey in the header X-Api-Key; the OpenAI Python SDK examples pass apikey=\"YOURAPI_KEY\" to the client (https://docs.reka.ai/quickstart.md)\nSet REKA_API_KEY in your .env file\nConfigure\nUse it\n\nPer-request credentials work as they do for every provider:\n\nBilling\n\nWhat the vendor's pages say, as opened on 2026-09-29:\nThe Quickstart (https://docs.reka.ai/quickstart.md): \"Create a free account on\n the Reka Platform to access your API key.\"\nThe FAQ (https://docs.reka.ai/resources/faqs.md), \"Do I need to pre-pay?\":\n \"Yes. Add credits to your account before making requests.\" It adds that when\n the balance hits $0 the error reads \"P001: Insufficient Balance\".\nThe API pricing page (https://docs.reka.ai/pricing.md) has a \"Pay as you go\"\n heading and says \"Get started with no upfront costs. You only pay for what you\n use.\"\nThe platform pricing page (https://platform.reka.ai/pricing) shows a \"Pay as\n you go\" tile with the text \"Add credits only when you need them.\" and a \"Start\n for free\" link to /sign-up; the page also carries the text \"Free credits used\".\n\nbillingPolicy holds free-tier, one of the three values the catalog schema\nallows (free-tier, free-with-card, no-free-tier).\n\nModels\n\n| Model | Context | Vision | $/M in Β· out | Notes |\n| ---------------- | ------- | ------ | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| reka-flash ⭐ | β€” | yes | $0.80 / $2.00 | NeuroLink default. Named in the code examples of the Chat overview, Function Calling and Chat API reference pages; the pricing page describes \"Reka Flash\" as \"Fast and cost-efficient model for ","hierarchy":{"lvl0":"Getting Started","lvl1":"Reka AI Provider Guide","lvl2":"","lvl3":""}},
7038
- {"objectID":"38095f1d07a68493e80f61e00e63dc03b2c3f1f7ddfc60ed826901938191b33e","title":"Reka AI Provider Guide","url":"/docs/getting-started/providers/reka#reka-ai-provider-guide","content":"Reka AI is a Tier-2 catalog provider: its entire integration is one JSON\nfile (src/lib/providers/catalog/reka.json) rather than hand-written code.\nThat file is the source of truth for everything on this page.\n\nVerification status: this entry is docs-verified only, not yet\nlive-verified. Reka's GET https://api.reka.ai/v1/models needs a key (it\nanswers HTTP 401 without one), so the three model ids come from Reka's public\ndocs (Models page, retrieved\n2026-09-29) and the roster has not been checked. No account was created, no\nAPI key was used and no POST request was sent to build it.\nevidence.liveMatrix is null until someone runs the live capability matrix\nwith a real key (see Verification status below).","hierarchy":{"lvl0":"Getting Started","lvl1":"Reka AI Provider Guide","lvl2":"Reka AI Provider Guide","lvl3":""}},
7039
- {"objectID":"b02f09d4dbdb71bc5dad5c0e801689e956e1f45e74e10d9fc471032ab2d34b3e","title":"Key Facts","url":"/docs/getting-started/providers/reka#key-facts","content":"Provider id: reka\nEndpoint: /chat/completions β€” the\n Quickstart says \"our API is fully\n OpenAI-compatible\"\nBase URL: https://api.reka.ai/v1\nDefault model: reka-flash\nModels in catalog: 3 β€” the ids on the Models page (reka-flash,\n reka-edge, reka-edge-2603)\nStreaming: supported β€” the\n Chat overview says \"The Chat API\n supports streaming\"\nTool calling: model-dependent β€” the\n Function Calling page\n documents the tools parameter and tool_calls, and says \"Currently, only\n Reka Flash supports function calling.\"\nTools while streaming: not declared (false) β€” no request combining them\n was sent\nStructured output: not declared (false) β€” the ChatRequest on the\n Chat API reference lists\n messages, model, frequency_penalty, max_tokens, presence_penalty,\n seed, stop, stream, temperature, tool_choice, tools, top_k and\n top_p\nStructured output + tools together: not declared (false) β€” no combined\n probe was run without credentials\nEmbeddings: not declared\nThinking: not declared\nVision: reka-flash, reka-edge and reka-edge-2603 are marked\n vision: true from the vendor's image examples (see Models)\nBilling: billingPolicy holds free-tier, one of the three values the\n catalog schema allows β€” the vendor wording is quoted in\n Billing below\nKey format: none declared","hierarchy":{"lvl0":"Getting Started","lvl1":"Reka AI Provider Guide","lvl2":"Key Facts","lvl3":""}},
7043
+ {"objectID":"253e96d7ea40ad1aea03bc5cb594922747b4cfc6eafdf54b8b1a8711a513a431","title":"Reka AI Provider Guide","url":"/docs/getting-started/providers/reka","content":"Reka AI Provider Guide\n\nReka AI is a Tier-2 catalog provider: its entire integration is one JSON\nfile (src/lib/providers/catalog/reka.json) rather than hand-written code.\nThat file is the source of truth for everything on this page.\n\nVerification status: this entry is docs-verified only, not yet\nlive-verified. Reka's GET https://api.reka.ai/v1/models needs a key (it\nanswers HTTP 401 without one), so the four model ids come from Reka's public\ndocs (Models page, retrieved\n2026-09-29 for the first three and 2026-10-17 for reka-flash-3) and the\nroster has not been checked. No account was created, no\nAPI key was used and no POST request was sent to build it.\nevidence.liveMatrix is null until someone runs the live capability matrix\nwith a real key (see Verification status below).\n\nKey Facts\nProvider id: reka\nEndpoint: /chat/completions β€” the\n Quickstart says \"our API is fully\n OpenAI-compatible\"\nBase URL: https://api.reka.ai/v1\nDefault model: reka-flash\nModels in catalog: 4 β€” reka-flash, reka-edge and reka-edge-2603\n from the Models page as first read, plus reka-flash-3 from the Models page\n as read on 2026-10-17\nStreaming: supported β€” the\n Chat overview says \"The Chat API\n supports streaming\"\nTool calling: model-dependent β€” the table on the\n Models page (retrieved 2026-10-17) has a\n \"Tools\" column that is Yes for reka-edge-2603 and No for reka-flash-3,\n and the Tools section of the\n Chat overview (the Function Calling\n page now redirects there) says \"Models that list tools in their\n supported_features accept OpenAI-format tools and tool_choice.\" So\n reka-edge-2603 and its alias reka-edge are marked tools: true and\n reka-flash-3 is tools: false. reka-flash keeps tools: true from the\n sentence \"Currently, only Reka Flash supports function calling.\" (retrieved\n 2026-09-29), which the current pages no longer carry, so that entry is\n unconfirmed\nTools while streaming: not declared (false) β€” no request combining them\n was sent\nStructured output: not declared (false) β€” the ChatRequest on the\n Chat API reference lists\n messages, model, frequency_penalty, max_tokens, presence_penalty,\n seed, stop, stream, temperature, tool_choice, tools, top_k and\n top_p\nStructured output + tools together: not declared (false) β€” no combined\n probe was run without credentials\nEmbeddings: not declared\nThinking: not declared\nVision: reka-flash, reka-edge and reka-edge-2603 are marked\n vision: true from the vendor's image examples and Models table;\n reka-flash-3 is vision: false because the Models table lists its input as\n text only (see Models)\nBilling: billingPolicy holds free-tier, one of the three values the\n catalog schema allows β€” the vendor wording is quoted in\n Billing below\nKey format: none declared\n\nQuick Start\nGet an API key\nVisit: https://platform.reka.ai/sign-up (the \"Start for free\" and \"Get started\" links on https://platform.reka.ai/pricing point to /sign-up). The Quickstart (https://docs.reka.ai/quickstart.md) says \"Create a free account on the Reka Platform to access your API key.\" and the FAQ (https://docs.reka.ai/resources/faqs.md) answers \"How do I get an API key?\" with \"Go to Platform, > API Keys to generate or copy your key.\"\nBilling as the vendor states it: https://docs.reka.ai/pricing.md says \"Get started with no upfront costs.\"; the FAQ (https://docs.reka.ai/resources/faqs.md) answers \"Do I need to pre-pay?\" with \"Yes. Add credits to your account before making requests.\" and says the balance error reads \"P001: Insufficient Balance\" when the balance hits $0\nAuthentication: the vendor's REST examples send the header X-Api-Key (https://docs.reka.ai/chat/overview.md) and the OpenAPI file https://docs.reka.ai/openapi/api-reference.yaml declares one security scheme, an apiKey in the header X-Api-Key; the OpenAI Python SDK examples pass apikey=\"YOURAPI_KEY\" to the client (https://docs.reka.ai/quickstart.md)\nSet REKA_API_KEY in your .env file\nConfigure\nUse it\n\nPer-request credentials work as they do for every provider:\n\nBilling\n\nWhat the vendor's pages say, as opened on 2026-09-29:\nThe Quickstart (https://docs.reka.ai/quickstart.md): \"Create a free account on\n the Reka Platform to access your API key.\"\nThe FAQ (https://docs.reka.ai/resources/faqs.md), \"Do I need to pre-pay?\":\n \"Yes. Add credits to your account before making requests.\" It adds that when\n the balance hits $0 the error reads \"P001: Insufficient Balance\".\nThe API pricing page (https://docs.reka.ai/pricing.md) has a \"Pay as you go\"\n heading and says \"Get started with no upfront costs. You only pay for what you\n use.\"\nThe platform pricing page (https://platform.reka.ai/pricing) shows a \"Pay as\n you go\" tile with the text \"Add credits only when you need them.\" and a \"Start\n for free\" link to /sign-up; the page also carries the text \"Free credits used\".\n\nbillingPolicy holds free-tier, one of the three values the catalog schema\nallows (free-tier, free-with-card, no-free-tier).\n\nModels\n\n| Model | Context | Vision | $/M in ","hierarchy":{"lvl0":"Getting Started","lvl1":"Reka AI Provider Guide","lvl2":"","lvl3":""}},
7044
+ {"objectID":"38095f1d07a68493e80f61e00e63dc03b2c3f1f7ddfc60ed826901938191b33e","title":"Reka AI Provider Guide","url":"/docs/getting-started/providers/reka#reka-ai-provider-guide","content":"Reka AI is a Tier-2 catalog provider: its entire integration is one JSON\nfile (src/lib/providers/catalog/reka.json) rather than hand-written code.\nThat file is the source of truth for everything on this page.\n\nVerification status: this entry is docs-verified only, not yet\nlive-verified. Reka's GET https://api.reka.ai/v1/models needs a key (it\nanswers HTTP 401 without one), so the four model ids come from Reka's public\ndocs (Models page, retrieved\n2026-09-29 for the first three and 2026-10-17 for reka-flash-3) and the\nroster has not been checked. No account was created, no\nAPI key was used and no POST request was sent to build it.\nevidence.liveMatrix is null until someone runs the live capability matrix\nwith a real key (see Verification status below).","hierarchy":{"lvl0":"Getting Started","lvl1":"Reka AI Provider Guide","lvl2":"Reka AI Provider Guide","lvl3":""}},
7045
+ {"objectID":"b02f09d4dbdb71bc5dad5c0e801689e956e1f45e74e10d9fc471032ab2d34b3e","title":"Key Facts","url":"/docs/getting-started/providers/reka#key-facts","content":"Provider id: reka\nEndpoint: /chat/completions β€” the\n Quickstart says \"our API is fully\n OpenAI-compatible\"\nBase URL: https://api.reka.ai/v1\nDefault model: reka-flash\nModels in catalog: 4 β€” reka-flash, reka-edge and reka-edge-2603\n from the Models page as first read, plus reka-flash-3 from the Models page\n as read on 2026-10-17\nStreaming: supported β€” the\n Chat overview says \"The Chat API\n supports streaming\"\nTool calling: model-dependent β€” the table on the\n Models page (retrieved 2026-10-17) has a\n \"Tools\" column that is Yes for reka-edge-2603 and No for reka-flash-3,\n and the Tools section of the\n Chat overview (the Function Calling\n page now redirects there) says \"Models that list tools in their\n supported_features accept OpenAI-format tools and tool_choice.\" So\n reka-edge-2603 and its alias reka-edge are marked tools: true and\n reka-flash-3 is tools: false. reka-flash keeps tools: true from the\n sentence \"Currently, only Reka Flash supports function calling.\" (retrieved\n 2026-09-29), which the current pages no longer carry, so that entry is\n unconfirmed\nTools while streaming: not declared (false) β€” no request combining them\n was sent\nStructured output: not declared (false) β€” the ChatRequest on the\n Chat API reference lists\n messages, model, frequency_penalty, max_tokens, presence_penalty,\n seed, stop, stream, temperature, tool_choice, tools, top_k and\n top_p\nStructured output + tools together: not declared (false) β€” no combined\n probe was run without credentials\nEmbeddings: not declared\nThinking: not declared\nVision: reka-flash, reka-edge and reka-edge-2603 are marked\n vision: true from the vendor's image examples and Models table;\n reka-flash-3 is vision: false because the Models table lists its input as\n text only (see Models)\nBilling: billingPolicy holds free-tier, one of the three values the\n catalog schema allows β€” the vendor wording is quoted in\n Billing below\nKey format: none declared","hierarchy":{"lvl0":"Getting Started","lvl1":"Reka AI Provider Guide","lvl2":"Key Facts","lvl3":""}},
7040
7046
  {"objectID":"387a63f66e05b9721faebe894f1be59d37ca90a54446fb46a92597c11e63392b","title":"1. Get an API key","url":"/docs/getting-started/providers/reka#1-get-an-api-key","content":"Visit: https://platform.reka.ai/sign-up (the \"Start for free\" and \"Get started\" links on https://platform.reka.ai/pricing point to /sign-up). The Quickstart (https://docs.reka.ai/quickstart.md) says \"Create a free account on the Reka Platform to access your API key.\" and the FAQ (https://docs.reka.ai/resources/faqs.md) answers \"How do I get an API key?\" with \"Go to Platform, > API Keys to generate or copy your key.\"\nBilling as the vendor states it: https://docs.reka.ai/pricing.md says \"Get started with no upfront costs.\"; the FAQ (https://docs.reka.ai/resources/faqs.md) answers \"Do I need to pre-pay?\" with \"Yes. Add credits to your account before making requests.\" and says the balance error reads \"P001: Insufficient Balance\" when the balance hits $0\nAuthentication: the vendor's REST examples send the header X-Api-Key (https://docs.reka.ai/chat/overview.md) and the OpenAPI file https://docs.reka.ai/openapi/api-reference.yaml declares one security scheme, an apiKey in the header X-Api-Key; the OpenAI Python SDK examples pass apikey=\"YOURAPI_KEY\" to the client (https://docs.reka.ai/quickstart.md)\nSet REKA_API_KEY in your .env file","hierarchy":{"lvl0":"Getting Started","lvl1":"Reka AI Provider Guide","lvl2":"1. Get an API key","lvl3":""}},
7041
7047
  {"objectID":"fa1555bea79084e58dc26d47a4b84902ff751b53983cd3d38a46298530cc33ab","title":"3. Use it","url":"/docs/getting-started/providers/reka#3-use-it","content":"`bash","hierarchy":{"lvl0":"Getting Started","lvl1":"Reka AI Provider Guide","lvl2":"3. Use it","lvl3":""}},
7042
7048
  {"objectID":"14c149de1fbf294e39961c7048587e20abfaeda1f31064d9f15b8afa4b69bc6f","title":"CLI","url":"/docs/getting-started/providers/reka#cli","content":"npx @juspay/neurolink generate \"Hello\" --provider reka\ntypescript\nawait neurolink.generate({\n input: { text: \"Hello\" },\n provider: \"reka\",\n credentials: { reka: { apiKey: process.env.REKAAPIKEY } },\n});\n`","hierarchy":{"lvl0":"Getting Started","lvl1":"Reka AI Provider Guide","lvl2":"CLI","lvl3":""}},
7043
7049
  {"objectID":"24b90c27fd9b6a0f9aa811dc072f50dcdbc865d66d37e282250e575ad113224e","title":"Billing","url":"/docs/getting-started/providers/reka#billing","content":"What the vendor's pages say, as opened on 2026-09-29:\nThe Quickstart (https://docs.reka.ai/quickstart.md): \"Create a free account on\n the Reka Platform to access your API key.\"\nThe FAQ (https://docs.reka.ai/resources/faqs.md), \"Do I need to pre-pay?\":\n \"Yes. Add credits to your account before making requests.\" It adds that when\n the balance hits $0 the error reads \"P001: Insufficient Balance\".\nThe API pricing page (https://docs.reka.ai/pricing.md) has a \"Pay as you go\"\n heading and says \"Get started with no upfront costs. You only pay for what you\n use.\"\nThe platform pricing page (https://platform.reka.ai/pricing) shows a \"Pay as\n you go\" tile with the text \"Add credits only when you need them.\" and a \"Start\n for free\" link to /sign-up; the page also carries the text \"Free credits used\".\n\nbillingPolicy holds free-tier, one of the three values the catalog schema\nallows (free-tier, free-with-card, no-free-tier).","hierarchy":{"lvl0":"Getting Started","lvl1":"Reka AI Provider Guide","lvl2":"Billing","lvl3":""}},
7044
- {"objectID":"4ab41102e701a4abfc0245d47b4c2bb799159cfec1967263d3ac1651dae9b9c4","title":"Models","url":"/docs/getting-started/providers/reka#models","content":"| Model | Context | Vision | $/M in Β· out | Notes |\n| ---------------- | ------- | ------ | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| reka-flash ⭐ | β€” | yes | $0.80 / $2.00 | NeuroLink default. Named in the code examples of the Chat overview, Function Calling and Chat API reference pages; the pricing page describes \"Reka Flash\" as \"Fast and cost-efficient model for most tasks\". |\n| reka-edge | β€” | yes | $0.10 / $0.10 | Listed as \"reka-edge (or reka-edge-2603)\" on the Models page and the Quickstart; the pricing page describes \"Reka Edge\" as \"Compact model ideal for on-device execution\". Fallback. |\n| reka-edge-2603 | β€” | yes | $0.10 / $0.10 | Named in the same table row as reka-edge; the Models page shows it in the example output of GET /v1/models. Vision and prices are those of the reka-edge row. |\n\nModel ids come from https://docs.reka.ai/chat/models.md, which says \"Our baseline\nmodels always available for public access are:\" and lists reka-flash and\nreka-edge (or reka-edge-2603). Prices come from https://docs.reka.ai/pricing.md\n(\"Input Tokens (per 1M)\" and \"Output Tokens (per 1M)\" columns, rows named \"Reka\nFlash\" and \"Reka Edge\"); the Models page says \"For full listing of models and\npricing, see the Reka API Pricing page\".","hierarchy":{"lvl0":"Getting Started","lvl1":"Reka AI Provider Guide","lvl2":"Models","lvl3":""}},
7050
+ {"objectID":"4ab41102e701a4abfc0245d47b4c2bb799159cfec1967263d3ac1651dae9b9c4","title":"Models","url":"/docs/getting-started/providers/reka#models","content":"| Model | Context | Vision | $/M in Β· out | Notes |\n| ---------------- | ------- | ------ | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| reka-flash ⭐ | β€” | yes | $0.80 / $2.00 | NeuroLink default. Named in the code examples of the Chat overview, Function Calling and Chat API reference pages; the pricing page describes \"Reka Flash\" as \"Fast and cost-efficient model for most tasks\". |\n| reka-edge | β€” | yes | $0.10 / $0.10 | Listed as \"reka-edge (or reka-edge-2603)\" on the Models page and the Quickstart (2026-09-29); the pricing page describes \"Reka Edge\" as \"Compact model ideal for on-device execution\". Fallback. |\n| reka-edge-2603 | β€” | yes | $0.10 / $0.10 | Named in the same table row as reka-edge; the Models page (2026-10-17) lists it with Tools = Yes, and shows it in the example output of GET /v1/models. Vision and prices are those of the reka-edge row. |\n| reka-flash-3 | β€” | no | $0.10 / $0.20 | On the Models page (2026-10-17) with input \"Text\" and Tools = No, so NeuroLink never sends it a tools array. Prices are from its card at https://developer.reka.ai/models. |\n\nModel ids come from https://docs.reka.ai/chat/models.md. As read on 2026-09-29\nit said \"Our baseline models always available for public access are:\" and\nlisted reka-flash and reka-edge (or reka-edge-2603); prices for those came\nfrom https://docs.reka.ai/pricing.md (\"Input Tokens (per 1M)\" and \"Output\nTokens (per 1M)\" columns, rows named \"Reka Flash\" and \"Reka Edge\").","hierarchy":{"lvl0":"Getting Started","lvl1":"Reka AI Provider Guide","lvl2":"Models","lvl3":""}},
7045
7051
  {"objectID":"264988d5885746bdddc0250edfc1ff32781c3cea6012cd76b865bc92f2e56941","title":"Verification status","url":"/docs/getting-started/providers/reka#verification-status","content":"Tier-2 onboarding requires evidence before a provider is accepted, and\npnpm run verify:provider-onboarding gates it in CI. This is what the catalog\ncurrently records for Reka AI β€” docs-verified only, not live-verified:\n\n| Probe | Result |\n| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| Roster | unauthenticated GET /v1/models answered HTTP 401 on 2026-09-29, so the model ids come from https://docs.reka.ai/chat/models.md; roster not verified |\n| Auth-failure shape | the same GET returned the JSON body {\"error\":{\"message\":\"Unauthorized\",\"type\":\"authentication_error\",\"code\":null,\"param\":null}}; evidence.authProbe records status 401 and code authentication_error (the body's error.type, because error.code is null).","hierarchy":{"lvl0":"Getting Started","lvl1":"Reka AI Provider Guide","lvl2":"Verification status","lvl3":""}},
7046
7052
  {"objectID":"571cbf193e411b2b478403e7f7e01ec48075061372c8ca2350399a470729c5de","title":"Troubleshooting","url":"/docs/getting-started/providers/reka#troubleshooting","content":"Each row is the Error Type and Client Action columns of the table on https://docs.reka.ai/errors.md.\n\n| Symptom | Vendor statement | Vendor's client action |\n| -------- | ---------------------- | ---------------------------------------------------------------------------------------------- |\n| HTTP 401 | authentication_error | \"Ensure that you're using a valid Reka API key\" |\n| HTTP 429 | rate_limit_error | \"Wait until your rate limit is restored and retry, or upgrade your API tier for higher limits\" |\n| HTTP 500 | server_error | \"Retry with backoff. If this persists, contact Reka at contact@reka.ai\" |","hierarchy":{"lvl0":"Getting Started","lvl1":"Reka AI Provider Guide","lvl2":"Troubleshooting","lvl3":""}},
7047
7053
  {"objectID":"499b23903fab98f2f8ceddc45f2091ae0ac3905c402ac0a0ab16fc11d348ff32","title":"See also","url":"/docs/getting-started/providers/reka#see-also","content":"Provider setup overview\nAll providers\nTier-2 onboarding β€” how this provider's JSON becomes a working integration\nProvider feature compatibility","hierarchy":{"lvl0":"Getting Started","lvl1":"Reka AI Provider Guide","lvl2":"See also","lvl3":""}},
@@ -7479,18 +7485,18 @@
7479
7485
  {"objectID":"7bc31a9a4e8ceaa9d384ce6953e41c6991344d5affeecf269a14248d769eb2f3","title":"\"xAI account has insufficient quota\"","url":"/docs/getting-started/providers/xai#xai-account-has-insufficient-quota","content":"Top up at https://console.x.ai/.","hierarchy":{"lvl0":"Getting Started","lvl1":"xAI Grok Provider Guide","lvl2":"\"xAI account has insufficient quota\"","lvl3":""}},
7480
7486
  {"objectID":"62c0c746ffa186a922276c344852f82e4ee3242f81c67b58a433defc4f4a4924","title":"\"Model not found\"","url":"/docs/getting-started/providers/xai#model-not-found","content":"Use one of the documented model IDs above. Custom fine-tunes are not\nexposed through the public API at this time.","hierarchy":{"lvl0":"Getting Started","lvl1":"xAI Grok Provider Guide","lvl2":"\"Model not found\"","lvl3":""}},
7481
7487
  {"objectID":"a55b6d892c11d17b5222d76096529452815cd15809b93c491a3c484756185910","title":"See Also","url":"/docs/getting-started/providers/xai#see-also","content":"Adding a new LLM provider β€” internal reference for the integration pattern this provider follows\nDeepSeek Provider β€” sibling OpenAI-compat provider with reasoning models\nGroq Provider β€” sibling OpenAI-compat provider with sub-100ms inference\n\nNeed Help? Open a GitHub Discussion or issue.","hierarchy":{"lvl0":"Getting Started","lvl1":"xAI Grok Provider Guide","lvl2":"See Also","lvl3":""}},
7482
- {"objectID":"03a891da2cc3529b3e4bfc042e5834454a779a2d3fa9389367ba4b3d05266871","title":"XOR Provider Guide","url":"/docs/getting-started/providers/xor","content":"XOR Provider Guide\n\nA provider of decide β€” the same typed boolean / choice /\nscore answers as TypeSafe's Jev and Laya, from\nJuspay's open-weights model, which also reads images and a video. It emits no\ntext at all.\n\nOverview\n\nXOR is Juspay's Apache-2.0 decision model, post-trained from Qwen3.6-35B-A3B;\nits model id is xor-1.1. You send one state plus named, typed questions, and\noptionally images or a video. XOR answers every question in a single batched\npass and returns a typed answer for each. NeuroLink calls whatever base URL you\nconfigure β€” a deployment of the model, or a LiteLLM proxy with a route to one.\nThere is no built-in endpoint. The weights and setup instructions are at\nhuggingface.co/juspay/xor.\n\nKey Facts\n\n| | |\n| --------------------- | -------------------------------------------------------------------- |\n| Inference type | decide only |\n| Model | xor-1.1 by default; XOR_MODEL sets the name your proxy uses |\n| Media | up to 8 images and one video; the whole request body at most 8 MB |\n| Input window | about 200,000 estimated tokens of state |\n| Questions per request | no cap in NeuroLink; a choice or score takes 2 to 255 options |\n| Endpoint | <base URL>/v1/systemone; the base URL is required, with no default |\n| Precedence | used automatically only when TypeSafe and Laya are not configured |\n\nQuick Start\nGet an endpoint and a key\n\nRun a deployment of XOR (see\nhuggingface.co/juspay/xor), or use a\nLiteLLM proxy with a route to one. NeuroLink posts to <base URL>/v1/systemone.\nThe base URL is the origin of the deployment or of the proxy route, and a\ntrailing /v1 is accepted. On a LiteLLM proxy the key's team must be allowed\nthe model you ask for (xor-1.1 by default); otherwise the proxy answers 403\nteam_model_access_denied. A proxy may serve XOR under a name of its own: set\nXOR_MODEL to that name.\nConfigure\n\nBoth the base URL and the key are required. Set them in the environment:\n\nor in the config passed to the SDK, exactly as for any other provider. Values\npassed per call override the constructor's, which override the environment:\nUse it\n\nFrom the CLI\n\nThe CLI reads the same environment variables:\n\nImages and video\n\nXOR reads images and one video alongside the state. TypeSafe and Laya do not\nread media, and Perplexity,\nCloudflare Clef and OpenAI Decisions\nread images but no video.\n\nFrom the CLI, pass --image <path> (repeatable) and --video <path>:\n\nThe rules:\nUp to 8 images and one video per request, in images and video.\nEach is a Buffer, a local file path or a data: URL. An http(s) URL is\n refused: NeuroLink does not fetch media for you.\nThe type comes from the bytes, not the file extension: PNG, JPEG, WebP\n and GIF images, and MP4, MOV and WebM video. NeuroLink\n sends a Buffer or a file to XOR as a data: URL. A data: URL you pass\n yourself must hold base64 image or video content, and is sent as given.\nThe whole request body may be at most 8 MB. The limit applies to the\n encoded body, so the base64 form counts, not the size of the files on disk. A\n file over the limit is refused from its size, before it is read.\nWhat can be checked locally is refused before any request, as a\n non-retryable invalid_request: a missing file, a directory, an empty Buffer\n or file, bytes that are not a recognised image or video, a remote URL or any\n other URL scheme, a string that is not a path or a data: URL, more than 8\n images, or a body over 8 MB. Bytes with the right signature that the model\n cannot decode are sent, and the server's refusal comes back as a server\n error, retried once.\nTypeSafe and Laya refuse media too, before any request, and the error\n names the providers that accept it. Perplexity, Cloudflare Clef and OpenAI\n Decisions refuse a video.\nImages and a video can be sent together (up to 8 images and one video),\n but the model does not reliably tell the two apart.\nThe result carries mediaBytes, the encoded size of the media sent. The\n decide spans carry decision.images.count and decision.media.bytes, and\n never any base64.\n\nWhen NeuroLink uses it\n\nEvery built-in consumer of decide β€” model routing, relevance-driven\ncompaction, tool routing and RAG planning β€” asks for the default decision\nprovider. That is the first one that is configured, in the environment or in the\ncredentials passed to the SDK, in the order TypeSafe, Laya, XOR,\nSubQ, Perplexity, Cloudflare Clef, then\nOpenAI Decisions. TypeSafe counts with either of its keys,\nTYPESAFE_API_KEY or AI_GATEWAY_API_KEY. Laya and XOR each count only with\nboth their key and their base URL. SubQ counts with its key alone. Perplexity\ncounts with its key alone, which is shared with Perplexity's text provider. Cloudflare Clef counts only with both\nCLOUDFLARE_API_KEY and CLOUDFLARE_ACC","hierarchy":{"lvl0":"Getting Started","lvl1":"XOR Provider Guide","lvl2":"","lvl3":""}},
7488
+ {"objectID":"03a891da2cc3529b3e4bfc042e5834454a779a2d3fa9389367ba4b3d05266871","title":"XOR Provider Guide","url":"/docs/getting-started/providers/xor","content":"XOR Provider Guide\n\nA provider of decide β€” the same typed boolean / choice /\nscore answers as TypeSafe's Jev and Laya, from\nJuspay's open-weights model, which also reads images and a video. It emits no\ntext at all.\n\nOverview\n\nXOR is Juspay's Apache-2.0 decision model, post-trained from Qwen3.6-35B-A3B;\nits model id is xor-1.1. You send one state plus named, typed questions, and\noptionally images or a video. XOR answers every question in a single batched\npass and returns a typed answer for each. NeuroLink calls whatever base URL you\nconfigure β€” a deployment of the model, or a LiteLLM proxy with a route to one.\nThere is no built-in endpoint. The weights and setup instructions are at\nhuggingface.co/juspay/xor.\n\nKey Facts\n\n| | |\n| --------------------- | -------------------------------------------------------------------- |\n| Inference type | decide only |\n| Model | xor-1.1 by default; XOR_MODEL sets the name your proxy uses |\n| Media | up to 8 images and one video; the whole request body at most 8 MB |\n| Input window | about 200,000 estimated tokens of state |\n| Questions per request | no cap in NeuroLink; a choice or score takes 2 to 255 options |\n| Endpoint | <base URL>/v1/systemone; the base URL is required, with no default |\n| Precedence | used automatically only when TypeSafe and Laya are not configured |\n\nQuick Start\nGet an endpoint and a key\n\nRun a deployment of XOR (see\nhuggingface.co/juspay/xor), or use a\nLiteLLM proxy with a route to one. NeuroLink posts to <base URL>/v1/systemone.\nThe base URL is the origin of the deployment or of the proxy route, and a\ntrailing /v1 is accepted. It must be https://; http:// is accepted only for\nlocalhost, 127.0.0.1 and [::1], because every request carries the key and the\nstate. A deployment reachable only over plain http inside a network needs an\nhttps:// front, or a port-forward to localhost. On a LiteLLM proxy the key's team must be allowed\nthe model you ask for (xor-1.1 by default); otherwise the proxy answers 403\nteam_model_access_denied. A proxy may serve XOR under a name of its own: set\nXOR_MODEL to that name.\nConfigure\n\nBoth the base URL and the key are required. Set them in the environment:\n\nor in the config passed to the SDK, exactly as for any other provider. Values\npassed per call override the constructor's, which override the environment:\nUse it\n\nFrom the CLI\n\nThe CLI reads the same environment variables:\n\nImages and video\n\nXOR reads images and one video alongside the state. TypeSafe and Laya do not\nread media, and Perplexity,\nCloudflare Clef and OpenAI Decisions\nread images but no video.\n\nFrom the CLI, pass --image <path> (repeatable) and --video <path>:\n\nThe rules:\nUp to 8 images and one video per request, in images and video.\nEach is a Buffer, a local file path or a data: URL. An http(s) URL is\n refused: NeuroLink does not fetch media for you.\nThe type comes from the bytes, not the file extension: PNG, JPEG, WebP\n and GIF images, and MP4, MOV and WebM video. NeuroLink\n sends a Buffer or a file to XOR as a data: URL. A data: URL you pass\n yourself must hold base64 image or video content, and is sent as given.\nThe whole request body may be at most 8 MB. The limit applies to the\n encoded body, so the base64 form counts, not the size of the files on disk. A\n file over the limit is refused from its size, before it is read.\nWhat can be checked locally is refused before any request, as a\n non-retryable invalid_request: a missing file, a directory, an empty Buffer\n or file, bytes that are not a recognised image or video, a remote URL or any\n other URL scheme, a string that is not a path or a data: URL, more than 8\n images, or a body over 8 MB. Bytes with the right signature that the model\n cannot decode are sent, and the server's refusal comes back as a server\n error, retried once.\nTypeSafe and Laya refuse media too, before any request, and the error\n names the providers that accept it. Perplexity, Cloudflare Clef and OpenAI\n Decisions refuse a video.\nImages and a video can be sent together (up to 8 images and one video),\n but the model does not reliably tell the two apart.\nThe result carries mediaBytes, the encoded size of the media sent. The\n decide spans carry decision.images.count and decision.media.bytes, and\n never any base64.\n\nWhen NeuroLink uses it\n\nEvery built-in consumer of decide β€” model routing, relevance-driven\ncompaction, tool routing and RAG planning β€” asks for the default decision\nprovider. That is the first one that is configured, in the environment or in the\ncredentials passed to the SDK, in the order TypeSafe, Laya, XOR,\nSubQ, Perplexity, Cloudflare Clef, then\nOpenAI Decisions. TypeSafe counts with either of its keys,\nTYPESAFE_API_KEY or AI_GATEWAY_API_KEY. Laya and X","hierarchy":{"lvl0":"Getting Started","lvl1":"XOR Provider Guide","lvl2":"","lvl3":""}},
7483
7489
  {"objectID":"5ed0d5759a64d045ba6c8acb04b0b6e6fef6f00399b88df9847c053d52a8e70c","title":"XOR Provider Guide","url":"/docs/getting-started/providers/xor#xor-provider-guide","content":"A provider of decide β€” the same typed boolean / choice /\nscore answers as TypeSafe's Jev and Laya, from\nJuspay's open-weights model, which also reads images and a video. It emits no\ntext at all.","hierarchy":{"lvl0":"Getting Started","lvl1":"XOR Provider Guide","lvl2":"XOR Provider Guide","lvl3":""}},
7484
7490
  {"objectID":"62f1da4b03072e86ddddfcfed9098a9efa475d349ea26f88c901347eca7fc77a","title":"Overview","url":"/docs/getting-started/providers/xor#overview","content":"XOR is Juspay's Apache-2.0 decision model, post-trained from Qwen3.6-35B-A3B;\nits model id is xor-1.1. You send one state plus named, typed questions, and\noptionally images or a video. XOR answers every question in a single batched\npass and returns a typed answer for each. NeuroLink calls whatever base URL you\nconfigure β€” a deployment of the model, or a LiteLLM proxy with a route to one.\nThere is no built-in endpoint. The weights and setup instructions are at\nhuggingface.co/juspay/xor.","hierarchy":{"lvl0":"Getting Started","lvl1":"XOR Provider Guide","lvl2":"Overview","lvl3":""}},
7485
7491
  {"objectID":"2a68b1796658b1e42d1fb20868e2f28c9b9b13e9e83ebb2ac4411de95d15b8e3","title":"Key Facts","url":"/docs/getting-started/providers/xor#key-facts","content":"| | |\n| --------------------- | -------------------------------------------------------------------- |\n| Inference type | decide only |\n| Model | xor-1.1 by default; XOR_MODEL sets the name your proxy uses |\n| Media | up to 8 images and one video; the whole request body at most 8 MB |\n| Input window | about 200,000 estimated tokens of state |\n| Questions per request | no cap in NeuroLink; a choice or score takes 2 to 255 options |\n| Endpoint | <base URL>/v1/systemone; the base URL is required, with no default |\n| Precedence | used automatically only when TypeSafe and Laya are not configured |","hierarchy":{"lvl0":"Getting Started","lvl1":"XOR Provider Guide","lvl2":"Key Facts","lvl3":""}},
7486
- {"objectID":"06cdd61cf369f5af93c8e03841be4ebddcc8e1fde819b193e35a9fabfa7db51a","title":"1. Get an endpoint and a key","url":"/docs/getting-started/providers/xor#1-get-an-endpoint-and-a-key","content":"Run a deployment of XOR (see\nhuggingface.co/juspay/xor), or use a\nLiteLLM proxy with a route to one. NeuroLink posts to <base URL>/v1/systemone.\nThe base URL is the origin of the deployment or of the proxy route, and a\ntrailing /v1 is accepted. On a LiteLLM proxy the key's team must be allowed\nthe model you ask for (xor-1.1 by default); otherwise the proxy answers 403\nteam_model_access_denied. A proxy may serve XOR under a name of its own: set\nXOR_MODEL to that name.","hierarchy":{"lvl0":"Getting Started","lvl1":"XOR Provider Guide","lvl2":"1. Get an endpoint and a key","lvl3":""}},
7492
+ {"objectID":"06cdd61cf369f5af93c8e03841be4ebddcc8e1fde819b193e35a9fabfa7db51a","title":"1. Get an endpoint and a key","url":"/docs/getting-started/providers/xor#1-get-an-endpoint-and-a-key","content":"Run a deployment of XOR (see\nhuggingface.co/juspay/xor), or use a\nLiteLLM proxy with a route to one. NeuroLink posts to <base URL>/v1/systemone.\nThe base URL is the origin of the deployment or of the proxy route, and a\ntrailing /v1 is accepted. It must be https://; http:// is accepted only for\nlocalhost, 127.0.0.1 and [::1], because every request carries the key and the\nstate. A deployment reachable only over plain http inside a network needs an\nhttps:// front, or a port-forward to localhost. On a LiteLLM proxy the key's team must be allowed\nthe model you ask for (xor-1.1 by default); otherwise the proxy answers 403\nteam_model_access_denied. A proxy may serve XOR under a name of its own: set\nXOR_MODEL to that name.","hierarchy":{"lvl0":"Getting Started","lvl1":"XOR Provider Guide","lvl2":"1. Get an endpoint and a key","lvl3":""}},
7487
7493
  {"objectID":"540db8a33720c64f9e3e59c312e3d3e2476799c726c6e5729729ecaf2bbefa05","title":"2. Configure","url":"/docs/getting-started/providers/xor#2-configure","content":"Both the base URL and the key are required. Set them in the environment:\n\nor in the config passed to the SDK, exactly as for any other provider. Values\npassed per call override the constructor's, which override the environment:","hierarchy":{"lvl0":"Getting Started","lvl1":"XOR Provider Guide","lvl2":"2. Configure","lvl3":""}},
7488
7494
  {"objectID":"3fd4afc9a2670046c937e06586a65b3b5eadb6de1560ee1e1a3abf5f05524876","title":"From the CLI","url":"/docs/getting-started/providers/xor#from-the-cli","content":"The CLI reads the same environment variables:","hierarchy":{"lvl0":"Getting Started","lvl1":"XOR Provider Guide","lvl2":"From the CLI","lvl3":""}},
7489
7495
  {"objectID":"90a0f1f65868c0d5b68bb8fb5828a32f704d4ed3a164081275a6837b65a8e2f7","title":"Images and video","url":"/docs/getting-started/providers/xor#images-and-video","content":"XOR reads images and one video alongside the state. TypeSafe and Laya do not\nread media, and Perplexity,\nCloudflare Clef and OpenAI Decisions\nread images but no video.\n\nFrom the CLI, pass --image <path> (repeatable) and --video <path>:\n\nThe rules:\nUp to 8 images and one video per request, in images and video.\nEach is a Buffer, a local file path or a data: URL. An http(s) URL is\n refused: NeuroLink does not fetch media for you.\nThe type comes from the bytes, not the file extension: PNG, JPEG, WebP\n and GIF images, and MP4, MOV and WebM video. NeuroLink\n sends a Buffer or a file to XOR as a data: URL. A data: URL you pass\n yourself must hold base64 image or video content, and is sent as given.\nThe whole request body may be at most 8 MB. The limit applies to the\n encoded body, so the base64 form counts, not the size of the files on disk. A\n file over the limit is refused from its size, before it is read.\nWhat can be checked locally is refused before any request, as a\n non-retryable invalid_request: a missing file, a directory, an empty Buffer\n or file, bytes that are not a recognised image or video, a remote URL or any\n other URL scheme, a string that is not a path or a data: URL, more than 8\n images, or a body over 8 MB. Bytes with the right signature that the model\n cannot decode are sent, and the server's refusal comes back as a server\n error, retried once.\nTypeSafe and Laya refuse media too, before any request, and the error\n names the providers that accept it. Perplexity, Cloudflare Clef and OpenAI\n Decisions refuse a video.\nImages and a video can be sent together (up to 8 images and one video),\n but the model does not reliably tell the two apart.\nThe result carries mediaBytes, the encoded size of the media sent. The\n decide spans carry decision.images.count and decision.media.bytes, and\n never any base64.","hierarchy":{"lvl0":"Getting Started","lvl1":"XOR Provider Guide","lvl2":"Images and video","lvl3":""}},
7490
7496
  {"objectID":"4fea1eacec247a5a95e9c0d017549cb5233da507c593a841ce0e392eb2d11e2a","title":"When NeuroLink uses it","url":"/docs/getting-started/providers/xor#when-neurolink-uses-it","content":"Every built-in consumer of decide β€” model routing, relevance-driven\ncompaction, tool routing and RAG planning β€” asks for the default decision\nprovider. That is the first one that is configured, in the environment or in the\ncredentials passed to the SDK, in the order TypeSafe, Laya, XOR,\nSubQ, Perplexity, Cloudflare Clef, then\nOpenAI Decisions. TypeSafe counts with either of its keys,\nTYPESAFE_API_KEY or AI_GATEWAY_API_KEY. Laya and XOR each count only with\nboth their key and their base URL. SubQ counts with its key alone. Perplexity\ncounts with its key alone, which is shared with Perplexity's text provider. Cloudflare Clef counts only with both\nCLOUDFLARE_API_KEY and CLOUDFLARE_ACCOUNT_ID, the same two variables the\nWorkers AI text provider reads. OpenAI Decisions counts with its key alone,\nOPENAI_API_KEY, which the OpenAI chat provider reads too. A caller can always\nname XOR with provider: \"xor\". So:\nA TypeSafe key, or Laya's key and base URL, plus XOR's key and base URL:\n built-in features use TypeSafe or Laya, in that order; XOR runs only where a\n caller asks for provider: \"xor\".\nXOR's key and base URL, plus SUBQ_API_KEY: built-in features use XOR;\n SubQ runs only where a caller asks for provider: \"subq\".\nXOR's key and base URL, plus a Perplexity key: built-in features use XOR;\n Perplexity runs only where a caller asks for\n provider: \"perplexity-decider\".\nXOR's key and base URL, plus CLOUDFLARE_API_KEY and\n CLOUDFLARE_ACCOUNT_ID: built-in features use XOR; Cloudflare Clef runs\n only where a caller asks for provider: \"cloudflare-clef\".\nOnly XOR's key and base URL: built-in features use XOR.\nAn XOR key with no base URL: XOR is not configured. Built-in features\n ignore it, and provider: \"xor\" fails with XOR requires a base URL.\nNone of TypeSafe, Laya, XOR, SubQ, Perplexity, Cloudflare Clef or OpenAI\n Decisions: everything behaves exactly as it did without a decision model.","hierarchy":{"lvl0":"Getting Started","lvl1":"XOR Provider Guide","lvl2":"When NeuroLink uses it","lvl3":""}},
7491
7497
  {"objectID":"20a784de9dff5b3afa1f5ee7c0c60e268a7274b7e0c2a447aca431642f8fcabc","title":"Limits","url":"/docs/getting-started/providers/xor#limits","content":"The window is large, but shared. NeuroLink allows about 200,000 estimated\ntokens of state, and refuses more before any network call, with\nmax_tokens_exceeded. The size is an estimate, not XOR's tokenizer: about four\ncharacters per token for ASCII text, and one token per character for other\nscripts, which errs toward refusing. The 200,000 figure is a conservative\ndefault under the deployment's 250,000-token prefill, and that prefill is shared\nby the state, the questions and any media.\n\nThe figures in this paragraph are measurements of one live LiteLLM route, not\nlimits of XOR: the model behind the route's name has not been confirmed as XOR,\nand its 262,144-token context length differs from the 250,000-token prefill\nabove. They were taken by sending requests to the route directly rather than\nthrough NeuroLink, which refuses a state of 1.2 million ASCII characters before\nany request, at about 315,000 estimated tokens. A state of about 215,000 tokens\n(1.2 million characters of English) was accepted, and one of about 430,000\ntokens was refused with a 500 whose text says the input is longer than the\nmodel's context length. The estimate is not exact in either direction. English\naveraged about 5.6 characters per token on the route, so the estimate\nover-counts it. Dense JSON averaged about 1.8, so the estimate under-counts it\nby more than half, and a dense state estimated under the limit can still be\nlonger than the server's context. A structured (non-string) state of 100,000\nChinese characters passed NeuroLink's local check and was refused by the\nserver, which counted it as 485,774 tokens.\n\nA state near the limit, or a lot of media, can therefore still be refused by the\nserver as too long. A 413, or a 5xx other than 503 whose message says the\ncontext was too long, arrives as max_tokens_exceeded and is not retried; every\nother reply is classified as in the Errors table below. Built-in consumers treat\na refusal as \"carry on as before\".\n\nA proxy may cap parallel requests.","hierarchy":{"lvl0":"Getting Started","lvl1":"XOR Provider Guide","lvl2":"Limits","lvl3":""}},
7492
7498
  {"objectID":"d3945a40a2095e352b8f5f71228a59bbcb1cb60823696dbe20f3fafffe6b7c29","title":"Errors","url":"/docs/getting-started/providers/xor#errors","content":"| Reply | Kind | Retried |\n| ------------------------------------------------------------ | --------------------------------------------------------- | --------- |\n| 401 | authentication β€” the provider instance stops retrying | no |\n| 403 / 402 | invalid_request β€” fixable; the instance is not disabled | no |\n| 413, or a 5xx other than 503 saying the context was exceeded | max_tokens_exceeded | no |\n| any other 4xx (for example 422, 404) | invalid_request | no |\n| 429 | rate_limit | yes, once |\n| 503 | overloaded | yes, once |\n| other 5xx | server | yes, once |\n| state over the window (local) | max_tokens_exceeded, with no network call | no |\n| unusable media (local) | invalid_request, with no network call | no |\n| no base URL configured (local) | invalid_request, with no network call | no |\n\nA 403 or 402 is deliberately not authentication. On a LiteLLM proxy a 403\nmeans the key's team does not allow the model you asked for\n(team_model_access_denied), and\na 402 means the team has no budget. An admin can fix either, so the provider\ninstance keeps working once it is fixed and is not disabled.","hierarchy":{"lvl0":"Getting Started","lvl1":"XOR Provider Guide","lvl2":"Errors","lvl3":""}},
7493
- {"objectID":"37466cda852e51cad898009d283cae74e18a20774a3ca0fad9f146e3efb8a5a9","title":"Troubleshooting","url":"/docs/getting-started/providers/xor#troubleshooting","content":"XOR requires a base URL β€” set XOR_BASE_URL, or pass\n credentials.xor.baseURL. There is no default endpoint.\nThe XOR base URL must not carry credentials… β€” the base URL has a user\n name, a password, a query string or a fragment. Set it to the origin only, for\n example https://your-proxy.example.com, and give the key through\n XOR_API_KEY or credentials.xor.apiKey.\nThe XOR base URL must start with https:// or http:// β€” the value has no\n scheme (for example xor.internal:8080) or uses another scheme. Add\n https:// or http://.\nThe XOR base URL is not a valid absolute URL β€” the value cannot be\n parsed as a URL. Set it to an absolute origin.\nXOR requires an API key β€” set XOR_API_KEY, or pass\n credentials.xor.apiKey.\nA 401 β€” the endpoint rejected the key. The provider instance stops\n retrying after a rejection, so fix the key and construct a new one.\nA 403 with team_model_access_denied β€” the LiteLLM proxy's team for this\n key does not allow the model you asked for (XOR_MODEL, or xor-1.1 by\n default). Add the model to the team; the instance works again without a\n restart.\nmax_tokens_exceeded β€” the state is over about 200,000 estimated tokens,\n or the state, the questions and the media together are more than the\n deployment's prefill. Shorten the state, or send fewer or smaller images or a\n shorter video.\nImages seem to be ignored β€” a deployment started without\n OPENJEV_IMAGES=1 answers 200 and silently ignores images, and NeuroLink\n cannot detect that. Send a red image and a blue image and check that the two\n answers differ. Video is not affected.\nBuilt-in routing never uses XOR β€” a TypeSafe key, or Laya's key and base\n URL, is also set and takes precedence, or XOR has no base URL.","hierarchy":{"lvl0":"Getting Started","lvl1":"XOR Provider Guide","lvl2":"Troubleshooting","lvl3":""}},
7499
+ {"objectID":"37466cda852e51cad898009d283cae74e18a20774a3ca0fad9f146e3efb8a5a9","title":"Troubleshooting","url":"/docs/getting-started/providers/xor#troubleshooting","content":"XOR requires a base URL β€” set XOR_BASE_URL, or pass\n credentials.xor.baseURL. There is no default endpoint.\nThe XOR base URL must not carry credentials… β€” the base URL has a user\n name, a password, a query string or a fragment. Set it to the origin only, for\n example https://your-proxy.example.com, and give the key through\n XOR_API_KEY or credentials.xor.apiKey.\nThe XOR base URL must start with https:// or http:// β€” the value has no\n scheme (for example xor.internal:8080) or uses another scheme. Add\n https://, or http:// for a server on this machine.\nThe XOR base URL must use https:// unless it points at this machine β€” the\n value is an http:// URL whose host is not localhost, 127.0.0.1 or [::1].\n A plain-http request would send the key and the state unencrypted. Put an\n https:// front on the deployment, or reach it through a port-forward to\n localhost.\nXOR answered with a redirect β€” the endpoint replied 301, 302, 307 or 308.\n The provider does not follow it and does not retry. Set the base URL to the\n address the redirect leads to.\nThe XOR base URL is not a valid absolute URL β€” the value cannot be\n parsed as a URL. Set it to an absolute origin.\nXOR requires an API key β€” set XOR_API_KEY, or pass\n credentials.xor.apiKey.\nA 401 β€” the endpoint rejected the key. The provider instance stops\n retrying after a rejection, so fix the key and construct a new one.\nA 403 with team_model_access_denied β€” the LiteLLM proxy's team for this\n key does not allow the model you asked for (XOR_MODEL, or xor-1.1 by\n default). Add the model to the team; the instance works again without a\n restart.\nmax_tokens_exceeded β€” the state is over about 200,000 estimated tokens,\n or the state, the questions and the media together are more than the\n deployment's prefill. Shorten the state, or send fewer or smaller images or a\n shorter video.","hierarchy":{"lvl0":"Getting Started","lvl1":"XOR Provider Guide","lvl2":"Troubleshooting","lvl3":""}},
7494
7500
  {"objectID":"cdd6e7c83dfa23afa5cf0bb7d23081881600f72a5ac64ca56d383736c209f285","title":"See also","url":"/docs/getting-started/providers/xor#see-also","content":"TypeSafe (Jev) Provider Guide\nLaya Provider Guide\nPerplexity Decisions Provider Guide\nCloudflare Clef Provider Guide\nSubQ Provider Guide\nOpenAI Decisions Provider Guide\nThe decide inference type\nXOR on Hugging Face","hierarchy":{"lvl0":"Getting Started","lvl1":"XOR Provider Guide","lvl2":"See also","lvl3":""}},
7495
7501
  {"objectID":"b62066defb7f4f21e315563cc367d3573fb4aacd3fa38685f76f1a3b110c0437","title":"Z.AI Provider Guide","url":"/docs/getting-started/providers/z-ai","content":"Z.AI Provider Guide\n\nZ.AI is a Tier-2 catalog provider: OpenAI-wire-compatible, so its entire\nintegration is one JSON file (src/lib/providers/catalog/z-ai.json) rather\nthan hand-written code. That file is the source of truth for everything on this\npage.\n\nVerification status: this entry is docs-verified only, not yet\nlive-verified. The vendor's GET https://api.z.ai/api/paas/v4/models needs\na key (it answers HTTP 401 without one), so the model ids come from Z.AI's\npublic docs and the roster has not been checked. No account was created and no\nAPI key was used to build this entry. evidence.liveMatrix is null until\nsomeone runs the live capability matrix with a real key (see\nVerification status below).\n\nKey Facts\nProvider id: z-ai (alias zai)\nProtocol: OpenAI-compatible (/chat/completions). The\n OpenAI Python SDK page\n says \"Z.AI provides interfaces compatible with OpenAI API\" and adds \"In some\n scenarios, there are still differences between Z.AI and OpenAI interfaces, but\n this does not affect overall compatibility.\"\nBase URL: https://api.z.ai/api/paas/v4 β€” the\n Introduction page calls it\n \"Z.ai Platform's general API endpoint\". Its warning says GLM Coding Plan users\n follow the Coding Plan tutorial to configure a dedicated endpoint, and the\n Coding Plan Endpoint Guide lists\n https://api.z.ai/api/coding/paas/v4 for OpenAI Chat Completions. This entry\n uses the general endpoint; Z_AI_BASE_URL overrides it.\nDefault model: glm-5.3 β€” the default of the model parameter in the\n Chat Completion reference\n and the model in its request examples\nModels in catalog: 12, curated from the 21 ids the Chat Completion\n reference lists (14 in its text-model enum, 7 in its vision-model enum). The\n nine ids left out to stay inside the 12-model cap are glm-4.5-x,\n glm-4.5-airx, glm-4.5-flash, glm-4-32b-0414-128k, glm-4.6v,\n glm-4.6v-flash, glm-4.6v-flashx, glm-4.5v and\n autoglm-phone-multilingual\nStreaming: supported β€” the\n Streaming Messages page\n documents stream=True with Server-Sent Events, and the Chat Completion\n reference says the Event Stream ends with a data: [DONE] message\nTool calling: model-dependent β€” the\n Function Calling page\n documents tools and a returned tool_calls array, and the Chat Completion\n reference says of tool_choice \"The default value is auto, and only auto is\n supported.\" For vision models it says tools are \"Only supported by\n GLM-5.3-Flash series, the GLM-4.6V series, and autoglm-phone-multilingual\"\nTools while streaming: supported (true) β€” the\n Thinking Mode page\n gives an Interleaved Thinking + Tool Calling example that sends tools with\n stream=True and reads tool_calls from the streamed deltas. The\n Tool Streaming Output page\n documents a separate tool_stream parameter, which this entry does not set.\n The Thinking Mode page also says \"thinking blocks should be explicitly\n preserved and returned together with the tool results.\", and its example\n appends an assistant message carrying reasoning_content and tool_calls\n before the tool message; this entry does not set\n quirks.replayReasoningContent\nStructured output: supported β€” the\n Structured Output page\n documents response_format set to {\"type\": \"json_object\"}. The Chat\n Completion reference lists text and json_object as the response_format\n type values, so the entry sets quirks.responseFormatDowngrade to send\n json_object for schema requests; generate({ schema }) still validates the\n result client-side. No request with json_schema was sent. The Chat\n Completion reference says of response_format \"Only text models support this\n field.\", and the\n GLM-5.3-Flash/FlashX page\n lists Structured Output among its Capabilities (\"Supports structured output\n formats such as JSON for seamless system integration.\")\nStructured output + tools together: not declared (false) β€” no combined\n probe was possible without credentials\nVision: glm-5.3-flash and glm-5.3-flashx β€” the\n GLM-5.3-Flash/FlashX page\n shows Input Modality \"Video / Image / Text / File\". The GLM-5.3 page says\n \"text-only inputs\", and the pages for the other nine catalog models show\n Input Modalities \"Text\"\nEmbeddings: not declared on this catalog entry\nThinking: not declared (false) β€” the entry sets none of the thinking\n or reasoning_effort request parameters. The Chat Completion reference\n documents both, and the\n GLM-5.3 page says \"GLM-5.3 always\n operates with reasoning enabled\"\nBilling: schema value free-tier, see Billing below\nKey format: none declared. The Introduction page shows the header\n Authorization: Bearer ZAI_API_KEY\n\nQuick Start\nGet an API key\nVisit: https://z.ai/manage-apikey/apikey-list β€” the Quick Start says to access the Z.AI Open Platform (https://z.ai/model-api) and \"Register or Login.\", then to \"Create an API Key\" in the API Keys management page and \"Copy your API Key for use.\"\nAuthentication is HTTP Bearer: the Introduction page (https://docs.z.ai/api-reference/introduction.md) shows the header Authorization: Bearer ZAIAPIKEY\n","hierarchy":{"lvl0":"Getting Started","lvl1":"Z.AI Provider Guide","lvl2":"","lvl3":""}},
7496
7502
  {"objectID":"ca9f10745365c71403f5bcba388684ac70aeb8f48c3d7b3fac85b832a4eead37","title":"Z.AI Provider Guide","url":"/docs/getting-started/providers/z-ai#zai-provider-guide","content":"Z.AI is a Tier-2 catalog provider: OpenAI-wire-compatible, so its entire\nintegration is one JSON file (src/lib/providers/catalog/z-ai.json) rather\nthan hand-written code. That file is the source of truth for everything on this\npage.\n\nVerification status: this entry is docs-verified only, not yet\nlive-verified. The vendor's GET https://api.z.ai/api/paas/v4/models needs\na key (it answers HTTP 401 without one), so the model ids come from Z.AI's\npublic docs and the roster has not been checked. No account was created and no\nAPI key was used to build this entry. evidence.liveMatrix is null until\nsomeone runs the live capability matrix with a real key (see\nVerification status below).","hierarchy":{"lvl0":"Getting Started","lvl1":"Z.AI Provider Guide","lvl2":"Z.AI Provider Guide","lvl3":""}},
@@ -7708,7 +7714,7 @@
7708
7714
  {"objectID":"95eff193e27371f9b79e1e2397bf27919e5e768ccbc6b4c2e6342778504e8671","title":"βœ… Good: Proactive alerting","url":"/docs/guides/enterprise/monitoring#-good-proactive-alerting","content":"alert: HighCosts\n expr: rate(aicosttotal_usd[1h]) * 3600 > 100\n`","hierarchy":{"lvl0":"Guides","lvl1":"Monitoring & Observability Guide","lvl2":"βœ… Good: Proactive alerting","lvl3":""}},
7709
7715
  {"objectID":"cbaee09bec9c8be5decd03d996ea7915c22a6eae1de2585a5c2833ecbbf07b9c","title":"Related Documentation","url":"/docs/guides/enterprise/monitoring#related-documentation","content":"Feature Guides:\nAuto Evaluation - Automated quality scoring and metrics export\nProvider Orchestration - Intelligent routing decisions to monitor\nRedis Conversation Export - Export session data for analysis\n\nEnterprise Guides:\nCost Optimization - Reduce AI costs\nMulti-Provider Failover - High availability\nAudit Trails - Compliance logging\nCompliance - Security and compliance","hierarchy":{"lvl0":"Guides","lvl1":"Monitoring & Observability Guide","lvl2":"Related Documentation","lvl3":""}},
7710
7716
  {"objectID":"ef4cbe78c7b98848293f27348588bd30a419d137f3bebd3320faadd493fcd6ce","title":"Additional Resources","url":"/docs/guides/enterprise/monitoring#additional-resources","content":"Prometheus Docs - Prometheus documentation\nGrafana Docs - Grafana documentation\nCloudWatch Docs - AWS CloudWatch\nApplication Insights - Azure monitoring\n\nNeed Help? Join our GitHub Discussions or open an issue.","hierarchy":{"lvl0":"Guides","lvl1":"Monitoring & Observability Guide","lvl2":"Additional Resources","lvl3":""}},
7711
- {"objectID":"a7aa8312fed00766063cdc68218594e125db0323be61438b8badd2f0eade8e04","title":"Multi-Provider Failover & High Availability","url":"/docs/guides/enterprise/multi-provider-failover","content":"Multi-Provider Failover Guide\n\nBuild resilient AI applications with automatic provider failover and redundancy\n\nOverview\n\nMulti-provider failover enables your application to automatically switch between AI providers when one fails, ensuring high availability and reliability. NeuroLink provides built-in failover capabilities with configurable priorities, conditions, and retry strategies.\n\nKey Benefits\nπŸ”’ 99.9%+ Uptime: Automatic failover when providers are down\n⚑ Zero Downtime: Seamless switching between providers\nπŸ’° Cost Optimization: Route to cheaper providers when available\n🌍 Geographic Redundancy: Distribute across regions\nπŸ”„ Smart Retries: Exponential backoff with configurable limits\nπŸ“Š Failover Metrics: Track provider reliability\n\nUse Cases\nProduction Applications: Ensure critical AI features never go down\nCost Optimization: Use expensive providers only when needed\nGeographic Distribution: Serve users from nearest region\nA/B Testing: Route traffic between providers for comparison\nCompliance: Route EU traffic to GDPR-compliant providers\n\nQuick Start\n\nBasic Failover Configuration\n\nTest Failover\n\nFailover Strategies\nPriority-Based Failover (Recommended)\n\nTry providers in priority order until one succeeds. Self-hosted providers (LiteLLM, Ollama) are recommended as primary to avoid external rate limits:\nCondition-Based Routing\n\nRoute to specific providers based on request conditions.\nSame priority: Both Mistral and OpenAI have priority 1, but conditions determine which one is used.\nGDPR compliance: Route EU users to Mistral AI (European provider) for automatic GDPR compliance.\nRegional routing: Non-EU users go to OpenAI. Multiple providers at same priority with mutually exclusive conditions.\nUniversal fallback: Google AI (priority 2) has no condition, so it's used if both priority 1 providers fail.\nPass routing metadata: Include userRegion in metadata so conditions can access it for routing decisions.\nCost-Based Routing\n\nTry cheaper providers first, fallback to premium providers.\nLoad-Balanced Failover\n\nCombine load balancing with failover.\n\nRetry Configuration\n\nExponential Backoff\n\nSelective Retry\nRetryable errors: Transient failures worth retrying. Network errors (ECONNREFUSED, ETIMEDOUT) and server issues (429, 5xx) often resolve on retry.\nNon-retryable errors: Client-side errors that won't be fixed by retrying. Invalid requests (400), authentication failures (401), and authorization issues (403) require code changes.\n\nCustom Retry Logic\n\nProvider Health Checks\n\nActive Health Monitoring\n\nCircuit Breaker Pattern\n\nProduction Patterns\n\nPattern 1: High Availability Setup\n\nPattern 2: Cost-Optimized Failover\n\nPattern 3: Geographic Routing\n\nPattern 4: Model-Specific Failover\n\nMonitoring and Metrics\n\nTrack Failover Events\n\nFailover Metrics Dashboard\n\nBest Practices\nβœ… Always Configure Multiple Providers\nβœ… Use Health Checks in Production\nβœ… Implement Circuit Breakers\nβœ… Monitor Failover Events\nβœ… Test Failover Regularly\n\nTroubleshooting\n\nIssue 1: Failover Not Triggering\n\nProblem: Requests fail without trying fallback providers.\n\nSolution:\n\nIssue 2: Too Many Retry Attempts\n\nProblem: Requests take too long due to excessive retries.\n\nSolution:\n\nIssue 3: Circuit Breaker Stuck Open\n\nProblem: Provider marked as failed even when healthy.\n\nSolution:\n\nRelated Documentation\n\nFeature Guides:\nProvider Orchestration - Intelligent provider selection and routing\nRegional Streaming - Region-specific failover strategies\nAuto Evaluation - Validate failover quality\n\nEnterprise Guides:\nLoad Balancing Guide - Distribution strategies\nCost Optimization - Reduce AI costs\nProvider Setup - Provider configuration\nMonitoring Guide - Observability and metrics\n\nAdditional Resources\nNeuroLink GitHub - Source code\nGitHub Discussions - Community support\nIssues - Report bugs\n\nNeed Help? Join our GitHub Discussions or open an issue.","hierarchy":{"lvl0":"Guides","lvl1":"Multi-Provider Failover & High Availability","lvl2":"","lvl3":""}},
7717
+ {"objectID":"a7aa8312fed00766063cdc68218594e125db0323be61438b8badd2f0eade8e04","title":"Multi-Provider Failover & High Availability","url":"/docs/guides/enterprise/multi-provider-failover","content":"Multi-Provider Failover Guide\n\nBuild resilient AI applications with automatic provider failover and redundancy\n\nOverview\n\nMulti-provider failover enables your application to automatically switch between AI providers when one fails, ensuring high availability and reliability. NeuroLink provides built-in failover capabilities with configurable priorities, conditions, and retry strategies.\n\nKey Benefits\nπŸ”’ 99.9%+ Uptime: Automatic failover when providers are down\n⚑ Zero Downtime: Seamless switching between providers\nπŸ’° Cost Optimization: Route to cheaper providers when available\n🌍 Geographic Redundancy: Distribute across regions\nπŸ”„ Smart Retries: Exponential backoff with configurable limits\nπŸ“Š Failover Metrics: Track provider reliability\n\nUse Cases\nProduction Applications: Ensure critical AI features never go down\nCost Optimization: Use expensive providers only when needed\nGeographic Distribution: Serve users from nearest region\nA/B Testing: Route traffic between providers for comparison\nCompliance: Route EU traffic to GDPR-compliant providers\n\nQuick Start\n\nBasic Failover Configuration\n\nTest Failover\n\nFailover Strategies\nPriority-Based Failover (Recommended)\n\nTry providers in priority order until one succeeds. Self-hosted providers (LiteLLM, Ollama) are recommended as primary to avoid external rate limits:\nCondition-Based Routing\n\nRoute to specific providers based on request conditions.\nSame priority: Both Mistral and OpenAI have priority 1, but conditions determine which one is used.\nGDPR compliance: Route EU users to Mistral AI (European provider) for automatic GDPR compliance.\nRegional routing: Non-EU users go to OpenAI. Multiple providers at same priority with mutually exclusive conditions.\nUniversal fallback: Google AI (priority 2) has no condition, so it's used if both priority 1 providers fail.\nPass routing metadata: Include userRegion in metadata so conditions can access it for routing decisions.\nCost-Based Routing\n\nTry cheaper providers first, fallback to premium providers.\nLoad-Balanced Failover\n\nCombine load balancing with failover.\n\nRetry Configuration\n\nExponential Backoff\n\nSelective Retry\nRetryable errors: Transient failures worth retrying. Network errors (ECONNREFUSED, ETIMEDOUT) and server issues (429, 5xx) often resolve on retry.\nNon-retryable errors: Client-side errors that won't be fixed by retrying. Invalid requests (400), authentication failures (401), and authorization issues (403) require code changes.\n\nCustom Retry Logic\n\nProvider Health Checks\n\nActive Health Monitoring\n\nCircuit Breaker Pattern\n\nPlanned: provider-level circuit breakers, getCircuitState() and resetCircuit() are not in the current release. The only circuit-breaker accessors today are per tool: getToolCircuitBreakerStatus() and resetToolCircuitBreaker(toolName).\n\nProduction Patterns\n\nPattern 1: High Availability Setup\n\nPattern 2: Cost-Optimized Failover\n\nPattern 3: Geographic Routing\n\nPattern 4: Model-Specific Failover\n\nMonitoring and Metrics\n\nTrack Failover Events\n\nFailover Metrics Dashboard\n\nBest Practices\nβœ… Always Configure Multiple Providers\nβœ… Use Health Checks in Production\nβœ… Implement Circuit Breakers\nβœ… Monitor Failover Events\nβœ… Test Failover Regularly\n\nTroubleshooting\n\nIssue 1: Failover Not Triggering\n\nProblem: Requests fail without trying fallback providers.\n\nSolution:\n\nIssue 2: Too Many Retry Attempts\n\nProblem: Requests take too long due to excessive retries.\n\nSolution:\n\nIssue 3: Circuit Breaker Stuck Open\n\nProblem: Provider marked as failed even when healthy.\n\nSolution:\n\nPlanned: provider-level circuit breakers and resetCircuit() are not in the current release.\n\nRelated Documentation\n\nFeature Guides:\nProvider Orchestration - Intelligent provider selection and routing\nRegional Streaming - Region-specific failover strategies\nAuto Evaluation - Validate failover quality\n\nEnterprise Guides:\nLoad Balancing Guide - Distribution strategies\nCost Optimization - Reduce AI costs\nProvider Setup - Provider configuration\nMonitoring Guide - Observability and metrics\n\nAdditional Resources\nNeuroLink GitHub - Source code\nGitHub Discussions - Community support\nIssues - Report bugs\n\nNeed Help? Join our GitHub Discussions or open an issue.","hierarchy":{"lvl0":"Guides","lvl1":"Multi-Provider Failover & High Availability","lvl2":"","lvl3":""}},
7712
7718
  {"objectID":"8fe7b07655a07a1fbcaf7565ee46c9b7f9211e9503db206462227e9b2d9e06d5","title":"Multi-Provider Failover Guide","url":"/docs/guides/enterprise/multi-provider-failover#multi-provider-failover-guide","content":"Build resilient AI applications with automatic provider failover and redundancy","hierarchy":{"lvl0":"Guides","lvl1":"Multi-Provider Failover & High Availability","lvl2":"Multi-Provider Failover Guide","lvl3":""}},
7713
7719
  {"objectID":"d07da2934e17b18079531f8310aa3f3ba6c67671508f9ee42e38af5066942cca","title":"Overview","url":"/docs/guides/enterprise/multi-provider-failover#overview","content":"Multi-provider failover enables your application to automatically switch between AI providers when one fails, ensuring high availability and reliability. NeuroLink provides built-in failover capabilities with configurable priorities, conditions, and retry strategies.","hierarchy":{"lvl0":"Guides","lvl1":"Multi-Provider Failover & High Availability","lvl2":"Overview","lvl3":""}},
7714
7720
  {"objectID":"157feae4cc1f45058f79d0903b5d836be6fbde2c37bb7cc375de37c2727e3994","title":"Key Benefits","url":"/docs/guides/enterprise/multi-provider-failover#key-benefits","content":"πŸ”’ 99.9%+ Uptime: Automatic failover when providers are down\n⚑ Zero Downtime: Seamless switching between providers\nπŸ’° Cost Optimization: Route to cheaper providers when available\n🌍 Geographic Redundancy: Distribute across regions\nπŸ”„ Smart Retries: Exponential backoff with configurable limits\nπŸ“Š Failover Metrics: Track provider reliability","hierarchy":{"lvl0":"Guides","lvl1":"Multi-Provider Failover & High Availability","lvl2":"Key Benefits","lvl3":""}},
@@ -7718,9 +7724,10 @@
7718
7724
  {"objectID":"069002a6eb4779a6146ac0a2ef6ee6c3247aee6438e88f344f4d34ef71e0ecf3","title":"3. Cost-Based Routing","url":"/docs/guides/enterprise/multi-provider-failover#3-cost-based-routing","content":"Try cheaper providers first, fallback to premium providers.","hierarchy":{"lvl0":"Guides","lvl1":"Multi-Provider Failover & High Availability","lvl2":"3. Cost-Based Routing","lvl3":""}},
7719
7725
  {"objectID":"4d65d193fea22dea8f670915e14445c8a7ef89b9bd3054e3f2f4eb6278c02e1f","title":"4. Load-Balanced Failover","url":"/docs/guides/enterprise/multi-provider-failover#4-load-balanced-failover","content":"Combine load balancing with failover.","hierarchy":{"lvl0":"Guides","lvl1":"Multi-Provider Failover & High Availability","lvl2":"4. Load-Balanced Failover","lvl3":""}},
7720
7726
  {"objectID":"219f642911e59cbccf69d0892d89d0fa44968c900fe9cabd43e2fdc1619d1451","title":"Selective Retry","url":"/docs/guides/enterprise/multi-provider-failover#selective-retry","content":"Retryable errors: Transient failures worth retrying. Network errors (ECONNREFUSED, ETIMEDOUT) and server issues (429, 5xx) often resolve on retry.\nNon-retryable errors: Client-side errors that won't be fixed by retrying. Invalid requests (400), authentication failures (401), and authorization issues (403) require code changes.","hierarchy":{"lvl0":"Guides","lvl1":"Multi-Provider Failover & High Availability","lvl2":"Selective Retry","lvl3":""}},
7727
+ {"objectID":"c6b5d4d6128064a55ec956af974cbfafc6bc9c483a0dd2461f3eaaae51b7768a","title":"Circuit Breaker Pattern","url":"/docs/guides/enterprise/multi-provider-failover#circuit-breaker-pattern","content":"Planned: provider-level circuit breakers, getCircuitState() and resetCircuit() are not in the current release. The only circuit-breaker accessors today are per tool: getToolCircuitBreakerStatus() and resetToolCircuitBreaker(toolName).","hierarchy":{"lvl0":"Guides","lvl1":"Multi-Provider Failover & High Availability","lvl2":"Circuit Breaker Pattern","lvl3":""}},
7721
7728
  {"objectID":"db24cb6dffef1677cccad00530567ba98fd8a1e0636af3d09dfabe115cbbad7d","title":"Issue 1: Failover Not Triggering","url":"/docs/guides/enterprise/multi-provider-failover#issue-1-failover-not-triggering","content":"Problem: Requests fail without trying fallback providers.\n\nSolution:","hierarchy":{"lvl0":"Guides","lvl1":"Multi-Provider Failover & High Availability","lvl2":"Issue 1: Failover Not Triggering","lvl3":""}},
7722
7729
  {"objectID":"b58baebb594528810be743104040d166313d090b6ad8cc772658802dcda0037b","title":"Issue 2: Too Many Retry Attempts","url":"/docs/guides/enterprise/multi-provider-failover#issue-2-too-many-retry-attempts","content":"Problem: Requests take too long due to excessive retries.\n\nSolution:","hierarchy":{"lvl0":"Guides","lvl1":"Multi-Provider Failover & High Availability","lvl2":"Issue 2: Too Many Retry Attempts","lvl3":""}},
7723
- {"objectID":"7a84eabfdea6feb9da4776623e0c3b218281f8c48b5b913102f1c37df8de84ea","title":"Issue 3: Circuit Breaker Stuck Open","url":"/docs/guides/enterprise/multi-provider-failover#issue-3-circuit-breaker-stuck-open","content":"Problem: Provider marked as failed even when healthy.\n\nSolution:","hierarchy":{"lvl0":"Guides","lvl1":"Multi-Provider Failover & High Availability","lvl2":"Issue 3: Circuit Breaker Stuck Open","lvl3":""}},
7730
+ {"objectID":"7a84eabfdea6feb9da4776623e0c3b218281f8c48b5b913102f1c37df8de84ea","title":"Issue 3: Circuit Breaker Stuck Open","url":"/docs/guides/enterprise/multi-provider-failover#issue-3-circuit-breaker-stuck-open","content":"Problem: Provider marked as failed even when healthy.\n\nSolution:\n\nPlanned: provider-level circuit breakers and resetCircuit() are not in the current release.","hierarchy":{"lvl0":"Guides","lvl1":"Multi-Provider Failover & High Availability","lvl2":"Issue 3: Circuit Breaker Stuck Open","lvl3":""}},
7724
7731
  {"objectID":"53e9f1ab457622770a84e8208a9c6646d88c5367b133ce18fdd209fcc8ac36cd","title":"Related Documentation","url":"/docs/guides/enterprise/multi-provider-failover#related-documentation","content":"Feature Guides:\nProvider Orchestration - Intelligent provider selection and routing\nRegional Streaming - Region-specific failover strategies\nAuto Evaluation - Validate failover quality\n\nEnterprise Guides:\nLoad Balancing Guide - Distribution strategies\nCost Optimization - Reduce AI costs\nProvider Setup - Provider configuration\nMonitoring Guide - Observability and metrics","hierarchy":{"lvl0":"Guides","lvl1":"Multi-Provider Failover & High Availability","lvl2":"Related Documentation","lvl3":""}},
7725
7732
  {"objectID":"843b846d091ce2aea4a3b16b46c40a60124ecc36599c7ab2c488c10b06bb0b58","title":"Additional Resources","url":"/docs/guides/enterprise/multi-provider-failover#additional-resources","content":"NeuroLink GitHub - Source code\nGitHub Discussions - Community support\nIssues - Report bugs\n\nNeed Help? Join our GitHub Discussions or open an issue.","hierarchy":{"lvl0":"Guides","lvl1":"Multi-Provider Failover & High Availability","lvl2":"Additional Resources","lvl3":""}},
7726
7733
  {"objectID":"7ba03c1cfac1073398597d634c8e815f71eff2e87ee7b45507767443d24a44f1","title":"Multi-Region Deployment Guide","url":"/docs/guides/enterprise/multi-region","content":"Multi-Region Deployment Guide\n\nDeploy AI applications globally with optimal latency, compliance, and reliability\n\nOverview\n\nMulti-region deployment distributes your AI application across geographic locations to minimize latency for global users, meet data residency requirements, and ensure high availability. This guide covers architecture patterns, routing strategies, and production deployment.\n\nKey Benefits\n⚑ Lower Latency: Serve users from nearest region (50-200ms improvement)\n🌍 Data Residency: Meet GDPR/compliance requirements\nπŸ”’ High Availability: Failover between regions\nπŸ“Š Load Distribution: Balance traffic globally\nπŸ’° Cost Optimization: Use cheapest region per location\nπŸš€ Performance: Parallel processing across regions\n\nTypical Latency Improvements\n\nQuick Start\n\nBasic Multi-Region Setup\n\nRegion Detection\n\nIP-Based Geolocation\n\nCloudFlare Workers Integration\n\nProvider-Specific Multi-Region\n\nOpenAI Multi-Region\n\nOpenAI doesn't have explicit region selection, but uses global load balancing.\n\nGoogle Cloud Vertex AI (Multi-Region)\n\nVertex AI supports explicit region selection.\n\nMistral AI (European Provider)\n\nMistral AI is EU-based, perfect for European users.\n\nDeployment Patterns\n\nPattern 1: Edge Deployment\n\nDeploy at edge locations (Cloudflare Workers, Vercel Edge).\n\nPattern 2: Kubernetes Multi-Region\n\nDeploy across multiple Kubernetes clusters.\n\nPattern 3: Multi-Cloud Deployment\n\nDistribute across AWS, GCP, Azure.\n\nLatency Optimization\n\nMeasure Latency by Region\n\nDynamic Region Selection\n\nRoute to fastest region based on real-time latency.\n\nData Residency & Compliance\n\nGDPR-Compliant Regional Routing\n\nRegion-Specific Data Storage\n\nMonitoring Multi-Region\n\nRegional Metrics Dashboard\n\nBest Practices\nβœ… Always Have Regional Fallbacks\nβœ… Monitor Latency by Region\nβœ… Enforce Data Residency\nβœ… Test Failover Between Regions\nβœ… Cache Regionally\n\nRelated Documentation\nMulti-Provider Failover - Automatic failover\nLoad Balancing - Distribution strategies\nCompliance Guide - GDPR data residency\nMonitoring - Regional monitoring\n\nAdditional Resources\nAWS Global Infrastructure - AWS regions\nGCP Locations - Google Cloud regions\nCloudflare Network Map - Edge locations\n\nNeed Help? Join our GitHub Discussions or open an issue.","hierarchy":{"lvl0":"Guides","lvl1":"Multi-Region Deployment Guide","lvl2":"","lvl3":""}},
@@ -8637,6 +8644,7 @@
8637
8644
  {"objectID":"b705813d5bc4a2b32142ded829b8021cb0917725ed6d2b44c2b63690af08408c","title":"Newline-Delimited JSON (NDJSON)","url":"/docs/guides/server-adapters/streaming#newline-delimited-json-ndjson","content":"Content-Type: application/x-ndjson\n\nBest for:\nServer-to-server communication\nCustom stream processing\nSimpler parsing logic\nHTTP/2 connections\n\nFormat example:\n\nClient-side usage:","hierarchy":{"lvl0":"Guides","lvl1":"Streaming Guide","lvl2":"Newline-Delimited JSON (NDJSON)","lvl3":""}},
8638
8645
  {"objectID":"cfeacaf59eff55ad439d999dee3f0ffac16abea4a53468d86e071cf433a153e6","title":"StreamingConfig","url":"/docs/guides/server-adapters/streaming#streamingconfig","content":"Configure streaming behavior in route definitions:","hierarchy":{"lvl0":"Guides","lvl1":"Streaming Guide","lvl2":"StreamingConfig","lvl3":""}},
8639
8646
  {"objectID":"f357ec16e6539a08ee6abef4d1984396e1bba956cdb38815c167d9071f9071de","title":"Configuration Fields","url":"/docs/guides/server-adapters/streaming#configuration-fields","content":"| Field | Type | Default | Description |\n| ------------------- | ------------------------------------------------- | ----------- | ---------------------------------- |\n| enabled | boolean | true | Enable streaming for this route |\n| contentType | \"text/event-stream\" \\| \"application/x-ndjson\" | SSE | Stream format |\n| keepAliveInterval | number | undefined | Interval for keep-alive pings (ms) |","hierarchy":{"lvl0":"Guides","lvl1":"Streaming Guide","lvl2":"Configuration Fields","lvl3":""}},
8647
+ {"objectID":"b6609bca09760918eeadbe4bbb9719956ed40138b8cb15092c4325c517e5a347","title":"Tool Call Streaming","url":"/docs/guides/server-adapters/streaming#tool-call-streaming","content":"Planned: streamWithTools() and its text-delta / tool-call / tool-result event stream are not in the current release. Today, call stream() for the text and listen for tool:start and tool:end on neurolink.getEventEmitter() to report tool activity.","hierarchy":{"lvl0":"Guides","lvl1":"Streaming Guide","lvl2":"Tool Call Streaming","lvl3":""}},
8640
8648
  {"objectID":"a2904cd94a81dfad88f6951167bc3a01cfcacf0a54fd7aba46adcb70df2db300","title":"Using pipeAsyncIterableToDataStream","url":"/docs/guides/server-adapters/streaming#using-pipeasynciterabletodatastream","content":"For simpler cases, use the helper function:","hierarchy":{"lvl0":"Guides","lvl1":"Streaming Guide","lvl2":"Using pipeAsyncIterableToDataStream","lvl3":""}},
8641
8649
  {"objectID":"6f3b352d7e81788c18106fb78bc8c9ee7f3333ac4b14050f8698fab172d13835","title":"Client-Side Consumption (Browser)","url":"/docs/guides/server-adapters/streaming#client-side-consumption-browser","content":"Using EventSource (SSE):\n\nUsing Fetch API (for POST requests):\n\nReact Hook Example:","hierarchy":{"lvl0":"Guides","lvl1":"Streaming Guide","lvl2":"Client-Side Consumption (Browser)","lvl3":""}},
8642
8650
  {"objectID":"118c2778817ca259b9ef809e6d0acbb7bb1a5598f56dad92c19272758d799979","title":"WebStreamWriter (Legacy)","url":"/docs/guides/server-adapters/streaming#webstreamwriter-legacy","content":"For simple SSE streaming without the full Data Stream Protocol:","hierarchy":{"lvl0":"Guides","lvl1":"Streaming Guide","lvl2":"WebStreamWriter (Legacy)","lvl3":""}},
@@ -8920,7 +8928,7 @@
8920
8928
  {"objectID":"b6314cb8e028cd9c91d2a52b93f00d448d7571745f9c80f9906caebc3a20b1f9","title":"Expected Results","url":"/docs/mcp/optimization#expected-results-1","content":"CLI: 12s β†’ 7s (additional 42% reduction)\nSDK: 23s β†’ 14s (additional 39% reduction)","hierarchy":{"lvl0":"Mcp","lvl1":"NeuroLink MCP Latency Optimization Implementation Guide","lvl2":"Expected Results","lvl3":""}},
8921
8929
  {"objectID":"6494a84cfc812f27703d2520acb0379a91686feb05b8e594065c6698db3033de","title":"Files to Modify","url":"/docs/mcp/optimization#files-to-modify-2","content":"src/cli/index.ts - Add CLI performance flags and mode logic","hierarchy":{"lvl0":"Mcp","lvl1":"NeuroLink MCP Latency Optimization Implementation Guide","lvl2":"Files to Modify","lvl3":""}},
8922
8930
  {"objectID":"61c9e3dba7fdc76eac512bd8a95af9a2bb3e5b3212ee78abdca5cf301ce0dc37","title":"Concept Implementation","url":"/docs/mcp/optimization#concept-implementation-2","content":"Provide explicit user control over tool loading through CLI flags:","hierarchy":{"lvl0":"Mcp","lvl1":"NeuroLink MCP Latency Optimization Implementation Guide","lvl2":"Concept Implementation","lvl3":""}},
8923
- {"objectID":"26c79c5bb7588d07558686142d0e9e78bc5a6e3580de5eb7859fae04be5c311d","title":"Detailed Code Changes","url":"/docs/mcp/optimization#detailed-code-changes-2","content":"File: src/cli/index.ts\n\nAdd CLI performance options:","hierarchy":{"lvl0":"Mcp","lvl1":"NeuroLink MCP Latency Optimization Implementation Guide","lvl2":"Detailed Code Changes","lvl3":""}},
8931
+ {"objectID":"26c79c5bb7588d07558686142d0e9e78bc5a6e3580de5eb7859fae04be5c311d","title":"Detailed Code Changes","url":"/docs/mcp/optimization#detailed-code-changes-2","content":"File: src/cli/index.ts\n\nAdd CLI performance options. Planned: initializeMCP() does not exist as a public method in the current release. MCP initialises on first use by generate(), stream(), getMCPStatus() and similar calls.","hierarchy":{"lvl0":"Mcp","lvl1":"NeuroLink MCP Latency Optimization Implementation Guide","lvl2":"Detailed Code Changes","lvl3":""}},
8924
8932
  {"objectID":"57e8f069eca59ec85810ddac37e41a07f7d34e19799b348ce3a412a059235433","title":"Expected Results","url":"/docs/mcp/optimization#expected-results-2","content":"CLI Speed Mode: 7s β†’ 1-2s (built-in tools only)\nCLI Selective: 7s β†’ 3-5s (based on tools needed)","hierarchy":{"lvl0":"Mcp","lvl1":"NeuroLink MCP Latency Optimization Implementation Guide","lvl2":"Expected Results","lvl3":""}},
8925
8933
  {"objectID":"16a39542059f14527055004277736c659dc32b665bfa4322f0f737ea53cc56ad","title":"Files to Modify","url":"/docs/mcp/optimization#files-to-modify-3","content":"src/lib/neurolink.ts - Add background warmup and smart initialization","hierarchy":{"lvl0":"Mcp","lvl1":"NeuroLink MCP Latency Optimization Implementation Guide","lvl2":"Files to Modify","lvl3":""}},
8926
8934
  {"objectID":"f4a87b4490067daade436b288b54b932747d44bc05009a8b63f83502d1634c50","title":"Concept Implementation","url":"/docs/mcp/optimization#concept-implementation-3","content":"Start MCP initialization in the background during SDK instantiation, before any user requests:","hierarchy":{"lvl0":"Mcp","lvl1":"NeuroLink MCP Latency Optimization Implementation Guide","lvl2":"Concept Implementation","lvl3":""}},
@@ -8965,7 +8973,7 @@
8965
8973
  {"objectID":"ac893b5f072fde8773a896fea14954f85a342e8c847cf35d8bbc6bd57baa0db8","title":"Security Features","url":"/docs/mcp/overview#security-features","content":"Input Validation: Comprehensive validation of all tool inputs\nOutput Sanitization: Clean and validate all tool outputs\nContext Boundaries: Prevent information leakage between contexts\nError Information: Sanitized error messages without sensitive data","hierarchy":{"lvl0":"Mcp","lvl1":"πŸ”§ MCP Foundation (Model Context Protocol)","lvl2":"Security Features","lvl3":""}},
8966
8974
  {"objectID":"ca790b1d1346aa0c03c289f273f9357e1ce40d5f5febc16c4b2a656e7e126890","title":"Performance Tracking","url":"/docs/mcp/overview#performance-tracking","content":"Execution Metrics: Track tool execution time and success rates\nUsage Analytics: Monitor tool usage patterns and trends\nError Analysis: Comprehensive error tracking and analysis\nPerformance Optimization: Identify and optimize slow operations","hierarchy":{"lvl0":"Mcp","lvl1":"πŸ”§ MCP Foundation (Model Context Protocol)","lvl2":"Performance Tracking","lvl3":""}},
8967
8975
  {"objectID":"e215ee8a243dd38779b738980379e271e93e4c51c4e1d36f07a60320639f15e7","title":"Monitoring Features","url":"/docs/mcp/overview#monitoring-features","content":"Real-time Dashboards: Live monitoring of tool performance\nHistorical Analysis: Long-term trend analysis and reporting\nAlert System: Automated alerts for performance issues\nUsage Reports: Detailed usage and cost reporting","hierarchy":{"lvl0":"Mcp","lvl1":"πŸ”§ MCP Foundation (Model Context Protocol)","lvl2":"Monitoring Features","lvl3":""}},
8968
- {"objectID":"689f8a5730ee6d983fbfac172c3c97a7cb11edbe14ecafacc480417fa530193c","title":"Direct Import Approach (1-2 weeks)","url":"/docs/mcp/overview#direct-import-approach-1-2-weeks","content":"BREAKTHROUGH: Instead of migrating 30+ tools (8-10 weeks), we now directly import Lighthouse's 60+ production-ready tools into NeuroLink.","hierarchy":{"lvl0":"Mcp","lvl1":"πŸ”§ MCP Foundation (Model Context Protocol)","lvl2":"Direct Import Approach (1-2 weeks)","lvl3":""}},
8976
+ {"objectID":"689f8a5730ee6d983fbfac172c3c97a7cb11edbe14ecafacc480417fa530193c","title":"Direct Import Approach (1-2 weeks)","url":"/docs/mcp/overview#direct-import-approach-1-2-weeks","content":"BREAKTHROUGH: Instead of migrating 30+ tools (8-10 weeks), we now directly import Lighthouse's 60+ production-ready tools into NeuroLink.\n\nPlanned: registerLighthouseServer() is not in the current release. Today a server is added with addExternalMCPServer() or addInMemoryMCPServer().","hierarchy":{"lvl0":"Mcp","lvl1":"πŸ”§ MCP Foundation (Model Context Protocol)","lvl2":"Direct Import Approach (1-2 weeks)","lvl3":""}},
8969
8977
  {"objectID":"4f931e0b60047ed3380c362447cc2c91a559379753e6434352c8280b276d99ba","title":"Payment Analytics Tools:","url":"/docs/mcp/overview#payment-analytics-tools","content":"get-success-rate-by-time - Payment success rates over time\nget-payment-method-wise-sr - Success rates by payment method\nget-transaction-trends - Transaction trend analysis\nget-failure-transactional-data - Failed transaction analysis\nget-gmv-order-value-payment-wise - Revenue by payment method","hierarchy":{"lvl0":"Mcp","lvl1":"πŸ”§ MCP Foundation (Model Context Protocol)","lvl2":"Payment Analytics Tools:","lvl3":""}},
8970
8978
  {"objectID":"365190926a8afaff68470383c9ab3809c75566342757a3aced99a7cc191fbcda","title":"E-commerce Analytics Tools:","url":"/docs/mcp/overview#e-commerce-analytics-tools","content":"get-conversion-rates - Shop conversion metrics\nprocess-analytics-data - Process raw analytics\nget-order-stats - Order statistics and trends\nget-merchant-data - Merchant information\nget-shop-performance - Shop performance metrics","hierarchy":{"lvl0":"Mcp","lvl1":"πŸ”§ MCP Foundation (Model Context Protocol)","lvl2":"E-commerce Analytics Tools:","lvl3":""}},
8971
8979
  {"objectID":"84414f11aa6d9670a28ce6185efe97df59fab48319fcab41bf6158a1fd2b9ef5","title":"Platform Integration Tools:","url":"/docs/mcp/overview#platform-integration-tools","content":"Shopify: Complete Shopify store integration\nWooCommerce: WooCommerce integration\nMagento: Magento store integration","hierarchy":{"lvl0":"Mcp","lvl1":"πŸ”§ MCP Foundation (Model Context Protocol)","lvl2":"Platform Integration Tools:","lvl3":""}},
@@ -9831,7 +9839,7 @@
9831
9839
  {"objectID":"205e4e44d27692634aa5454565d9f060ceb88cdac97e7d37622bc5b9a1eefeb6","title":"Verification commands","url":"/docs/provider-integration/tiers/tier-1-aggregator-passthrough#verification-commands","content":"`bash","hierarchy":{"lvl0":"Provider Integration","lvl1":"Tier 1 β€” Aggregator Passthrough","lvl2":"Verification commands","lvl3":""}},
9832
9840
  {"objectID":"09ead22698863d776e82e2f0f3dfdd9a596f39cc106302a02c51a6ef37b436de","title":"LiteLLM example","url":"/docs/provider-integration/tiers/tier-1-aggregator-passthrough#litellm-example","content":"pnpm run cli generate \"hello\" --provider litellm --model","hierarchy":{"lvl0":"Provider Integration","lvl1":"Tier 1 β€” Aggregator Passthrough","lvl2":"LiteLLM example","lvl3":""}},
9833
9841
  {"objectID":"f46ff1668fbf30431a2b6578654212feb2043845eb7a28281e47075703948472","title":"OpenRouter example","url":"/docs/provider-integration/tiers/tier-1-aggregator-passthrough#openrouter-example","content":"pnpm run cli generate \"hello\" --provider openrouter --model /\n\n\nBoth should return a normal GenerateResult with non-empty content`. If\neither 400s with an \"unknown model\" style error, the aggregator doesn't\nactually serve that model yet β€” fix the aggregator-side config, not\nNeuroLink.","hierarchy":{"lvl0":"Provider Integration","lvl1":"Tier 1 β€” Aggregator Passthrough","lvl2":"OpenRouter example","lvl3":""}},
9834
- {"objectID":"0c443abf0cfa1b31edc3337559bddbf37453d87732cfd17b08d461f55c77b195","title":"Tier 2 β€” Catalog Entry","url":"/docs/provider-integration/tiers/tier-2-catalog-entry","content":"Tier 2 β€” Catalog Entry\n\nWhen this applies: the vendor speaks the OpenAI /v1/chat/completions\nwire format (Bearer auth, standard SSE, standard JSON body) and needs\nzero behavioral overrides β€” no custom adjustRequestBody, no\nadjustResponseFormat, no nonstandard auth header, no adjustBodyAfter400.\nThis is the Groq/xAI/Together AI/Fireworks/Perplexity/Cloudflare/Mistral\nshape from before the redesign β€” now expressed as one JSON file instead of\na hand-written subclass (see ../adr/0002-catalog-over-subclass-default.md\nand the single-JSON spec at\ndocs/superpowers/plans/2026-08-28-provider-json-catalog-spec.md).\n\nIf you're not sure whether your provider is quirk-free, start writing the\nJSON anyway β€” if it turns out you need a hook, migrate to Tier 3 instead of\nforcing the quirk into the catalog shape.\n\nFiles touched (end state)\n\n| # | File | Change |\n| --- | ------------------------------------- | ------------------------------- |\n| 1 | src/lib/providers/catalog/<id>.json | The entire integration, as data |\n\nThat is the whole list. Everything else is generated or derived:\npnpm run codegen:catalog writes the AIProviderName member, the\n <Name>Models enum and the NeurolinkCredentials key into marked\n regions, plus the generated catalog index. Pre-commit and CI fail on\n stale output, so it can't drift.\nThe runtime loader builds the registry entry, descriptor, config options,\n context windows, pricing, vision map and model choices from the JSON.\nThe test suites derive their spec rows, matrix rows and counts from the\n built catalog.\n\nScaffold it with:\n\nTier 2 emits exactly two files: a pre-filled <id>.json (with TODO markers\nwhere only a live probe can supply the truth) and a short checklist. The\nJSON deliberately fails schema validation until every TODO is replaced.\n\nCount pins β€” nothing to bump\n\nThere are none left. The wiring and descriptor suites compute their\nexpected totals from CATALOG_PROVIDER_IDS, and the matrix rows spread\nfrom the catalog with a completeness guard that throws if any catalog\nprovider is missing. Adding a provider changes no test file.\n\nsrc/lib/factories/providerRegistry.ts isn't in the table either:\n_doRegister() loops over the catalog and registers every entry\ngenerically.\n\nOne historical exception worth re-checking: commandFactory.ts's separate\nsetup [provider] subcommand hand-hardcoded its own provider-choices array.\nThat was migrated to derive from the enum (PR #1583) β€” confirm it still\ndoes before assuming you need a manual edit.\n\nThe JSON, field by field\n\nid, displayName, aliases, tier, then:\n\nwire β€” baseURL for the normal case. Env var names derive by\nconvention (<CONSTANT_CASE(id)>_API_KEY / _BASE_URL / _MODEL); set\nenvOverrides only for a vendor that breaks it. For a URL computed from\nanother credential (Cloudflare's account id) use baseURLTemplate plus\nexactly one extraCredentials entry.\n\nmodels β€” default, fallbacks, defaultContextWindow,\ndefaultMaxOutputTokens, and a catalog map of model id β†’ {contextWindow?,\nmaxOutputTokens?, pricingPerMTok?, vision, tools?, status, description, enumMember?}.\nOmit a number rather than invent one. Optional refinements:\n\n| Field | Use it when |\n| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| enumMember | The derived constant-case name would break an existing export |\n| enumTypeName | The <Name>Models enum name must differ from the derived one |\n| fallbackModelName | The legacy fallback differs from fallbacks[1] ?? fallbacks[0] |\n| registryDefaultModel | The registry default differs from default |\n| topModels | The CLI picker should show a curated ordered subset |\n| visionModel | Vision tests need a specific model (the default is text-only) |\n| testModel | The catalog default is retired/gated on the testing account |\n| tools (per model) | capabilities.tools is \"model-dependent\" and the vendor's own docs say which served models actually accept tool definitions (Reka: only reka-flash) |\n\ntestModel is matrix-only","hierarchy":{"lvl0":"Provider Integration","lvl1":"Tier 2 β€” Catalog Entry","lvl2":"","lvl3":""}},
9842
+ {"objectID":"0c443abf0cfa1b31edc3337559bddbf37453d87732cfd17b08d461f55c77b195","title":"Tier 2 β€” Catalog Entry","url":"/docs/provider-integration/tiers/tier-2-catalog-entry","content":"Tier 2 β€” Catalog Entry\n\nWhen this applies: the vendor speaks the OpenAI /v1/chat/completions\nwire format (Bearer auth, standard SSE, standard JSON body) and needs\nzero behavioral overrides β€” no custom adjustRequestBody, no\nadjustResponseFormat, no nonstandard auth header, no adjustBodyAfter400.\nThis is the Groq/xAI/Together AI/Fireworks/Perplexity/Cloudflare/Mistral\nshape from before the redesign β€” now expressed as one JSON file instead of\na hand-written subclass (see ../adr/0002-catalog-over-subclass-default.md\nand the single-JSON spec at\ndocs/superpowers/plans/2026-08-28-provider-json-catalog-spec.md).\n\nIf you're not sure whether your provider is quirk-free, start writing the\nJSON anyway β€” if it turns out you need a hook, migrate to Tier 3 instead of\nforcing the quirk into the catalog shape.\n\nFiles touched (end state)\n\n| # | File | Change |\n| --- | ------------------------------------- | ------------------------------- |\n| 1 | src/lib/providers/catalog/<id>.json | The entire integration, as data |\n\nThat is the whole list. Everything else is generated or derived:\npnpm run codegen:catalog writes the AIProviderName member, the\n <Name>Models enum and the NeurolinkCredentials key into marked\n regions, plus the generated catalog index. Pre-commit and CI fail on\n stale output, so it can't drift.\nThe runtime loader builds the registry entry, descriptor, config options,\n context windows, pricing, vision map and model choices from the JSON.\nThe test suites derive their spec rows, matrix rows and counts from the\n built catalog.\n\nScaffold it with:\n\nTier 2 emits exactly two files: a pre-filled <id>.json (with TODO markers\nwhere only a live probe can supply the truth) and a short checklist. The\nJSON deliberately fails schema validation until every TODO is replaced.\n\nCount pins β€” nothing to bump\n\nThere are none left. The wiring and descriptor suites compute their\nexpected totals from CATALOG_PROVIDER_IDS, and the matrix rows spread\nfrom the catalog with a completeness guard that throws if any catalog\nprovider is missing. Adding a provider changes no test file.\n\nsrc/lib/factories/providerRegistry.ts isn't in the table either:\n_doRegister() loops over the catalog and registers every entry\ngenerically.\n\nOne historical exception worth re-checking: commandFactory.ts's separate\nsetup [provider] subcommand hand-hardcoded its own provider-choices array.\nThat was migrated to derive from the enum (PR #1583) β€” confirm it still\ndoes before assuming you need a manual edit.\n\nThe JSON, field by field\n\nid, displayName, aliases, tier, then:\n\nwire β€” baseURL for the normal case. Env var names derive by\nconvention (<CONSTANT_CASE(id)>_API_KEY / _BASE_URL / _MODEL); set\nenvOverrides only for a vendor that breaks it. For a URL computed from\nanother credential (Cloudflare's account id) use baseURLTemplate plus\nexactly one extraCredentials entry.\n\nmodels β€” default, fallbacks, defaultContextWindow,\ndefaultMaxOutputTokens, and a catalog map of model id β†’ {contextWindow?,\nmaxOutputTokens?, pricingPerMTok?, vision, tools?, status, description, enumMember?}.\nOmit a number rather than invent one. Optional refinements:\n\n| Field | Use it when |\n| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| enumMember | The derived constant-case name would break an existing export |\n| enumTypeName | The <Name>Models enum name must differ from the derived one |\n| fallbackModelName | The legacy fallback differs from fallbacks[1] ?? fallbacks[0] |\n| registryDefaultModel | The registry default differs from default |\n| topModels | The CLI picker should show a curated ordered subset |\n| visionModel | Vision tests need a specific model (the default is text-only) |\n| testModel | The catalog default is retired/gated on the testing account |\n| tools (per model) | capabilities.tools is \"model-dependent\" and the vendor's own docs say which served models actually accept tool definitions (Reka: flash-3 doesn't) |\n\ntestModel is matrix-only","hierarchy":{"lvl0":"Provider Integration","lvl1":"Tier 2 β€” Catalog Entry","lvl2":"","lvl3":""}},
9835
9843
  {"objectID":"4b278bfa53040dfc60deaffd7c0042488d914cc4eff89ded532f5582eceadce6","title":"Tier 2 β€” Catalog Entry","url":"/docs/provider-integration/tiers/tier-2-catalog-entry#tier-2-catalog-entry","content":"When this applies: the vendor speaks the OpenAI /v1/chat/completions\nwire format (Bearer auth, standard SSE, standard JSON body) and needs\nzero behavioral overrides β€” no custom adjustRequestBody, no\nadjustResponseFormat, no nonstandard auth header, no adjustBodyAfter400.\nThis is the Groq/xAI/Together AI/Fireworks/Perplexity/Cloudflare/Mistral\nshape from before the redesign β€” now expressed as one JSON file instead of\na hand-written subclass (see ../adr/0002-catalog-over-subclass-default.md\nand the single-JSON spec at\ndocs/superpowers/plans/2026-08-28-provider-json-catalog-spec.md).\n\nIf you're not sure whether your provider is quirk-free, start writing the\nJSON anyway β€” if it turns out you need a hook, migrate to Tier 3 instead of\nforcing the quirk into the catalog shape.","hierarchy":{"lvl0":"Provider Integration","lvl1":"Tier 2 β€” Catalog Entry","lvl2":"Tier 2 β€” Catalog Entry","lvl3":""}},
9836
9844
  {"objectID":"1bb614eb5848cace52afb691aa99aeab78366a84a216f758ef9df6c86e49c0cc","title":"Files touched (end state)","url":"/docs/provider-integration/tiers/tier-2-catalog-entry#files-touched-end-state","content":"| # | File | Change |\n| --- | ------------------------------------- | ------------------------------- |\n| 1 | src/lib/providers/catalog/<id>.json | The entire integration, as data |\n\nThat is the whole list. Everything else is generated or derived:\npnpm run codegen:catalog writes the AIProviderName member, the\n <Name>Models enum and the NeurolinkCredentials key into marked\n regions, plus the generated catalog index. Pre-commit and CI fail on\n stale output, so it can't drift.\nThe runtime loader builds the registry entry, descriptor, config options,\n context windows, pricing, vision map and model choices from the JSON.\nThe test suites derive their spec rows, matrix rows and counts from the\n built catalog.\n\nScaffold it with:\n\nTier 2 emits exactly two files: a pre-filled <id>.json (with TODO markers\nwhere only a live probe can supply the truth) and a short checklist. The\nJSON deliberately fails schema validation until every TODO is replaced.","hierarchy":{"lvl0":"Provider Integration","lvl1":"Tier 2 β€” Catalog Entry","lvl2":"Files touched (end state)","lvl3":""}},
9837
9845
  {"objectID":"9627a6b63ab505017fbc3edd7f9ec312f548b35aef74edd6e2be5eac8e1ade0f","title":"Count pins β€” nothing to bump","url":"/docs/provider-integration/tiers/tier-2-catalog-entry#count-pins-nothing-to-bump","content":"There are none left. The wiring and descriptor suites compute their\nexpected totals from CATALOG_PROVIDER_IDS, and the matrix rows spread\nfrom the catalog with a completeness guard that throws if any catalog\nprovider is missing. Adding a provider changes no test file.\n\nsrc/lib/factories/providerRegistry.ts isn't in the table either:\n_doRegister() loops over the catalog and registers every entry\ngenerically.\n\nOne historical exception worth re-checking: commandFactory.ts's separate\nsetup [provider] subcommand hand-hardcoded its own provider-choices array.\nThat was migrated to derive from the enum (PR #1583) β€” confirm it still\ndoes before assuming you need a manual edit.","hierarchy":{"lvl0":"Provider Integration","lvl1":"Tier 2 β€” Catalog Entry","lvl2":"Count pins β€” nothing to bump","lvl3":""}},
@@ -10947,27 +10955,26 @@
10947
10955
  {"objectID":"6f89b36a7ecd601d33def72e99335dc92de7b6dd2cf73cbdd0b8aeaaca3b44af","title":"Out-of-Scope Items Identified During Review","url":"/docs/review-fixes-documentation#out-of-scope-items-identified-during-review","content":"Evaluation/Scoring module has 0 test coverage -- 11 source files (1,822 lines) with no tests. This is a known gap tracked separately.\nStream path cost estimation -- While generate() now has accurate cost via calculateCost(), the stream path records cost only on BaseProvider.generate() spans. Stream consumption spans do not yet include cost because final token counts are only available after stream completion. A future improvement could add cost calculation to the wrapStreamWithMetrics() completion handler.\nRedis ConversationMemoryManager OTel parity -- OTel spans were added to the in-memory ConversationMemoryManager, but the Redis implementation should also be checked for equivalent instrumentation.\nProvider-specific retry configuration -- Currently all providers share the same MAX_PROVIDER_RETRIES = 2 constant. Some providers (e.g., rate-limited free-tier APIs) might benefit from configurable retry counts.\nOllama provider -- Was not touched by any fixes. Does not have resolveTools() because Ollama has a different streaming architecture. Should be reviewed separately.","hierarchy":{"lvl0":"Review Fixes Documentation","lvl1":"NeuroLink Review Fixes Documentation","lvl2":"Out-of-Scope Items Identified During Review","lvl3":""}},
10948
10956
  {"objectID":"055eaf06d4550d4f8d8f01ae90a482b15d96b608ecd6e0fc9352e981c5919fb4","title":"Test Coverage Gaps","url":"/docs/review-fixes-documentation#test-coverage-gaps","content":"No unit tests specifically for resolveTools() method behavior.\nNo unit tests for the new wrapStreamWithMetrics() stream instrumentation wrapper.\nNo unit tests for abort error differentiation in the stream catch block.\nThe OTel span assertions in existing tests may not cover all new span attributes.","hierarchy":{"lvl0":"Review Fixes Documentation","lvl1":"NeuroLink Review Fixes Documentation","lvl2":"Test Coverage Gaps","lvl3":""}},
10949
10957
  {"objectID":"ea5a23d822d68cc15995c306a682c4d2a5b7fbc75ec1109cfb3d123b77ade11a","title":"8. Files Changed Summary","url":"/docs/review-fixes-documentation#8-files-changed-summary","content":"| File | Lines Added | Lines Removed | Net |\n| -------------------------------------------- | ----------- | ------------- | ---------- |\n| src/lib/neurolink.ts | +1029 | -529 | +500 |\n| src/lib/mcp/externalServerManager.ts | +574 | -392 | +182 |\n| src/lib/core/modules/MessageBuilder.ts | +501 | -340 | +161 |\n| src/lib/mcp/mcpClientFactory.ts | +449 | -300 | +149 |\n| src/lib/core/conversationMemoryManager.ts | +369 | -180 | +189 |\n| src/lib/mcp/toolDiscoveryService.ts | +367 | -220 | +147 |\n| src/lib/utils/providerRetry.ts | +214 | -86 | +128 |\n| src/lib/core/baseProvider.ts | +178 | -18 | +160 |\n| src/lib/core/modules/GenerationHandler.ts | +130 | -10 | +120 |\n| src/lib/providers/azureOpenai.ts | +85 | -21 | +64 |\n| src/lib/core/modules/StreamHandler.ts | +72 | -36 | +36 |\n| src/lib/providers/huggingFace.ts | +70 | -36 | +34 |\n| src/lib/core/modules/ToolsManager.ts | +168 | -50 | +118 |\n| src/lib/providers/mistral.ts | +62 | -21 | +41 |\n| src/lib/mcp/mcpCircuitBreaker.ts | +27 | -0 | +27 |\n| src/lib/providers/googleVertex.ts | +15 | -16 | -1 |\n| src/lib/providers/openAI.ts | +14 | -14 | 0 |\n| src/lib/mcp/httpRetryHandler.ts | +11 | -7 | +4 |\n| src/lib/providers/openRouter.ts | +11 | -13 | -2 |\n| src/lib/providers/litellm.ts | +11 | -13 | -2 |\n|","hierarchy":{"lvl0":"Review Fixes Documentation","lvl1":"NeuroLink Review Fixes Documentation","lvl2":"8. Files Changed Summary","lvl3":""}},
10950
- {"objectID":"c3d93c4536c96f6eb66c6aafd01e65b45492889dc7f61272f8456660bd5f8e1c","title":"Advanced SDK Features","url":"/docs/sdk/advanced-features","content":"Advanced SDK Features\n\nAdvanced features and capabilities of the NeuroLink SDK.\n\nStreaming\n\nUse stream() for incremental token delivery:\n\nStructured Output\n\nUse schema with a Zod schema to get typed JSON responses:\n\nNote: Google Gemini models cannot combine tools and JSON schema output simultaneously. Pass disableTools: true when using schema with Vertex AI or Google AI Studio.\n\nConversation Memory\n\nEnable conversation memory for stateful multi-turn interactions:\n\nThinking Level\n\nControl extended thinking for supported models (Anthropic Claude, Gemini 2.5+):\n\nEmbeddings\n\nGenerate vector embeddings for text:\n\nRAG Integration\n\nPass files directly to generate() or stream() for retrieval-augmented generation:\n\nExternal MCP Servers\n\nAdd external tool servers using the Model Context Protocol:\n\nMultimodal Input\n\nPass images and files alongside text:\n\nContext Compaction\n\nConfigure automatic context window management for long conversations:\n\nObservability\n\nIntegrate with Langfuse for tracing and monitoring:\n\nRelated Documentation\nAPI Reference -- SDK method signatures and options\nConfiguration Guide -- Environment setup\nMultimodal Chat -- Images, PDFs, CSV, and more\nRAG Processing -- Chunking, hybrid search, and reranking","hierarchy":{"lvl0":"Sdk","lvl1":"Advanced SDK Features","lvl2":"","lvl3":""}},
10958
+ {"objectID":"c3d93c4536c96f6eb66c6aafd01e65b45492889dc7f61272f8456660bd5f8e1c","title":"Advanced SDK Features","url":"/docs/sdk/advanced-features","content":"Advanced SDK Features\n\nAdvanced features and capabilities of the NeuroLink SDK.\n\nStreaming\n\nUse stream() for incremental token delivery:\n\nStructured Output\n\nUse schema with a Zod schema to get typed JSON responses:\n\nNote: Google Gemini models cannot combine tools and JSON schema output simultaneously. Pass disableTools: true when using schema with Vertex AI or Google AI Studio.\n\nConversation Memory\n\nEnable conversation memory for stateful multi-turn interactions:\n\nThinking Level\n\nControl extended thinking for supported models (Anthropic Claude, Gemini 2.5+):\n\nEmbeddings\n\nGenerate vector embeddings for text. NeuroLink has no embed() of its own: the embedding methods live on the provider instance (see the embeddings guide):\n\nRAG Integration\n\nPass files directly to generate() or stream() for retrieval-augmented generation:\n\nExternal MCP Servers\n\nAdd external tool servers using the Model Context Protocol:\n\nMultimodal Input\n\nPass images and files alongside text:\n\nContext Compaction\n\nConfigure automatic context window management for long conversations:\n\nObservability\n\nIntegrate with Langfuse for tracing and monitoring:\n\nRelated Documentation\nAPI Reference -- SDK method signatures and options\nConfiguration Guide -- Environment setup\nMultimodal Chat -- Images, PDFs, CSV, and more\nRAG Processing -- Chunking, hybrid search, and reranking","hierarchy":{"lvl0":"Sdk","lvl1":"Advanced SDK Features","lvl2":"","lvl3":""}},
10951
10959
  {"objectID":"9ca47aaa85fec7ae724ef11230908f8bcb56c6d449a5c4355be3259aa9074c23","title":"Advanced SDK Features","url":"/docs/sdk/advanced-features#advanced-sdk-features","content":"Advanced features and capabilities of the NeuroLink SDK.","hierarchy":{"lvl0":"Sdk","lvl1":"Advanced SDK Features","lvl2":"Advanced SDK Features","lvl3":""}},
10952
10960
  {"objectID":"7745774d9a729946df6445ad943871fb8fcb9249203185f1b3bdbcdddb104bdc","title":"Streaming","url":"/docs/sdk/advanced-features#streaming","content":"Use stream() for incremental token delivery:","hierarchy":{"lvl0":"Sdk","lvl1":"Advanced SDK Features","lvl2":"Streaming","lvl3":""}},
10953
10961
  {"objectID":"4734b55455966df0f4d03d701c16b6bee03a2d106d3fd1e3692e6a22c4325d3c","title":"Structured Output","url":"/docs/sdk/advanced-features#structured-output","content":"Use schema with a Zod schema to get typed JSON responses:\n\nNote: Google Gemini models cannot combine tools and JSON schema output simultaneously. Pass disableTools: true when using schema with Vertex AI or Google AI Studio.","hierarchy":{"lvl0":"Sdk","lvl1":"Advanced SDK Features","lvl2":"Structured Output","lvl3":""}},
10954
10962
  {"objectID":"23f1a214de97bebe5eb716f66dae81b115068e2a2324bf95b80b4f7ab657a7ea","title":"Conversation Memory","url":"/docs/sdk/advanced-features#conversation-memory","content":"Enable conversation memory for stateful multi-turn interactions:","hierarchy":{"lvl0":"Sdk","lvl1":"Advanced SDK Features","lvl2":"Conversation Memory","lvl3":""}},
10955
10963
  {"objectID":"182905b251e22fd430f91d384095c6dec1007640055169b46e6a8b53a2a5d1cd","title":"Thinking Level","url":"/docs/sdk/advanced-features#thinking-level","content":"Control extended thinking for supported models (Anthropic Claude, Gemini 2.5+):","hierarchy":{"lvl0":"Sdk","lvl1":"Advanced SDK Features","lvl2":"Thinking Level","lvl3":""}},
10956
- {"objectID":"72d31d15d25ceac32168aeba1615a9a4692bc34b4069267f866cfbaaf315cfd2","title":"Embeddings","url":"/docs/sdk/advanced-features#embeddings","content":"Generate vector embeddings for text:","hierarchy":{"lvl0":"Sdk","lvl1":"Advanced SDK Features","lvl2":"Embeddings","lvl3":""}},
10964
+ {"objectID":"72d31d15d25ceac32168aeba1615a9a4692bc34b4069267f866cfbaaf315cfd2","title":"Embeddings","url":"/docs/sdk/advanced-features#embeddings","content":"Generate vector embeddings for text. NeuroLink has no embed() of its own: the embedding methods live on the provider instance (see the embeddings guide):","hierarchy":{"lvl0":"Sdk","lvl1":"Advanced SDK Features","lvl2":"Embeddings","lvl3":""}},
10957
10965
  {"objectID":"53ba8426883db45b25ff63679ccd674b6473116f9be325fe5879f519676fb4a7","title":"RAG Integration","url":"/docs/sdk/advanced-features#rag-integration","content":"Pass files directly to generate() or stream() for retrieval-augmented generation:","hierarchy":{"lvl0":"Sdk","lvl1":"Advanced SDK Features","lvl2":"RAG Integration","lvl3":""}},
10958
10966
  {"objectID":"016a7f67b4ea689e7d6a19b4007c16860f3f8822d8671898237af8f702eb22f4","title":"External MCP Servers","url":"/docs/sdk/advanced-features#external-mcp-servers","content":"Add external tool servers using the Model Context Protocol:","hierarchy":{"lvl0":"Sdk","lvl1":"Advanced SDK Features","lvl2":"External MCP Servers","lvl3":""}},
10959
10967
  {"objectID":"c4a4a5289f29a76de062a561b750ec21b3169453a874260fd0c041f0f77e5b26","title":"Multimodal Input","url":"/docs/sdk/advanced-features#multimodal-input","content":"Pass images and files alongside text:","hierarchy":{"lvl0":"Sdk","lvl1":"Advanced SDK Features","lvl2":"Multimodal Input","lvl3":""}},
10960
10968
  {"objectID":"a5f97b93ac6d92b1bc564beda1c830e535b665f40428308790c401afd7f0e603","title":"Context Compaction","url":"/docs/sdk/advanced-features#context-compaction","content":"Configure automatic context window management for long conversations:","hierarchy":{"lvl0":"Sdk","lvl1":"Advanced SDK Features","lvl2":"Context Compaction","lvl3":""}},
10961
10969
  {"objectID":"4f32d0db19d09b2acf642069e413b3919bb40e7c4dfb87c3b61c0540bb878fc4","title":"Observability","url":"/docs/sdk/advanced-features#observability","content":"Integrate with Langfuse for tracing and monitoring:","hierarchy":{"lvl0":"Sdk","lvl1":"Advanced SDK Features","lvl2":"Observability","lvl3":""}},
10962
10970
  {"objectID":"9ac039b5cf6ab485859171f39638a7e5a350511717f8d5a2df9076aa8fbac92e","title":"Related Documentation","url":"/docs/sdk/advanced-features#related-documentation","content":"API Reference -- SDK method signatures and options\nConfiguration Guide -- Environment setup\nMultimodal Chat -- Images, PDFs, CSV, and more\nRAG Processing -- Chunking, hybrid search, and reranking","hierarchy":{"lvl0":"Sdk","lvl1":"Advanced SDK Features","lvl2":"Related Documentation","lvl3":""}},
10963
- {"objectID":"17165721044c9d39fff765d1252ff2f0606cddcca07dde1f3364f3e957c0e335","title":"API Reference","url":"/docs/sdk/api-reference","content":"{JSON.stringify({\n \"@context\": \"https://schema.org\",\n \"@type\": \"SoftwareSourceCode\",\n \"name\": \"NeuroLink SDK β€” Real-time AI Streaming\",\n \"programmingLanguage\": \"TypeScript\",\n \"codeRepository\": \"https://github.com/juspay/neurolink\",\n \"license\": \"https://opensource.org/licenses/MIT\"\n })}\n\nAPI Reference\n\nComplete reference for NeuroLink's TypeScript API.\n\nNeuroLink Class\n\nThe NeuroLink class is the main entry point for all SDK functionality.\n\nConstructor: new NeuroLink(config?)\n\nCreate a new NeuroLink instance with optional configuration for conversation memory, orchestration, HITL, and observability.\n\nParameters:\n\nExamples:\n\nSee also:\nRedis Conversation Export\nHuman-in-the-Loop (HITL)\nProvider Orchestration\n\nCore Methods\n\ngenerate(options) {#generate}\n\nGenerate text content synchronously.\n\nParameters:\n\nReturns:\n\nBasic Example:\n\nWith Analytics and Evaluation:\n\nWith Video Generation (Veo 3.1):\n\nNote: Video generation requires Vertex AI credentials and currently only supports Veo 3.1 model. See Video Generation Guide for complete documentation.\n\nSchema Limitations by Provider\n\nGoogle Gemini Limitation (Vertex AI and Google AI Studio):\nCannot combine schema + tools (including built-in tools)\nSolution: Use disableTools: true when using schemas\nNote: This limitation applies to all Gemini models, including Gemini 3 models\n\nExample:\n\nProvider Support Matrix:\n\n| Provider | Tools + Schema | Notes |\n| ------------------ | ------------------------ | --------------------- |\n| OpenAI | Full Support | No limitations |\n| Anthropic | Full Support | No limitations |\n| Vertex AI (Gemini) | Use disableTools: true | Google API limitation |\n| Google AI Studio | Use disableTools: true | Google API limitation |\n| Vertex AI (Claude) | Full Support | Uses Anthropic models |\n| Azure OpenAI | Full Support | No limitations |\n| Bedrock | Full Support | No limitations |\n\nstream(options)\n\nGenerate content with streaming responses.\n\nParameters:\n\nReturns:\n\nExample:\n\ngen(options)\n\nShort alias for generate(). Identical signature and behavior.\n\nEmbeddings\n\nGenerate embeddings directly via the provider's embed() and embedMany() methods.\n\nprovider.embed(text, modelName?)\n\nGenerate an embedding vector for a single text.\n\nprovider.embedMany(texts, modelName?)\n\nGenerate embedding vectors for multiple texts in a single batch. The AI SDK automatically handles chunking for models with batch limits.\n\nSupported providers and default models:\n\n| Provider | Default Embedding Model | Env Override |\n| ---------------- | ------------------------------ | --------------------------- |\n| OpenAI | text-embedding-3-small | β€” |\n| Google AI Studio | gemini-embedding-001 | GOOGLE_AI_EMBEDDING_MODEL |\n| Google Vertex | text-embedding-004 | VERTEX_EMBEDDING_MODEL |\n| Amazon Bedrock | amazon.titan-embed-text-v2:0 | β€” |\n\nRAG Integration\n\nPass rag: { files: [...] } to generate() or stream() for automatic RAG pipeline setup:\n\nRAGConfig Type:\n\n| Property | Type | Default | Description |\n| ------------------- | ------------------ | ------------------------- | ----------------------- |\n| files | string[] | required | File paths to load |\n| strategy | ChunkingStrategy | auto-detected | Chunking strategy |\n| chunkSize | number | 1000 | Max chunk size |\n| chunkOverlap | number | 200 | Chunk overlap |\n| topK | number | 5 | Top results to retrieve |\n| toolName | string | \"search_knowledge_base\" | Tool name for AI |\n| toolDescription | string | auto-generated | Tool description |\n| embeddingProvider | string | generation provider | Embedding provider |\n| embeddingModel | string | provider default | Embedding model |\n\nExports:\n\nMCP Server Management\n\naddExternalMCPServer(serverId, config)\n\nProgrammatically add external MCP servers at runtime. Supports stdio, SSE, WebSocket, and HTTP transports.\n\nExamples:\n\nUse Cases:\nExternal service integration (Bitbucket, Slack, Jira)\nCustom tool development\nDynamic workflow configuration\nEnterprise application toolchain management\nRemote MCP server connectivity with authentication\nOAuth 2.1 protected enterprise APIs\n\ngetMCPStatus()\n\nGet current MCP server status and statistics.\n\nExample:\n\nConversation History Management\n\nCurrently Available Methods\n\ngetConversationHistory(sessionId)\n\nRetrieve the complete conversation history for a specific session.\n\nParameters:\n\n| Parameter | Ty","hierarchy":{"lvl0":"Sdk","lvl1":"API Reference","lvl2":"","lvl3":""}},
10971
+ {"objectID":"17165721044c9d39fff765d1252ff2f0606cddcca07dde1f3364f3e957c0e335","title":"API Reference","url":"/docs/sdk/api-reference","content":"{JSON.stringify({\n \"@context\": \"https://schema.org\",\n \"@type\": \"SoftwareSourceCode\",\n \"name\": \"NeuroLink SDK β€” Real-time AI Streaming\",\n \"programmingLanguage\": \"TypeScript\",\n \"codeRepository\": \"https://github.com/juspay/neurolink\",\n \"license\": \"https://opensource.org/licenses/MIT\"\n })}\n\nAPI Reference\n\nComplete reference for NeuroLink's TypeScript API.\n\nNeuroLink Class\n\nThe NeuroLink class is the main entry point for all SDK functionality.\n\nConstructor: new NeuroLink(config?)\n\nCreate a new NeuroLink instance with optional configuration for conversation memory, orchestration, HITL, and observability.\n\nParameters:\n\nExamples:\n\nSee also:\nRedis Conversation Export\nHuman-in-the-Loop (HITL)\nProvider Orchestration\n\nCore Methods\n\ngenerate(options) {#generate}\n\nGenerate text content synchronously.\n\nParameters:\n\nReturns:\n\nBasic Example:\n\nWith Analytics and Evaluation:\n\nWith Video Generation (Veo 3.1):\n\nNote: Video generation requires Vertex AI credentials and currently only supports Veo 3.1 model. See Video Generation Guide for complete documentation.\n\nSchema Limitations by Provider\n\nGoogle Gemini Limitation (Vertex AI and Google AI Studio):\nCannot combine schema + tools (including built-in tools)\nSolution: Use disableTools: true when using schemas\nNote: This limitation applies to all Gemini models, including Gemini 3 models\n\nExample:\n\nProvider Support Matrix:\n\n| Provider | Tools + Schema | Notes |\n| ------------------ | ------------------------ | --------------------- |\n| OpenAI | Full Support | No limitations |\n| Anthropic | Full Support | No limitations |\n| Vertex AI (Gemini) | Use disableTools: true | Google API limitation |\n| Google AI Studio | Use disableTools: true | Google API limitation |\n| Vertex AI (Claude) | Full Support | Uses Anthropic models |\n| Azure OpenAI | Full Support | No limitations |\n| Bedrock | Full Support | No limitations |\n\nstream(options)\n\nGenerate content with streaming responses.\n\nParameters:\n\nReturns:\n\nExample:\n\nEmbeddings\n\nGenerate embeddings directly via the provider's embed() and embedMany() methods.\n\nprovider.embed(text, modelName?)\n\nGenerate an embedding vector for a single text.\n\nprovider.embedMany(texts, modelName?)\n\nGenerate embedding vectors for multiple texts in a single batch. The AI SDK automatically handles chunking for models with batch limits.\n\nSupported providers and default models:\n\n| Provider | Default Embedding Model | Env Override |\n| ---------------- | ------------------------------ | --------------------------- |\n| OpenAI | text-embedding-3-small | β€” |\n| Google AI Studio | gemini-embedding-001 | GOOGLE_AI_EMBEDDING_MODEL |\n| Google Vertex | text-embedding-004 | VERTEX_EMBEDDING_MODEL |\n| Amazon Bedrock | amazon.titan-embed-text-v2:0 | β€” |\n\nRAG Integration\n\nPass rag: { files: [...] } to generate() or stream() for automatic RAG pipeline setup:\n\nRAGConfig Type:\n\n| Property | Type | Default | Description |\n| ------------------- | ------------------ | ------------------------- | ----------------------- |\n| files | string[] | required | File paths to load |\n| strategy | ChunkingStrategy | auto-detected | Chunking strategy |\n| chunkSize | number | 1000 | Max chunk size |\n| chunkOverlap | number | 200 | Chunk overlap |\n| topK | number | 5 | Top results to retrieve |\n| toolName | string | \"search_knowledge_base\" | Tool name for AI |\n| toolDescription | string | auto-generated | Tool description |\n| embeddingProvider | string | generation provider | Embedding provider |\n| embeddingModel | string | provider default | Embedding model |\n\nExports:\n\nMCP Server Management\n\naddExternalMCPServer(serverId, config)\n\nProgrammatically add external MCP servers at runtime. Supports stdio, SSE, WebSocket, and HTTP transports.\n\nExamples:\n\nUse Cases:\nExternal service integration (Bitbucket, Slack, Jira)\nCustom tool development\nDynamic workflow configuration\nEnterprise application toolchain management\nRemote MCP server connectivity with authentication\nOAuth 2.1 protected enterprise APIs\n\ngetMCPStatus()\n\nGet current MCP server status and statistics.\n\nExample:\n\nConversation History Management\n\nCurrently Available Methods\n\ngetConversationHistory(sessionId)\n\nRetrieve the complete conversation history for a specific session.\n\nParameters:\n\n| Parameter | Type | Description |\n| ----------- | -------- | ","hierarchy":{"lvl0":"Sdk","lvl1":"API Reference","lvl2":"","lvl3":""}},
10964
10972
  {"objectID":"67e25cb84e1a45413d246db21b885f83c9f9cd929f6c5b130208fdc7299645ed","title":"API Reference","url":"/docs/sdk/api-reference#api-reference","content":"Complete reference for NeuroLink's TypeScript API.","hierarchy":{"lvl0":"Sdk","lvl1":"API Reference","lvl2":"API Reference","lvl3":""}},
10965
10973
  {"objectID":"75a2e62a64c504c936e31eee81df59a23b4a5282186e916dda0e93b306c943b0","title":"NeuroLink Class","url":"/docs/sdk/api-reference#neurolink-class","content":"The NeuroLink class is the main entry point for all SDK functionality.","hierarchy":{"lvl0":"Sdk","lvl1":"API Reference","lvl2":"NeuroLink Class","lvl3":""}},
10966
10974
  {"objectID":"32e2583180be8785a68bc3b3e6f8e202e041a150f8fe091f824b8a3bf45fa0a2","title":"Constructor: new NeuroLink(config?)","url":"/docs/sdk/api-reference#constructor-new-neurolinkconfig","content":"Create a new NeuroLink instance with optional configuration for conversation memory, orchestration, HITL, and observability.\n\nParameters:\n\nExamples:\n\nSee also:\nRedis Conversation Export\nHuman-in-the-Loop (HITL)\nProvider Orchestration","hierarchy":{"lvl0":"Sdk","lvl1":"API Reference","lvl2":"Constructor: new NeuroLink(config?)","lvl3":""}},
10967
10975
  {"objectID":"35d1b65e6ba5ec2dc7240c7861dcfd57b1ba0c547cc2ef53707d9ca10fef034c","title":"generate(options)","url":"/docs/sdk/api-reference#generate","content":"Generate text content synchronously.\n\nParameters:\n\nReturns:\n\nBasic Example:\n\nWith Analytics and Evaluation:\n\nWith Video Generation (Veo 3.1):\n\nNote: Video generation requires Vertex AI credentials and currently only supports Veo 3.1 model. See Video Generation Guide for complete documentation.","hierarchy":{"lvl0":"Sdk","lvl1":"API Reference","lvl2":"generate(options)","lvl3":""}},
10968
10976
  {"objectID":"b18968db6b2af6a05aea4f70a791c4e548476c7a26eabc4edb12fc7e947c32d9","title":"Schema Limitations by Provider","url":"/docs/sdk/api-reference#schema-limitations-by-provider","content":"Google Gemini Limitation (Vertex AI and Google AI Studio):\nCannot combine schema + tools (including built-in tools)\nSolution: Use disableTools: true when using schemas\nNote: This limitation applies to all Gemini models, including Gemini 3 models\n\nExample:\n\nProvider Support Matrix:\n\n| Provider | Tools + Schema | Notes |\n| ------------------ | ------------------------ | --------------------- |\n| OpenAI | Full Support | No limitations |\n| Anthropic | Full Support | No limitations |\n| Vertex AI (Gemini) | Use disableTools: true | Google API limitation |\n| Google AI Studio | Use disableTools: true | Google API limitation |\n| Vertex AI (Claude) | Full Support | Uses Anthropic models |\n| Azure OpenAI | Full Support | No limitations |\n| Bedrock | Full Support | No limitations |","hierarchy":{"lvl0":"Sdk","lvl1":"API Reference","lvl2":"Schema Limitations by Provider","lvl3":""}},
10969
10977
  {"objectID":"c4427ee44db90ee80e9d793a7c422e797e54060eedd9e4bd3d42f48095d7464f","title":"stream(options)","url":"/docs/sdk/api-reference#streamoptions","content":"Generate content with streaming responses.\n\nParameters:\n\nReturns:\n\nExample:","hierarchy":{"lvl0":"Sdk","lvl1":"API Reference","lvl2":"stream(options)","lvl3":""}},
10970
- {"objectID":"517bf503c0fd729563d25fe09a7fe535d7acf840f493cb3a4e1b412078612948","title":"gen(options)","url":"/docs/sdk/api-reference#genoptions","content":"Short alias for generate(). Identical signature and behavior.","hierarchy":{"lvl0":"Sdk","lvl1":"API Reference","lvl2":"gen(options)","lvl3":""}},
10971
10978
  {"objectID":"920ab224a864dd15a53aab69ff83c2e46afd81398c24836d8b76756954c07c4c","title":"Embeddings","url":"/docs/sdk/api-reference#embeddings","content":"Generate embeddings directly via the provider's embed() and embedMany() methods.","hierarchy":{"lvl0":"Sdk","lvl1":"API Reference","lvl2":"Embeddings","lvl3":""}},
10972
10979
  {"objectID":"f48e03eb99d3690aba3e315617d2f7f883ea6494cab456cf3783866c81fda171","title":"provider.embed(text, modelName?)","url":"/docs/sdk/api-reference#providerembedtext-modelname","content":"Generate an embedding vector for a single text.","hierarchy":{"lvl0":"Sdk","lvl1":"API Reference","lvl2":"provider.embed(text, modelName?)","lvl3":""}},
10973
10980
  {"objectID":"337c3be911d15fad136ed35c3e4157662e339b22b84204beb2ed9621ec0d96b3","title":"provider.embedMany(texts, modelName?)","url":"/docs/sdk/api-reference#providerembedmanytexts-modelname","content":"Generate embedding vectors for multiple texts in a single batch. The AI SDK automatically handles chunking for models with batch limits.\n\nSupported providers and default models:\n\n| Provider | Default Embedding Model | Env Override |\n| ---------------- | ------------------------------ | --------------------------- |\n| OpenAI | text-embedding-3-small | β€” |\n| Google AI Studio | gemini-embedding-001 | GOOGLE_AI_EMBEDDING_MODEL |\n| Google Vertex | text-embedding-004 | VERTEX_EMBEDDING_MODEL |\n| Amazon Bedrock | amazon.titan-embed-text-v2:0 | β€” |","hierarchy":{"lvl0":"Sdk","lvl1":"API Reference","lvl2":"provider.embedMany(texts, modelName?)","lvl3":""}},
@@ -10997,7 +11004,7 @@
10997
11004
  {"objectID":"97c113933d8bdbd9378ae8346e0736690afb5616ed42ecf2e25f8f61df7a4246","title":"Lifecycle","url":"/docs/sdk/api-reference#lifecycle","content":"Methods for gracefully releasing resources held by a NeuroLink instance.","hierarchy":{"lvl0":"Sdk","lvl1":"API Reference","lvl2":"Lifecycle","lvl3":""}},
10998
11005
  {"objectID":"2632d94ed68c14fc865dc9ade97c5ed2aa7288897dd23bccf40eec7090703351","title":"shutdown()","url":"/docs/sdk/api-reference#shutdown","content":"Gracefully shut down all NeuroLink resources. Flushes and shuts down OpenTelemetry, closes external MCP server connections, and releases conversation memory resources (e.g., Redis connections).\n\nExample:","hierarchy":{"lvl0":"Sdk","lvl1":"API Reference","lvl2":"shutdown()","lvl3":""}},
10999
11006
  {"objectID":"7930d5375b69918f200c4e74b48c900c8f35346e6df92ccd8129c44b22764aba","title":"dispose()","url":"/docs/sdk/api-reference#dispose","content":"Full resource disposal. Performs everything shutdown() does, plus removes all event listeners, clears circuit breakers, purges internal caches and maps, and resets initialization state. Use this when you are completely done with the instance, especially in test environments where multiple NeuroLink instances are created.\n\nExample:","hierarchy":{"lvl0":"Sdk","lvl1":"API Reference","lvl2":"dispose()","lvl3":""}},
11000
- {"objectID":"d79631a303031924a7185daa0471458026c9d9ef6bee4a13e49d9ce0610262b9","title":"Event System","url":"/docs/sdk/api-reference#event-system","content":"NeuroLink is a TypedEventEmitter that emits events throughout the generation and streaming lifecycle. Subscribe to events with on(), unsubscribe with off().","hierarchy":{"lvl0":"Sdk","lvl1":"API Reference","lvl2":"Event System","lvl3":""}},
11007
+ {"objectID":"d79631a303031924a7185daa0471458026c9d9ef6bee4a13e49d9ce0610262b9","title":"Event System","url":"/docs/sdk/api-reference#event-system","content":"NeuroLink emits events throughout the generation and streaming lifecycle through a TypedEventEmitter. NeuroLink does not extend EventEmitter itself, so there is no neurolink.on(): get the emitter with getEventEmitter(), subscribe with on() and unsubscribe with off().","hierarchy":{"lvl0":"Sdk","lvl1":"API Reference","lvl2":"Event System","lvl3":""}},
11001
11008
  {"objectID":"357bbb718f458d764e00524826a1d42a64da83167df93a52c04d9ddec3651764","title":"Core Events","url":"/docs/sdk/api-reference#core-events","content":"| Event | Emitted When |\n| ------------------ | ------------------------------------ |\n| generation:start | A generate() call begins |\n| generation:end | A generate() call completes |\n| stream:start | A stream() call begins |\n| stream:chunk | A new chunk arrives during streaming |\n| stream:end | Streaming completes normally |\n| stream:complete | Stream fully consumed |\n| stream:error | An error occurs during streaming |\n| tool:start | A tool execution begins |\n| tool:end | A tool execution completes |\n| response:start | A provider response begins |\n| response:end | A provider response completes |","hierarchy":{"lvl0":"Sdk","lvl1":"API Reference","lvl2":"Core Events","lvl3":""}},
11002
11009
  {"objectID":"efcf19aa651c13dbc72ef4b3d0f83986ee180008a076c0db030509880e4d4b1a","title":"MCP Server Events","url":"/docs/sdk/api-reference#mcp-server-events","content":"| Event | Emitted When |\n| -------------------------------- | ----------------------------------------- |\n| externalMCP:serverConnected | An external MCP server connects |\n| externalMCP:serverDisconnected | An external MCP server disconnects |\n| externalMCP:serverFailed | An external MCP server connection fails |\n| externalMCP:toolDiscovered | A new tool is discovered on an MCP server |\n| externalMCP:toolRemoved | A tool is removed from an MCP server |\n| externalMCP:serverAdded | A new MCP server registration is added |\n| externalMCP:serverRemoved | An MCP server registration is removed |","hierarchy":{"lvl0":"Sdk","lvl1":"API Reference","lvl2":"MCP Server Events","lvl3":""}},
11003
11010
  {"objectID":"c4d157804d0d96f1d8571e6aabeff4305aca0c07c151894dee3804d611331de6","title":"Other Events","url":"/docs/sdk/api-reference#other-events","content":"| Event | Emitted When |\n| ---------------------- | ----------------------------------- |\n| tools-register:start | Tool registration process begins |\n| tools-register:end | Tool registration process completes |\n| connected | Connection established |\n| message | General message event |\n| error | An error occurs |\n| log | A log message is emitted |\n| log-event | A structured log event is emitted |\n\nTypedEventEmitter Interface:","hierarchy":{"lvl0":"Sdk","lvl1":"API Reference","lvl2":"Other Events","lvl3":""}},
@@ -11980,7 +11987,7 @@
11980
11987
  {"objectID":"e92084a30a916a056bff9e20cf474366ae2de4fc519ba87b428bf7a716343bdf","title":"How to Submit","url":"/docs/tutorials/videos#how-to-submit","content":"Fork the NeuroLink repository\nAdd your video to docs/tutorials/videos.md\nCreate a Pull Request with:\nVideo title and description\nYouTube/Vimeo embed code\nTopics covered\nRelated documentation links\nYour attribution (name, social links)\n\nTemplate:\n\n`markdown","hierarchy":{"lvl0":"Tutorials","lvl1":"Video Tutorials","lvl2":"How to Submit","lvl3":""}},
11981
11988
  {"objectID":"67e8b41e68b809d8843797f693b588919a20c4d234e701c304bc68a272840c04","title":"[Your Video Title] ([Duration])","url":"/docs/tutorials/videos#your-video-title-duration","content":"By Your Name\n\n[Brief description of what the video covers]\n\nTopics Covered:\nTopic 1\nTopic 2\nTopic 3\n\nRelated Resources:\n[Link 1]\n[Link 2]\n`\n\nSee our full Contributing Guide for more details.","hierarchy":{"lvl0":"Tutorials","lvl1":"Video Tutorials","lvl2":"[Your Video Title] ([Duration])","lvl3":""}},
11982
11989
  {"objectID":"e2870bd5699e0fc52a179dfafceac0f7b1d1c04d50f079c52231c9e8dfcd901e","title":"Need Help?","url":"/docs/tutorials/videos#need-help","content":"Documentation: Complete Documentation\nGetting Started: Quick Start Guide\nExamples: Code Examples\nInteractive: Try the Playground\nCommunity: GitHub Discussions\nSupport: GitHub Issues","hierarchy":{"lvl0":"Tutorials","lvl1":"Video Tutorials","lvl2":"Need Help?","lvl3":""}},
11983
- {"objectID":"33f13411e6976fb3535aedca0aeb39b2c98822e024bac011c525e479622834fa","title":"Step-by-Step Integration Tutorials","url":"/docs/tutorials","content":"πŸ“š Step-by-Step Integration Tutorials\n\nπŸš€ Quick Start (15 minutes) {#quick-start-15-minutes}\n\nStep 1: Installation\n\nStep 2: Enable Analytics\n\nStep 3: Add Quality Evaluation\n\nVideo Generation (Veo 3.1)\n\nGenerate videos from images using Google's Veo 3.1 model via Vertex AI.\n\nPrerequisites\n\nSDK Video Generation\n\nImage Requirements:\nFormats: PNG, JPEG, or WebP only\nSize limit: 20MB maximum\nAspect ratio: Should be compatible with target video aspect ratio (16:9 or 9:16)\n\nCLI Video Generation\n\nNote: The --provider vertex flag is optional for video generationβ€”NeuroLink automatically switches to Vertex AI when --outputMode video is specified.\n\nFor complete documentation, see the Video Generation Guide.\n\nπŸ“Š PPT Generation Tutorial\n\nGenerate professional PowerPoint presentations using the CLI:\n\nSDK Usage:\n\nFor complete documentation, see the PPT Generation Guide.\n\n🌐 Web App Integration\n\nExpress.js API\n\nπŸ“Š Cost Optimization\n\nAutomatic Model Selection\n\nπŸ”„ Batch Processing\n\nπŸ“ˆ Real-Time Monitoring\n\nAnalytics Dashboard\n\n🎯 CLI Usage Patterns\n\nBasic Generation with Analytics\n\nQuality Control\n\nFull Features\n\n🏒 Industry Examples\n\nE-commerce: Product Descriptions\n\nHealthcare: Patient Education\n\nCustomer Support\n\nπŸ’¬ Building a Conversational Agent\n\nNeuroLink can maintain a stateful conversation history, making it easy to build conversational agents and chatbots. By enabling context summarization, NeuroLink will automatically manage the conversation's context, summarizing it when it grows too long.\n\nStep 1: Enable Context Summarization\n\nTo enable this feature, simply call the enableContextSummarization() method on your NeuroLink instance.\n\nStep 2: Simulate a Conversation\n\nNow, you can interact with the agent by calling generate() multiple times. The agent will remember the context of previous turns.\n\nExpected Output\n\nThe agent will correctly recall the information provided in earlier prompts, demonstrating its stateful nature.\n\nπŸ“‹ Implementation Checklist\n\nβœ… Basic Setup\n[ ] Install NeuroLink SDK\n[ ] Configure API keys in .env\n[ ] Test basic generation\n[ ] Enable analytics tracking\n[ ] Add evaluation scoring\n\nβœ… Production Setup\n[ ] Implement quality gates\n[ ] Set up cost monitoring\n[ ] Create analytics dashboard\n[ ] Configure department tracking\n[ ] Set up batch processing\n\nβœ… Optimization\n[ ] Model selection strategy\n[ ] Cost optimization rules\n[ ] Quality improvement process\n[ ] Performance monitoring\n[ ] ROI measurement\n\n🎯 Next Steps\nStart Simple: Basic analytics and evaluation\nAdd Quality Gates: Implement quality thresholds\nMonitor Costs: Track spending by department/usage\nOptimize: Use data to improve cost and quality\nScale: Implement across organization\n\nEach tutorial builds on the previous ones - start with the Quick Start and progress based on your needs.","hierarchy":{"lvl0":"Tutorials","lvl1":"Step-by-Step Integration Tutorials","lvl2":"","lvl3":""}},
11990
+ {"objectID":"33f13411e6976fb3535aedca0aeb39b2c98822e024bac011c525e479622834fa","title":"Step-by-Step Integration Tutorials","url":"/docs/tutorials","content":"πŸ“š Step-by-Step Integration Tutorials\n\nπŸš€ Quick Start (15 minutes) {#quick-start-15-minutes}\n\nStep 1: Installation\n\nStep 2: Enable Analytics\n\nStep 3: Add Quality Evaluation\n\nVideo Generation (Veo 3.1)\n\nGenerate videos from images using Google's Veo 3.1 model via Vertex AI.\n\nPrerequisites\n\nSDK Video Generation\n\nImage Requirements:\nFormats: PNG, JPEG, or WebP only\nSize limit: 20MB maximum\nAspect ratio: Should be compatible with target video aspect ratio (16:9 or 9:16)\n\nCLI Video Generation\n\nNote: The --provider vertex flag is optional for video generationβ€”NeuroLink automatically switches to Vertex AI when --outputMode video is specified.\n\nFor complete documentation, see the Video Generation Guide.\n\nπŸ“Š PPT Generation Tutorial\n\nGenerate professional PowerPoint presentations using the CLI:\n\nSDK Usage:\n\nFor complete documentation, see the PPT Generation Guide.\n\n🌐 Web App Integration\n\nExpress.js API\n\nπŸ“Š Cost Optimization\n\nAutomatic Model Selection\n\nπŸ”„ Batch Processing\n\nπŸ“ˆ Real-Time Monitoring\n\nAnalytics Dashboard\n\n🎯 CLI Usage Patterns\n\nBasic Generation with Analytics\n\nQuality Control\n\nFull Features\n\n🏒 Industry Examples\n\nE-commerce: Product Descriptions\n\nHealthcare: Patient Education\n\nCustomer Support\n\nπŸ’¬ Building a Conversational Agent\n\nNeuroLink can maintain a stateful conversation history, making it easy to build conversational agents and chatbots. By enabling context summarization, NeuroLink will automatically manage the conversation's context, summarizing it when it grows too long.\n\nStep 1: Enable Context Summarization\n\nTo enable this feature, turn on conversation memory with summarization when you create your NeuroLink instance.\n\nStep 2: Simulate a Conversation\n\nNow, you can interact with the agent by calling generate() multiple times. The agent will remember the context of previous turns.\n\nExpected Output\n\nThe agent will correctly recall the information provided in earlier prompts, demonstrating its stateful nature.\n\nπŸ“‹ Implementation Checklist\n\nβœ… Basic Setup\n[ ] Install NeuroLink SDK\n[ ] Configure API keys in .env\n[ ] Test basic generation\n[ ] Enable analytics tracking\n[ ] Add evaluation scoring\n\nβœ… Production Setup\n[ ] Implement quality gates\n[ ] Set up cost monitoring\n[ ] Create analytics dashboard\n[ ] Configure department tracking\n[ ] Set up batch processing\n\nβœ… Optimization\n[ ] Model selection strategy\n[ ] Cost optimization rules\n[ ] Quality improvement process\n[ ] Performance monitoring\n[ ] ROI measurement\n\n🎯 Next Steps\nStart Simple: Basic analytics and evaluation\nAdd Quality Gates: Implement quality thresholds\nMonitor Costs: Track spending by department/usage\nOptimize: Use data to improve cost and quality\nScale: Implement across organization\n\nEach tutorial builds on the previous ones - start with the Quick Start and progress based on your needs.","hierarchy":{"lvl0":"Tutorials","lvl1":"Step-by-Step Integration Tutorials","lvl2":"","lvl3":""}},
11984
11991
  {"objectID":"4dad40e5a49a62cc67fac6f30dea1c333e5c8e2d5a93dd8bad8716a13085e40f","title":"Video Generation (Veo 3.1)","url":"/docs/tutorials#video-generation-veo-31","content":"Generate videos from images using Google's Veo 3.1 model via Vertex AI.","hierarchy":{"lvl0":"Tutorials","lvl1":"Step-by-Step Integration Tutorials","lvl2":"Video Generation (Veo 3.1)","lvl3":""}},
11985
11992
  {"objectID":"b450e05d969c75b63963ded7221ecfc723f90366de4adce6a4de8a2ff4c9d840","title":"Prerequisites","url":"/docs/tutorials#prerequisites","content":"`bash","hierarchy":{"lvl0":"Tutorials","lvl1":"Step-by-Step Integration Tutorials","lvl2":"Prerequisites","lvl3":""}},
11986
11993
  {"objectID":"c71964badc2f5d37f987ee5b0d36b8621f6304663c5a2f26a3275a40f1ae0195","title":"Set up Vertex AI credentials","url":"/docs/tutorials#set-up-vertex-ai-credentials","content":"`","hierarchy":{"lvl0":"Tutorials","lvl1":"Step-by-Step Integration Tutorials","lvl2":"Set up Vertex AI credentials","lvl3":""}},
@@ -11992,7 +11999,7 @@
11992
11999
  {"objectID":"df3602c90eec372a23578352682526c940cd9d6d0a9f40944b6a2e100c147271","title":"Basic presentation generation","url":"/docs/tutorials#basic-presentation-generation","content":"npx @juspay/neurolink generate \"Create a 10-slide presentation about AI in healthcare\" \\\n --outputMode ppt \\\n --pptOutput ./healthcare-ai.pptx","hierarchy":{"lvl0":"Tutorials","lvl1":"Step-by-Step Integration Tutorials","lvl2":"Basic presentation generation","lvl3":""}},
11993
12000
  {"objectID":"32fe2048ce2080acde86f90c644b797cb933cb3420f46b579c1d9f6c496b9e61","title":"Full options with custom theme and AI images","url":"/docs/tutorials#full-options-with-custom-theme-and-ai-images","content":"npx @juspay/neurolink generate \"Create a sales deck for our SaaS product\" \\\n --provider vertex \\\n --model gemini-2.5-pro \\\n --outputMode ppt \\\n --pptTheme corporate \\\n --pptPages 12 \\\n --pptOutput ./sales-deck.pptx\ntypescript\n\nconst neurolink = new NeuroLink();\n\nconst result = await neurolink.generate({\n input: { text: \"Create a product launch presentation\" },\n output: {\n mode: \"ppt\",\n ppt: {\n theme: \"modern\",\n pages: 10,\n generateAIImages: true,\n outputPath: \"./launch-deck.pptx\",\n },\n },\n});\n\nconsole.log(Generated ${result.ppt?.totalSlides} slides);\n`\n\nFor complete documentation, see the PPT Generation Guide.","hierarchy":{"lvl0":"Tutorials","lvl1":"Step-by-Step Integration Tutorials","lvl2":"Full options with custom theme and AI images","lvl3":""}},
11994
12001
  {"objectID":"92a8a285b6395fe4eae093fae54f3fc1c9219ab11b39a784a8f2ae5daa11d0a5","title":"πŸ’¬ Building a Conversational Agent","url":"/docs/tutorials#-building-a-conversational-agent","content":"NeuroLink can maintain a stateful conversation history, making it easy to build conversational agents and chatbots. By enabling context summarization, NeuroLink will automatically manage the conversation's context, summarizing it when it grows too long.","hierarchy":{"lvl0":"Tutorials","lvl1":"Step-by-Step Integration Tutorials","lvl2":"πŸ’¬ Building a Conversational Agent","lvl3":""}},
11995
- {"objectID":"b6adfc358fe86f968ff6c6031bc116f4d62ec2c71cb099329646d8ed276dfec8","title":"Step 1: Enable Context Summarization","url":"/docs/tutorials#step-1-enable-context-summarization","content":"To enable this feature, simply call the enableContextSummarization() method on your NeuroLink instance.","hierarchy":{"lvl0":"Tutorials","lvl1":"Step-by-Step Integration Tutorials","lvl2":"Step 1: Enable Context Summarization","lvl3":""}},
12002
+ {"objectID":"b6adfc358fe86f968ff6c6031bc116f4d62ec2c71cb099329646d8ed276dfec8","title":"Step 1: Enable Context Summarization","url":"/docs/tutorials#step-1-enable-context-summarization","content":"To enable this feature, turn on conversation memory with summarization when you create your NeuroLink instance.","hierarchy":{"lvl0":"Tutorials","lvl1":"Step-by-Step Integration Tutorials","lvl2":"Step 1: Enable Context Summarization","lvl3":""}},
11996
12003
  {"objectID":"e59b8e32d2b0211242f39e262dd3ae2e2c59946e42166f0120935a57c9f64905","title":"Step 2: Simulate a Conversation","url":"/docs/tutorials#step-2-simulate-a-conversation","content":"Now, you can interact with the agent by calling generate() multiple times. The agent will remember the context of previous turns.","hierarchy":{"lvl0":"Tutorials","lvl1":"Step-by-Step Integration Tutorials","lvl2":"Step 2: Simulate a Conversation","lvl3":""}},
11997
12004
  {"objectID":"e1135416e9630f7da897c51c4f5db63c1e2bf95acce1b3278704565ae70491aa","title":"Expected Output","url":"/docs/tutorials#expected-output","content":"The agent will correctly recall the information provided in earlier prompts, demonstrating its stateful nature.","hierarchy":{"lvl0":"Tutorials","lvl1":"Step-by-Step Integration Tutorials","lvl2":"Expected Output","lvl3":""}},
11998
12005
  {"objectID":"3b8d8978d6e6c35857dbf106ba3b298a0ad5c2dcd2539a45cdfed3ea0f30f60f","title":"βœ… Basic Setup","url":"/docs/tutorials#-basic-setup","content":"[ ] Install NeuroLink SDK\n[ ] Configure API keys in .env\n[ ] Test basic generation\n[ ] Enable analytics tracking\n[ ] Add evaluation scoring","hierarchy":{"lvl0":"Tutorials","lvl1":"Step-by-Step Integration Tutorials","lvl2":"βœ… Basic Setup","lvl3":""}},