@juspay/neurolink 12.57.0 β†’ 12.58.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/CHANGELOG.md +3 -3
  2. package/README.md +75 -51
  3. package/dist/browser/neurolink.min.js +419 -416
  4. package/dist/cli/commands/decide.d.ts +4 -1
  5. package/dist/cli/commands/decide.js +6 -3
  6. package/dist/cli/commands/setup.d.ts +1 -1
  7. package/dist/cli/commands/setup.js +1 -1
  8. package/dist/cli/factories/commandFactory.js +1 -1
  9. package/dist/constants/enums.d.ts +4 -0
  10. package/dist/constants/enums.js +5 -0
  11. package/dist/core/factory.d.ts +7 -0
  12. package/dist/core/factory.js +20 -0
  13. package/dist/factories/providerDescriptors.js +96 -7
  14. package/dist/processors/media/VideoProcessor.d.ts +2 -2
  15. package/dist/providers/catalog/index.generated.d.ts +1 -1
  16. package/dist/providers/catalog/index.generated.js +8 -1
  17. package/dist/providers/catalog/openai-decisions.json +75 -0
  18. package/dist/providers/catalog/provider-catalog.schema.json +56 -3
  19. package/dist/providers/catalog/schema.js +92 -11
  20. package/dist/providers/configuredDecision.js +9 -14
  21. package/dist/providers/decide/dialects/index.js +2 -0
  22. package/dist/providers/decide/dialects/openaiDecisions.d.ts +2 -0
  23. package/dist/providers/decide/dialects/openaiDecisions.js +228 -0
  24. package/dist/providers/decide/dialects/systemOne.js +17 -0
  25. package/dist/providers/systemOneDecision.js +6 -1
  26. package/dist/telemetry/attributes.d.ts +10 -3
  27. package/dist/telemetry/attributes.js +142 -10
  28. package/dist/telemetry/index.d.ts +1 -1
  29. package/dist/telemetry/index.js +1 -1
  30. package/dist/types/classifierRouter.d.ts +21 -9
  31. package/dist/types/cli.d.ts +4 -2
  32. package/dist/types/decision.d.ts +67 -3
  33. package/dist/types/processor.d.ts +10 -0
  34. package/dist/types/providerCatalog.d.ts +7 -11
  35. package/dist/types/providerCatalog.generated.d.ts +2 -2
  36. package/dist/types/providers.d.ts +12 -1
  37. package/dist/utils/pricing.js +9 -0
  38. package/docs-site/static/search-index.json +84 -59
  39. package/package.json +6 -2
  40. package/dist/client/reactHooks.tsx +0 -1473
@@ -114,9 +114,9 @@
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
116
  {"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
- {"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 and Cloudflare Clef (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":""}},
117
+ {"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
118
  {"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":""}},
119
- {"objectID":"58e5ab0de0df2a0949ae12798cd53ac3133b2c253880bcbf0c573938376fd84f","title":"Neurons β€” LLM Providers","url":"/docs/about/nervous-system-model#neurons-llm-providers","content":"Neurons 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 and Cloudflare Clef (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.","hierarchy":{"lvl0":"About","lvl1":"The Nervous System Model","lvl2":"Neurons β€” LLM Providers","lvl3":""}},
119
+ {"objectID":"58e5ab0de0df2a0949ae12798cd53ac3133b2c253880bcbf0c573938376fd84f","title":"Neurons β€” LLM Providers","url":"/docs/about/nervous-system-model#neurons-llm-providers","content":"Neurons 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.","hierarchy":{"lvl0":"About","lvl1":"The Nervous System Model","lvl2":"Neurons β€” LLM Providers","lvl3":""}},
120
120
  {"objectID":"96f94c64476fe5567b61e5374da6d1b5c5020e22654c6c082b8936ae3f72eb51","title":"The Pipe β€” NeuroLink","url":"/docs/about/nervous-system-model#the-pipe-neurolink","content":"The 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","hierarchy":{"lvl0":"About","lvl1":"The Nervous System Model","lvl2":"The Pipe β€” NeuroLink","lvl3":""}},
121
121
  {"objectID":"1c74200e8d4572e84dca981b50bb162912b4c6700ea7495d60fe286cfb16347f","title":"Organs β€” Connectors","url":"/docs/about/nervous-system-model#organs-connectors","content":"Organs 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","hierarchy":{"lvl0":"About","lvl1":"The Nervous System Model","lvl2":"Organs β€” Connectors","lvl3":""}},
122
122
  {"objectID":"6c97c4e15e0de12e62fbb1994cc7b18328c9f2b0afa2b721d8f40f01e70d32f7","title":"Why This Model Works","url":"/docs/about/nervous-system-model#why-this-model-works","content":"The 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.","hierarchy":{"lvl0":"About","lvl1":"The Nervous System Model","lvl2":"Why This Model Works","lvl3":""}},
@@ -784,7 +784,7 @@
784
784
  {"objectID":"6df70184b50cfe765cb953c7f99da86bcc5085d7c1bd9c009ad1d936cd313d54","title":"decide [state]","url":"/docs/cli/commands#decide","content":"Get typed, calibrated judgements from a decision model β€” the decide inference type, alongside generate and stream. Takes one state plus a map of named typed questions and prints one answer per question; there is no free text anywhere in the response.\n\n`bash","hierarchy":{"lvl0":"Cli","lvl1":"CLI Command Reference","lvl2":"decide [state]","lvl3":""}},
785
785
  {"objectID":"0076ed0bb97c3c91b6019b1168d3de94687353bc588fc474812ff9a55bf325d3","title":"State as a positional argument","url":"/docs/cli/commands#state-as-a-positional-argument","content":"npx @juspay/neurolink decide \"Refund request for a damaged item\" \\\n --questions '{\"urgent\":{\"type\":\"boolean\",\"instructions\":\"Is this urgent?\"}}'","hierarchy":{"lvl0":"Cli","lvl1":"CLI Command Reference","lvl2":"State as a positional argument","lvl3":""}},
786
786
  {"objectID":"e7605e932a3b0b4ce109cdb2cbb0d1d5012cb18891ee886ed14d4873544bd69e","title":"State and questions from files, raw JSON output","url":"/docs/cli/commands#state-and-questions-from-files-raw-json-output","content":"npx @juspay/neurolink decide --state-file ticket.json \\\n --questions-file questions.json --format json","hierarchy":{"lvl0":"Cli","lvl1":"CLI Command Reference","lvl2":"State and questions from files, raw JSON output","lvl3":""}},
787
- {"objectID":"bbd1f018ee4492d0ec7f492e6a84291f0eaa12b81d211cf285fe6d5ac8ed273d","title":"Ask about an image (XOR, Perplexity and Cloudflare Clef read images); repeat --image for several, or use --video (XOR)","url":"/docs/cli/commands#ask-about-an-image-xor-perplexity-and-cloudflare-clef-read-images-repeat---image-for-several-or-use---video-xor","content":"npx @juspay/neurolink decide \"What color is this?\" --provider xor \\\n --image ./photo.png \\\n --questions '{\"color\":{\"type\":\"choice\",\"instructions\":\"What color is the image?\",\"criteria\":{\"red\":\"red\",\"blue\":\"blue\"}}}'\n\n\n| Option | Description |\n| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| state | The content to judge, as a positional argument (or use --state-file). |\n| --state-file | Path to a file holding the state (plain text or JSON). |\n| --questions | Inline JSON map of questions. Exactly one of this or --questions-file. |\n| --questions-file | Path to a JSON file holding the questions map. |\n| --provider | Decision provider to use: typesafe, laya, xor, subq, perplexity-decider or cloudflare-clef. Defaults to the first configured, in that order (TypeSafe, Laya, XOR, SubQ, Perplexity, Cloudflare Clef). |\n| --model | Overrides the provider's configured model for this call.","hierarchy":{"lvl0":"Cli","lvl1":"CLI Command Reference","lvl2":"Ask about an image (XOR, Perplexity and Cloudflare Clef read images); repeat --image for several, or use --video (XOR)","lvl3":""}},
787
+ {"objectID":"fa49a31228234b0ba43f669692d1eaa0226061bb36c99c5019d4fc0451af9384","title":"Ask about an image (XOR, Perplexity, Cloudflare Clef and OpenAI Decisions read images); repeat --image for several, or use --video (XOR)","url":"/docs/cli/commands#ask-about-an-image-xor-perplexity-cloudflare-clef-and-openai-decisions-read-images-repeat---image-for-several-or-use---video-xor","content":"npx @juspay/neurolink decide \"What color is this?\" --provider xor \\\n --image ./photo.png \\\n --questions '{\"color\":{\"type\":\"choice\",\"instructions\":\"What color is the image?\",\"criteria\":{\"red\":\"red\",\"blue\":\"blue\"}}}'\n\n\n| Option | Description |\n| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| state | The content to judge, as a positional argument (or use --state-file). |\n| --state-file | Path to a file holding the state (plain text or JSON). |\n| --questions | Inline JSON map of questions. Exactly one of this or --questions-file. |\n| --questions-file | Path to a JSON file holding the questions map.","hierarchy":{"lvl0":"Cli","lvl1":"CLI Command Reference","lvl2":"Ask about an image (XOR, Perplexity, Cloudflare Clef and OpenAI Decisions read images); repeat --image for several, or use --video (XOR)","lvl3":""}},
788
788
  {"objectID":"74ddf3bb2432e4cbdfe3a2e78aa95391bd1967ac817b4af735f337554b5b405a","title":"transcribe <file|->","url":"/docs/cli/commands#transcribe","content":"Turn audio into text β€” the transcribe inference type. Pass a file, or - to read the audio from stdin. With no STT provider configured, the built-in local engine (Whistle) runs on this machine with no key; set NEUROLINK_STT_PROVIDER (and that provider's key) to use another one.\n\n`bash","hierarchy":{"lvl0":"Cli","lvl1":"CLI Command Reference","lvl2":"transcribe <file|->","lvl3":""}},
789
789
  {"objectID":"b71aa574620a9889a24a23e9d02ca657151930b6fb1754cb48144df208ef0215","title":"Plain transcription with the default engine","url":"/docs/cli/commands#plain-transcription-with-the-default-engine","content":"npx @juspay/neurolink transcribe meeting.wav","hierarchy":{"lvl0":"Cli","lvl1":"CLI Command Reference","lvl2":"Plain transcription with the default engine","lvl3":""}},
790
790
  {"objectID":"688deed48aeb424e78413fcb7603c09c1d4bea2bc3db5c25d4fe8616a23d9a42","title":"Repair names the engine mis-hears, guarded by the decision model, then an LLM rewrite","url":"/docs/cli/commands#repair-names-the-engine-mis-hears-guarded-by-the-decision-model-then-an-llm-rewrite","content":"npx @juspay/neurolink transcribe call.mp3 \\\n --term \"Acme|akmee,ack me|the company name\" --correct","hierarchy":{"lvl0":"Cli","lvl1":"CLI Command Reference","lvl2":"Repair names the engine mis-hears, guarded by the decision model, then an LLM rewrite","lvl3":""}},
@@ -2629,8 +2629,8 @@
2629
2629
  {"objectID":"b0a5b78dc4cfcabcd52b58ea94936ee81e97b59b5907f058ccba74881a7aeacd","title":"Context-window filtering","url":"/docs/features/classifier-router-catalog#context-window-filtering","content":"Nothing in routing read maxContextTokens before this. Two independent checks\nnow do:\nrankCatalogue() filters candidates whose contextWindow is below the\n request's estimated input tokens, applied only when it would leave something\n behind (an empty result falls back to the unfiltered pool rather than\n routing nowhere).\nThe classifier's own pick is separately vetoed. Even when jev picks a\n model directly, fitsRequest() checks whether that specific model's window\n can hold the request. If it can't, the pick is dropped regardless of\n confidence β€” this is a hard provider error, not a degraded answer, because\n an oversized request against a real model puts that model into ModelPool's\n permanent (10-year) cooldown. A wrong guess here is not \"less accurate,\" it\n is unrecoverable for the life of the process.","hierarchy":{"lvl0":"Features","lvl1":"The model catalogue","lvl2":"Context-window filtering","lvl3":""}},
2630
2630
  {"objectID":"e34966644db91aef39b46ef5c2f2fa259e9c828895197c9b2260a07c6e640bce","title":"What this is bad at","url":"/docs/features/classifier-router-catalog#what-this-is-bad-at","content":"Registry quality is coarse, and the catalogue path never shows its own\n work. Auto-enriched quality is a 3-bucket scale (high/medium/low)\n before buildModelCatalog() turns it into 1/2/3; two \"high\" models\n cannot be separated on capability alone. Worse for this page's topic: because\n the catalogue always populates cost/quality, its rendered line never\n shows the registry's own price, speed bucket, or \"strong at …\" scores β€” only\n the terse capability N / relative cost N form. Declare tiers/quality\n on a hand-declared pool member for finer control over the number itself; there\n is no way to get the richer rendering for a catalogue-sourced model.\nA catalogue candidate's \"relative cost\" is real pricing wearing a relative\n label. buildModelCatalog() seeds it from inputCostPer1K + outputCostPer1K\n β€” a small decimal like 0.00074 β€” not a small integer a host would typically\n pick for a hand-declared cost. The number is still correct and still never\n rendered as currency, but it does not compare cleanly against a hand-declared\n member's cost: 1 in the same pool, since one is a real price and the other\n is an arbitrary scale.\nUnknown-to-the-registry models rank on relative numbers, not real prices.\n A model the registry doesn't know (self-hosted, brand-new) keeps whatever\n cost/quality the host declared, compared only against other declared\n values on the same relative scale β€” never rendered as a dollar figure it\n isn't.\nA wide catalogue is still one choice question, and the cap is hard, not\n smart, when it does bind. Every model adds tokens to that single question;\n maxModels is the safeguard, and a model past it would simply never be\n offered rather than offered with lower priority. Today this is theoretical β€”\n the registry is 64 models against a default cap of 120, so nothing is\n dropped β€” but the mechanism has no ranking behavior for the day a registry\n does exceed it.\nPermissive reachability means occasional dead candidates.","hierarchy":{"lvl0":"Features","lvl1":"The model catalogue","lvl2":"What this is bad at","lvl3":""}},
2631
2631
  {"objectID":"2d7354001109ce1051977450cf365d1f2a8e13b345ad206ee23b1f5466228454","title":"See also","url":"/docs/features/classifier-router-catalog#see-also","content":"Classifier Router\nModel routing with a decision model\nThe decide inference type","hierarchy":{"lvl0":"Features","lvl1":"The model catalogue","lvl2":"See also","lvl3":""}},
2632
- {"objectID":"57703ab4e28ce3ad7f4c83d5d3e43f1b1d5541cbb2ac1d6f10f7a057046f0e1b","title":"Model routing with a decision model","url":"/docs/features/classifier-router-jev-strategy","content":"Model routing with a decision model\n\nThe classifier router has a jev strategy: one\ndecision-model round trip answers difficulty,\nrequired capabilities, risk and the model pick simultaneously, with a\ncalibrated confidence on each. This page is the strategy's own mechanics β€”\nclassifier-router.md covers the router as a whole.\n\nThe degradation contract. With no decision provider configured,\nresolveStrategy() resolves auto to heuristic, exactly as it always did.\nclassifyJev() itself never throws: any failure, timeout, or malformed answer\nfalls back to classifyHeuristic(). Configuring a decision provider (for example TYPESAFE_API_KEY or\nAI_GATEWAY_API_KEY) upgrades routing; it cannot make routing worse than before\nthe key existed. The same holds for PERPLEXITY_API_KEY, which is also the\nPerplexity text provider's key, and for CLOUDFLARE_API_KEY with\nCLOUDFLARE_ACCOUNT_ID, which are also the Cloudflare Workers AI text provider's\ntoken and account id, and for SUBQ_API_KEY. \"Configured\" counts the environment, the instance\ncredentials, and the request's own per-call credentials β€” a host that holds\nno decision key but passes a tenant's credentials: { laya } on a generate()\ncall routes that call with jev, and the decision goes to the tenant's account.\n\nWhat goes into the state\n\nclassifyJev() sends the request truncated to 8000 characters, plus four\nsignals the caller already has on hand:\n\nAlongside it, one batch asks: difficulty (a choice over the five tiers),\nneeds_vision / needs_tools / needs_reasoning (boolean), risky\n(boolean), context (a score β€” see\nper-request context budget), and, only when the\npool has more than one member, model (a choice over the pool, rendered by\nthe catalogue). All of this rides in\none request. On TypeSafe that takes ~400ms, because latency is flat in question\ncount; on Perplexity each further question adds about 65 ms, up to 128 (see\nits guide); on\nCloudflare Clef a small request took 0.3 to 1.0 s on 2026-10-03 (see\nits guide). See\nthe batching rule.\n\nNeuroLink refuses a state it estimates at more than 16,000 tokens (about 60,000\ncharacters of prose) with max_tokens_exceeded, to keep Clef inside what it was\nseen to read in full and inside a timeout a fail-open consumer can afford. A\nlonger request is refused there, and the heuristic classifier's tier stands, as it\ndoes on any failure.\n\nThe difficulty rubric\n\nFive tiers, ordered easiest to hardest, worded about the shape of the work β€”\nthe model is never told a provider or model name:\n\n| Tier | Criterion |\n| ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |\n| trivial | Mechanical and local: rename a symbol, fix a typo, add an import, run one named command, or answer something already stated. |\n| simple | A small localised change or a direct factual answer. One file, one obvious approach. |\n| moderate | Ordinary engineering: implement a well-specified change across a few files, write tests, fix a clearly described bug, review a small diff. |\n| hard | Deep reasoning: architecture and design, debugging a failure whose cause is unknown, security analysis, concurrency, cross-system refactors. |\n| expert | Frontier-level work: ambiguous requirements, novel design with no established pattern, or analysis where a wrong answer is costly and hard to detect. |\n\nAsymmetric confidence bars, and why they differ\n\nA verdict harder than the neutral tier (moderate) spends more if wrong; a\nverdict easier than neutral spends less if wrong. Those are not the same\nmistake:\nRouting a simple task to an expensive model wastes money. Cheap to be wrong\n about, so the bar to route up is low: minUpgradeConfidence defaults to\n 0.3.\nRouting a hard task to a weak model produces a wrong answer. Expensive to be\n wrong about, so the bar to route down is high: minDowngradeConfidence\n defaults to 0.6.\n\nBelow the applicable bar, the difficulty verdict is discarded and the heuristic\nclassifier's tier stands instead β€” not a downgraded jev answer, the ordinary\nzero-cost fallback.\n\nOne case skips both bars: a risky reading above 0.7 forces the tier to at\nleast hard, unconditionally. Risk can only ever raise the tier, never lower\none, and it is not itself gated by confidence.\n\nAsk about the act, not the subject\n\nThe risk question is not \"does this touch production, money, or credentials\":\n\nCarrying out this request would itself change production, move real money,\nexpose credentials, or alter data that cannot be restored. Writing or testing\ncode that deals with such things, without running it against the real system,\ndoes not count.\n\nThe naive phrasing was tried first and scored high on ordinary code that m","hierarchy":{"lvl0":"Features","lvl1":"Model routing with a decision model","lvl2":"","lvl3":""}},
2633
- {"objectID":"bd360e5abf4e93403d1fb23a27c946fed1b86d8d8863a98519338332ca726639","title":"Model routing with a decision model","url":"/docs/features/classifier-router-jev-strategy#model-routing-with-a-decision-model","content":"The classifier router has a jev strategy: one\ndecision-model round trip answers difficulty,\nrequired capabilities, risk and the model pick simultaneously, with a\ncalibrated confidence on each. This page is the strategy's own mechanics β€”\nclassifier-router.md covers the router as a whole.\n\nThe degradation contract. With no decision provider configured,\nresolveStrategy() resolves auto to heuristic, exactly as it always did.\nclassifyJev() itself never throws: any failure, timeout, or malformed answer\nfalls back to classifyHeuristic(). Configuring a decision provider (for example TYPESAFE_API_KEY or\nAI_GATEWAY_API_KEY) upgrades routing; it cannot make routing worse than before\nthe key existed. The same holds for PERPLEXITY_API_KEY, which is also the\nPerplexity text provider's key, and for CLOUDFLARE_API_KEY with\nCLOUDFLARE_ACCOUNT_ID, which are also the Cloudflare Workers AI text provider's\ntoken and account id, and for SUBQ_API_KEY. \"Configured\" counts the environment, the instance\ncredentials, and the request's own per-call credentials β€” a host that holds\nno decision key but passes a tenant's credentials: { laya } on a generate()\ncall routes that call with jev, and the decision goes to the tenant's account.","hierarchy":{"lvl0":"Features","lvl1":"Model routing with a decision model","lvl2":"Model routing with a decision model","lvl3":""}},
2632
+ {"objectID":"57703ab4e28ce3ad7f4c83d5d3e43f1b1d5541cbb2ac1d6f10f7a057046f0e1b","title":"Model routing with a decision model","url":"/docs/features/classifier-router-jev-strategy","content":"Model routing with a decision model\n\nThe classifier router has a jev strategy: one\ndecision-model round trip answers difficulty,\nrequired capabilities, risk and the model pick simultaneously, with a\ncalibrated confidence on each. This page is the strategy's own mechanics β€”\nclassifier-router.md covers the router as a whole.\n\nThe degradation contract. With no decision provider configured,\nresolveStrategy() resolves auto to heuristic, exactly as it always did.\nclassifyJev() itself never throws: any failure, timeout, or malformed answer\nfalls back to classifyHeuristic(). Configuring a decision provider (for example TYPESAFE_API_KEY or\nAI_GATEWAY_API_KEY) upgrades routing; it cannot make routing worse than before\nthe key existed. The same holds for PERPLEXITY_API_KEY, which is also the\nPerplexity text provider's key, and for CLOUDFLARE_API_KEY with\nCLOUDFLARE_ACCOUNT_ID, which are also the Cloudflare Workers AI text provider's\ntoken and account id, and for SUBQ_API_KEY, and for OPENAI_API_KEY, which is also the OpenAI chat\nprovider's key (for a host with only that key auto now resolves to jev,\nanswered by OpenAI Decisions as the last-resort decision provider, unless OPENAI_BASE_URL,\nOPENAI_API_BASE or credentials.openai.baseURL names a host other than https://api.openai.com, which makes it a gateway's key). \"Configured\" counts the environment, the instance\ncredentials, and the request's own per-call credentials β€” a host that holds\nno decision key but passes a tenant's credentials: { laya } on a generate()\ncall routes that call with jev, and the decision goes to the tenant's account.\n\nWhat goes into the state\n\nclassifyJev() sends the request truncated to 8000 characters, plus four\nsignals the caller already has on hand:\n\nAlongside it, one batch asks: difficulty (a choice over the five tiers),\nneeds_vision / needs_tools / needs_reasoning (boolean), risky\n(boolean), context (a score β€” see\nper-request context budget), and, only when the\npool has more than one member, model (a choice over the pool, rendered by\nthe catalogue). All of this rides in\none request. On TypeSafe that takes ~400ms, because latency is flat in question\ncount; on Perplexity each further question adds about 65 ms, up to 128 (see\nits guide); on\nCloudflare Clef a small request took 0.3 to 1.0 s on 2026-10-03 (see\nits guide). See\nthe batching rule.\n\nNeuroLink refuses a state it estimates at more than 16,000 tokens (about 60,000\ncharacters of prose) with max_tokens_exceeded, to keep Clef inside what it was\nseen to read in full and inside a timeout a fail-open consumer can afford. A\nlonger request is refused there, and the heuristic classifier's tier stands, as it\ndoes on any failure.\n\nThe difficulty rubric\n\nFive tiers, ordered easiest to hardest, worded about the shape of the work β€”\nthe model is never told a provider or model name:\n\n| Tier | Criterion |\n| ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |\n| trivial | Mechanical and local: rename a symbol, fix a typo, add an import, run one named command, or answer something already stated. |\n| simple | A small localised change or a direct factual answer. One file, one obvious approach. |\n| moderate | Ordinary engineering: implement a well-specified change across a few files, write tests, fix a clearly described bug, review a small diff. |\n| hard | Deep reasoning: architecture and design, debugging a failure whose cause is unknown, security analysis, concurrency, cross-system refactors. |\n| expert | Frontier-level work: ambiguous requirements, novel design with no established pattern, or analysis where a wrong answer is costly and hard to detect. |\n\nAsymmetric confidence bars, and why they differ\n\nA verdict harder than the neutral tier (moderate) spends more if wrong; a\nverdict easier than neutral spends less if wrong. Those are not the same\nmistake:\nRouting a simple task to an expensive model wastes money. Cheap to be wrong\n about, so the bar to route up is low: minUpgradeConfidence defaults to\n 0.3.\nRouting a hard task to a weak model produces a wrong answer. Expensive to be\n wrong about, so the bar to route down is high: minDowngradeConfidence\n defaults to 0.6.\n\nBelow the applicable bar, the difficulty verdict is discarded and the heuristic\nclassifier's tier stands instead β€” not a downgraded jev answer, the ordinary\nzero-cost fallback.\n\nOne case skips both bars: a risky reading above 0.7 forces the tier to at\nleast hard, unconditionally. Risk can only ever raise the tier, never lower\none, and it is not itself gated by confidence.\n\nAsk about the act, not the subject\n\nThe risk question is not \"does this touch production, mon","hierarchy":{"lvl0":"Features","lvl1":"Model routing with a decision model","lvl2":"","lvl3":""}},
2633
+ {"objectID":"bd360e5abf4e93403d1fb23a27c946fed1b86d8d8863a98519338332ca726639","title":"Model routing with a decision model","url":"/docs/features/classifier-router-jev-strategy#model-routing-with-a-decision-model","content":"The classifier router has a jev strategy: one\ndecision-model round trip answers difficulty,\nrequired capabilities, risk and the model pick simultaneously, with a\ncalibrated confidence on each. This page is the strategy's own mechanics β€”\nclassifier-router.md covers the router as a whole.\n\nThe degradation contract. With no decision provider configured,\nresolveStrategy() resolves auto to heuristic, exactly as it always did.\nclassifyJev() itself never throws: any failure, timeout, or malformed answer\nfalls back to classifyHeuristic(). Configuring a decision provider (for example TYPESAFE_API_KEY or\nAI_GATEWAY_API_KEY) upgrades routing; it cannot make routing worse than before\nthe key existed. The same holds for PERPLEXITY_API_KEY, which is also the\nPerplexity text provider's key, and for CLOUDFLARE_API_KEY with\nCLOUDFLARE_ACCOUNT_ID, which are also the Cloudflare Workers AI text provider's\ntoken and account id, and for SUBQ_API_KEY, and for OPENAI_API_KEY, which is also the OpenAI chat\nprovider's key (for a host with only that key auto now resolves to jev,\nanswered by OpenAI Decisions as the last-resort decision provider, unless OPENAI_BASE_URL,\nOPENAI_API_BASE or credentials.openai.baseURL names a host other than https://api.openai.com, which makes it a gateway's key). \"Configured\" counts the environment, the instance\ncredentials, and the request's own per-call credentials β€” a host that holds\nno decision key but passes a tenant's credentials: { laya } on a generate()\ncall routes that call with jev, and the decision goes to the tenant's account.","hierarchy":{"lvl0":"Features","lvl1":"Model routing with a decision model","lvl2":"Model routing with a decision model","lvl3":""}},
2634
2634
  {"objectID":"a6b27c365174a477eafb6835b9ab5990c7434acd58cb21534f8419ea21c63dd5","title":"What goes into the state","url":"/docs/features/classifier-router-jev-strategy#what-goes-into-the-state","content":"classifyJev() sends the request truncated to 8000 characters, plus four\nsignals the caller already has on hand:\n\nAlongside it, one batch asks: difficulty (a choice over the five tiers),\nneeds_vision / needs_tools / needs_reasoning (boolean), risky\n(boolean), context (a score β€” see\nper-request context budget), and, only when the\npool has more than one member, model (a choice over the pool, rendered by\nthe catalogue). All of this rides in\none request. On TypeSafe that takes ~400ms, because latency is flat in question\ncount; on Perplexity each further question adds about 65 ms, up to 128 (see\nits guide); on\nCloudflare Clef a small request took 0.3 to 1.0 s on 2026-10-03 (see\nits guide). See\nthe batching rule.\n\nNeuroLink refuses a state it estimates at more than 16,000 tokens (about 60,000\ncharacters of prose) with max_tokens_exceeded, to keep Clef inside what it was\nseen to read in full and inside a timeout a fail-open consumer can afford. A\nlonger request is refused there, and the heuristic classifier's tier stands, as it\ndoes on any failure.","hierarchy":{"lvl0":"Features","lvl1":"Model routing with a decision model","lvl2":"What goes into the state","lvl3":""}},
2635
2635
  {"objectID":"ed3d90e1e698e522c2fb4cbd27b81d89a769c3d860bbbb85d004ef5cf1d1090d","title":"The difficulty rubric","url":"/docs/features/classifier-router-jev-strategy#the-difficulty-rubric","content":"Five tiers, ordered easiest to hardest, worded about the shape of the work β€”\nthe model is never told a provider or model name:\n\n| Tier | Criterion |\n| ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |\n| trivial | Mechanical and local: rename a symbol, fix a typo, add an import, run one named command, or answer something already stated. |\n| simple | A small localised change or a direct factual answer. One file, one obvious approach. |\n| moderate | Ordinary engineering: implement a well-specified change across a few files, write tests, fix a clearly described bug, review a small diff. |\n| hard | Deep reasoning: architecture and design, debugging a failure whose cause is unknown, security analysis, concurrency, cross-system refactors. |\n| expert | Frontier-level work: ambiguous requirements, novel design with no established pattern, or analysis where a wrong answer is costly and hard to detect. |","hierarchy":{"lvl0":"Features","lvl1":"Model routing with a decision model","lvl2":"The difficulty rubric","lvl3":""}},
2636
2636
  {"objectID":"2bcf89adce5486bff7cc01f6916f9bf26080de8996ec2277df6e15eb3eb264e3","title":"Asymmetric confidence bars, and why they differ","url":"/docs/features/classifier-router-jev-strategy#asymmetric-confidence-bars-and-why-they-differ","content":"A verdict harder than the neutral tier (moderate) spends more if wrong; a\nverdict easier than neutral spends less if wrong. Those are not the same\nmistake:\nRouting a simple task to an expensive model wastes money. Cheap to be wrong\n about, so the bar to route up is low: minUpgradeConfidence defaults to\n 0.3.\nRouting a hard task to a weak model produces a wrong answer. Expensive to be\n wrong about, so the bar to route down is high: minDowngradeConfidence\n defaults to 0.6.\n\nBelow the applicable bar, the difficulty verdict is discarded and the heuristic\nclassifier's tier stands instead β€” not a downgraded jev answer, the ordinary\nzero-cost fallback.\n\nOne case skips both bars: a risky reading above 0.7 forces the tier to at\nleast hard, unconditionally. Risk can only ever raise the tier, never lower\none, and it is not itself gated by confidence.","hierarchy":{"lvl0":"Features","lvl1":"Model routing with a decision model","lvl2":"Asymmetric confidence bars, and why they differ","lvl3":""}},
@@ -2638,10 +2638,10 @@
2638
2638
  {"objectID":"d90c4af28403b7660202646864195bb2ff353a7f7a29ae72f01fd8aa997a39dd","title":"The model pick faces a bar too β€” but a different one","url":"/docs/features/classifier-router-jev-strategy#the-model-pick-faces-a-bar-too-but-a-different-one","content":"When the pool has more than one member, jev is also asked to choose directly:\n_\"Which of these models is the cheapest one that can still complete this\nrequest correctly?\"_ β€” over\nthe rendered candidate lines.\nThat pick is reported with its own confidence, separate from the difficulty\nconfidence, and the router decides which bar applies:\n\nPicking something costlier than what the difficulty tier would have picked\non its own risks only spending more than necessary, so it clears the low\nupgrade bar. Picking something cheaper risks handing the task to a model\nthat cannot do it, so it must clear the high downgrade bar. Agreeing with the\ntier needs no bar at all. If the pick fails its bar, it is dropped β€” logged as\n\"classifier pick dropped β€” below its bar\" β€” and the tier's own ranked list is\nused instead.\n\nThis is a genuinely different question from the difficulty asymmetry above:\nthat one asks whether the tier is trustworthy; this one asks whether the\nspecific model choice, once a tier is settled, is trustworthy β€” and the two\ncan point in opposite directions (a confident-enough \"hard\" verdict whose model\npick still misses its own, stricter bar).\n\nA pick that cannot physically hold the request is not gated at all β€” it is\ndropped outright, regardless of confidence, because that is a hard provider\nerror rather than a degraded answer: see\nthe catalogue's context-window filtering.\n\nThe llm strategy's picks are exempt from both bars: it reports no confidence\nfor its pick, so a bar would either always pass or always fail. Its picks are\nhonoured exactly as they were before jev existed β€” imposing a bar here would\nsilently change an unrelated, already-shipped strategy.","hierarchy":{"lvl0":"Features","lvl1":"Model routing with a decision model","lvl2":"The model pick faces a bar too β€” but a different one","lvl3":""}},
2639
2639
  {"objectID":"4553a84789531ca2e1bad075175d684e27e4ab3fcbb009062048cdf11765c2fb","title":"What this is bad at","url":"/docs/features/classifier-router-jev-strategy#what-this-is-bad-at","content":"It cannot tell you why. The reason field is a debug string built from\n the numbers, not an explanation the model gave. If you need an auditable\n rationale for a routing decision, this is the wrong tool.\nA close call still routes somewhere. A 0.29 upgrade verdict and a 0.61\n downgrade verdict are both one hundredth of a point from the bar, and both\n fall all the way back to the heuristic tier rather than to \"the second most\n likely tier.\" There is no partial credit.\nThe risk question is a single boolean. It cannot express \"risky, but\n only mildly\" β€” anything past 0.7 jumps straight to hard, whatever the\n actual severity.\nIt shares the base model's general limits. Literal reading, no\n arithmetic, and state relevance affecting accuracy all apply here exactly as\n described in what decide is bad at.\nThe pool still has to exist. jev chooses among what you declared (or\n what the catalogue built); it\n cannot invent a model you have no credentials for.","hierarchy":{"lvl0":"Features","lvl1":"Model routing with a decision model","lvl2":"What this is bad at","lvl3":""}},
2640
2640
  {"objectID":"ab4d25365369a722077741378e60be6e3ef36f612ed7a85340c93cf9d47223da","title":"See also","url":"/docs/features/classifier-router-jev-strategy#see-also","content":"The decide inference type\nClassifier Router\nThe model catalogue\nPer-request context budget","hierarchy":{"lvl0":"Features","lvl1":"Model routing with a decision model","lvl2":"See also","lvl3":""}},
2641
- {"objectID":"3f990fb1489f99d505b19941e00fd05b9368a5a91745c83666639aac85865343","title":"Classifier Router","url":"/docs/features/classifier-router","content":"Classifier Router\n\nStatus: Stable | Availability: SDK + CLI | Opt-in (disabled by default)\n\nOverview\n\nThe Classifier Router lets NeuroLink decide, per request, which model to use (and, optionally, which tools to expose) from a pool you declare β€” routing hard/complex tasks to more capable models and easy tasks to cheaper, faster ones. You give it a pool of models; it classifies the incoming prompt and switches to the best one transparently before the call runs.\n\nIt is opt-in (classifierRouter.enabled defaults to false), fails open (any classifier/selection error leaves the call exactly as it would have been), and is fully backward compatible β€” a default new NeuroLink() is unchanged.\n\nTypical use cases:\nCost optimization β€” send \"hi\" to a cheap model and a multi-step architecture question to a powerful one, automatically.\nLatency optimization β€” keep simple turns on fast models.\nCustom / self-hosted fleets β€” route across LiteLLM, OpenAI-compatible, or Ollama models that aren't in any registry.\nPer-difficulty tool scoping β€” expose fewer tools for trivial tasks.\n\nHow it works\n\nEach request flows through two stages:\nClassify β€” produce a difficulty bucket (trivial | simple | moderate | hard | expert) plus optional requiredCapabilities and tool hints. Four strategies:\nauto (default): resolves to jev when a decision provider is configured (TYPESAFE_API_KEY or AI_GATEWAY_API_KEY, LAYA_API_KEY with LAYA_BASE_URL, XOR_API_KEY with XOR_BASE_URL, SUBQ_API_KEY, PERPLEXITY_API_KEY, or CLOUDFLARE_API_KEY with CLOUDFLARE_ACCOUNT_ID), and heuristic otherwise. Setting a key therefore upgrades routing with no code change; without one, behaviour is exactly as it was. PERPLEXITY_API_KEY is also the Perplexity text provider's key, so it counts here too, and CLOUDFLARE_API_KEY with CLOUDFLARE_ACCOUNT_ID are also the Cloudflare Workers AI text provider's token and account id, so they count here as well. The gate counts the credentials given to the NeuroLink constructor, the environment and the request's own per-call credentials, so a credentials.subq.apiKey (or credentials.laya, credentials.xor, credentials.perplexityDecider, credentials.cloudflareClef and the other decision providers' slices) passed on a single call can make auto pick jev rather than heuristic, and the decision then goes to that account.\nheuristic: zero-cost keyword/length scoring of the prompt text. No LLM call, fully deterministic, provider-agnostic.\nllm: a cheap \"classifier model\" reads the prompt and returns a difficulty β€” and, when given your pool, picks a model directly by id.\njev: a decision model (the first configured decision provider, in the order TypeSafe's Jev, Laya, XOR, SubQ, Perplexity, Cloudflare Clef) answers difficulty, required capabilities and the model pick in one request, with a confidence for each answer. On TypeSafe's Jev that request takes ~400 ms and the confidence is calibrated; the Perplexity guide gives its latency and the confidence it reports, and the Cloudflare Clef guide gives its latency and its state limit (16,000 estimated tokens, so a longer prompt is refused and the heuristic stands). Verdicts that miss the applicable confidence bar (minUpgradeConfidence 0.3 to route up, minDowngradeConfidence 0.6 to route down) fall through to the heuristic rather than acting on a guess. See the decide inference type.\nSelect β€” turn that into a concrete { provider, model, region } from your pool, optionally narrowing tools.\n\nThe router runs before the provider/model is constructed (it reuses the same pre-call seam as requestRouter). It is skipped when the caller pinned both provider and model, or when a modelPool is configured (the pool owns selection).\n\nQuick start (heuristic, SDK)\n\nDefining \"which model for which case\"\n\nThe router resolves a model using the first of these that applies:\n\n| # | Mechanism | How you define it | Best for |\n| --- | ---------------------- | ---------------------------------------------------------------------------------- | ------------------------------------- |\n| 1 | LLM direct pick | classifier: \"llm\" + a description on each pool member | Custom/registry-less models; smartest |\n| 2 | tierMap | Explicit difficulty β†’ members map | Full, deterministic control |\n| 3 | Per-member tiers | tiers: [\"hard\",\"expert\"] on a member | Simple, explicit, generic |\n| 4 | Metadata scoring | cost / quality per member (declared, or auto-enriched from the model registry) | Known models with comparable metadata |\n\nWhen two members can't be separated (e.g. equal declared quality, or the model registry only knows both as \"high\" quality), the router keeps the declared pool order. For reliable hard-vs-easy separation, prefer mechanisms 1–3, or give members distinct quality va","hierarchy":{"lvl0":"Features","lvl1":"Classifier Router","lvl2":"","lvl3":""}},
2641
+ {"objectID":"3f990fb1489f99d505b19941e00fd05b9368a5a91745c83666639aac85865343","title":"Classifier Router","url":"/docs/features/classifier-router","content":"Classifier Router\n\nStatus: Stable | Availability: SDK + CLI | Opt-in (disabled by default)\n\nOverview\n\nThe Classifier Router lets NeuroLink decide, per request, which model to use (and, optionally, which tools to expose) from a pool you declare β€” routing hard/complex tasks to more capable models and easy tasks to cheaper, faster ones. You give it a pool of models; it classifies the incoming prompt and switches to the best one transparently before the call runs.\n\nIt is opt-in (classifierRouter.enabled defaults to false), fails open (any classifier/selection error leaves the call exactly as it would have been), and is fully backward compatible β€” a default new NeuroLink() is unchanged.\n\nTypical use cases:\nCost optimization β€” send \"hi\" to a cheap model and a multi-step architecture question to a powerful one, automatically.\nLatency optimization β€” keep simple turns on fast models.\nCustom / self-hosted fleets β€” route across LiteLLM, OpenAI-compatible, or Ollama models that aren't in any registry.\nPer-difficulty tool scoping β€” expose fewer tools for trivial tasks.\n\nHow it works\n\nEach request flows through two stages:\nClassify β€” produce a difficulty bucket (trivial | simple | moderate | hard | expert) plus optional requiredCapabilities and tool hints. Four strategies:\nauto (default): resolves to jev when a decision provider is configured (TYPESAFE_API_KEY or AI_GATEWAY_API_KEY, LAYA_API_KEY with LAYA_BASE_URL, XOR_API_KEY with XOR_BASE_URL, SUBQ_API_KEY, PERPLEXITY_API_KEY, CLOUDFLARE_API_KEY with CLOUDFLARE_ACCOUNT_ID, or OPENAI_API_KEY), and heuristic otherwise. Setting a key therefore upgrades routing with no code change; without one, behaviour is exactly as it was. PERPLEXITY_API_KEY is also the Perplexity text provider's key, so it counts here too, and CLOUDFLARE_API_KEY with CLOUDFLARE_ACCOUNT_ID are also the Cloudflare Workers AI text provider's token and account id, so they count here as well; OPENAI_API_KEY is also the OpenAI chat provider's key, so for a host with only that key auto now resolves to jev, answered by OpenAI Decisions as the last-resort decision provider (a paid call, though routing still falls back to the heuristic on any failure), unless OPENAI_BASE_URL, OPENAI_API_BASE or credentials.openai.baseURL names a host other than https://api.openai.com: that key is taken to be a gateway's and auto stays on heuristic. The gate counts the credentials given to the NeuroLink constructor, the environment and the request's own per-call credentials, so a credentials.subq.apiKey (or credentials.laya, credentials.xor, credentials.perplexityDecider, credentials.cloudflareClef, credentials.openaiDecisions and the other decision providers' slices) passed on a single call can make auto pick jev rather than heuristic, and the decision then goes to that account.\nheuristic: zero-cost keyword/length scoring of the prompt text. No LLM call, fully deterministic, provider-agnostic.\nllm: a cheap \"classifier model\" reads the prompt and returns a difficulty β€” and, when given your pool, picks a model directly by id.\njev: a decision model (the first configured decision provider, in the order TypeSafe's Jev, Laya, XOR, SubQ, Perplexity, Cloudflare Clef, OpenAI Decisions) answers difficulty, required capabilities and the model pick in one request, with a confidence for each answer. On TypeSafe's Jev that request takes ~400 ms and the confidence is calibrated; the Perplexity guide gives its latency and the confidence it reports, and the Cloudflare Clef guide gives its latency and its state limit (16,000 estimated tokens, so a longer prompt is refused and the heuristic stands). Verdicts that miss the applicable confidence bar (minUpgradeConfidence 0.3 to route up, minDowngradeConfidence 0.6 to route down) fall through to the heuristic rather than acting on a guess. See the decide inference type.\nSelect β€” turn that into a concrete { provider, model, region } from your pool, optionally narrowing tools.\n\nThe router runs before the provider/model is constructed (it reuses the same pre-call seam as requestRouter). It is skipped when the caller pinned both provider and model, or when a modelPool is configured (the pool owns selection).\n\nQuick start (heuristic, SDK)\n\nDefining \"which model for which case\"\n\nThe router resolves a model using the first of these that applies:\n\n| # | Mechanism | How you define it | Best for |\n| --- | ---------------------- | ---------------------------------------------------------------------------------- | ------------------------------------- |\n| 1 | LLM direct pick | classifier: \"llm\" + a description on each pool member | Custom/registry-less models; smartest |\n| 2 | tierMap | Explicit difficulty β†’ members map | Full, deterministic control |\n| 3 | Per-member tiers | tiers: [\"hard\",\"expert\"] on a ","hierarchy":{"lvl0":"Features","lvl1":"Classifier Router","lvl2":"","lvl3":""}},
2642
2642
  {"objectID":"b8bb35b0db438959a0a557c68b22afa16480504b96128260a8947ba3c8a81f9f","title":"Classifier Router","url":"/docs/features/classifier-router#classifier-router","content":"Status: Stable | Availability: SDK + CLI | Opt-in (disabled by default)","hierarchy":{"lvl0":"Features","lvl1":"Classifier Router","lvl2":"Classifier Router","lvl3":""}},
2643
2643
  {"objectID":"543ddabeefd7754f6047758090a6a0ac6f517c98b9afb146645b9073ad75c5ee","title":"Overview","url":"/docs/features/classifier-router#overview","content":"The Classifier Router lets NeuroLink decide, per request, which model to use (and, optionally, which tools to expose) from a pool you declare β€” routing hard/complex tasks to more capable models and easy tasks to cheaper, faster ones. You give it a pool of models; it classifies the incoming prompt and switches to the best one transparently before the call runs.\n\nIt is opt-in (classifierRouter.enabled defaults to false), fails open (any classifier/selection error leaves the call exactly as it would have been), and is fully backward compatible β€” a default new NeuroLink() is unchanged.\n\nTypical use cases:\nCost optimization β€” send \"hi\" to a cheap model and a multi-step architecture question to a powerful one, automatically.\nLatency optimization β€” keep simple turns on fast models.\nCustom / self-hosted fleets β€” route across LiteLLM, OpenAI-compatible, or Ollama models that aren't in any registry.\nPer-difficulty tool scoping β€” expose fewer tools for trivial tasks.","hierarchy":{"lvl0":"Features","lvl1":"Classifier Router","lvl2":"Overview","lvl3":""}},
2644
- {"objectID":"abdbdbfcfd51c6b40ef9cdf848fa23aeb87e4e4513c71572f89ee754be41d834","title":"How it works","url":"/docs/features/classifier-router#how-it-works","content":"Each request flows through two stages:\nClassify β€” produce a difficulty bucket (trivial | simple | moderate | hard | expert) plus optional requiredCapabilities and tool hints. Four strategies:\nauto (default): resolves to jev when a decision provider is configured (TYPESAFE_API_KEY or AI_GATEWAY_API_KEY, LAYA_API_KEY with LAYA_BASE_URL, XOR_API_KEY with XOR_BASE_URL, SUBQ_API_KEY, PERPLEXITY_API_KEY, or CLOUDFLARE_API_KEY with CLOUDFLARE_ACCOUNT_ID), and heuristic otherwise. Setting a key therefore upgrades routing with no code change; without one, behaviour is exactly as it was. PERPLEXITY_API_KEY is also the Perplexity text provider's key, so it counts here too, and CLOUDFLARE_API_KEY with CLOUDFLARE_ACCOUNT_ID are also the Cloudflare Workers AI text provider's token and account id, so they count here as well. The gate counts the credentials given to the NeuroLink constructor, the environment and the request's own per-call credentials, so a credentials.subq.apiKey (or credentials.laya, credentials.xor, credentials.perplexityDecider, credentials.cloudflareClef and the other decision providers' slices) passed on a single call can make auto pick jev rather than heuristic, and the decision then goes to that account.\nheuristic: zero-cost keyword/length scoring of the prompt text. No LLM call, fully deterministic, provider-agnostic.\nllm: a cheap \"classifier model\" reads the prompt and returns a difficulty β€” and, when given your pool, picks a model directly by id.\njev: a decision model (the first configured decision provider, in the order TypeSafe's Jev, Laya, XOR, SubQ, Perplexity, Cloudflare Clef) answers difficulty, required capabilities and the model pick in one request, with a confidence for each answer.","hierarchy":{"lvl0":"Features","lvl1":"Classifier Router","lvl2":"How it works","lvl3":""}},
2644
+ {"objectID":"abdbdbfcfd51c6b40ef9cdf848fa23aeb87e4e4513c71572f89ee754be41d834","title":"How it works","url":"/docs/features/classifier-router#how-it-works","content":"Each request flows through two stages:\nClassify β€” produce a difficulty bucket (trivial | simple | moderate | hard | expert) plus optional requiredCapabilities and tool hints. Four strategies:\nauto (default): resolves to jev when a decision provider is configured (TYPESAFE_API_KEY or AI_GATEWAY_API_KEY, LAYA_API_KEY with LAYA_BASE_URL, XOR_API_KEY with XOR_BASE_URL, SUBQ_API_KEY, PERPLEXITY_API_KEY, CLOUDFLARE_API_KEY with CLOUDFLARE_ACCOUNT_ID, or OPENAI_API_KEY), and heuristic otherwise. Setting a key therefore upgrades routing with no code change; without one, behaviour is exactly as it was. PERPLEXITY_API_KEY is also the Perplexity text provider's key, so it counts here too, and CLOUDFLARE_API_KEY with CLOUDFLARE_ACCOUNT_ID are also the Cloudflare Workers AI text provider's token and account id, so they count here as well; OPENAI_API_KEY is also the OpenAI chat provider's key, so for a host with only that key auto now resolves to jev, answered by OpenAI Decisions as the last-resort decision provider (a paid call, though routing still falls back to the heuristic on any failure), unless OPENAI_BASE_URL, OPENAI_API_BASE or credentials.openai.baseURL names a host other than https://api.openai.com: that key is taken to be a gateway's and auto stays on heuristic. The gate counts the credentials given to the NeuroLink constructor, the environment and the request's own per-call credentials, so a credentials.subq.apiKey (or credentials.laya, credentials.xor, credentials.perplexityDecider, credentials.cloudflareClef, credentials.openaiDecisions and the other decision providers' slices) passed on a single call can make auto pick jev rather than heuristic, and the decision then goes to that account.\nheuristic: zero-cost keyword/length scoring of the prompt text. No LLM call, fully deterministic, provider-agnostic.\nllm: a cheap \"classifier model\" reads the prompt and returns a difficulty β€” and, when given your pool, picks a model directly by id.","hierarchy":{"lvl0":"Features","lvl1":"Classifier Router","lvl2":"How it works","lvl3":""}},
2645
2645
  {"objectID":"08f69ffa1f39bf410a5c236efa5f21f51efc93034747ddab6d761f4b1615d7df","title":"Defining \"which model for which case\"","url":"/docs/features/classifier-router#defining-which-model-for-which-case","content":"The router resolves a model using the first of these that applies:\n\n| # | Mechanism | How you define it | Best for |\n| --- | ---------------------- | ---------------------------------------------------------------------------------- | ------------------------------------- |\n| 1 | LLM direct pick | classifier: \"llm\" + a description on each pool member | Custom/registry-less models; smartest |\n| 2 | tierMap | Explicit difficulty β†’ members map | Full, deterministic control |\n| 3 | Per-member tiers | tiers: [\"hard\",\"expert\"] on a member | Simple, explicit, generic |\n| 4 | Metadata scoring | cost / quality per member (declared, or auto-enriched from the model registry) | Known models with comparable metadata |\n\nWhen two members can't be separated (e.g. equal declared quality, or the model registry only knows both as \"high\" quality), the router keeps the declared pool order. For reliable hard-vs-easy separation, prefer mechanisms 1–3, or give members distinct quality values.","hierarchy":{"lvl0":"Features","lvl1":"Classifier Router","lvl2":"Defining \"which model for which case\"","lvl3":""}},
2646
2646
  {"objectID":"bd4863bf711f00f17fb26ea1e60a541aef1f396afc1050ee47b9e29731c90f9a","title":"Metadata scoring rules","url":"/docs/features/classifier-router#metadata-scoring-rules","content":"trivial / simple β†’ cheapest first (cost ascending)\nmoderate β†’ best quality βˆ’ cost\nhard / expert β†’ most capable first (quality descending)\n\nMembers may declare cost (relative, lower = cheaper) and quality (relative, higher = more capable). If omitted, NeuroLink tries to enrich them from its model registry; if the model is unknown (e.g. a custom LiteLLM endpoint), use mechanisms 1–3 instead.","hierarchy":{"lvl0":"Features","lvl1":"Classifier Router","lvl2":"Metadata scoring rules","lvl3":""}},
2647
2647
  {"objectID":"9e5f93906c1460117b27372537b30d578daec8b1d3fc38ecf1b0fb05c9944801","title":"Custom & self-hosted models (LiteLLM, OpenAI-compatible, Ollama)","url":"/docs/features/classifier-router#custom-self-hosted-models-litellm-openai-compatible-ollama","content":"These models aren't in any registry, so define routing explicitly β€” both approaches are fully generic:\n\nHeuristic + tiers (deterministic, no LLM cost):\n\nLLM picks per-prompt from plain-English descriptions (most flexible):\n\nThe classifier model is shown each candidate's id (defaults to provider/model) and description, and returns the best id for the prompt. An invalid or absent pick falls back to difficulty-based selection; any classifier failure falls back to the heuristic.","hierarchy":{"lvl0":"Features","lvl1":"Classifier Router","lvl2":"Custom & self-hosted models (LiteLLM, OpenAI-compatible, Ollama)","lvl3":""}},
@@ -2650,7 +2650,7 @@
2650
2650
  {"objectID":"cc0754af3d357fb93691ebfaad77343948f167866e856d3e941738c8293fa323","title":"Heuristic routing across a pool (inline JSON or a file path)","url":"/docs/features/classifier-router#heuristic-routing-across-a-pool-inline-json-or-a-file-path","content":"neurolink generate \"hi\" \\\n --classifier-router \\\n --classifier-pool '[{\"provider\":\"vertex\",\"model\":\"gemini-2.5-flash\",\"tiers\":[\"trivial\",\"simple\",\"moderate\"]},{\"provider\":\"vertex\",\"model\":\"gemini-2.5-pro\",\"tiers\":[\"hard\",\"expert\"]}]'","hierarchy":{"lvl0":"Features","lvl1":"Classifier Router","lvl2":"Heuristic routing across a pool (inline JSON or a file path)","lvl3":""}},
2651
2651
  {"objectID":"c1599b72e48c45d71d427eff367de7a998cb96e25063546d18d1d8a9a520a74d","title":"LLM classifier picks the model per prompt (descriptions drive the choice)","url":"/docs/features/classifier-router#llm-classifier-picks-the-model-per-prompt-descriptions-drive-the-choice","content":"neurolink generate \"Design a multi-region architecture\" \\\n --classifier-router \\\n --classifier-strategy llm \\\n --classifier-model-provider vertex --classifier-model-name gemini-2.5-flash \\\n --classifier-pool ./pool.json\n\n\n| Flag | Description |\n| --------------------------------------- | ------------------------------------------------------- |\n| --classifier-router | Enable the classifier router. |\n| --classifier-strategy | auto (default), heuristic, llm or jev. |\n| --classifier-min-upgrade-confidence | Confidence needed to route UP (jev; 0.3). |\n| --classifier-min-downgrade-confidence | Confidence needed to route DOWN (jev; 0.6). |\n| --classifier-model-provider | Provider for the LLM classifier model (strategy=llm). |\n| --classifier-model-name | Model name for the LLM classifier model. |\n| --classifier-model-region | Region for the LLM classifier model. |\n| --classifier-pool | JSON file path or inline JSON array of pool members. |\n| --classifier-timeout | LLM classifier hard timeout (ms). |\n\n> CLI flags cover the common case (strategy, classifier model, pool). For tierMap and toolDirectives`, use the SDK config.","hierarchy":{"lvl0":"Features","lvl1":"Classifier Router","lvl2":"LLM classifier picks the model per prompt (descriptions drive the choice)","lvl3":""}},
2652
2652
  {"objectID":"9fe3ff72b1728db15b0ad44eb4108926b4917c45feb4a7f6842cf5c247d300e3","title":"Precedence & interactions","url":"/docs/features/classifier-router#precedence-interactions","content":"Model selection resolves in this order: caller-pinned provider+model > classifierRouter > requestRouter > legacy enableOrchestration. The classifier marks the request so the downstream selectors stand down.\nmodelPool β€” when a modelPool is configured the classifier stands down (the pool owns selection); use one or the other for model choice.\ntoolRouting β€” the dedicated tool-routing feature still applies; classifier toolDirectives are additive.","hierarchy":{"lvl0":"Features","lvl1":"Classifier Router","lvl2":"Precedence & interactions","lvl3":""}},
2653
- {"objectID":"fac896bd6ef5ba1295df2e3b8249209a904d5a4b66780e388934069517ed6014","title":"Caveats","url":"/docs/features/classifier-router#caveats","content":"Registry quality is coarse. Auto-enrichment maps a model to a 3-bucket quality (high/medium/low), so two \"high\" models can't be separated on capability alone β€” declare quality/tiers/tierMap or use the LLM pick for reliable hard-vs-easy routing.\nLLM classifier latency/cost. The llm strategy adds one cheap call per uncached turn; prefer a small, fast, non-Gemini model and use heuristic where determinism matters.\nJev confidence is a gate, not a score. Unlike the llm strategy β€” whose self-reported confidence defaults to a hard-coded 0.7 when the model omits it β€” jev returns the confidence the decision provider reports (calibrated, on TypeSafe's Jev) rather than a constant, which is what makes minConfidence meaningful. The two bars differ because the mistakes cost differently: spending more on a wrong guess wastes money, spending less produces a wrong answer. Set either above 1 to force the heuristic while leaving the strategy configured.\nGemini tools + JSON schema. The classifier call uses a schema with tools disabled, so the Gemini exclusivity rule doesn't apply to it; when routing a tools + structured-output request, prefer a non-Gemini target model.\nPrompt privacy (llm and jev). Both strategies send a truncated copy of the prompt off-machine β€” to the classifier model, or to the configured decision provider β€” so the same data-handling and retention considerations as any provider call apply. heuristic keeps classification fully in-process (no prompt leaves your environment); prefer it where that matters, and note that auto selects jev as soon as a decision provider's key is present, including a PERPLEXITY_API_KEY set only for the Perplexity text provider, or a CLOUDFLARE_API_KEY and CLOUDFLARE_ACCOUNT_ID set only for the Cloudflare Workers AI text provider.","hierarchy":{"lvl0":"Features","lvl1":"Classifier Router","lvl2":"Caveats","lvl3":""}},
2653
+ {"objectID":"fac896bd6ef5ba1295df2e3b8249209a904d5a4b66780e388934069517ed6014","title":"Caveats","url":"/docs/features/classifier-router#caveats","content":"Registry quality is coarse. Auto-enrichment maps a model to a 3-bucket quality (high/medium/low), so two \"high\" models can't be separated on capability alone β€” declare quality/tiers/tierMap or use the LLM pick for reliable hard-vs-easy routing.\nLLM classifier latency/cost. The llm strategy adds one cheap call per uncached turn; prefer a small, fast, non-Gemini model and use heuristic where determinism matters.\nJev confidence is a gate, not a score. Unlike the llm strategy β€” whose self-reported confidence defaults to a hard-coded 0.7 when the model omits it β€” jev returns the confidence the decision provider reports (calibrated, on TypeSafe's Jev) rather than a constant, which is what makes minConfidence meaningful. The two bars differ because the mistakes cost differently: spending more on a wrong guess wastes money, spending less produces a wrong answer. Set either above 1 to force the heuristic while leaving the strategy configured.\nGemini tools + JSON schema. The classifier call uses a schema with tools disabled, so the Gemini exclusivity rule doesn't apply to it; when routing a tools + structured-output request, prefer a non-Gemini target model.\nPrompt privacy (llm and jev). Both strategies send a truncated copy of the prompt off-machine β€” to the classifier model, or to the configured decision provider β€” so the same data-handling and retention considerations as any provider call apply. heuristic keeps classification fully in-process (no prompt leaves your environment); prefer it where that matters, and note that auto selects jev as soon as a decision provider's key is present, including a PERPLEXITY_API_KEY set only for the Perplexity text provider, a CLOUDFLARE_API_KEY and CLOUDFLARE_ACCOUNT_ID set only for the Cloudflare Workers AI text provider, or an OPENAI_API_KEY set only for the OpenAI chat provider.","hierarchy":{"lvl0":"Features","lvl1":"Classifier Router","lvl2":"Caveats","lvl3":""}},
2654
2654
  {"objectID":"44f6d5bc4c0e752129323d87508ca78b8f296e06d39a994f0b93706adff75033","title":"See also","url":"/docs/features/classifier-router#see-also","content":"Provider Orchestration & Model Pool\nProvider Fallback\nPer-Request Credentials\nModel routing with a decision model\nThe model catalogue","hierarchy":{"lvl0":"Features","lvl1":"Classifier Router","lvl2":"See also","lvl3":""}},
2655
2655
  {"objectID":"2c5c9a8afc6acb37fc955bbc5ed44588962efef98dbf7e9dd26126eb58d08241","title":"Claude Proxy Architecture","url":"/docs/features/claude-proxy-architecture","content":"Claude Proxy Architecture\nSystem Overview\n\nThe Claude proxy is a local HTTP server that sits between Claude Code and the Anthropic API. It provides multi-account rotation, automatic token refresh, rate-limit handling with exponential backoff, and optional model translation to non-Anthropic providers.\n\nTwo operational modes\n\n| Mode | When | What happens |\n| --------------- | ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Passthrough | Target provider is anthropic (or null) | The request body is forwarded byte-for-byte to api.anthropic.com via plain fetch() with client headers forwarded. No parsing, no tool injection, no SDK involvement. |\n| Translation | Target provider is anything else (e.g. vertex, openai) | The Claude-format request is parsed by parseClaudeRequest(), routed through ctx.neurolink.stream() / ctx.neurolink.generate(), and the NeuroLink response is serialized back to Claude SSE format via ClaudeStreamSerializer. |\n\nPassthrough exists because Claude Code sends complex bodies (multi-turn conversations, tool definitions, thinking blocks, context management betas) that would be lossy to parse and re-serialize. The proxy's job for Claude-to-Claude is purely auth and account management.\n\nHow it fits into NeuroLink\n\nThe proxy is started via the CLI (neurolink proxy start) and creates a Hono HTTP server. It registers routes from createClaudeProxyRoutes() and injects a live NeuroLink SDK instance into the request context for translation-mode and fallback paths. MCP initialization is explicitly skipped (NEUROLINK_SKIP_MCP=true) because tools come from Claude Code, not from MCP servers.\nRequest Lifecycle\n\nA complete request through the passthrough path:\nAccount Management\n\nAccount loading priority\n\nAccounts are loaded in the POST /v1/messages handler on every request (not cached across requests), in this order:\nTokenStore compound keys (anthropic:<label>) β€” The primary source. tokenStore.listProviders() returns all stored keys; those starting with anthropic: are loaded via tokenStore.loadTokens(key). Each yields { accessToken, refreshToken, expiresAt }.\nLegacy credentials file (~/.neurolink/anthropic-credentials.json) β€” Only checked when zero compound keys exist. Reads creds.oauth.accessToken directly from JSON.\nEnvironment variable (ANTHROPIC_API_KEY) β€” Only used when no OAuth accounts were found at all. Creates a single api_key-type account.\n\nAccount selection: strategy-driven with fill-first default\n\nThe request handler supports two real account-selection strategies:\nfill-first (default) β€” always begin with the current primary account and stay on it until it cools down or fails.\nround-robin β€” rotate the starting account on each request, then try the remaining accounts sequentially.\n\nExpired accounts are pruned at startup via tokenStore.pruneExpired() (one-time). Accounts that are persisted as disabled (via tokenStore.isDisabled()) are skipped. Expired tokens with a refresh token get one refresh attempt at startup; on failure, the account is disabled until re-authentication.\n\nThe CLI --strategy flag and the proxy config routing.strategy field both map directly to this account ordering logic. There are only two supported values today: fill-first and round-robin.\n\nPer-status cooldowns\n\n| HTTP Status | Cooldown | Behavior |\n| ------------------------------------ | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| 429 (rate limit) | Exponential backoff (see below) | Continue to next account |\n| 401/402/403 (auth failure) | 5 minutes (AUTH_COOLDOWN_MS) | Attempt token refresh first (up to 5 retries); if all fail, cooldown and continue. After 15 consecutive refresh failures, account permanently disabled. |\n| 404 (not found) | None | Return error immediately (no failover) |\n| 5xx, 52x (t","hierarchy":{"lvl0":"Features","lvl1":"Claude Proxy Architecture","lvl2":"","lvl3":""}},
2656
2656
  {"objectID":"9992141969480e207aca925aec7f3d174e0dda96fa7b13097cf2b0d671cf7114","title":"1. System Overview","url":"/docs/features/claude-proxy-architecture#1-system-overview","content":"The Claude proxy is a local HTTP server that sits between Claude Code and the Anthropic API. It provides multi-account rotation, automatic token refresh, rate-limit handling with exponential backoff, and optional model translation to non-Anthropic providers.","hierarchy":{"lvl0":"Features","lvl1":"Claude Proxy Architecture","lvl2":"1. System Overview","lvl3":""}},
@@ -3247,7 +3247,7 @@
3247
3247
  {"objectID":"a18da32e2f63d235059c36cf45cff486c8f1dc0c4d4e55ee5f239dd89ede5d21","title":"BudgetCheckResult","url":"/docs/features/context-compaction#budgetcheckresult","content":"Returned by checkContextBudget().","hierarchy":{"lvl0":"Features","lvl1":"Context Compaction","lvl2":"BudgetCheckResult","lvl3":""}},
3248
3248
  {"objectID":"1a2b7ee1dace651a8300809eec11e00b29da084cbfe5b040e4760d58ea0b5879","title":"BudgetCheckParams","url":"/docs/features/context-compaction#budgetcheckparams","content":"Parameters for checkContextBudget().\n\nSource: src/lib/context/budgetChecker.ts:18-54","hierarchy":{"lvl0":"Features","lvl1":"Context Compaction","lvl2":"BudgetCheckParams","lvl3":""}},
3249
3249
  {"objectID":"4bad23fd2858cc71b5af8506276229485c7d0a9636cfddae5c5d9df400bc28b8","title":"The 5-Stage Pipeline","url":"/docs/features/context-compaction#the-5-stage-pipeline","content":"The ContextCompactor runs stages sequentially. Each stage only runs if the\nprevious stage didn't bring tokens below the target budget.\n\n| # | Stage | CompactionStage | Needs a decision model |\n| --- | ------------------------- | ----------------- | -------------------------------------- |\n| 0 | Relevance drop | relevance | yes β€” skipped entirely without one |\n| 1 | Tool output pruning | prune | no |\n| 2 | File read deduplication | deduplicate | no |\n| 3 | LLM summarization | summarize | no (its gate uses one) |\n| 4 | Sliding window truncation | truncate | no |\n\nresult.stagesUsed reports the ones that actually ran, in order.","hierarchy":{"lvl0":"Features","lvl1":"Context Compaction","lvl2":"The 5-Stage Pipeline","lvl3":""}},
3250
- {"objectID":"918fce938e3acd086621a86be0faaaecccf78059d8a0ef53b2dbc4fcd87347a1","title":"Stage 0: Relevance drop","url":"/docs/features/context-compaction#stage-0-relevance-drop","content":"File: src/lib/context/contextDecision.ts\n\nEverything below Stage 0 is chronological: the pipeline's only notion of\n\"droppable\" is \"old\". Stage 0 is the one stage that asks what a message is\nfor β€” one boolean per message (\"is this needed to answer the current\nrequest?\") in a single batch. On TypeSafe that costs the same for 200 messages\nas for one because decision latency is flat in question count; on Perplexity each\nfurther question adds about 65 ms and a request takes at most 128 (see\nits guide); on\nCloudflare Clef a request takes at most 64 questions, which tryDecide() splits\ninto batches of 64 (see its guide).\nNeuroLink also refuses a state it estimates at more than 16,000 tokens (about\n60,000 characters of prose), so a longer set of eligible messages gets a refusal\nand the stage is skipped, as on any failure.\n\nIt is strictly additive. With no decision provider configured the stage\ndoes not run, stagesUsed omits relevance, and the pipeline behaves exactly\nas the four-stage one always did. It is also bounded by maxDropRatio and\nwalks oldest-first, so when the cap binds it spares the newest candidates β€”\nthe same recency assumption every other stage makes.","hierarchy":{"lvl0":"Features","lvl1":"Context Compaction","lvl2":"Stage 0: Relevance drop","lvl3":""}},
3250
+ {"objectID":"918fce938e3acd086621a86be0faaaecccf78059d8a0ef53b2dbc4fcd87347a1","title":"Stage 0: Relevance drop","url":"/docs/features/context-compaction#stage-0-relevance-drop","content":"File: src/lib/context/contextDecision.ts\n\nEverything below Stage 0 is chronological: the pipeline's only notion of\n\"droppable\" is \"old\". Stage 0 is the one stage that asks what a message is\nfor β€” one boolean per message (\"is this needed to answer the current\nrequest?\") in a single batch. On TypeSafe that costs the same for 200 messages\nas for one because decision latency is flat in question count; on Perplexity each\nfurther question adds about 65 ms and a request takes at most 128 (see\nits guide); on\nCloudflare Clef a request takes at most 64 questions, which tryDecide() splits\ninto batches of 64 (see its guide);\nOpenAI Decisions declares no question cap, so the request goes whole and what the\nendpoint accepts is not established\n(see its guide).\nNeuroLink also refuses a state it estimates at more than 16,000 tokens (about\n60,000 characters of prose), so a longer set of eligible messages gets a refusal\nand the stage is skipped, as on any failure.\n\nIt is strictly additive. With no decision provider configured the stage\ndoes not run, stagesUsed omits relevance, and the pipeline behaves exactly\nas the four-stage one always did. It is also bounded by maxDropRatio and\nwalks oldest-first, so when the cap binds it spares the newest candidates β€”\nthe same recency assumption every other stage makes.","hierarchy":{"lvl0":"Features","lvl1":"Context Compaction","lvl2":"Stage 0: Relevance drop","lvl3":""}},
3251
3251
  {"objectID":"c1fa9b4e362150149aa7889fbd1374625457cdc5cba6f57fb15d82ef305fc492","title":"The summary gate","url":"/docs/features/context-compaction#the-summary-gate","content":"Stage 3 used to accept any non-empty string as a summary. When a decision\nmodel is configured, the generated summary is now checked first (\"does this\npreserve every decision and open question?\") and a rejected summary leaves the\nmessages untouched so a later stage can try instead. The rejection is recorded\non the span as compaction.stage3.summaryRejected, because a gate that\nsilently discarded work would be indistinguishable from one that never ran.\n\nRejection is deliberately rare: the gate exists to catch a summary that lost a\ndecision, not to second-guess wording.","hierarchy":{"lvl0":"Features","lvl1":"Context Compaction","lvl2":"The summary gate","lvl3":""}},
3252
3252
  {"objectID":"2a518830a84553879be50318dfc47b77a34bf2c61cb5bc21a443ad5a5fcba95b","title":"Stage 1: Tool Output Pruning","url":"/docs/features/context-compaction#stage-1-tool-output-pruning","content":"File: src/lib/context/stages/toolOutputPruner.ts\n\nWalks messages backwards, protecting the most recent tool outputs, and replaces older tool results with \"[Tool result cleared]\".\n\nPruneConfig:\n\n| Field | Type | Default | Description |\n| ---------------- | ---------- | ----------- | ----------------------------------------------------------- |\n| protectTokens | number | 40,000 | Token budget of recent tool outputs to protect from pruning |\n| minimumSavings | number | 20,000 | Minimum tokens that must be saved for pruning to be applied |\n| protectedTools | string[] | [\"skill\"] | Tool names that are never pruned |\n| provider | string | β€” | Provider name for token estimation multiplier |\n\nPruneResult:","hierarchy":{"lvl0":"Features","lvl1":"Context Compaction","lvl2":"Stage 1: Tool Output Pruning","lvl3":""}},
3253
3253
  {"objectID":"7c30f222482767920767c8a3dee1c3955d4b615a31c54b58851b467e409a9e64","title":"Stage 2: File Read Deduplication","url":"/docs/features/context-compaction#stage-2-file-read-deduplication","content":"File: src/lib/context/stages/fileReadDeduplicator.ts\n\nDetects multiple reads of the same file path. Keeps only the latest read, replaces earlier reads with \"[File <path> - refer to latest read below]\".\n\nDeduplicationResult:\n\nFile read detection uses the regex pattern: /(?:read|reading|read_file|readFile|Read file|cat)\\s+['\"]?([^\\s'\"\\n]+)/i\n\nA 30% savings threshold (DEDUP_THRESHOLD = 0.3) must be met for deduplication to be applied.","hierarchy":{"lvl0":"Features","lvl1":"Context Compaction","lvl2":"Stage 2: File Read Deduplication","lvl3":""}},
@@ -3358,22 +3358,23 @@
3358
3358
  {"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":""}},
3359
3359
  {"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":""}},
3360
3360
  {"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":""}},
3361
- {"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, and Cloudflare's Clef models on Workers AI,\nwhich also read 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. 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; ","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"","lvl3":""}},
3362
- {"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, and Cloudflare's Clef models on Workers AI,\nwhich also read 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":""}},
3361
+ {"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":""}},
3362
+ {"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":""}},
3363
3363
  {"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":""}},
3364
3364
  {"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":""}},
3365
3365
  {"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":""}},
3366
3366
  {"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":""}},
3367
- {"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. 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":""}},
3367
+ {"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":""}},
3368
3368
  {"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":""}},
3369
3369
  {"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":""}},
3370
- {"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 variables\nare set.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"Cloudflare Clef, on Workers AI","lvl3":""}},
3370
+ {"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":""}},
3371
+ {"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":""}},
3371
3372
  {"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":""}},
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\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) always gets one request.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"Using it","lvl3":""}},
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 and Cloudflare Clef read images only,\nand 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":""}},
3373
+ {"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":""}},
3374
+ {"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":""}},
3374
3375
  {"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":""}},
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 and\nCloudflare Clef, 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 and Perplexity each declare; Cloudflare\n 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.\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 256,000 bytes for Cloudflare Clef. The limit applies to the encoded body, so\n the base64 form counts, and a photo usually has to be resized to well under\n 190 KB before Clef will take it.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"Images and video","lvl3":""}},
3376
- {"objectID":"a6077cedd1ca3e03b757da9a2ef8c185a56d2f1032dd5ed43fe28bd71454836c","title":"The one rule: batch, never fan out","url":"/docs/features/decide-inference-type#the-one-rule-batch-never-fan-out","content":"This inverts the instinct you have from LLMs.\n\nOn TypeSafe, question count barely affects latency (measured against its live\nAPI):\n\n| questions | round trip | input tokens |\n| --------- | ---------- | ------------ |\n| 1 | 393 ms | 310 |\n| 10 | 390 ms | 481 |\n| 100 | 423 ms | 2 281 |\n| 400 | 465 ms | 8 581 |\n\nThese are TypeSafe's figures. perplexity-decider differs: about 0.3 to 1.1 s\nfor one question, about 65 ms for each further question (a request takes at\nmost 128), and an input time that grows faster than linearly with size: 3.9 s\nat 65,000 tokens, 10 s at 146,000 and 22.9 s at 251,000. See\nits latency section.\ncloudflare-clef takes 0.3 to 1.0 s for a small request and 1.1 to 1.3 s for\n64 questions (measured 2026-10-03). A 64-question request with the same\nquestions and a shorter state took 1.5 s on clef-flash and 2.3 s on clef on 2026-10-04; see\nits latency section.\n\nOn TypeSafe, 400 questions cost ~70 ms more than one. Concurrent requests, by\ncontrast, queue: ten parallel calls take ~1.4 s wall with nine landing together\nat the end, while the server's own upstream time stays flat at 64–169 ms.\n\nSo on TypeSafe, 400 things in one request take ~465 ms; the same 400 as separate\nrequests take roughly a minute. Add every question you might need to the call\nyou are already making β€” speculative questions are nearly free on TypeSafe (on\nPerplexity each costs about 65 ms, up to 128 in a request; Cloudflare Clef takes\nup to 64), and a second round trip is not.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"The one rule: batch, never fan out","lvl3":""}},
3376
+ {"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":""}},
3377
+ {"objectID":"a6077cedd1ca3e03b757da9a2ef8c185a56d2f1032dd5ed43fe28bd71454836c","title":"The one rule: batch, never fan out","url":"/docs/features/decide-inference-type#the-one-rule-batch-never-fan-out","content":"This inverts the instinct you have from LLMs.\n\nOn TypeSafe, question count barely affects latency (measured against its live\nAPI):\n\n| questions | round trip | input tokens |\n| --------- | ---------- | ------------ |\n| 1 | 393 ms | 310 |\n| 10 | 390 ms | 481 |\n| 100 | 423 ms | 2 281 |\n| 400 | 465 ms | 8 581 |\n\nThese are TypeSafe's figures. perplexity-decider differs: about 0.3 to 1.1 s\nfor one question, about 65 ms for each further question (a request takes at\nmost 128), and an input time that grows faster than linearly with size: 3.9 s\nat 65,000 tokens, 10 s at 146,000 and 22.9 s at 251,000. See\nits latency section.\ncloudflare-clef takes 0.3 to 1.0 s for a small request and 1.1 to 1.3 s for\n64 questions (measured 2026-10-03). A 64-question request with the same\nquestions and a shorter state took 1.5 s on clef-flash and 2.3 s on clef on 2026-10-04; see\nits latency section.\nopenai-decisions has not been timed: its latency is not measured.\n\nOn TypeSafe, 400 questions cost ~70 ms more than one. Concurrent requests, by\ncontrast, queue: ten parallel calls take ~1.4 s wall with nine landing together\nat the end, while the server's own upstream time stays flat at 64–169 ms.\n\nSo on TypeSafe, 400 things in one request take ~465 ms; the same 400 as separate\nrequests take roughly a minute. Add every question you might need to the call\nyou are already making β€” speculative questions are nearly free on TypeSafe (on\nPerplexity each costs about 65 ms, up to 128 in a request; Cloudflare Clef takes\nup to 64), and a second round trip is not.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"The one rule: batch, never fan out","lvl3":""}},
3377
3378
  {"objectID":"0c1ce0b91d624674d6b4cc3b1f67fad986bcdfd379812b89e121784a94408ec3","title":"Model routing","url":"/docs/features/decide-inference-type#model-routing","content":"The classifier router gains a jev\nstrategy, and its default becomes auto β€” resolving to jev when a decision\nprovider is configured and heuristic when not.\n\nOne request asks for the difficulty tier, whether the task needs\nvision/tools/reasoning, whether carrying it out is risky, and which pool\nmember to use β€” all at once, in ~400 ms on TypeSafe's Jev.\n\n| | heuristic | llm | jev |\n| ---------------------- | ------------- | ------------------------------- | --------------------------------------------------- |\n| Added latency | 0 ms | ~1–8 s | ~400 ms on TypeSafe |\n| Cost per decision | none | a full LLM call | ~$0.00002 on TypeSafe |\n| Confidence | keyword score | self-reported (defaults to 0.7) | as the provider reports it (calibrated on TypeSafe) |\n| Picks a model directly | no | yes | yes |\n\nThe jev column is TypeSafe's figures; the\nPerplexity guide gives its\nlatency and the confidence it reports. The\nCloudflare Clef guide gives its\nlatency; a prompt NeuroLink estimates over 16,000 tokens is refused there and\nrouting falls back to the heuristic, as it does on any failure.\n\nThresholds are asymmetric, because the two mistakes do not cost the same:\nminUpgradeConfidence defaults to 0.3 (spending more on a wrong guess costs\nmoney) and minDowngradeConfidence to 0.6 (spending less on a wrong guess\nproduces a wrong answer).\n\nThe key upgrades routing; it does not switch routing on. The classifier\nrouter is still opt-in (classifierRouter.enabled) and still needs a pool,\nbecause NeuroLink cannot invent the set of models you are willing to route\nbetween. What the key changes is which classifier runs inside a router you\nalready enabled.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"Model routing","lvl3":""}},
3378
3379
  {"objectID":"40f783ceca290c039cce7f0199ab5758d7a0719b0a91c335c1c6e490a72b1412","title":"The model catalogue","url":"/docs/features/decide-inference-type#the-model-catalogue","content":"Enabling classifierRouter.catalog widens the routable pool beyond what you\ndeclared by hand: candidates are built from the 64-model registry (7\nproviders β€” see the model catalogue\nfor which), intersected with the credentials this host actually holds, and\nranked by a deterministic formula whenever no decision provider is available\nto choose among them.\n\n| | Without catalog | With catalog.enabled |\n| -------------- | ------------------------ | ------------------------------------- |\n| Candidate pool | only the declared pool | declared pool plus registry matches |\n| Fallback pick | first pool member | tierScore()-ranked, tier-aware |\n| Cap | none needed | maxModels, default 120 |\n\nSee the model catalogue for how\ncandidates are filtered, rendered, and ranked.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"The model catalogue","lvl3":""}},
3379
3380
  {"objectID":"1362463e9ab1e8a456cb34a4e5ac2ec8493f18ddc2a8d277282de858c0420131","title":"Per-request context budget","url":"/docs/features/decide-inference-type#per-request-context-budget","content":"A per-request compactionThreshold option lowers the point at which history\ngets compacted, below the 0.8-of-window default. The jev strategy can fill\nit in automatically from a four-level scope rubric (current-message through\neverything) β€” and the mapping is a one-directional invariant: it can only\never lower the 0.8 default, never raise it, because over-filling a window is\nan unrecoverable provider error.\n\nSee per-request context budget for the\nrubric, the invariant, and how the threshold scales the compaction target.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"Per-request context budget","lvl3":""}},
@@ -3381,8 +3382,8 @@
3381
3382
  {"objectID":"451d199b91f25696bed61dedb5ebc0465143dbf3bc350ca8a3943e622f9aedf8","title":"Tool / MCP routing","url":"/docs/features/decide-inference-type#tool-mcp-routing","content":"The shipped tool router asks a generative model for {servers: string[]} on\na 15-second budget β€” a shape that cannot express uncertainty. A decision\nmodel instead asks one yes/no question per server, answered with a probability,\nand a server is excluded only on a confident \"no\" (minDropConfidence default\n0.6), because dropping a needed server breaks the turn while keeping an unneeded\none only costs a few tokens.\n\nA measured wording change moved unrelated servers from a mean probability of\n0.31 (dropping 12 of 39 unneeded servers) to a mean of 0.03 (dropping 37 of\n39, with zero wrong drops) β€” seen in\ntool / MCP routing by decision model,\nwhich also covers the exact question shape and its size guards.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"Tool / MCP routing","lvl3":""}},
3382
3383
  {"objectID":"b35e1ab2390a7b132037c293ecaf436f9ff9498591ccdd47b58ee0a6a95e7616","title":"RAG retrieval planning","url":"/docs/features/decide-inference-type#rag-retrieval-planning","content":"RAGPipelineConfig.decide lets each RAG query get its own topK/hybrid/\ngraph/rerank plan instead of one fixed configuration for every query. An\nexplicit per-call QueryOptions field always wins over the plan, and a\ncapability the pipeline wasn't configured with can never be switched on by\nit.\n\nSee per-query RAG retrieval planning\nfor the breadth rubric and why its confidence bar is deliberately lower than\ntool routing's or compaction's.","hierarchy":{"lvl0":"Features","lvl1":"The `decide` inference type","lvl2":"RAG retrieval planning","lvl3":""}},
3383
3384
  {"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":""}},
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":""}},
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); its absence is what the\nmedia refusal for TypeSafe and Laya is based 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, whose descriptor row is marked advisory and is reported but never\nenforced here β€” a local refusal would turn a measured server ceiling into a\nclient 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":""}},
3385
+ {"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":""}},
3386
+ {"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":""}},
3386
3387
  {"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":""}},
3387
3388
  {"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":""}},
3388
3389
  {"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":""}},
@@ -3582,9 +3583,9 @@
3582
3583
  {"objectID":"a6f80762fe08ca735f864be4541b6863065a0acfc5849344db2e40f38db28db3","title":"Verify file","url":"/docs/features/image-generation#verify-file","content":"file ./test-output/square.png","hierarchy":{"lvl0":"Features","lvl1":"Image Generation Streaming Guide","lvl2":"Verify file","lvl3":""}},
3583
3584
  {"objectID":"0de2f95f5125f67748b214f7ed674edcf44078cc415fa081f6edf46428d7c65f","title":"Output: ./test-output/square.png: PNG image data, 1024 x 1024, 8-bit/color RGB","url":"/docs/features/image-generation#output-test-outputsquarepng-png-image-data-1024-x-1024-8-bitcolor-rgb","content":"`","hierarchy":{"lvl0":"Features","lvl1":"Image Generation Streaming Guide","lvl2":"Output: ./test-output/square.png: PNG image data, 1024 x 1024, 8-bit/color RGB","lvl3":""}},
3584
3585
  {"objectID":"aa931e13d4db435aa9de30f72f599057c2977804e4316c3cb61f84d8e43fd97e","title":"Conclusion","url":"/docs/features/image-generation#conclusion","content":"NeuroLink's image generation streaming provides a unified interface for both text and image generation. The fake streaming approach ensures consistency while maintaining the benefits of streaming APIs. By following the patterns and examples in this guide, you can effectively integrate image generation into your applications.\n\nFor more information:\nAPI Reference\nProvider Comparison\nProvider Status Monitoring","hierarchy":{"lvl0":"Features","lvl1":"Image Generation Streaming Guide","lvl2":"Conclusion","lvl3":""}},
3585
- {"objectID":"e3366024d1a12d0c73fbcb1592927d2dcc0d92c12eaea661cf5164bb7217c32f","title":"Feature Guides","url":"/docs/features","content":"Feature Guides\n\nComprehensive guides for all NeuroLink features organized by category. Each guide includes setup, usage patterns, configuration, and troubleshooting.\n\nLatest Features (Q1 2026)\n\n| Feature | Description |\n| ---------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| decide Inference Type | A third inference type alongside generate/stream: typed, calibrated boolean/choice/score judgments in one parallel pass β€” no text. ~400ms, ~$0.00002 per decision on TypeSafe; Perplexity adds about 65 ms for each further question, up to 128 (see its guide); Cloudflare Clef takes up to 64 questions and about 2,048 tokens of state (see its guide). Providers: TypeSafe Jev; Laya, open-weights and self-hosted; XOR, Juspay's open-weights model that also reads images and video; SubQ, a hosted API; Perplexity, a hosted API that also reads images; and Cloudflare Clef, hosted on Workers AI, which also reads images. Fail-open: a no-op when no decision provider is configured (the credentials of Perplexity and Cloudflare Clef are shared with their text providers). |\n| Model Routing with a Decision Model | One round trip answers difficulty, capabilities, risk, context scope and the model pick, with asymmetric confidence bars (0.3 up / 0.6 down). |\n| Model Catalogue | Ranks the 64-model registry as an addition to a host-declared pool, never a replacement. One choice question ranks all N candidates. ","hierarchy":{"lvl0":"Features","lvl1":"Feature Guides","lvl2":"","lvl3":""}},
3586
+ {"objectID":"e3366024d1a12d0c73fbcb1592927d2dcc0d92c12eaea661cf5164bb7217c32f","title":"Feature Guides","url":"/docs/features","content":"Feature Guides\n\nComprehensive guides for all NeuroLink features organized by category. Each guide includes setup, usage patterns, configuration, and troubleshooting.\n\nLatest Features (Q1 2026)\n\n| Feature | Description |\n| ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| decide Inference Type | A third inference type alongside generate/stream: typed, calibrated boolean/choice/score judgments in one parallel pass β€” no text. ~400ms, ~$0.00002 per decision on TypeSafe; Perplexity adds about 65 ms for each further question, up to 128 (see its guide); Cloudflare Clef takes up to 64 questions and about 2,048 tokens of state (see its guide). Providers: TypeSafe Jev; Laya, open-weights and self-hosted; XOR, Juspay's open-weights model that also reads images and video; SubQ, a hosted API; Perplexity, a hosted API that also reads images; Cloudflare Clef, hosted on Workers AI, which also reads images; and OpenAI Decisions, OpenAI's Decisions API (public beta), which also reads images. Fail-open: a no-op when no decision provider is configured (the credentials of Perplexity, Cloudflare Clef and OpenAI Decisions are shared with their text providers). |\n| Model Routing with a Decision Model | One round trip answers difficulty, capabilities, risk, context scope and the model pick, with asymmetric confidence bars (0.3 up / 0.6 down). ","hierarchy":{"lvl0":"Features","lvl1":"Feature Guides","lvl2":"","lvl3":""}},
3586
3587
  {"objectID":"a477c76a577a17e7aeaf89736289a0a41734b4bcfe479a523cdd9e2051bd0ba7","title":"Feature Guides","url":"/docs/features#feature-guides","content":"Comprehensive guides for all NeuroLink features organized by category. Each guide includes setup, usage patterns, configuration, and troubleshooting.","hierarchy":{"lvl0":"Features","lvl1":"Feature Guides","lvl2":"Feature Guides","lvl3":""}},
3587
- {"objectID":"a43e81fa4a6c594f8b6b4cfc216db1356d75b3e4ebb54279dd2da7f69001d28f","title":"Latest Features (Q1 2026)","url":"/docs/features#latest-features-q1-2026","content":"| Feature | Description |\n| ---------------------------------------------------------------------------------------- |","hierarchy":{"lvl0":"Features","lvl1":"Feature Guides","lvl2":"Latest Features (Q1 2026)","lvl3":""}},
3588
+ {"objectID":"a43e81fa4a6c594f8b6b4cfc216db1356d75b3e4ebb54279dd2da7f69001d28f","title":"Latest Features (Q1 2026)","url":"/docs/features#latest-features-q1-2026","content":"| Feature | Description |\n| ---------------------------------------------------------------------------------------- |","hierarchy":{"lvl0":"Features","lvl1":"Feature Guides","lvl2":"Latest Features (Q1 2026)","lvl3":""}},
3588
3589
  {"objectID":"84c604ce940f85fbe8aa8d94675e4c1dae80b22ede558d58102426598f6a7d06","title":"Core Features (shipped 2025)","url":"/docs/features#core-features-shipped-2025","content":"| Feature | Description |\n| -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |\n| Image Generation | Generate images from text prompts using Gemini models via Vertex AI or Google AI Studio. |\n| Enterprise HITL | Production-ready HITL with approval workflows, confidence thresholds, and enterprise patterns. |\n| Interactive CLI | AI development environment with loop mode, session variables, and conversation memory. |\n| MCP Tools Showcase | Complete guide to 6 built-in tools and connecting external MCP servers across 6 categories. |\n| Human-in-the-Loop (HITL) | Pause AI tool execution for user approval before risky operations like file deletion or API calls. |\n| Guardrails Middleware | Content filtering, PII detection, and safety checks for AI outputs with zero configuration. |\n| Redis Conversation Export | Export complete session history as JSON for analytics, debugging, and compliance auditing. |\n| Context Compaction | Automatic conversation compression for long-running sessions to stay within token limits. |\n| LiteLLM Integration | Access 100+ AI models across a broad range of AI providers through unified LiteLLM routing interface. |\n| SageMaker Integration | Deploy and use custom-trained models on AWS SageMaker infrastructure with full control. |","hierarchy":{"lvl0":"Features","lvl1":"Feature Guides","lvl2":"Core Features (shipped 2025)","lvl3":""}},
3589
3590
  {"objectID":"f64aba3e564a8f56064839c33b533971468da990a9cc95d86ceb1e9d13223478","title":"Earlier Core Features (shipped Q3 2025)","url":"/docs/features#earlier-core-features-shipped-q3-2025","content":"| Feature | Description |\n| ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |\n| Multimodal Chat Experiences | Stream text and images together with automatic provider fallbacks and format conversion. |\n| CSV File Support | Process CSV files for data analysis with automatic format conversion. Works across supported providers. |\n| PDF File Support | Process PDF documents for visual analysis and content extraction. Native provider support. |\n| Office Documents | Process DOCX, PPTX, XLSX files for document analysis. Native Bedrock, Vertex, Anthropic support. |\n| Auto Evaluation Engine | Automated quality scoring and metrics export for AI response validation using LLM-as-judge. |\n| CLI Loop Sessions | Persistent interactive mode with conversation memory and session state for prompt engineering. |\n| Regional Streaming Controls | Region-specific model deployment and routing for compliance and latency optimization. |\n| Provider Orchestration Brain | Adaptive provider and model selection with intelligent fallbacks based on task classification. |","hierarchy":{"lvl0":"Features","lvl1":"Feature Guides","lvl2":"Earlier Core Features (shipped Q3 2025)","lvl3":""}},
3590
3591
  {"objectID":"fbd682fc148477639d38ab175c38363d003a1464834e84b2a48d88087d001b91","title":"Platform Capabilities at a Glance","url":"/docs/features#platform-capabilities-at-a-glance","content":"| Category | Features | Documentation |\n| ------------------------ | ------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- |\n| Provider unification | Provider integrations with automatic failover, cost-aware routing, providerFallback policy, modelChain config | Provider Setup |\n| Multimodal pipeline | Stream images + CSV data + PDF documents + Office files across providers with auto-detection for mixed file types. | Multimodal Guide, CSV Support, PDF Support, Office Docs |\n| Voice pipeline | TTS (6 providers) + STT (4 providers) + realtime APIs (OpenAI Realtime, Gemini Live) | TTS Guide, STT Guide, Realtime Services |\n| Quality & governance | Auto-evaluation engine (14 scorers), guardrails middleware, HITL workflows, audit logging | Auto Evaluation, Guardrails, HITL |\n| Memory & context | Per-user condensed memory (S3/Redis/SQLite), Redis session export, 5-stage context compaction | Conversation Memory, Memory, Redis Export |\n| CLI tooling | Loop sessions, setup wizard, config validation, Redis auto-detect, JSON output, TTS/STT flags | CLI Loop, CLI Commands |\n| Enterprise ops | Claude proxy, OTLP observability, OpenObserve dashboard, regional routing,","hierarchy":{"lvl0":"Features","lvl1":"Feature Guides","lvl2":"Platform Capabilities at a Glance","lvl3":""}},
@@ -3969,7 +3970,8 @@
3969
3970
  {"objectID":"6dd068b5a05003f273d4814560c2aab4d2e80c7ded42e841b4295e2b811a65e5","title":"Overview","url":"/docs/features/observability#overview","content":"NeuroLink provides comprehensive observability features for monitoring AI operations in production:\nLangfuse Integration: LLM-specific observability with token tracking, cost analysis, and trace visualization\nOpenTelemetry Support: Standard distributed tracing compatible with Jaeger, Zipkin, and other backends\nExternal Provider Mode: Integrate with existing OpenTelemetry instrumentation without conflicts\nContext Propagation: Automatic context enrichment with user, session, and custom metadata\n\nFor the Claude proxy's local OpenObserve stack and maintained dashboard, use Claude Proxy and Claude Proxy Observability. Those guides cover neurolink proxy telemetry setup, dashboard import, stream names, and how to interpret proxy-specific logs, metrics, and traces.","hierarchy":{"lvl0":"Features","lvl1":"Observability Guide","lvl2":"Overview","lvl3":""}},
3970
3971
  {"objectID":"f5b277d3ae78e90affc7f614bbe8f4ea0e076874c57d77d204bd0764d0952622","title":"Environment Variables","url":"/docs/features/observability#environment-variables","content":"`bash","hierarchy":{"lvl0":"Features","lvl1":"Observability Guide","lvl2":"Environment Variables","lvl3":""}},
3971
3972
  {"objectID":"e282cefcd21de2af047fc4d4a88d29eea980c9cbdef0a72b4526cdf0e2ce0170","title":"Langfuse credentials","url":"/docs/features/observability#langfuse-credentials","content":"LANGFUSEPUBLICKEY=pk-lf-...\nLANGFUSESECRETKEY=sk-lf-...\nLANGFUSEBASEURL=https://cloud.langfuse.com # or self-hosted","hierarchy":{"lvl0":"Features","lvl1":"Observability Guide","lvl2":"Langfuse credentials","lvl3":""}},
3972
- {"objectID":"f106fb2f59d571149ec64cb1a8c0cc5086f99d98fee77d5b9f56a838c1144284","title":"Optional defaults","url":"/docs/features/observability#optional-defaults","content":"LANGFUSE_ENVIRONMENT=production\nLANGFUSE_RELEASE=1.0.0\n`","hierarchy":{"lvl0":"Features","lvl1":"Observability Guide","lvl2":"Optional defaults","lvl3":""}},
3973
+ {"objectID":"f106fb2f59d571149ec64cb1a8c0cc5086f99d98fee77d5b9f56a838c1144284","title":"Optional defaults","url":"/docs/features/observability#optional-defaults","content":"LANGFUSE_ENVIRONMENT=production\nLANGFUSE_RELEASE=1.0.0","hierarchy":{"lvl0":"Features","lvl1":"Observability Guide","lvl2":"Optional defaults","lvl3":""}},
3974
+ {"objectID":"88c92784744e5dd73ef59159dade30855280e6c98407b596a484e4ed5c25822d","title":"spans; anything over it is trimmed to valid JSON, keeping the user's question.","url":"/docs/features/observability#spans-anything-over-it-is-trimmed-to-valid-json-keeping-the-users-question","content":"NEUROLINKSPANATTRIBUTEMAXCHARS=40000\n`","hierarchy":{"lvl0":"Features","lvl1":"Observability Guide","lvl2":"spans; anything over it is trimmed to valid JSON, keeping the user's question.","lvl3":""}},
3973
3975
  {"objectID":"2e424a89666870b887e95be2075dc80aba5d9a635c4b711aaadce25b776d8654","title":"Setting Context","url":"/docs/features/observability#setting-context","content":"Use setLangfuseContext to attach metadata to all spans in an async context:","hierarchy":{"lvl0":"Features","lvl1":"Observability Guide","lvl2":"Setting Context","lvl3":""}},
3974
3976
  {"objectID":"a5d647d37c18f927e33ff9a3146d65deaffe05ebab47410e85b5615e47e2d4df","title":"Context Fields","url":"/docs/features/observability#context-fields","content":"| Field | Purpose |\n| ---------------- | ------------------------------------------ |\n| userId | Identify the user for per-user analytics |\n| sessionId | Group traces within a user session |\n| conversationId | Group traces in a conversation thread |\n| requestId | Correlate with application logs |\n| traceName | Custom name in Langfuse UI |\n| metadata | Key-value pairs for filtering and analysis |","hierarchy":{"lvl0":"Features","lvl1":"Observability Guide","lvl2":"Context Fields","lvl3":""}},
3975
3977
  {"objectID":"89f1a2e53dff482b3f106f6bc884a5928996cd4458b2881f87bf70065edc3d3a","title":"Operation Name Support","url":"/docs/features/observability#operation-name-support","content":"NeuroLink automatically detects operation names from AI SDK spans and includes them in trace names for better observability. This provides immediate visibility into what type of AI operation is being performed.","hierarchy":{"lvl0":"Features","lvl1":"Observability Guide","lvl2":"Operation Name Support","lvl3":""}},
@@ -4523,8 +4525,8 @@
4523
4525
  {"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":""}},
4524
4526
  {"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":""}},
4525
4527
  {"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":""}},
4526
- {"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), 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 servers than necessary β€” it cannot register a server that wasn't already\n configured.\n\nSee also\nThe decide inference type\nModel routi","hierarchy":{"lvl0":"Features","lvl1":"Tool / MCP routing by decision model","lvl2":"","lvl3":""}},
4527
- {"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), 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":""}},
4528
+ {"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":""}},
4529
+ {"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":""}},
4528
4530
  {"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":""}},
4529
4531
  {"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":""}},
4530
4532
  {"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":""}},
@@ -4536,7 +4538,7 @@
4536
4538
  {"objectID":"25734eb9746d69fee91c94beaab37ba0433ce9d1bc944c78ac54b14ddaf10f83","title":"Result","url":"/docs/features/transcribe#result","content":"TranscribeResult 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 term, term or literal, and the probability. |\n| engine | { provider, model, fallbackUsed?, secondOpinion? }. |\n| timings | transcribeMs, secondOpinionMs, decideMs, rewriteMs, correctionMs, totalMs. |\n| steps | A readable trail: \"dictionary 2/2\", \"rewrite timed out Β· kept text\" … |","hierarchy":{"lvl0":"Features","lvl1":"The transcribe inference type","lvl2":"Result","lvl3":""}},
4537
4539
  {"objectID":"cfe99c9441a998e039ecbe92d247fb981326eb5e5a56e51aa7abb49fd4662663","title":"Providers and environment","url":"/docs/features/transcribe#providers-and-environment","content":"| Provider (aliases) | Configured by | Notes |\n| --------------------------------------------- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------- |\n| whisper (openai-stt, openai-compatible) | OPENAI_STT_API_KEY or OPENAI_API_KEY; OPENAI_STT_BASE_URL for another server | Any OpenAI-compatible /audio/transcriptions endpoint. |\n| deepgram | DEEPGRAM_API_KEY | Native streaming. |\n| elevenlabs-stt (scribe, elevenlabs) | ELEVENLABS_API_KEY | |\n| google-stt | GOOGLE_API_KEY, GOOGLE_AI_API_KEY, GEMINI_API_KEY or GOOGLE_APPLICATION_CREDENTIALS | |\n| azure-stt | AZURE_SPEECH_KEY | |\n| whistle (local) | nothing | Built-in, local, always available. |\n\nThe order of that table is precedence: without provider or\nNEUROLINK_STT_PROVIDER, the first configured provider is used, and Whistle\nonly when none is.","hierarchy":{"lvl0":"Features","lvl1":"The transcribe inference type","lvl2":"Providers and environment","lvl3":""}},
4538
4540
  {"objectID":"1c83e72d0998d73b45f4a810514691aa3fb8979166eea4883ffe4bec728140d7","title":"Dictionary","url":"/docs/features/transcribe#dictionary","content":"A dictionary teaches the pipeline the words an engine cannot know β€” product\nnames, people's names, internal jargon β€” and how engines tend to mis-hear them:\n\n| Field | Required | Use |\n| --------- | -------- | ------------------------------------------------------------------------------------------------- |\n| term | yes | The correct spelling, written exactly like this in the output. |\n| heardAs | no | Mis-hearings, in any script. Each one found in a transcript becomes a candidate for replacement. |\n| meaning | no | What the term means, given to the decision model and the rewrite so they can tell term from word. |\n\nThe dictionary is used three ways: its terms are sent to engines that take a\nprompt or vocabulary, each heardAs found in the transcript becomes a\ncandidate repair, and the whole list is given to the rewrite model.","hierarchy":{"lvl0":"Features","lvl1":"The transcribe inference type","lvl2":"Dictionary","lvl3":""}},
4539
- {"objectID":"bb0871357646359062274d9ec5e47b41771d77b2c86ccd2d29cf96f43a538b64","title":"Correction","url":"/docs/features/transcribe#correction","content":"Correction runs on a finished transcript (or on each final utterance when\nstreaming), in two stages:\nDictionary, guarded. Each candidate is put to the decision model as one\n question β€” did the speaker mean the term, or the ordinary word? β€” so a\n product name never rewrites the everyday word it sounds like. All\n candidates go in one tryDecide() call. With no decision provider, on a\n timeout (decideTimeoutMs, default 4000) or on any error, the dictionary is\n applied as is. guard: \"none\" always applies it.\nRewrite. A text model fixes spelling, punctuation and capitalisation,\n writes dictionary terms correctly, reconciles a second opinion and writes\n Indic-script words in Latin letters the way people type them (Hinglish,\n Tanglish …) β€” never translating them. transliterate: \"native\" keeps the\n original script. rewrite: false stops after the dictionary.\n\n| Option | Default | Meaning |\n| ----------------- | ----------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |\n| enabled | on with a dictionary or any correction object, unless it is only rewrite: false | Run the layer at all. |\n| guard | \"decide\" | \"decide\" asks the decision model per candidate; \"none\" always applies. |\n| decideTimeoutMs | 4000 | Guard timeout. |\n| rewrite | the instance's default text provider | { provider?, model?, timeoutMs? } (timeout default 12000), or false.","hierarchy":{"lvl0":"Features","lvl1":"The transcribe inference type","lvl2":"Correction","lvl3":""}},
4541
+ {"objectID":"bb0871357646359062274d9ec5e47b41771d77b2c86ccd2d29cf96f43a538b64","title":"Correction","url":"/docs/features/transcribe#correction","content":"Correction runs on a finished transcript (or on each final utterance when\nstreaming), in two stages:\nDictionary, guarded. Each candidate is put to the decision model as one\n question β€” did the speaker mean the term, or the ordinary word? β€” so a\n product name never rewrites the everyday word it sounds like. All\n candidates go in one tryDecide() call. With no decision provider, on a\n timeout (decideTimeoutMs, default 4000) or on any error, the dictionary is\n applied as is. guard: \"none\" always applies it. The guard asks for the\n default decision provider, and it sends the first 4,000 characters of the\n transcript to it. A lone OPENAI_API_KEY counts as one (it is also Whisper's\n key), so a host that set it only for Whisper and passes a dictionary sends the\n transcript text to OpenAI's Decisions endpoint, unless OPENAI_BASE_URL,\n OPENAI_API_BASE or credentials.openai.baseURL names a host other than https://api.openai.com (a gateway's\n key is not used for the default); see\n One key, two providers.\nRewrite. A text model fixes spelling, punctuation and capitalisation,\n writes dictionary terms correctly, reconciles a second opinion and writes\n Indic-script words in Latin letters the way people type them (Hinglish,\n Tanglish …) β€” never translating them. transliterate: \"native\" keeps the\n original script. rewrite: false stops after the dictionary.\n\n| Option | Default | Meaning |\n| ----------------- | ----------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |\n| enabled | on with a dictionary or any correction object, unless it is only rewrite: false | Run the layer at all.","hierarchy":{"lvl0":"Features","lvl1":"The transcribe inference type","lvl2":"Correction","lvl3":""}},
4540
4542
  {"objectID":"7c55169273332aab63f54e94bae343516bd630e062d60a4d427d004b72ee287e","title":"Nothing is ever dropped","url":"/docs/features/transcribe#nothing-is-ever-dropped","content":"Every layer fails open, and none may lose words:\nA rewrite that drops more than maxDropRatio of the words is discarded and\n the dictionary-applied text is kept.\nA rewrite that times out, fails or returns nothing keeps the text it was\n given.\nA guard that times out or fails applies the dictionary as is.\nWhen streaming, a final pass that returns less than the live text keeps the\n live text, and an utterance no engine could read is reported as a silence\n event with its length rather than disappearing.\nraw always holds the engine's own text, so a caller can show or diff it.\n\nEach of those outcomes is written to steps, so a degraded path is visible\nrather than silent.","hierarchy":{"lvl0":"Features","lvl1":"The transcribe inference type","lvl2":"Nothing is ever dropped","lvl3":""}},
4541
4543
  {"objectID":"c0207627f5f88b7914c2fbe84a641879ece05ae20f7e2194a9f0bc29c24cfd65","title":"Fallback and second opinion","url":"/docs/features/transcribe#fallback-and-second-opinion","content":"Fallback takes the request (or, when streaming, the utterance) when the\n primary engine cannot read it: when defaults to [\"unsure\", \"empty\"] β€” a\n low language-detection score, or no text β€” and \"error\" adds engine\n failures. engine.fallbackUsed says when it ran.\nSecond opinion runs a second engine on the same audio in parallel; the\n rewrite reconciles the two transcripts, taking each language's words from the\n engine that reads it better. When the primary reports an unsure language,\n or no text, the second opinion's text leads. With rewrite: false that is\n all it does β€” there is no reconciliation without the rewrite.","hierarchy":{"lvl0":"Features","lvl1":"The transcribe inference type","lvl2":"Fallback and second opinion","lvl3":""}},
4542
4544
  {"objectID":"c903ddf3ec717cab3ff063e2bbb762f634ff09b05e5199c35d95283aba82f2f6","title":"Streaming","url":"/docs/features/transcribe#streaming","content":"Engines with a native stream use it; every other engine is streamed on the\nclient by a chunked adapter (an energy gate finds utterances, the current\nutterance is re-transcribed every intervalMs, and the prefix two passes agree\non is committed). streaming.mode: \"chunked\" forces the adapter.\n\n| Event | Carries |\n| ------------ | ---------------------------------------------------------------------------------------------- |\n| interim | The utterance's current text, split into committed (stable) and tail (may still change). |\n| language | The detected language and whether the engine was sure. |\n| final | The utterance's final text, segment and words, the engine, and whether the fallback took it. |\n| correcting | Partial text of the streamed rewrite. |\n| corrected | The corrected text, its raw, decisions, steps and timings. |\n| silence | An utterance no engine could read, with its length. |\n| error | A message, and recoverable: true when the stream carries on with the next utterance. |\n\nTuning (streaming): sampleRate (16000), endSilenceMs (750), intervalMs\n(900), softCutSeconds (16), maxUtteranceSeconds (28), onsetRms (0.006),\nprerollMs (350), minSpeechMs (250).","hierarchy":{"lvl0":"Features","lvl1":"The transcribe inference type","lvl2":"Streaming","lvl3":""}},
@@ -5659,8 +5661,8 @@
5659
5661
  {"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":""}},
5660
5662
  {"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":""}},
5661
5663
  {"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":""}},
5662
- {"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 and\nPerplexity, from Cloudflare's Clef models on Workers\nAI, and it also reads images. It emits no 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 | last: after TypeSafe, Laya, XOR, SubQ and Perplexity |\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 is part of the\nro","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Clef Provider Guide","lvl2":"","lvl3":""}},
5663
- {"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 and\nPerplexity, from Cloudflare's Clef models on Workers\nAI, and it also reads images. It emits no 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":""}},
5664
+ {"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":""}},
5665
+ {"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":""}},
5664
5666
  {"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":""}},
5665
5667
  {"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":""}},
5666
5668
  {"objectID":"5f8fca781ea20214c667a17eb2e49fc41c5a9187b58b202f67758f2bfc581c4e","title":"1. Get a token and your account id","url":"/docs/getting-started/providers/cloudflare-clef#1-get-a-token-and-your-account-id","content":"Create 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.","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Clef Provider Guide","lvl2":"1. Get a token and your account id","lvl3":""}},
@@ -5668,7 +5670,7 @@
5668
5670
  {"objectID":"de4ffe6ae22db4a0719caae8e38b4a0a8a438224c94701a762c9e1f4cc209393","title":"Optional","url":"/docs/getting-started/providers/cloudflare-clef#optional","content":"typescript\n\nconst neurolink = new NeuroLink({\n credentials: {\n cloudflareClef: { apiKey: \"…\", accountId: \"…\" }, // baseURL is optional\n },\n});\n`\n\nBoth the token and the account id are needed: the account id is part of the\nroute, so a token alone does not count as configured.","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Clef Provider Guide","lvl2":"Optional","lvl3":""}},
5669
5671
  {"objectID":"0b26521b87bd72415fe58482c8628d4c3d04a49575ca2e89a55f29cf65834ccc","title":"3. Use it","url":"/docs/getting-started/providers/cloudflare-clef#3-use-it","content":"The figures in the comments are what a live call to clef returned for this\nexample on 2026-10-03, rounded; clef-flash answered the same example with\n0.96, 0.82 and 0.50, 2.72. Pick the faster model for one call with\nmodel: \"clef-flash\".","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Clef Provider Guide","lvl2":"3. Use it","lvl3":""}},
5670
5672
  {"objectID":"251d84b27d167ed1d24cad4c91fb45246bf057457ea226ad977f4e581af03d28","title":"Images","url":"/docs/getting-started/providers/cloudflare-clef#images","content":"Pass up to four images beside the state, as a Buffer, a file path or a\ndata:image/…;base64, URL; an http(s) URL is refused. PNG, JPEG and WebP are\nread; image/jpg is accepted as a JPEG alias and sent as image/jpeg. Other formats are refused before they are sent.\nThey travel in their own images array, not inside the state. Cloudflare\n places them before the state.\nThe Workers AI API accepts no video. Its model page says it does, but the API refuses\n a video and has no field for one, so NeuroLink refuses a video too.\nPixels: Cloudflare documents 16 megapixels an image. 16.00 megapixels were\n accepted (4096 Γ— 3900 at 15.97 MP, 8000 Γ— 2000 and 16000 Γ— 1000 at 16.00 MP);\n 16.38 megapixels (4096 Γ— 4000) were refused with a 422. The limit is on the\n pixel count, not on either side.\nCost: an image costs at most about 1,000 input tokens however large it is.\n A test request with one 512 Γ— 512 image counted 389 input tokens in all, one\n with a 1,024 Γ— 1,024 image counted 1,157, and larger images up to the pixel\n limit counted between 1,125 and 1,157.\nHow many: exactly four tiny PNG/JPEG/WebP images succeeded on both models\n on 2026-10-04; a fifth was refused with a 422. Four is also NeuroLink's limit.\nNeuroLink's size limit is 256,000 bytes for the encoded request body,\n including base64 image data. A 195 KB PNG encodes to about 260,000 characters\n and is refused locally. Resize or compress a photo to well under 190 KB first.\n The 2026-10-03 API probe accepted a 195 KB PNG and refused a 202 KB one.\n That boundary has since moved: on 2026-10-05 both models accepted PNG\n requests with encoded bodies up to 492,485 bytes and refused 532,505 bytes\n (clef-flash) and 532,499 (clef) (see below), so the 195/202 KB figures are historical and NeuroLink's cap is\n the stricter limit.","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Clef Provider Guide","lvl2":"Images","lvl3":""}},
5671
- {"objectID":"f98057fa646a175aee28fef3b525786c83a66b8ac8489feec28fd872866cf4ab","title":"When NeuroLink uses it","url":"/docs/getting-started/providers/cloudflare-clef#when-neurolink-uses-it","content":"Built-in features that call decide() pick the first decision provider that is\nconfigured, in this order: TypeSafe, Laya, XOR, SubQ, Perplexity,\nthen Clef. A host with none of the first five, but with CLOUDFLARE_API_KEY and\nCLOUDFLARE_ACCOUNT_ID set for the Workers AI text provider, therefore has Clef\nas its default decision provider. Naming provider: \"cloudflare-clef\" reaches it\nwhatever else is configured.\n\nBecause of the state limit below, a built-in feature whose state is longer than\nabout 16,000 estimated tokens (about 60,000 characters of prose) gets a refusal\nfrom Clef, which each of them treats as \"carry on as before\". Clef suits short decisions: routing a request, a\nguardrail on one action, classifying one message or one picture.","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Clef Provider Guide","lvl2":"When NeuroLink uses it","lvl3":""}},
5673
+ {"objectID":"f98057fa646a175aee28fef3b525786c83a66b8ac8489feec28fd872866cf4ab","title":"When NeuroLink uses it","url":"/docs/getting-started/providers/cloudflare-clef#when-neurolink-uses-it","content":"Built-in features that call decide() pick the first decision provider that is\nconfigured, in this order: TypeSafe, Laya, XOR, SubQ, Perplexity, Clef, then\nOpenAI Decisions. A host with none of the first five, but\nwith CLOUDFLARE_API_KEY and\nCLOUDFLARE_ACCOUNT_ID set for the Workers AI text provider, therefore has Clef\nas its default decision provider. Naming provider: \"cloudflare-clef\" reaches it\nwhatever else is configured.\n\nBecause of the state limit below, a built-in feature whose state is longer than\nabout 16,000 estimated tokens (about 60,000 characters of prose) gets a refusal\nfrom Clef, which each of them treats as \"carry on as before\". Clef suits short decisions: routing a request, a\nguardrail on one action, classifying one message or one picture.","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Clef Provider Guide","lvl2":"When NeuroLink uses it","lvl3":""}},
5672
5674
  {"objectID":"69f3db3e89a8fd474930cba6df7b01125fa2d9dd41aaadf8d8838423632ace30","title":"What is sent to Cloudflare","url":"/docs/getting-started/providers/cloudflare-clef#what-is-sent-to-cloudflare","content":"boolean is the SDK's name for the wire's noul. model is sent although the\npath already names it: Cloudflare's schema marks it required, and a body whose\nmodel differs from the path is refused. A request with no model was accepted\nlive and answered by clef-flash, so sending it matters only for following the\nschema. Cloudflare wraps every answer in its own\nenvelope, and NeuroLink reads the answers out of it:\n\nThe request id is the cf-ai-req-id response header; where that is absent (a\nrejected token never reaches the model) it is the edge's cf-ray.","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Clef Provider Guide","lvl2":"What is sent to Cloudflare","lvl3":""}},
5673
5675
  {"objectID":"37eb6d126d3af6ca22085fbf94025a8f23da15691c8f6070b946f5aaa27e2f10","title":"One token, two providers","url":"/docs/getting-started/providers/cloudflare-clef#one-token-two-providers","content":"cloudflare-clef and cloudflare read the same two variables, but each has its\nown credentials slice, so the two cannot be mixed up:\n\n| | cloudflare (text) | cloudflare-clef (decide) |\n| --------------- | --------------------------- | ---------------------------- |\n| Token | CLOUDFLARE_API_KEY | CLOUDFLARE_API_KEY |\n| Account id | CLOUDFLARE_ACCOUNT_ID | CLOUDFLARE_ACCOUNT_ID |\n| SDK credentials | credentials.cloudflare | credentials.cloudflareClef |\n| Serves | generate() and stream() | decide() only |\n\ncredentials.cloudflare does not configure decide. Setting the two\nvariables for the text provider also lets decide() use Clef when no other\ndecision provider is configured, and no switch turns that off while the two\nvariables are set in the environment. A host that wants the Workers AI text\nprovider without Clef can give the text provider its token and account id only\nthrough credentials.cloudflare, and leave the environment variables unset.","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Clef Provider Guide","lvl2":"One token, two providers","lvl3":""}},
5674
5676
  {"objectID":"fee62c91a128411e33fcad60cf048405bd86ff0f4015189d992b70d34fe1b86f","title":"Measured on a real account, October 2026","url":"/docs/getting-started/providers/cloudflare-clef#measured-on-a-real-account-october-2026","content":"The Workers AI endpoint ignored text past about 2,048 tokens until 2026-10-04,\nfar below Cloudflare's documented 64K context, and read far more on 2026-10-07\n(hosted service or model: unknown). Request-size refusals also changed between two measurement dates.\nThe original measurements were on 2026-10-03; the bounded follow-up campaign\nused 133 probe calls on 2026-10-04, with one request at a time.\n\nWhich model: on both clef-flash and clef, the follow-up still read the\nfact at the 2026-10-03 clef-flash lower bound for logs, number lists, digit\narrays and compact JSON, and did not read it 2.5% to 3.1% further on. English prose and\nrandom CJK had already matched on both models. It also checked the question\ncount, pixel and four/five-image boundaries on both models, the id, option,\nscore-level and PNG/JPEG/WebP boundaries on clef, and the image/jpg case on\nboth models. Natural-script\nprose was measured on clef; a reworked many-key object probe matched on both.\nTypeScript, minified JSON and synthetic Devanagari/emoji cuts remain 9B-only\nmeasurements. Historical latency, billing and burst figures retain their dates.","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Clef Provider Guide","lvl2":"Measured on a real account, October 2026","lvl3":""}},
@@ -5678,8 +5680,8 @@
5678
5680
  {"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":""}},
5679
5681
  {"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":""}},
5680
5682
  {"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":""}},
5681
- {"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\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":""}},
5682
- {"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 last decision provider\nNeuroLink falls back to: built-in features that call decide() use the first one\nconfigured, in the order TypeSafe, Laya, XOR, SubQ, Perplexity, then Clef. 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":""}},
5683
+ {"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":""}},
5684
+ {"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":""}},
5683
5685
  {"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":""}},
5684
5686
  {"objectID":"25503e78c2d92fb7cee70f0a5e3045de4dbad7279ef1b5cb1a6c834a89c4d006","title":"Overview","url":"/docs/getting-started/providers/cloudflare#overview","content":"Cloudflare Workers AI\nserves Meta Llama, Mistral, and other open models from Cloudflare's\nglobal GPU cluster. NeuroLink talks to the OpenAI-compatible endpoint.","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Workers AI Provider Guide","lvl2":"Overview","lvl3":""}},
5685
5687
  {"objectID":"11f1e13f3ceb9f43bdaceb8669617ec44d6a62676514a7899f65463375681501","title":"Key Facts","url":"/docs/getting-started/providers/cloudflare#key-facts","content":"Protocol: 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)","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Workers AI Provider Guide","lvl2":"Key Facts","lvl3":""}},
@@ -5687,7 +5689,7 @@
5687
5689
  {"objectID":"088e2cc83205e7cef6bcdc0633aee37efb875a215914292fe0d8472ad9956f7f","title":"Supported Models (sample)","url":"/docs/getting-started/providers/cloudflare#supported-models-sample","content":"| 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","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Workers AI Provider Guide","lvl2":"Supported Models (sample)","lvl3":""}},
5688
5690
  {"objectID":"e1e8b466c22f042a3d3095b12f19a9fe24a96d6480b008310cfc189f341d45a5","title":"Provider Aliases","url":"/docs/getting-started/providers/cloudflare#provider-aliases","content":"| Alias | Example |\n| ------------ | ----------------------- |\n| cloudflare | --provider cloudflare |\n| cf | --provider cf |","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Workers AI Provider Guide","lvl2":"Provider Aliases","lvl3":""}},
5689
5691
  {"objectID":"62de16314951fdc73f9dd06c4c146e4c9202ddb9445bea480242fcac6cf0ab83","title":"Configuration Reference","url":"/docs/getting-started/providers/cloudflare#configuration-reference","content":"| 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 |","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Workers AI Provider Guide","lvl2":"Configuration Reference","lvl3":""}},
5690
- {"objectID":"a12a3191a8590f0031973af941fe6c2be7f7cf931536ea38903ef8e8bf9bb5c6","title":"Also configures decisions","url":"/docs/getting-started/providers/cloudflare#also-configures-decisions","content":"CLOUDFLARE_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 last decision provider\nNeuroLink falls back to: built-in features that call decide() use the first one\nconfigured, in the order TypeSafe, Laya, XOR, SubQ, Perplexity, then Clef. 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.","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Workers AI Provider Guide","lvl2":"Also configures decisions","lvl3":""}},
5692
+ {"objectID":"a12a3191a8590f0031973af941fe6c2be7f7cf931536ea38903ef8e8bf9bb5c6","title":"Also configures decisions","url":"/docs/getting-started/providers/cloudflare#also-configures-decisions","content":"CLOUDFLARE_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.","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Workers AI Provider Guide","lvl2":"Also configures decisions","lvl3":""}},
5691
5693
  {"objectID":"c18937da302797e2d1727a8d5894df09424bcf4d107a5500e2a04ce958eb9673","title":"See Also","url":"/docs/getting-started/providers/cloudflare#see-also","content":"Cloudflare 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":"See Also","lvl3":""}},
5692
5694
  {"objectID":"771db3571626e1c1eb3472bc9a61338f884160a5415735e50731de5e772d00f0","title":"Cohere Provider Guide","url":"/docs/getting-started/providers/cohere","content":"Cohere Provider Guide\n\nCommand R chat + Embed v3 embeddings via the Cohere API\n\nOverview\n\nCohere offers a production-grade chat\ncatalog (Command R / R+ / R7B) plus top-tier embeddings (Embed v3) and\nreranking (Rerank v3). NeuroLink wraps chat via the OpenAI-compatible\nendpoint and embeddings via the native /v2/embed endpoint.\n\nKey Facts\nProtocol: OpenAI-compatible chat at /compatibility/v1,\n native embed at /v2/embed\nDefault base URL: https://api.cohere.com/compatibility/v1\nDefault chat model: command-r-plus-08-2024\nDefault embed model: embed-english-v3.0\nStreaming: Yes\nTool calling: Yes (Command R / R+)\n\nQuick Start\nGet an API Key\n\nhttps://dashboard.cohere.com/api-keys\nConfigure\nGenerate Text\nGenerate Embeddings\n\nSupported Models\n\n| Model ID | Family | Notes |\n| ----------------------------- | ---------------- | ------------------------ |\n| command-r-plus-08-2024 | Chat (default) | Flagship |\n| command-r-08-2024 | Chat | Mid-tier |\n| command-r7b-12-2024 | Chat | Most compact |\n| command-a-reasoning-08-2025 | Reasoning | Reasoning traces |\n| embed-english-v3.0 | Embeddings (def) | 1024 dim, English |\n| embed-multilingual-v3.0 | Embeddings | 1024 dim, 100+ languages |\n\nCLI Usage\n\nConfiguration Reference\n\n| Environment Variable | Required | Default |\n| -------------------- | -------- | ----------------------------------------- |\n| COHERE_API_KEY | Yes | β€” |\n| COHERE_MODEL | No | command-r-plus-08-2024 |\n| COHERE_BASE_URL | No | https://api.cohere.com/compatibility/v1 |\n\nFeature Support Matrix\n\n| Feature | Support |\n| ----------------- | ------------ |\n| Text generation | Yes |\n| Streaming | Yes |\n| Tool calling | Yes |\n| Structured output | Yes |\n| Vision | No |\n| Embeddings | Yes (native) |\n| Reranking | Yes |\n\nTroubleshooting\nNot Found β€” the chosen model may not be available on your tier.\n Try command-r-plus-08-2024 or command-r-08-2024.\n\nSee Also\nVoyage Provider\nJina Provider","hierarchy":{"lvl0":"Getting Started","lvl1":"Cohere Provider Guide","lvl2":"","lvl3":""}},
5693
5695
  {"objectID":"765ab44d68aaf7fc0fe06a519c53fb7aad3106753d2a1b679c26293cce92e958","title":"Cohere Provider Guide","url":"/docs/getting-started/providers/cohere#cohere-provider-guide","content":"Command R chat + Embed v3 embeddings via the Cohere API","hierarchy":{"lvl0":"Getting Started","lvl1":"Cohere Provider Guide","lvl2":"Cohere Provider Guide","lvl3":""}},
@@ -6236,13 +6238,14 @@
6236
6238
  {"objectID":"6ad36ba3488491bb913c7a77b86a278cc86509da88a054975bcded71f5c02130","title":"[OpenRouter](/docs/getting-started/providers/openrouter)","url":"/docs/getting-started/providers#openrouterdocsgetting-startedprovidersopenrouter","content":"300+ models from 60+ providers\n🌐 Single API across many AI providers (Anthropic, OpenAI, Google, Meta, etc.)\n⚑ Automatic failover and routing\nπŸ’° Competitive pricing with cost optimization\n🎯 Zero lock-in - switch models instantly\nπŸ“Š Usage tracking dashboard\nπŸ†“ Free models available\n\nSetup Guide β†’","hierarchy":{"lvl0":"Getting Started","lvl1":"AI Provider Guides","lvl2":"[OpenRouter](/docs/getting-started/providers/openrouter)","lvl3":""}},
6237
6239
  {"objectID":"733a2fa8ea4c547cdcdf502f89f003a2208c0e5828e36e7faaaa94e0903d3d49","title":"[OpenAI Compatible](/docs/getting-started/providers/openai-compatible)","url":"/docs/getting-started/providers#openai-compatibledocsgetting-startedprovidersopenai-compatible","content":"OpenRouter, vLLM, LocalAI, and more\n🌐 100+ models through OpenRouter\nπŸ’» Local deployment with vLLM\nπŸ”“ Self-hosted with LocalAI\nπŸ”„ Drop-in OpenAI replacement\n\nSetup Guide β†’","hierarchy":{"lvl0":"Getting Started","lvl1":"AI Provider Guides","lvl2":"[OpenAI Compatible](/docs/getting-started/providers/openai-compatible)","lvl3":""}},
6238
6240
  {"objectID":"fc415454bfde58f3634df544ef2adb88836c75fb1344b7042af7a9d6fdfa63d4","title":"[LiteLLM](/docs/getting-started/providers/litellm)","url":"/docs/getting-started/providers#litellmdocsgetting-startedproviderslitellm","content":"100+ providers through proxy\nπŸ”„ Unified API for 100+ providers\nπŸ“Š Load balancing and fallbacks\nπŸ’° Cost tracking\n🎯 Model routing\n\nSetup Guide β†’","hierarchy":{"lvl0":"Getting Started","lvl1":"AI Provider Guides","lvl2":"[LiteLLM](/docs/getting-started/providers/litellm)","lvl3":""}},
6239
- {"objectID":"6337b6964b5ebadd9610f93633594d912ee39f49c2ef5e1683214dce45a1aee3","title":"🧠 Decision-Only Providers","url":"/docs/getting-started/providers#decision-only-providers","content":"The providers that serve decide rather than generate/stream:\nTypeSafe, Laya, XOR,\nSubQ, Perplexity and Cloudflare Clef. Each returns typed boolean/choice/score\nanswers and emits no text, so none appears in generation fallback chains or the\nhealth sweep.","hierarchy":{"lvl0":"Getting Started","lvl1":"AI Provider Guides","lvl2":"🧠 Decision-Only Providers","lvl3":""}},
6241
+ {"objectID":"6337b6964b5ebadd9610f93633594d912ee39f49c2ef5e1683214dce45a1aee3","title":"🧠 Decision-Only Providers","url":"/docs/getting-started/providers#decision-only-providers","content":"The providers that serve decide rather than generate/stream:\nTypeSafe, Laya, XOR,\nSubQ, Perplexity, Cloudflare Clef and\nOpenAI Decisions. Each returns typed boolean/choice/score\nanswers and emits no text, so none appears in generation fallback chains or the\nhealth sweep.","hierarchy":{"lvl0":"Getting Started","lvl1":"AI Provider Guides","lvl2":"🧠 Decision-Only Providers","lvl3":""}},
6240
6242
  {"objectID":"50860d1f7a27dbe3ad7452ad7079ea437658db372b97081d0a509429369cacc6","title":"[TypeSafe (Jev)](/docs/getting-started/providers/typesafe)","url":"/docs/getting-started/providers#typesafe-jevdocsgetting-startedproviderstypesafe","content":"Typed, calibrated judgments instead of text\n🎯 boolean / choice / score answers, each with a calibrated confidence\n⚑ Latency flat in question count β€” 1 question ~393 ms, 400 questions ~465 ms\nπŸ’° ~$0.00002 per decision (~$0.042/M input, output billed at zero)\nπŸ”Œ Two transports: TypeSafe direct, or the Vercel AI Gateway\nπŸ›‘οΈ Fails open β€” with no decision provider configured, every consumer behaves exactly as before\nπŸ”‘ API key from console.typesafe.ai/keys\nπŸ”„ Aliases: jev, typesafe-ai\n\nSetup Guide β†’","hierarchy":{"lvl0":"Getting Started","lvl1":"AI Provider Guides","lvl2":"[TypeSafe (Jev)](/docs/getting-started/providers/typesafe)","lvl3":""}},
6241
6243
  {"objectID":"43b838d60f2794ce46361196d6fc8a708b3a301398dd55f2c8015d567aa21c2c","title":"[Laya](/docs/getting-started/providers/laya)","url":"/docs/getting-started/providers#layadocsgetting-startedproviderslaya","content":"Open-weights decision provider β€” the same typed boolean/choice/score answers as Jev, from Convai Innovations' Apache-2.0 checkpoints, at a Laya server or LiteLLM proxy route you configure\n🧭 Serves decide only; built-in features use it when its key and base URL are set and neither TYPESAFE_API_KEY nor AI_GATEWAY_API_KEY is\nπŸ“ Refuses more than ~768 tokens of state (320 on english) before any network call, since its encoders read only 1,024 (512)\nπŸ”Œ No built-in endpoint: LAYA_BASE_URL (or credentials.laya.baseURL) names a Laya server or a LiteLLM pass-through route to one\nπŸ”‘ LAYA_API_KEY is the key that endpoint accepts; on LiteLLM, the route must be in the key's Allowed Routes\n\nSetup Guide β†’","hierarchy":{"lvl0":"Getting Started","lvl1":"AI Provider Guides","lvl2":"[Laya](/docs/getting-started/providers/laya)","lvl3":""}},
6242
6244
  {"objectID":"613cbeca5e8fa0bbe765b8db9ec4ed2ff76a913dd45b8dab5e2de06a6e5f19ff","title":"[XOR](/docs/getting-started/providers/xor)","url":"/docs/getting-started/providers#xordocsgetting-startedprovidersxor","content":"Open-weights decision provider β€” the same typed boolean/choice/score answers as Jev, from xor-1.1, Juspay's Apache-2.0 model, at a deployment or LiteLLM proxy route you configure\n🧭 Serves decide only; built-in features use it when its key and base URL are set and no TypeSafe key, no AI_GATEWAY_API_KEY and no Laya key and base URL is\nπŸ–ΌοΈ Takes up to 8 images or one video with a decision, as a Buffer, a local file path or a data: URL; TypeSafe and Laya refuse media before any request, and Perplexity refuses a video\nπŸ“ Refuses more than about 200,000 estimated tokens of state before any network call\nπŸ”Œ No built-in endpoint: XOR_BASE_URL (or credentials.xor.baseURL) is the origin of a deployment or of a LiteLLM route to one; requests go to <base URL>/v1/systemone\nπŸ”‘ XOR_API_KEY is the key that endpoint accepts; on LiteLLM, the key's team must allow xor-1.1\nπŸ“¦ Weights and setup: huggingface.co/juspay/xor\n\nSetup Guide β†’","hierarchy":{"lvl0":"Getting Started","lvl1":"AI Provider Guides","lvl2":"[XOR](/docs/getting-started/providers/xor)","lvl3":""}},
6243
6245
  {"objectID":"9fd996aaa27fb32250d5434f0e2764d8bf348370af0e011f9e447a0fdf26e3a8","title":"[SubQ](/docs/getting-started/providers/subq)","url":"/docs/getting-started/providers#subqdocsgetting-startedproviderssubq","content":"Hosted decision provider β€” the same typed boolean/choice/score answers as Jev, from Subquadratic's subq-snap-preview (public preview), at https://api.subq.ai\n🧭 Serves decide only (provider id subq; the aliases subquadratic and subq-snap work too); built-in features use it when it is configured and none of TypeSafe, Laya or XOR is β€” it comes ahead of Perplexity and Cloudflare Clef, because its key is shared with no other provider\nπŸ”‘ SUBQ_API_KEY alone configures it (keys come from console.subq.ai, shown once); SUBQ_MODEL is optional\nπŸ–ΌοΈ No image or video input yet: SubQ's image format is not one the decide catalog can describe, so images are refused before any request\nπŸ“ NeuroLink reports an advisory state window (376,000 estimated tokens; SubQ's own 400 response states a maximum model length of 393,216) and enforces none; no question cap is declared\nπŸ”Œ Hosted endpoint, so no base URL is needed; SUBQ_BASE_URL (or credentials.subq.baseURL) can name another origin\n\nSetup Guide β†’","hierarchy":{"lvl0":"Getting Started","lvl1":"AI Provider Guides","lvl2":"[SubQ](/docs/getting-started/providers/subq)","lvl3":""}},
6244
6246
  {"objectID":"6ab8cdd8152a0d7c9844d54b6d4eaccc905b60e79f4b28508d78d52c3cfe9470","title":"[Perplexity Decisions](/docs/getting-started/providers/perplexity-decider)","url":"/docs/getting-started/providers#perplexity-decisionsdocsgetting-startedprovidersperplexity-decider","content":"Hosted decision provider β€” the same typed boolean/choice/score answers as Jev, from Perplexity's pplx-decider-v1-27b, at https://api.perplexity.ai\n🧭 Serves decide only (provider id perplexity-decider, not the Sonar text provider perplexity); built-in features use it when it is configured and no TypeSafe key, no AI_GATEWAY_API_KEY, no Laya key and base URL, no XOR key and base URL and no SUBQ_API_KEY is\nπŸ”‘ PERPLEXITY_API_KEY alone configures it, and it is the same key the Perplexity text provider reads, so a key set for Sonar also lets built-in features use it when none of TypeSafe, Laya, XOR or SubQ is configured; the guide lists what each consumer then sends\nπŸ–ΌοΈ Takes up to 8 PNG, JPEG or WebP images with a decision; no video\nπŸ’° $0.04 per million input tokens (image tokens included), output free, as Perplexity documents it\nπŸ“ Refuses more than about 100,000 estimated tokens of state (NeuroLink's own window; the server's ceiling is 262,144 input tokens), or more than 128 questions in a decide() call (tryDecide() splits them), before any network call. The 128-question cap, the server's token ceiling and the latency were measured on a real account in October 2026\nπŸ”Œ Hosted endpoint, so no base URL is needed; PERPLEXITY_DECIDER_BASE_URL (or credentials.perplexityDecider.baseURL) can name another origin\n\nSetup Guide β†’","hierarchy":{"lvl0":"Getting Started","lvl1":"AI Provider Guides","lvl2":"[Perplexity Decisions](/docs/getting-started/providers/perplexity-decider)","lvl3":""}},
6245
- {"objectID":"94b24c75db64d3f04ba04b2ee0f04ec13bc0509de0aea1fa1b3e5516dea73ea9","title":"[Cloudflare Clef](/docs/getting-started/providers/cloudflare-clef)","url":"/docs/getting-started/providers#cloudflare-clefdocsgetting-startedproviderscloudflare-clef","content":"Hosted decision provider on Workers AI β€” the same typed boolean/choice/score answers as Jev, from Cloudflare's clef (27B) and clef-flash (9B), at https://api.cloudflare.com/client/v4\n🧭 Serves decide only (provider id cloudflare-clef, not the Workers AI text provider cloudflare); built-in features use it only when it is configured and none of TypeSafe, Laya, XOR, SubQ or Perplexity is β€” it comes last\nπŸ”‘ CLOUDFLARE_API_KEY (Workers AI permission) and CLOUDFLARE_ACCOUNT_ID configure it, and they are the same two variables the Cloudflare text provider reads, so a pair set for that provider also lets built-in features use it when no other decision provider is configured\nπŸ–ΌοΈ Takes up to 4 PNG, JPEG or WebP images with a decision; no video\nπŸ’° $0.24 per million input tokens for clef, $0.09 for clef-flash; no output price is listed on Cloudflare's pricing page\nπŸ“ The state window changed in October 2026 (hosted service or model: unknown): until 2026-10-04 the endpoint ignored text past about 2,048 tokens without an error, and on 2026-10-07 it read states of at least 190,153 tokens (clef-flash) and 52,154 (clef); NeuroLink refuses more than 16,000 estimated tokens (digits count a token each, punctuation 0.75, emoji 3), more than 64 questions in a decide() call (tryDecide() splits them) and a request over 256,000 bytes, base64 image data included, before any network call. The state cut and the request ceiling were measured on a real account in October 2026, with the follow-up text cuts and API limits checked on both models; see the guide for the tested shapes and dates\nπŸ”Œ Hosted endpoint, so no base URL is needed; CLOUDFLARE_CLEF_BASE_URL (or credentials.cloudflareClef.baseURL) can name another base\n\nSetup Guide β†’","hierarchy":{"lvl0":"Getting Started","lvl1":"AI Provider Guides","lvl2":"[Cloudflare Clef](/docs/getting-started/providers/cloudflare-clef)","lvl3":""}},
6247
+ {"objectID":"94b24c75db64d3f04ba04b2ee0f04ec13bc0509de0aea1fa1b3e5516dea73ea9","title":"[Cloudflare Clef](/docs/getting-started/providers/cloudflare-clef)","url":"/docs/getting-started/providers#cloudflare-clefdocsgetting-startedproviderscloudflare-clef","content":"Hosted decision provider on Workers AI β€” the same typed boolean/choice/score answers as Jev, from Cloudflare's clef (27B) and clef-flash (9B), at https://api.cloudflare.com/client/v4\n🧭 Serves decide only (provider id cloudflare-clef, not the Workers AI text provider cloudflare); built-in features use it only when it is configured and none of TypeSafe, Laya, XOR, SubQ or Perplexity is β€” it comes after those five\nπŸ”‘ CLOUDFLARE_API_KEY (Workers AI permission) and CLOUDFLARE_ACCOUNT_ID configure it, and they are the same two variables the Cloudflare text provider reads, so a pair set for that provider also lets built-in features use it when no other decision provider is configured\nπŸ–ΌοΈ Takes up to 4 PNG, JPEG or WebP images with a decision; no video\nπŸ’° $0.24 per million input tokens for clef, $0.09 for clef-flash; no output price is listed on Cloudflare's pricing page\nπŸ“ The state window changed in October 2026 (hosted service or model: unknown): until 2026-10-04 the endpoint ignored text past about 2,048 tokens without an error, and on 2026-10-07 it read states of at least 190,153 tokens (clef-flash) and 52,154 (clef); NeuroLink refuses more than 16,000 estimated tokens (digits count a token each, punctuation 0.75, emoji 3), more than 64 questions in a decide() call (tryDecide() splits them) and a request over 256,000 bytes, base64 image data included, before any network call. The state cut and the request ceiling were measured on a real account in October 2026, with the follow-up text cuts and API limits checked on both models; see the guide for the tested shapes and dates\nπŸ”Œ Hosted endpoint, so no base URL is needed; CLOUDFLARE_CLEF_BASE_URL (or credentials.cloudflareClef.baseURL) can name another base\n\nSetup Guide β†’","hierarchy":{"lvl0":"Getting Started","lvl1":"AI Provider Guides","lvl2":"[Cloudflare Clef](/docs/getting-started/providers/cloudflare-clef)","lvl3":""}},
6248
+ {"objectID":"bcc625210e66063fe8068d952207922cf92704dbb5424a7a3f8192f66de3bab2","title":"[OpenAI Decisions](/docs/getting-started/providers/openai-decisions)","url":"/docs/getting-started/providers#openai-decisionsdocsgetting-startedprovidersopenai-decisions","content":"Hosted decision provider (public beta) β€” the same typed boolean/choice/score answers as Jev, from OpenAI's Decisions API (gpt-6-luna), at https://api.openai.com/v1/decisions\n🧭 Serves decide only (provider id openai-decisions, not the OpenAI chat provider openai); built-in features use it only when it is configured and none of TypeSafe, Laya, XOR, SubQ, Perplexity or Cloudflare Clef is β€” it comes last\nπŸ”‘ OPENAI_API_KEY alone configures it, and it is the same key the OpenAI chat provider reads, so a key set for chat also lets built-in features (and a transcription dictionary's correction check) use it, and make paid decision calls, when no other decision provider is configured, unless OPENAI_BASE_URL, OPENAI_API_BASE or credentials.openai.baseURL names a host other than https://api.openai.com (the key is then taken to be a gateway's and is not used by default; a call that names the provider still uses it and sends it to api.openai.com); the guide lists what each consumer then sends\nπŸ–ΌοΈ Takes up to 8 images as inline data URLs with a decision (NeuroLink's own allowance, not OpenAI's); no video\nπŸ’° $0.10 per million input tokens, input only, per OpenAI's Decisions guide as read on 2026-10-07; regional and long-context multipliers are not modelled\nπŸ“ Question and option limits, image formats, rate limits and latency are not established (none measured); NeuroLink reports 922,000 state tokens as an advisory figure and never refuses on it\nπŸ”Œ Hosted endpoint, so no base URL is needed; OPENAI_DECISIONS_BASE_URL (or credentials.openaiDecisions.baseURL) can name another origin\n\nSetup Guide β†’","hierarchy":{"lvl0":"Getting Started","lvl1":"AI Provider Guides","lvl2":"[OpenAI Decisions](/docs/getting-started/providers/openai-decisions)","lvl3":""}},
6246
6249
  {"objectID":"c98403894a115164f29a019817b7f39c93b59623a9854b4575ad06bc5f597320","title":"🧩 Additional Catalog Providers","url":"/docs/getting-started/providers#-additional-catalog-providers","content":"Every provider below is a Tier-2 catalog entry. Provider-specific\nbehavioural quirks may apply, so check the provider's catalog file. The whole\nintegration is one JSON file under src/lib/providers/catalog/. Each page is\ngenerated from that file, which is also what the CI onboarding gate reads.","hierarchy":{"lvl0":"Getting Started","lvl1":"AI Provider Guides","lvl2":"🧩 Additional Catalog Providers","lvl3":""}},
6247
6250
  {"objectID":"026138da0a559269ecd9f0b2ceb72d9039096e72e064142afb7bfb74a5cb7455","title":"[API Route](/docs/getting-started/providers/api-route)","url":"/docs/getting-started/providers#api-routedocsgetting-startedprovidersapi-route","content":"Claude Sonnet 4.6\nπŸ€– 8 models; default claude-sonnet-4-6 (1M context)\nπŸ› οΈ Native tool calling + structured output together\nπŸ’³ Free tier available\nβœ… Roster verified 2026-09-17 (authenticated GET /v1/models)\nπŸ”‘ API key from api-route.com\nπŸ”„ Aliases: apiroute\n\nSetup Guide β†’","hierarchy":{"lvl0":"Getting Started","lvl1":"AI Provider Guides","lvl2":"[API Route](/docs/getting-started/providers/api-route)","lvl3":""}},
6248
6251
  {"objectID":"85aa65949d959db077347ecf93a4c40ade9ebab4300d4d52c62c702f6929053b","title":"[Baseten](/docs/getting-started/providers/baseten)","url":"/docs/getting-started/providers#basetendocsgetting-startedprovidersbaseten","content":"GLM 5.3 Flash\nπŸ€– 16 models; default zai-org/GLM-5.3-Flash (1M context)\nπŸ› οΈ Native tool calling + structured output together\nπŸ’³ Free tier available\nβœ… Roster verified 2026-09-03 (authenticated GET /v1/models)\nπŸ”‘ API key from app.baseten.co\n\nSetup Guide β†’","hierarchy":{"lvl0":"Getting Started","lvl1":"AI Provider Guides","lvl2":"[Baseten](/docs/getting-started/providers/baseten)","lvl3":""}},
@@ -6329,18 +6332,18 @@
6329
6332
  {"objectID":"4e0264790a48f8469b5d25d609cab04fae1ad3ba2ccee40c8829cd8571c265c6","title":"Verification status","url":"/docs/getting-started/providers/koscompute#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 KosCompute β€” and, just as importantly, what it does\nnot yet record:\n\n| Probe | Result |\n| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Roster | unauthenticated GET /v1/models, HTTP 200, 7 models, 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.","hierarchy":{"lvl0":"Getting Started","lvl1":"KosCompute Provider Guide","lvl2":"Verification status","lvl3":""}},
6330
6333
  {"objectID":"3944867506991deef1761c0dab4d9fa3bc0efe0d53bfb3f9acb78437c41f3ecf","title":"Troubleshooting","url":"/docs/getting-started/providers/koscompute#troubleshooting","content":"| Symptom | Cause | Fix |\n| ------------------------------------ | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Invalid KosCompute API key | KOSCOMPUTE_API_KEY unset, wrong, expired, or lacks access | KosCompute's docs describe 401 as \"missing, invalid, expired, inactive, or conflicting credentials\" but publish no example error body or code string |\n| Model not found | Wrong model id, or the roster changed since 2026-09-28 | Pick a current id from an unauthenticated GET https://api.koscompute.com/v1/models |\n| 429 with concurrent_limit_exceeded | Per-key concurrency limit exceeded | Wait for an in-flight request to finish, or reduce parallel requests, before retrying |\n| No signup page found | Expected β€” KosCompute publishes no public signup or key-management page | Obtain a key out of band; there is no self-serve console to link to |","hierarchy":{"lvl0":"Getting Started","lvl1":"KosCompute Provider Guide","lvl2":"Troubleshooting","lvl3":""}},
6331
6334
  {"objectID":"2de12b046642ad2cef71f2aa84ab6de9163a41b51a046794c2d34738958d382d","title":"See also","url":"/docs/getting-started/providers/koscompute#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":"KosCompute Provider Guide","lvl2":"See also","lvl3":""}},
6332
- {"objectID":"6d919d5032d8bf60b8341d6b8ff90eeb0c7d2f87553ca6e6e96d08b988c7e6e9","title":"Laya Provider Guide","url":"/docs/getting-started/providers/laya","content":"Laya Provider Guide\n\nA provider of decide β€” the same typed boolean / choice / score\nanswers as TypeSafe's Jev, from an open-weights model you can\nrun yourself. It emits no text at all.\n\nOverview\n\nLaya is Convai Innovations' Apache-2.0 \"System One\" decision model. You send\none state plus named, typed questions; an encoder answers every question in a\nsingle forward pass and returns a probability distribution for each. NeuroLink\ncalls whatever base URL you configure β€” a Laya server, or a LiteLLM proxy with a\npass-through route to one. There is no built-in endpoint.\n\nKey Facts\n\n| | |\n| --------------------- | ------------------------------------------------------------------------------------------------- |\n| Inference type | decide only |\n| Checkpoints | typed-decisions (default, fine-tuned for typed decisions), multilingual, english, or auto |\n| Input window | 1,024 tokens (typed-decisions, multilingual); 512 (english) |\n| Questions per request | up to 64 |\n| Endpoint | <base URL>/predict; the base URL is required, with no default |\n| Precedence | used automatically when its key and base URL are set and no TypeSafe key is |\n\nQuick Start\nGet an endpoint and a key\n\nRun a Laya server (see below), or use a LiteLLM\nproxy with a pass-through route to one. On LiteLLM, create a virtual key and add\nthe route's /predict path (and /health, if you want to probe it) to the\nkey's Allowed Routes; a key without them is refused with a 403\nKey/team not allowed to access passthrough route.\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\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\nthe credentials passed to the SDK β€” in the order TypeSafe, Laya,\nXOR, SubQ, Perplexity, then\nCloudflare Clef. TypeSafe has two keys,\nTYPESAFE_API_KEY and AI_GATEWAY_API_KEY (its Vercel AI Gateway route), and\neither one counts. Laya counts only with both its key and its base URL, and so\ndoes XOR. SubQ counts with its key alone, SUBQ_API_KEY. Perplexity counts with\nits key alone, and that key,\nPERPLEXITY_API_KEY, is shared with Perplexity's text provider. Cloudflare Clef\ncounts only with both CLOUDFLARE_API_KEY and CLOUDFLARE_ACCOUNT_ID, the same\ntwo variables the Workers AI text provider reads. So:\nA TypeSafe key, plus Laya's key and base URL: built-in features use\n TypeSafe; Laya runs only where a caller asks for provider: \"laya\".\nOnly Laya's key and base URL: built-in features use Laya.\nLaya's key and base URL, plus XOR's: built-in features use Laya; XOR runs\n only where a caller asks for provider: \"xor\".\nA Laya key with no base URL: Laya is not configured. Built-in features\n ignore it, and provider: \"laya\" fails with Laya requires a base URL.\nLaya's key and base URL, plus a Perplexity key: built-in features use\n Laya; Perplexity runs only where a caller asks for\n provider: \"perplexity-decider\".\nLaya's key and base URL, plus CLOUDFLARE_API_KEY and\n CLOUDFLARE_ACCOUNT_ID: built-in features use Laya; Cloudflare Clef runs\n only where a caller asks for provider: \"cloudflare-clef\".\nLaya's key and base URL, plus SUBQ_API_KEY: built-in features use Laya;\n SubQ runs only where a caller asks for provider: \"subq\".\nNone of TypeSafe, Laya, XOR, SubQ, Perplexity or Cloudflare Clef:\n everything behaves exactly as it did without a decision model.\n\nLimits\n\nThe window is small. Laya's encoders read 1,024 tokens, and 512 on the\nenglish checkpoint, against roughly 33,000 for Jev. Part of that is reserved\nfor each question and its options, so NeuroLink allows about 768 tokens of\nstate on typed-decisions and multilingual, and 320 on english, auto and\nany model name it does not recognise. Laya's server does not refuse a longer\nstate β€” it answers from the start of it and says nothing β€” so NeuroLink\nrefuses it instead, before any network call, with max_tokens_exceeded.\n\nThe size is an estimate, not Laya's tokenizer: about four characters per token\nfor ASCII text, and 1.5 tokens per character for other scripts (0.6 on\nmultilingual), calibrated against a live Laya 0.3.5 server. It errs toward refusing. Built-in\nconsumers treat a refusal as \"carry on as before\", which means long-prompt\nmodel routing usually falls back to the heuristic when L","hierarchy":{"lvl0":"Getting Started","lvl1":"Laya Provider Guide","lvl2":"","lvl3":""}},
6335
+ {"objectID":"6d919d5032d8bf60b8341d6b8ff90eeb0c7d2f87553ca6e6e96d08b988c7e6e9","title":"Laya Provider Guide","url":"/docs/getting-started/providers/laya","content":"Laya Provider Guide\n\nA provider of decide β€” the same typed boolean / choice / score\nanswers as TypeSafe's Jev, from an open-weights model you can\nrun yourself. It emits no text at all.\n\nOverview\n\nLaya is Convai Innovations' Apache-2.0 \"System One\" decision model. You send\none state plus named, typed questions; an encoder answers every question in a\nsingle forward pass and returns a probability distribution for each. NeuroLink\ncalls whatever base URL you configure β€” a Laya server, or a LiteLLM proxy with a\npass-through route to one. There is no built-in endpoint.\n\nKey Facts\n\n| | |\n| --------------------- | ------------------------------------------------------------------------------------------------- |\n| Inference type | decide only |\n| Checkpoints | typed-decisions (default, fine-tuned for typed decisions), multilingual, english, or auto |\n| Input window | 1,024 tokens (typed-decisions, multilingual); 512 (english) |\n| Questions per request | up to 64 |\n| Endpoint | <base URL>/predict; the base URL is required, with no default |\n| Precedence | used automatically when its key and base URL are set and no TypeSafe key is |\n\nQuick Start\nGet an endpoint and a key\n\nRun a Laya server (see below), or use a LiteLLM\nproxy with a pass-through route to one. On LiteLLM, create a virtual key and add\nthe route's /predict path (and /health, if you want to probe it) to the\nkey's Allowed Routes; a key without them is refused with a 403\nKey/team not allowed to access passthrough route.\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\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\nthe credentials passed to the SDK β€” in the order TypeSafe, Laya,\nXOR, SubQ, Perplexity,\nCloudflare Clef, then\nOpenAI Decisions. TypeSafe has two keys,\nTYPESAFE_API_KEY and AI_GATEWAY_API_KEY (its Vercel AI Gateway route), and\neither one counts. Laya counts only with both its key and its base URL, and so\ndoes XOR. SubQ counts with its key alone, SUBQ_API_KEY. Perplexity counts with\nits key alone, and that key,\nPERPLEXITY_API_KEY, is shared with Perplexity's text provider. Cloudflare Clef\ncounts only with both CLOUDFLARE_API_KEY and CLOUDFLARE_ACCOUNT_ID, the same\ntwo variables the Workers AI text provider reads. OpenAI Decisions counts with its\nkey alone, OPENAI_API_KEY, which the OpenAI chat provider reads too. So:\nA TypeSafe key, plus Laya's key and base URL: built-in features use\n TypeSafe; Laya runs only where a caller asks for provider: \"laya\".\nOnly Laya's key and base URL: built-in features use Laya.\nLaya's key and base URL, plus XOR's: built-in features use Laya; XOR runs\n only where a caller asks for provider: \"xor\".\nA Laya key with no base URL: Laya is not configured. Built-in features\n ignore it, and provider: \"laya\" fails with Laya requires a base URL.\nLaya's key and base URL, plus a Perplexity key: built-in features use\n Laya; Perplexity runs only where a caller asks for\n provider: \"perplexity-decider\".\nLaya's key and base URL, plus CLOUDFLARE_API_KEY and\n CLOUDFLARE_ACCOUNT_ID: built-in features use Laya; Cloudflare Clef runs\n only where a caller asks for provider: \"cloudflare-clef\".\nLaya's key and base URL, plus SUBQ_API_KEY: built-in features use Laya;\n SubQ runs only where a caller asks for provider: \"subq\".\nNone of TypeSafe, Laya, XOR, SubQ, Perplexity, Cloudflare Clef or OpenAI\n Decisions: everything behaves exactly as it did without a decision model.\n\nLimits\n\nThe window is small. Laya's encoders read 1,024 tokens, and 512 on the\nenglish checkpoint, against roughly 33,000 for Jev. Part of that is reserved\nfor each question and its options, so NeuroLink allows about 768 tokens of\nstate on typed-decisions and multilingual, and 320 on english, auto and\nany model name it does not recognise. Laya's server does not refuse a longer\nstate β€” it answers from the start of it and says nothing β€” so NeuroLink\nrefuses it instead, before any network call, with max_tokens_exceeded.\n\nThe size is an estimate, not Laya's tokenizer: about four characters per token\nfor ASCII text, and 1.5 tokens per character for other scripts (0.6 on\nmultilingual), calibrated against a live Laya 0.3.5 server. It errs toward refusing. Bu","hierarchy":{"lvl0":"Getting Started","lvl1":"Laya Provider Guide","lvl2":"","lvl3":""}},
6333
6336
  {"objectID":"c57a78b27b2b64f684ee60c36022d5b19a81323647a32687608b35530b4d3ed7","title":"Laya Provider Guide","url":"/docs/getting-started/providers/laya#laya-provider-guide","content":"A provider of decide β€” the same typed boolean / choice / score\nanswers as TypeSafe's Jev, from an open-weights model you can\nrun yourself. It emits no text at all.","hierarchy":{"lvl0":"Getting Started","lvl1":"Laya Provider Guide","lvl2":"Laya Provider Guide","lvl3":""}},
6334
6337
  {"objectID":"969ae83c9e8333da8d49838b0595db3588d8828b67611944cd46f08435f19d97","title":"Overview","url":"/docs/getting-started/providers/laya#overview","content":"Laya is Convai Innovations' Apache-2.0 \"System One\" decision model. You send\none state plus named, typed questions; an encoder answers every question in a\nsingle forward pass and returns a probability distribution for each. NeuroLink\ncalls whatever base URL you configure β€” a Laya server, or a LiteLLM proxy with a\npass-through route to one. There is no built-in endpoint.","hierarchy":{"lvl0":"Getting Started","lvl1":"Laya Provider Guide","lvl2":"Overview","lvl3":""}},
6335
6338
  {"objectID":"acf4d054e73fb41ef18db1c578cf1beb1117c3f43b24c6743ba30a4fe6569fb7","title":"Key Facts","url":"/docs/getting-started/providers/laya#key-facts","content":"| | |\n| --------------------- | ------------------------------------------------------------------------------------------------- |\n| Inference type | decide only |\n| Checkpoints | typed-decisions (default, fine-tuned for typed decisions), multilingual, english, or auto |\n| Input window | 1,024 tokens (typed-decisions, multilingual); 512 (english) |\n| Questions per request | up to 64 |\n| Endpoint | <base URL>/predict; the base URL is required, with no default |\n| Precedence | used automatically when its key and base URL are set and no TypeSafe key is |","hierarchy":{"lvl0":"Getting Started","lvl1":"Laya Provider Guide","lvl2":"Key Facts","lvl3":""}},
6336
6339
  {"objectID":"ae5970b1821e7485e9d952384e4d6749a99d486ea648241bcbd8a9d43579e79a","title":"1. Get an endpoint and a key","url":"/docs/getting-started/providers/laya#1-get-an-endpoint-and-a-key","content":"Run a Laya server (see below), or use a LiteLLM\nproxy with a pass-through route to one. On LiteLLM, create a virtual key and add\nthe route's /predict path (and /health, if you want to probe it) to the\nkey's Allowed Routes; a key without them is refused with a 403\nKey/team not allowed to access passthrough route.","hierarchy":{"lvl0":"Getting Started","lvl1":"Laya Provider Guide","lvl2":"1. Get an endpoint and a key","lvl3":""}},
6337
6340
  {"objectID":"662bbcdcfe03b7cb5abd93bb0088ff4bdcd8558ad74a79d70f1f7ab36023842c","title":"2. Configure","url":"/docs/getting-started/providers/laya#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":"Laya Provider Guide","lvl2":"2. Configure","lvl3":""}},
6338
- {"objectID":"c99b86a6719e50f022a261b2688e6c849e03afaed0e6e398e9353d84cbf76835","title":"When NeuroLink uses it","url":"/docs/getting-started/providers/laya#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\nthe credentials passed to the SDK β€” in the order TypeSafe, Laya,\nXOR, SubQ, Perplexity, then\nCloudflare Clef. TypeSafe has two keys,\nTYPESAFE_API_KEY and AI_GATEWAY_API_KEY (its Vercel AI Gateway route), and\neither one counts. Laya counts only with both its key and its base URL, and so\ndoes XOR. SubQ counts with its key alone, SUBQ_API_KEY. Perplexity counts with\nits key alone, and that key,\nPERPLEXITY_API_KEY, is shared with Perplexity's text provider. Cloudflare Clef\ncounts only with both CLOUDFLARE_API_KEY and CLOUDFLARE_ACCOUNT_ID, the same\ntwo variables the Workers AI text provider reads. So:\nA TypeSafe key, plus Laya's key and base URL: built-in features use\n TypeSafe; Laya runs only where a caller asks for provider: \"laya\".\nOnly Laya's key and base URL: built-in features use Laya.\nLaya's key and base URL, plus XOR's: built-in features use Laya; XOR runs\n only where a caller asks for provider: \"xor\".\nA Laya key with no base URL: Laya is not configured. Built-in features\n ignore it, and provider: \"laya\" fails with Laya requires a base URL.\nLaya's key and base URL, plus a Perplexity key: built-in features use\n Laya; Perplexity runs only where a caller asks for\n provider: \"perplexity-decider\".\nLaya's key and base URL, plus CLOUDFLARE_API_KEY and\n CLOUDFLARE_ACCOUNT_ID: built-in features use Laya; Cloudflare Clef runs\n only where a caller asks for provider: \"cloudflare-clef\".\nLaya's key and base URL, plus SUBQ_API_KEY: built-in features use Laya;\n SubQ runs only where a caller asks for provider: \"subq\".\nNone of TypeSafe, Laya, XOR, SubQ, Perplexity or Cloudflare Clef:\n everything behaves exactly as it did without a decision model.","hierarchy":{"lvl0":"Getting Started","lvl1":"Laya Provider Guide","lvl2":"When NeuroLink uses it","lvl3":""}},
6341
+ {"objectID":"c99b86a6719e50f022a261b2688e6c849e03afaed0e6e398e9353d84cbf76835","title":"When NeuroLink uses it","url":"/docs/getting-started/providers/laya#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\nthe credentials passed to the SDK β€” in the order TypeSafe, Laya,\nXOR, SubQ, Perplexity,\nCloudflare Clef, then\nOpenAI Decisions. TypeSafe has two keys,\nTYPESAFE_API_KEY and AI_GATEWAY_API_KEY (its Vercel AI Gateway route), and\neither one counts. Laya counts only with both its key and its base URL, and so\ndoes XOR. SubQ counts with its key alone, SUBQ_API_KEY. Perplexity counts with\nits key alone, and that key,\nPERPLEXITY_API_KEY, is shared with Perplexity's text provider. Cloudflare Clef\ncounts only with both CLOUDFLARE_API_KEY and CLOUDFLARE_ACCOUNT_ID, the same\ntwo variables the Workers AI text provider reads. OpenAI Decisions counts with its\nkey alone, OPENAI_API_KEY, which the OpenAI chat provider reads too. So:\nA TypeSafe key, plus Laya's key and base URL: built-in features use\n TypeSafe; Laya runs only where a caller asks for provider: \"laya\".\nOnly Laya's key and base URL: built-in features use Laya.\nLaya's key and base URL, plus XOR's: built-in features use Laya; XOR runs\n only where a caller asks for provider: \"xor\".\nA Laya key with no base URL: Laya is not configured. Built-in features\n ignore it, and provider: \"laya\" fails with Laya requires a base URL.\nLaya's key and base URL, plus a Perplexity key: built-in features use\n Laya; Perplexity runs only where a caller asks for\n provider: \"perplexity-decider\".\nLaya's key and base URL, plus CLOUDFLARE_API_KEY and\n CLOUDFLARE_ACCOUNT_ID: built-in features use Laya; Cloudflare Clef runs\n only where a caller asks for provider: \"cloudflare-clef\".\nLaya's key and base URL, plus SUBQ_API_KEY: built-in features use Laya;\n SubQ runs only where a caller asks for provider: \"subq\".","hierarchy":{"lvl0":"Getting Started","lvl1":"Laya Provider Guide","lvl2":"When NeuroLink uses it","lvl3":""}},
6339
6342
  {"objectID":"adbc69b418b48f0bcaa2ae6e9f87f6bf8efc0dea1fe0d614cc12973156148d9f","title":"Limits","url":"/docs/getting-started/providers/laya#limits","content":"The window is small. Laya's encoders read 1,024 tokens, and 512 on the\nenglish checkpoint, against roughly 33,000 for Jev. Part of that is reserved\nfor each question and its options, so NeuroLink allows about 768 tokens of\nstate on typed-decisions and multilingual, and 320 on english, auto and\nany model name it does not recognise. Laya's server does not refuse a longer\nstate β€” it answers from the start of it and says nothing β€” so NeuroLink\nrefuses it instead, before any network call, with max_tokens_exceeded.\n\nThe size is an estimate, not Laya's tokenizer: about four characters per token\nfor ASCII text, and 1.5 tokens per character for other scripts (0.6 on\nmultilingual), calibrated against a live Laya 0.3.5 server. It errs toward refusing. Built-in\nconsumers treat a refusal as \"carry on as before\", which means long-prompt\nmodel routing usually falls back to the heuristic when Laya is the only\ndecision provider.\n\nMany options degrade it. A choice's options share a fixed token budget,\nso accuracy drops past about 20 options; some Laya servers also reject a\nquestion whose options overflow the budget, as invalid_request.\n\nPick the checkpoint deliberately. Laya's own benchmark puts its general\nenglish and multilingual checkpoints close to chance on typed decisions\nwithout fine-tuning; typed-decisions is the fine-tuned one, which is why it is\nthe default.","hierarchy":{"lvl0":"Getting Started","lvl1":"Laya Provider Guide","lvl2":"Limits","lvl3":""}},
6340
6343
  {"objectID":"141537feff8c79df3ecbca258b80136e36da0fdeff342aa93a971be020313215","title":"Errors","url":"/docs/getting-started/providers/laya#errors","content":"| Reply | Kind | Retried |\n| ----------------------------------------------- | ------------------------------------------------------- | ------- |\n| 401 / 403 from the proxy | authentication β€” the provider instance stops retrying | no |\n| 400 / 422 from Laya | invalid_request, with Laya's reason | no |\n| 413 from Laya | max_tokens_exceeded | no |\n| 429 | rate_limit | yes |\n| 503 | overloaded | yes |\n| other 5xx | server | yes |\n| more questions or state than Laya reads (local) | max_tokens_exceeded, with no network call | no |\n| no base URL configured (local) | invalid_request, with no network call | no |\n\nLiteLLM's 401 text echoes a masked copy of the rejected key and its hash; the\nprovider drops that part before the message reaches a log or an error.","hierarchy":{"lvl0":"Getting Started","lvl1":"Laya Provider Guide","lvl2":"Errors","lvl3":""}},
6341
6344
  {"objectID":"de358abc64cad163c1666dce7b06fc5f7b3637b9568e420ceb9269a526929d54","title":"Running your own Laya server","url":"/docs/getting-started/providers/laya#running-your-own-laya-server","content":"Laya's example server exposes the same /predict route. Point\nLAYA_BASE_URL at it:","hierarchy":{"lvl0":"Getting Started","lvl1":"Laya Provider Guide","lvl2":"Running your own Laya server","lvl3":""}},
6342
6345
  {"objectID":"e0dd67e8f79c7801d3e199dcd765a559f64a9d65d43cf1611026725a8ae1ee82","title":"Troubleshooting","url":"/docs/getting-started/providers/laya#troubleshooting","content":"Laya requires a base URL β€” set LAYA_BASE_URL, or pass\n credentials.laya.baseURL. There is no default endpoint.\nAuthentication failed β€” the proxy rejected the key. Check it in the\n LiteLLM Dashboard, including its Allowed Routes. The provider instance does\n not retry after a rejection.\nA 403 with error code: 1010 β€” Cloudflare in front of your proxy blocked\n the client by its signature. Node's fetch is accepted; a proxy or agent that\n rewrites the user agent may not be.\nexceeded the provider's token limit β€” the state is larger than Laya\n reads. Shorten it, or configure TypeSafe for long inputs.\nBuilt-in routing never uses Laya β€” a TypeSafe key is also set and takes\n precedence, or Laya has no base URL.","hierarchy":{"lvl0":"Getting Started","lvl1":"Laya Provider Guide","lvl2":"Troubleshooting","lvl3":""}},
6343
- {"objectID":"fb160b657869a262fd7735599ce2c2ffd49423f4a0f7c43f4ef5ee74aa4dcde5","title":"See also","url":"/docs/getting-started/providers/laya#see-also","content":"The decide inference type\nTypeSafe (Jev) Provider Guide\nXOR Provider Guide\nPerplexity Decisions Provider Guide\nCloudflare Clef Provider Guide\nSubQ Provider Guide\nLaya on GitHub","hierarchy":{"lvl0":"Getting Started","lvl1":"Laya Provider Guide","lvl2":"See also","lvl3":""}},
6346
+ {"objectID":"fb160b657869a262fd7735599ce2c2ffd49423f4a0f7c43f4ef5ee74aa4dcde5","title":"See also","url":"/docs/getting-started/providers/laya#see-also","content":"The decide inference type\nTypeSafe (Jev) Provider Guide\nXOR Provider Guide\nPerplexity Decisions Provider Guide\nCloudflare Clef Provider Guide\nSubQ Provider Guide\nOpenAI Decisions Provider Guide\nLaya on GitHub","hierarchy":{"lvl0":"Getting Started","lvl1":"Laya Provider Guide","lvl2":"See also","lvl3":""}},
6344
6347
  {"objectID":"df16212357acdf1cff3460cb04e276abe1c702cc845767f49a4bc0cd2a92a763","title":"Lemonfox AI Provider Guide","url":"/docs/getting-started/providers/lemonfox-ai","content":"Lemonfox AI Provider Guide\n\nLemonfox AI is a Tier-2 catalog provider: its integration is one JSON file\n(src/lib/providers/catalog/lemonfox-ai.json) rather than hand-written code.\n\nVerification status: this entry is docs-verified only, not yet\nlive-verified. The vendor's GET https://api.lemonfox.ai/v1/models needs a\nkey (it answers HTTP 401 without one), so the two model ids come from the\nvendor's public chat API page, https://www.lemonfox.ai/apis/chat (retrieved\n2026-09-29), and the roster has not been checked. No account was created and no\nAPI key was used to build it. evidence.liveMatrix is null until someone\nruns the live capability matrix with a real key (see\nVerification status below).\n\nKey Facts\nProvider id: lemonfox-ai (alias lemonfox)\nProtocol: OpenAI-compatible (/chat/completions) β€” the chat API page says\n \"Our OpenAI-compatible API takes a list of messages as input and provides an\n AI-generated (assistant) message as output.\"\nBase URL: https://api.lemonfox.ai/v1\nDefault model: deepseek-v4-flash\nModels in catalog: 2, taken from the model table of\n https://www.lemonfox.ai/apis/chat\nStreaming: supported β€” the page's stream parameter reads \"incremental\n message updates are transmitted as server-sent events with data-only\n messages.\"\nTool calling: not declared (false) β€” the page's API Parameters section\n lists messages, model, max_tokens, stop, stream,\n frequency_penalty, presence_penalty, temperature and top_p\nTools while streaming: not declared (false)\nStructured output: not declared (false), same parameter list as above\nStructured output + tools together: not declared (false) β€” no combined\n probe was possible without credentials\nEmbeddings: not declared\nThinking: not declared\nBilling: free-with-card is the growth queue's classification, one of the\n three values the catalog schema allows; see Billing below for the\n vendor's own wording\nKey format: none declared\n\nQuick Start\nGet an API key\nVisit: https://lemonfox.ai/signup (the \"Get started\" and \"Start Your Free Trial\" links on https://www.lemonfox.ai/apis/chat both point to /signup); sign-up was not attempted while building this entry\nCreate an API key at https://lemonfox.ai/apis/keys β€” https://www.lemonfox.ai/apis/chat links \"create an API key\" to that page, and the API's 401 reply says \"You can obtain an API key from https://lemonfox.ai/apis/keys.\"\nBilling as the vendor states it: see Billing below\nSet LEMONFOX_AI_API_KEY in your .env file\nConfigure\nUse it\n\nPer-request credentials:\n\nBilling\n\nWhat the vendor's public pages show (retrieved 2026-09-29):\nhttps://www.lemonfox.ai/ β€” \"Try our APIs for 1 month for free.\"\nhttps://www.lemonfox.ai/apis/chat β€” \"First month for free!\" and \"Start Your\n Free Trial\"\nhttps://www.lemonfox.ai/terms β€” Lemon Fox GmbH uses Paddle as its Merchant of\n Record and offers \"subscription-based pricing and usage-based pricing\"\n\nThe entry records free-with-card, the growth queue's classification, because\nthe catalog schema has no unknown value; it is not a vendor statement of\nsign-up terms.\n\nModels\n\n| Model | Context | Price / 1M tokens | Notes |\n| ---------------------- | ------- | ----------------- | -------------------------------------------------------------------------------------------------------------------------------- |\n| deepseek-v4-flash ⭐ | 1M | $0.50 | NeuroLink default. Vendor: \"DeepSeek V4 Flash is our default model β€” fast, cost-effective, and suitable for most tasks.\" |\n| mimo-v2.5-pro | β€” | $1.25 | NeuroLink fallback. Vendor: \"MiMo V2.5 Pro is a powerful model from Xiaomi, recommended for complex reasoning and coding tasks.\" |\n\nModel ids, the 1M context figure and the two prices come from the model table\non https://www.lemonfox.ai/apis/chat (retrieved 2026-09-29), whose price column\nis headed \"Price / 1M tokens\". The table's context text for deepseek-v4-flash\nreads \"Supports a 1M token context window.\"; the catalog stores it as 1,000,000\n(NeuroLink's decimal reading of \"1M\"). mimo-v2.5-pro has no context window set.\nThe page also shows the model parameter as \"Specify the model ID to be used.\nDefault: deepseek-v4-flash. Also supported: mimo-v2.5-pro.\"\n\nmodels.defaultContextWindow (32,768) and models.defaultMaxOutputTokens\n(4,096) are placeholders the vendor does not publish, for model ids outside the\ncatalog; the page's max_tokens parameter reads \"integer, optional, default:\ninfinity\". pricingPerMTok is unset on both models because the catalog field\ntakes separate input and output figures and the table has the one \"Price / 1M\ntokens\" column.\n\nEach model's vision flag is false in the catalog, a placeholder for a\nboolean the schema requires; it is not a vendor statement. Each model's\nstatus is production, a value the schema requires.\n\nDeprecated models: a second table on the same page, under the heading\n\"Deprecated","hierarchy":{"lvl0":"Getting Started","lvl1":"Lemonfox AI Provider Guide","lvl2":"","lvl3":""}},
6345
6348
  {"objectID":"3fca5359ef393150cf2b043c562fa6d28cdd3d17be9b09b089efaf425beb7ef6","title":"Lemonfox AI Provider Guide","url":"/docs/getting-started/providers/lemonfox-ai#lemonfox-ai-provider-guide","content":"Lemonfox AI is a Tier-2 catalog provider: its integration is one JSON file\n(src/lib/providers/catalog/lemonfox-ai.json) rather than hand-written code.\n\nVerification status: this entry is docs-verified only, not yet\nlive-verified. The vendor's GET https://api.lemonfox.ai/v1/models needs a\nkey (it answers HTTP 401 without one), so the two model ids come from the\nvendor's public chat API page, https://www.lemonfox.ai/apis/chat (retrieved\n2026-09-29), and the roster has not been checked. No account was created and no\nAPI key was used to build it. evidence.liveMatrix is null until someone\nruns the live capability matrix with a real key (see\nVerification status below).","hierarchy":{"lvl0":"Getting Started","lvl1":"Lemonfox AI Provider Guide","lvl2":"Lemonfox AI Provider Guide","lvl3":""}},
6346
6349
  {"objectID":"58c275813c578b02ad4927ca1b96bc8b37a07c75c8829608a8098f8fd53256f1","title":"Key Facts","url":"/docs/getting-started/providers/lemonfox-ai#key-facts","content":"Provider id: lemonfox-ai (alias lemonfox)\nProtocol: OpenAI-compatible (/chat/completions) β€” the chat API page says\n \"Our OpenAI-compatible API takes a list of messages as input and provides an\n AI-generated (assistant) message as output.\"\nBase URL: https://api.lemonfox.ai/v1\nDefault model: deepseek-v4-flash\nModels in catalog: 2, taken from the model table of\n https://www.lemonfox.ai/apis/chat\nStreaming: supported β€” the page's stream parameter reads \"incremental\n message updates are transmitted as server-sent events with data-only\n messages.\"\nTool calling: not declared (false) β€” the page's API Parameters section\n lists messages, model, max_tokens, stop, stream,\n frequency_penalty, presence_penalty, temperature and top_p\nTools while streaming: not declared (false)\nStructured output: not declared (false), same parameter list as above\nStructured output + tools together: not declared (false) β€” no combined\n probe was possible without credentials\nEmbeddings: not declared\nThinking: not declared\nBilling: free-with-card is the growth queue's classification, one of the\n three values the catalog schema allows; see Billing below for the\n vendor's own wording\nKey format: none declared","hierarchy":{"lvl0":"Getting Started","lvl1":"Lemonfox AI Provider Guide","lvl2":"Key Facts","lvl3":""}},
@@ -6809,6 +6812,28 @@
6809
6812
  {"objectID":"434f0d25d455ebbe0d3df640f00fe02c0c1b090343b8d702427dae3ab7aa99e7","title":"For local servers, use 'none' or empty string","url":"/docs/getting-started/providers/openai-compatible#for-local-servers-use-none-or-empty-string","content":"OPENAICOMPATIBLEAPI_KEY=none # βœ… For vLLM\n`","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI-Compatible Providers Guide","lvl2":"For local servers, use 'none' or empty string","lvl3":""}},
6810
6813
  {"objectID":"1de0ce7944bc2cfd6fbf7e218b3d22113f1921563cd445573fb45c834ba477da","title":"Related Documentation","url":"/docs/getting-started/providers/openai-compatible#related-documentation","content":"Provider Setup Guide - General provider configuration\nCost Optimization - Reduce AI costs\nEnterprise Multi-Region - Self-hosted and vLLM deployment","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI-Compatible Providers Guide","lvl2":"Related Documentation","lvl3":""}},
6811
6814
  {"objectID":"dc5208d2366ed5f49efa96638cae619c0fd5aa2eacae848c64a297ac6ec5d07e","title":"Additional Resources","url":"/docs/getting-started/providers/openai-compatible#additional-resources","content":"OpenRouter - Multi-provider aggregator\nvLLM Documentation - Self-hosted inference\nLocalAI - Local OpenAI alternative\nOpenAI API Spec - API standard\n\nNeed Help? Join our GitHub Discussions or open an issue.","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI-Compatible Providers Guide","lvl2":"Additional Resources","lvl3":""}},
6815
+ {"objectID":"91c74eec73961742b805cee0d280bcf53e9f216a17578ab686dea50f305b0ba4","title":"OpenAI Decisions Provider Guide","url":"/docs/getting-started/providers/openai-decisions","content":"OpenAI Decisions Provider Guide\n\nA provider of decide β€” the same typed boolean / choice / score\nanswers as TypeSafe's Jev, Laya, XOR,\nPerplexity and Cloudflare Clef,\nfrom OpenAI's Decisions API, and it also reads images. It emits no text at all.\n\nThis is not the OpenAI chat provider (openai), which serves\ngenerate() and stream(). The two share one API key, which has a\nconsequence worth reading before you set it. See\nWhat is sent to OpenAI and\nOne key, two providers.\n\nPublic beta. OpenAI documents the Decisions API as a public beta, so its\nwire may change before general availability. NeuroLink lists its one model as\npreview. Much about the endpoint is not established: see\nWhat is not established. No request in this\nguide, or in NeuroLink's tests, records a reply from the live endpoint; the\nreplies in the tests are stand-ins built from OpenAI's published examples.\n\nOverview\n\ngpt-6-luna is the one model OpenAI's Decisions guide lists for the endpoint.\nYou send one input plus named, typed questions, and optionally images. The\nendpoint returns a typed answer for each question, with a probability instead of\na sentence. NeuroLink calls OpenAI's public endpoint, so a key alone configures\nit: there is no base URL to set.\n\nKey Facts\n\n| | |\n| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Provider id | openai-decisions (no aliases) β€” distinct from openai, the chat provider |\n| Inference type | decide only |\n| Model | gpt-6-luna; OPENAI_DECISIONS_MODEL or a per-call model sets it |\n| Key | OPENAI_API_KEY, shared with the OpenAI chat provider, or credentials.openaiDecisions.apiKey |\n| Endpoint | https://api.openai.com/v1/decisions; OPENAI_DECISIONS_BASE_URL can name another origin |\n| Media | images as inline data URLs, up to 8 per request (NeuroLink's own allowance, not OpenAI's); the endpoint has no video part |\n| Request body cap | 32 MiB on the encoded request, NeuroLink's own allowance, not OpenAI's |\n| State window | 922,000 tokens is reported as an advisory figure (the model page's input figure); NeuroLink neve","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Decisions Provider Guide","lvl2":"","lvl3":""}},
6816
+ {"objectID":"e277b3d342fd3fb79433f472e660f6c52f72efe27989a4d67d5484fd148cc161","title":"OpenAI Decisions Provider Guide","url":"/docs/getting-started/providers/openai-decisions#openai-decisions-provider-guide","content":"A provider of decide β€” the same typed boolean / choice / score\nanswers as TypeSafe's Jev, Laya, XOR,\nPerplexity and Cloudflare Clef,\nfrom OpenAI's Decisions API, and it also reads images. It emits no text at all.\n\nThis is not the OpenAI chat provider (openai), which serves\ngenerate() and stream(). The two share one API key, which has a\nconsequence worth reading before you set it. See\nWhat is sent to OpenAI and\nOne key, two providers.\n\nPublic beta. OpenAI documents the Decisions API as a public beta, so its\nwire may change before general availability. NeuroLink lists its one model as\npreview. Much about the endpoint is not established: see\nWhat is not established. No request in this\nguide, or in NeuroLink's tests, records a reply from the live endpoint; the\nreplies in the tests are stand-ins built from OpenAI's published examples.","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Decisions Provider Guide","lvl2":"OpenAI Decisions Provider Guide","lvl3":""}},
6817
+ {"objectID":"49eb266610612a7852f59caabbf8ad2c11b45f0cf611089a69ea264bc34a4851","title":"Overview","url":"/docs/getting-started/providers/openai-decisions#overview","content":"gpt-6-luna is the one model OpenAI's Decisions guide lists for the endpoint.\nYou send one input plus named, typed questions, and optionally images. The\nendpoint returns a typed answer for each question, with a probability instead of\na sentence. NeuroLink calls OpenAI's public endpoint, so a key alone configures\nit: there is no base URL to set.","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Decisions Provider Guide","lvl2":"Overview","lvl3":""}},
6818
+ {"objectID":"bf5a6a94239f41122a6e62abc5358dd4226541e57007bc5b220a28229b86fbc9","title":"Key Facts","url":"/docs/getting-started/providers/openai-decisions#key-facts","content":"| | |\n| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Provider id | openai-decisions (no aliases) β€” distinct from openai, the chat provider |\n| Inference type | decide only |\n| Model | gpt-6-luna; OPENAI_DECISIONS_MODEL or a per-call model sets it","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Decisions Provider Guide","lvl2":"Key Facts","lvl3":""}},
6819
+ {"objectID":"399bde759d649245ede8e1d2215c73851d6446e43dfeb6c5dabf5d715353ed19","title":"1. Get a key","url":"/docs/getting-started/providers/openai-decisions#1-get-a-key","content":"Create one in the OpenAI dashboard. It is\nthe same kind of key the OpenAI chat provider uses.","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Decisions Provider Guide","lvl2":"1. Get a key","lvl3":""}},
6820
+ {"objectID":"08b1702a4ad8240cce1dc774b5326214664f7c6fae91197a0dff51d62cce7155","title":"2. Configure","url":"/docs/getting-started/providers/openai-decisions#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.openaiDecisions is its own slice (apiKey and baseURL). A key\npassed as credentials.openai belongs to the chat provider and does not\nconfigure this one. OPENAI_BASE_URL, which moves the chat provider, never\nroutes a decision, and neither does OPENAI_MODEL pick its model; the overrides\nfor this provider are OPENAI_DECISIONS_BASE_URL and OPENAI_DECISIONS_MODEL.\nOPENAI_BASE_URL, OPENAI_API_BASE and the SDK's credentials.openai.baseURL\nare read for one purpose only: to tell whether the environment key is OpenAI's\nown, so that a gateway's key is not used for the default; see\nA gateway's key.","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Decisions Provider Guide","lvl2":"2. Configure","lvl3":""}},
6821
+ {"objectID":"d1990335200138e7298ff0afc1ecb603368cb5543cb1bfe5450e78ac7f2f6763","title":"3. Use it","url":"/docs/getting-started/providers/openai-decisions#3-use-it","content":"A boolean answer carries a probability and no confidence of its own. A choice\nor score answer carries the confidence the endpoint reports; when a reply\nomits it, NeuroLink uses the highest probability in that answer's distribution\ninstead. Whether the endpoint's confidence is calibrated is not established, so\ntune a threshold on it against your own labelled data.","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Decisions Provider Guide","lvl2":"3. Use it","lvl3":""}},
6822
+ {"objectID":"fa7b1e8110b1ba9997e80c48a06a56c4d992f73fc4da5273cd272514914e75b2","title":"From the CLI","url":"/docs/getting-started/providers/openai-decisions#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\nendpoint reports.","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Decisions Provider Guide","lvl2":"From the CLI","lvl3":""}},
6823
+ {"objectID":"1fb4b574ff2f3fdea932808581c38c395288773d198fcb522245d28da677122d","title":"How a question is sent","url":"/docs/getting-started/providers/openai-decisions#how-a-question-is-sent","content":"OpenAI's wire differs from the one the other decide providers share, so\nNeuroLink translates both ways. You write the same boolean, choice and\nscore questions as for any provider.\n\n| NeuroLink | Sent to /v1/decisions |\n| ------------------- | ----------------------------------------------------------------------------------------------------- |\n| state (text) | input, the text as given |\n| state (an object) | input, the object as JSON text |\n| state with images | input as one user message: an input_text part, then one input_image part per image |\n| question id | the question's name, echoed back on its answer |\n| boolean | type: \"predicate\" with instructions |\n| choice | type: \"choice\" with choices: one { value, description } per option, in the order you wrote them |\n| score | type: \"score\" with levels: one { label, description } per level, lowest first |\n| the model | model in the body (gpt-6-luna unless you set another) |\n\nA boolean question has no per-side text on this wire, so each side you give in\ncriteria is appended to its instructions, with fixed wording:\n\nEither line is left out when you did not give that side. A choice option whose\ntext is null is sent without a description. For a score, the label is the\nlevel's index (\"0\", \"1\", ...) and the rubric text goes in description, so a\nreturned level and its label cannot disagree about which level it is. Option names\nthat look like integers (\"1\", \"2\") are reordered by JavaScript's key order, as\nfor every decide provider.","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Decisions Provider Guide","lvl2":"How a question is sent","lvl3":""}},
6824
+ {"objectID":"df550a22381e831fbd8e7b17e43ed09b0b2c49d33ef518c609867ed8d72c09af","title":"Worked example","url":"/docs/getting-started/providers/openai-decisions#worked-example","content":"These are the three examples from\nOpenAI's Decisions guide\n(saved 2026-10-07), as NeuroLink sends and reads them. The questions:\n\ngo out as:\n\nThe guide's example answers, read back by name:\n\n| Question | Answer in the guide | result.answers[name] |\n| ---------------- | ----------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |\n| visible_damage | probability 0.92 | { type: \"boolean\", probability: 0.92 } |\n| department | choice billing; probabilities 0.95 / 0.02 / 0.01 / 0.02; confidence 0.93 | { type: \"choice\", choice: \"billing\", confidence: 0.93, probabilities: { billing: 0.95, technical: 0.02, shipping: 0.01, other: 0.02 } } |\n| severity | score 1.1; probabilities 0.1 / 0.7 / 0.2 for levels 0, 1 and 2; confidence 0.55 | { type: \"score\", score: 1.1, confidence: 0.55, probabilities: { \"0\": 0.1, \"1\": 0.7, \"2\": 0.2 }, legend: { \"0\": \"Appearance only; …\", … } } |\n\nThe score is the probability-weighted average of the level indices (0 Γ— 0.1 +\n1 Γ— 0.7 + 2 Γ— 0.2 = 1.1), the same meaning as NeuroLink's score everywhere. The\nendpoint returns no legend, so NeuroLink builds legend from the rubric you\nsent, keyed by level index, and a level with no text has the empty string. A\nlevel label in the reply is not read: the integer value identifies the level.","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Decisions Provider Guide","lvl2":"Worked example","lvl3":""}},
6825
+ {"objectID":"e32095e540af0c39d6aae4a574d82e9d3cc00d55996e76dd1e88d5334fde4b58","title":"What a reply must look like","url":"/docs/getting-started/providers/openai-decisions#what-a-reply-must-look-like","content":"NeuroLink checks each answer against the question it asked and drops an answer\nthat fails any check, with a warning that names the question and never quotes the\nreply. It does not repair or default an answer, and the other answers in the same\nreply survive. An answer is dropped when:\nit has no name, or a name NeuroLink did not ask, or the same name appears\n more than once (every answer under a repeated name is dropped);\nits type is not the type asked (predicate, choice or score);\na probability is not a number from 0 to 1;\na choice's choice is not one of the options asked, or its probabilities do\n not list each asked option exactly once;\na score's probabilities do not list each level index exactly once as an\n integer value, or its score is not a number from 0 to the highest index;\nits confidence is a number outside 0 to 1 (a missing or non-numeric one is\n replaced by the highest probability in the distribution);\nits probabilities do not sum to 1, within a tolerance of 0.01 (with a rounding\n slack of 1e-9 for floating point). Whether OpenAI rounds the probabilities it\n returns, and by how much, is not established; an answer whose rounding drifts\n past the tolerance is dropped like any other.\n\nA refusal answer (type: \"refusal\") means the model declined that question.\nNeuroLink has no refusal answer type: the question is simply absent from\nresult.answers, and a warning records the model declined to answer \"<id>\".\nA question the reply never mentions is absent too, without a warning. Every\ninternal consumer treats an absent answer as no decision. A reply whose answers\nis not an array fails as a server error.","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Decisions Provider Guide","lvl2":"What a reply must look like","lvl3":""}},
6826
+ {"objectID":"b4619d81305066595c1fe14d0bd051d2a4534341b991a72c7b6ca8172d877bc7","title":"Images","url":"/docs/getting-started/providers/openai-decisions#images","content":"OpenAI's Decisions API reads images, and no video part exists. Pass them as for\nany decide provider that reads images:\n\nor neurolink decide ... --provider openai-decisions --image ./photo.png from the\nCLI. An image can be a Buffer, a file path or a data: URL; a remote http(s)\nURL is not fetched for you. Every image is sent inline as a base64 data URL in an\ninput_image part. The endpoint takes no hosted URL and no file id, and\nNeuroLink sets no detail.\n\nNeuroLink refuses these before any request, as a non-retried invalid_request:\nmore than 8 images, which is NeuroLink's own allowance (the same number it\n allows XOR and Perplexity), not a limit OpenAI documents;\na video, because the endpoint has no video part;\nan image NeuroLink cannot recognise from its bytes, a file that cannot be read,\n or an encoded request body over 32 MiB (also NeuroLink's own number).\n\nThe accepted image formats, the per-request image limit and the body cap on\nOpenAI's side are not established. NeuroLink does not check the format against a\nlist of OpenAI's, because it has none to check against.","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Decisions Provider Guide","lvl2":"Images","lvl3":""}},
6827
+ {"objectID":"9ea430557ccbea3760eeb08f9ddfc727349d78df4612512eb4c634fc537d9e93","title":"When NeuroLink uses it","url":"/docs/getting-started/providers/openai-decisions#when-neurolink-uses-it","content":"Every built-in consumer of decide asks for the default decision provider. That\nis the first one that is configured, in the environment or in the credentials\npassed to the SDK, in the order TypeSafe, Laya, XOR, SubQ, Perplexity,\nCloudflare Clef, then OpenAI Decisions. TypeSafe counts\nwith either of its keys, TYPESAFE_API_KEY or AI_GATEWAY_API_KEY. Laya and XOR\neach count only with both their key and their base URL. Perplexity counts with\nits key alone. Cloudflare Clef counts only with both CLOUDFLARE_API_KEY and\nCLOUDFLARE_ACCOUNT_ID. OpenAI Decisions counts with its key alone, a non-blank\nOPENAI_API_KEY or credentials.openaiDecisions.apiKey, except that a key found\nonly in the environment does not count while OPENAI_BASE_URL,\nOPENAI_API_BASE or credentials.openai.baseURL names a host other than https://api.openai.com: see\nA gateway's key is never used for the default.\nA caller can always name it with provider: \"openai-decisions\". So:\nOnly an OpenAI key, and no base URL for another host: built-in features use\n OpenAI Decisions.\nAn OpenAI key beside OPENAI_BASE_URL, OPENAI_API_BASE or credentials.openai.baseURL naming a gateway:\n the key is taken to be the gateway's, and built-in features behave exactly as\n they did without a decision model, unless OPENAI_DECISIONS_BASE_URL is set or\n a credentials.openaiDecisions key or base URL is passed.\nAn OpenAI key, plus any key or credentials that configure an earlier provider:\n built-in features use the earlier provider, in the order above. OpenAI\n Decisions runs only where a caller asks for provider: \"openai-decisions\".\nA key for the chat provider only: the same as the first case. The key is\n shared, so the chat provider's key also configures this one. See\n One key, two providers.\nNone of TypeSafe, Laya, XOR, SubQ, Perplexity, Cloudflare Clef or OpenAI Decisions\n configured: everything behaves exactly as it did without a decision model.","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Decisions Provider Guide","lvl2":"When NeuroLink uses it","lvl3":""}},
6828
+ {"objectID":"4c0c98775b0c21bdaeffbd51a77736e61ca1847dfea62204eab148c02317a84d","title":"What is sent to OpenAI","url":"/docs/getting-started/providers/openai-decisions#what-is-sent-to-openai","content":"OpenAI receives the state and the questions of every decision made on your\nbehalf. The questions are NeuroLink's fixed wording, plus text from your own\nconversation where a consumer quotes it; the state is where your text goes.\nThis is what each built-in consumer sends and what turns it on, read from the\ncode:\nModel routing. One request behind the router, the model catalogue and the\n per-request context budget.\nSends: the first 8,000 characters of the prompt of the call being routed,\n plus whether tools are available, whether the request includes images, the\n estimated input tokens, the requested thinking level, whether a session is\n bound and how many prior messages the caller passed in. When the pool has\n more than one model, the questions carry the ids and descriptions of the\n models in it. The images, the session id and the conversation itself are not\n sent.\nTurned on by: classifierRouter.enabled with a pool: an opt-in. With\n the default classifier: \"auto\", a configured decision provider selects the\n decision strategy. classifier: \"heuristic\" or \"llm\" never calls a\n decision provider. A call that pins both provider and model is not\n routed.\nRelevance compaction. Stage 0 of context compaction.\nSends: the current request (first 4,000 characters) and, for each earlier\n user or assistant message that is plain text (not a tool call or result, a\n summary or a pinned skill), its role and its first 1,200 characters. That\n text travels twice, once in the state and once in the message's question. By\n default the six most recent messages are never sent\n (contextRelevance.protectRecent), and at most 300 are asked about.\nTurned on by: nothing beyond a configured decision provider. It runs\n inside context compaction, which starts when a conversation outgrows its\n context budget.\nSummary-quality gate. Guards the summarization stage of compaction.","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Decisions Provider Guide","lvl2":"What is sent to OpenAI","lvl3":""}},
6829
+ {"objectID":"ebe4c10fa9c8ba932d0fa55fd540a3c022964f71e344c17bc1f01673aa141398","title":"One key, two providers","url":"/docs/getting-started/providers/openai-decisions#one-key-two-providers","content":"OPENAI_API_KEY is the variable the OpenAI chat provider reads to\nserve generate() and stream(). It is also the variable that configures this\nprovider, and nothing else needs to be set. This changes what a host with only\nan OpenAI key does by default. A host that set the key only to use OpenAI chat\nhas also configured decide:\nWith none of TypeSafe, Laya, XOR, SubQ, Perplexity or Cloudflare Clef configured,\n the texts listed in What is sent to OpenAI go to\n OpenAI's Decisions API, and each decision is a paid call. Context compaction\n needs no other opt-in, so a host with long conversations starts sending\n conversation text the first time one outgrows its budget. Model routing, tool\n routing and RAG planning do so only where you have turned them on. A host that\n passes a transcription dictionary also sends transcript text. No code changes:\n the key is the switch.\nIt is fail-open, and every other decision provider takes precedence. If you\n have configured any of them, the shared key changes nothing for the built-in\n consumers. A failure here leaves behaviour as it was, so a key the Decisions\n endpoint does not accept costs requests, not correctness.\nA rejected key is not remembered across calls. A 401 stops one provider\n instance from retrying, but neurolink.decide() and neurolink.tryDecide()\n build a fresh provider for every call, so the breaker never latches across\n them. A host whose key the endpoint rejects makes one failing request for each\n decision site that runs, every time it runs.\nWith no decision provider configured at all, nothing is sent.","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Decisions Provider Guide","lvl2":"One key, two providers","lvl3":""}},
6830
+ {"objectID":"589d4b33834cecbfd79e7a3eeac0c17d5ba4b2b1f72e19c703f9495f7604207d","title":"A gateway's key is never used for the default","url":"/docs/getting-started/providers/openai-decisions#a-gateways-key-is-never-used-for-the-default","content":"OPENAI_API_KEY is also the key of every OpenAI-compatible gateway (LiteLLM,\nvLLM, LM Studio and the like), and a host that points the chat provider at one\nsets OPENAI_BASE_URL (or, in LangChain-style setups, OPENAI_API_BASE), or an SDK\nhost passes credentials.openai.baseURL, to it. The chat provider prefers the\ncredentials field over the variable.\nThat key belongs to the gateway, and the decision text belongs on the gateway's\nside of the wire, so NeuroLink does not take such a key to be OpenAI's: while\nOPENAI_BASE_URL, OPENAI_API_BASE or credentials.openai.baseURL names a host other than\nhttps://api.openai.com, the environment key is not used to pick OpenAI Decisions\nas the default. The built-in consumers send nothing to api.openai.com for it:\neach behaves as it did without a decision model, and the \"no decision provider\"\nerror says why the key is ignored. Only a call that names the provider reaches\nOpenAI, as described below.\n\nThe check reads each value's origin, that is scheme, host and port, compared\nwithout regard to case. A path, a trailing slash and /v1 do not matter.\n\n| OPENAI_BASE_URL / OPENAI_API_BASE / credentials.openai.baseURL | The environment key is used for the default |\n| ----------------------------------------------------------------------------------- | ------------------------------------------- |\n| unset, empty or blank | yes |\n| https://api.openai.com, https://api.openai.com/v1/, https://API.openai.com | yes |\n| https://gateway.example/v1, http://127.0.0.1:4000/v1, http://localhost:11434 | no |\n| https://eu.api.openai.com, http://api.openai.com, https://api.openai.com:8443 | no: another host, scheme or port |\n| api.openai.com (no scheme), not a url, ftp://...","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Decisions Provider Guide","lvl2":"A gateway's key is never used for the default","lvl3":""}},
6831
+ {"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":""}},
6832
+ {"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":""}},
6833
+ {"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":""}},
6834
+ {"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":""}},
6835
+ {"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":""}},
6836
+ {"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":""}},
6812
6837
  {"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":""}},
6813
6838
  {"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":""}},
6814
6839
  {"objectID":"b0ec9b5b8b5214c2b809622c60e20e66d39e7e3db9353215ab1f5de78036fac8","title":"Overview","url":"/docs/getting-started/providers/openai-tts#overview","content":"NeuroLink 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.","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI TTS Provider Guide","lvl2":"Overview","lvl3":""}},
@@ -6837,7 +6862,7 @@
6837
6862
  {"objectID":"e2d66c098b27a18e31a0985c2b41817ec2896b37532ec07b38e09f1ed760c1b7","title":"\"OpenAI TTS request timed out after 30 seconds\"","url":"/docs/getting-started/providers/openai-tts#openai-tts-request-timed-out-after-30-seconds","content":"A network issue or overloaded API caused the request to time out. Retry the request β€” the error is marked retriable by NeuroLink's error system.","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI TTS Provider Guide","lvl2":"\"OpenAI TTS request timed out after 30 seconds\"","lvl3":""}},
6838
6863
  {"objectID":"9a54f6363be2937d7c7f9328a1e90b4e1945f5d0c31f3e66477c6468d131b099","title":"Audio sounds distorted at high speed","url":"/docs/getting-started/providers/openai-tts#audio-sounds-distorted-at-high-speed","content":"Speeds above 2.0 can introduce artifacts. Use speed: 1.0 – 1.5 for natural-sounding output.","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI TTS Provider Guide","lvl2":"Audio sounds distorted at high speed","lvl3":""}},
6839
6864
  {"objectID":"f98d39032204ab3aed29744d24a667388d714a7e1214577e166e2d377469d80e","title":"See Also","url":"/docs/getting-started/providers/openai-tts#see-also","content":"TTS Integration Guide β€” complete multi-provider TTS reference\nAudio Input (STT) β€” speech-to-text counterpart\nOpenAI Provider Guide β€” full OpenAI text generation provider\nElevenLabs Provider Guide β€” alternative TTS provider with voice cloning\n\nNeed Help? Join the GitHub Discussions or open an issue.","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI TTS Provider Guide","lvl2":"See Also","lvl3":""}},
6840
- {"objectID":"988dc021ae1e24ac074ba6ccd12141310a44053f1327466076993828c5bf0d61","title":"OpenAI Provider Guide","url":"/docs/getting-started/providers/openai","content":"OpenAI Provider Guide\n\nAccess GPT-5.4, GPT-5, GPT-4o, o-series reasoning models, and embedding models through the OpenAI API\n\nOverview\n\nOpenAI provides API access to the GPT model family, including the GPT-6 family, the GPT-5.4 series, GPT-5 series, GPT-4o multimodal models, and o-series reasoning models. NeuroLink talks to the OpenAI HTTP API directly β€” generation, streaming, tool calling, vision and embeddings are all served by NeuroLink's own client, with no third-party model SDK in the path.\n\nKey Benefits\nGPT-5.4 Series: Flagship models (March 2026) with 1.05M context (gpt-5.4, gpt-5.4-pro; mini and nano 400K)\nGPT-5 Series: Flagship models with up to 400K context windows\nGPT-4.1 Series: 1M context window models for large document processing\nGPT-4o: Multimodal model with vision support\no-Series Reasoning: o3, o3-pro, and o4-mini for deep reasoning tasks\nEmbeddings: text-embedding-3-small and other embedding models\nTool/Function Calling: Full support for agent workflows\nStreaming: Real-time streaming responses with tool execution\nProxy Support: Route requests through HTTP/HTTPS/SOCKS proxies\n\nProvider Aliases\n\nYou can reference this provider using any of the following names:\n\n| Alias | Usage |\n| --------- | --------------------------- |\n| openai | Canonical provider name |\n| gpt | Short alias for convenience |\n| chatgpt | Alternative alias |\n\nThese aliases are registered in src/lib/factories/providerRegistry.ts.\n\nQuick Start\nGet Your API Key\nVisit platform.openai.com/api-keys\nSign in or create an account\nClick Create new secret key\nCopy your new API key (starts with sk-)\nConfigure Environment\n\nAdd to your .env file:\nTest the Setup\n\nSupported Models\n\nAvailable Models (from OpenAIModels enum)\n\n| Enum Key | Model ID | Series | Context Window | Notes |\n| --------------------- | --------------------- | ------------ | -------------- | ------------------------ |\n| GPT_6_ASTRA | gpt-6-astra | GPT-6 | 1.05M | New (September 2026) |\n| GPT_6_SOL | gpt-6-sol | GPT-6 | 1.05M | New (September 2026) |\n| GPT_6_LUNA | gpt-6-luna | GPT-6 | 1.05M | New (September 2026) |\n| GPT_5_4 | gpt-5.4 | GPT-5.4 | 1.05M | New (March 2026) |\n| GPT_5_4_MINI | gpt-5.4-mini | GPT-5.4 | 400K | New (March 2026) |\n| GPT_5_4_NANO | gpt-5.4-nano | GPT-5.4 | 400K | New (March 2026) |\n| GPT_5_3_CODEX | gpt-5.3-codex | GPT-5.3 | 400K | |\n| GPT_5_2 | gpt-5.2 | GPT-5.2 | 400K | |\n| GPT_5_2_CHAT_LATEST | gpt-5.2-chat-latest | GPT-5.2 | 128K | |\n| GPT_5_2_PRO | gpt-5.2-pro | GPT-5.2 | 400K | |\n| GPT_5_2_CODEX | gpt-5.2-codex | GPT-5.2 | 400K | |\n| GPT_5_1 | gpt-5.1 | GPT-5.1 | 400K | |\n| GPT_5_1_CHAT_LATEST | gpt-5.1-chat-latest | GPT-5.1 | 128K | |\n| GPT_5_1_CODEX | gpt-5.1-codex | GPT-5.1 | 400K | |\n| GPT_5_1_CODEX_MAX | gpt-5.1-codex-max | GPT-5.1 | 400K | |\n| GPT_5_1_CODEX_MINI | gpt-5.1-codex-mini | GPT-5.1 | 400K | |\n| GPT_5 | gpt-5 | GPT-5 | 400K | |\n| GPT_5_MINI | gpt-5-mini | GPT-5 | 400K | |\n| GPT_5_NANO | gpt-5-nano | GPT-5 | 400K | |\n| GPT_5_PRO | gpt-5-pro | GPT-5 | 400K | |\n| GPT_5_CHAT_LATEST | gpt-5-chat-latest | GPT-5 | 128K | |\n| GPT_5_CODEX | gpt-5-codex | GPT-5 | 400K | |\n| GPT_OSS_120B | gpt-oss-120b | GPT OSS | 128K | |\n| GPT_OSS_20B | gpt-oss-20b | GPT OSS | 128K | |\n| GPT_4_1 | gpt-4.1 | GPT-4.1 | 1M | |\n| GPT_4_1_MINI | gpt-4.1-mini | GPT-4.1 | 1M | |\n| GPT_4_1_NANO | gpt-4.1-nano | GPT-4.1 | 1M | |\n| GPT_4O | gpt-4o | GPT-4o | 128K | |\n| GPT_4O_MINI | gpt-4o-mini | GPT-4o | 128K | Default model ","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Provider Guide","lvl2":"","lvl3":""}},
6865
+ {"objectID":"988dc021ae1e24ac074ba6ccd12141310a44053f1327466076993828c5bf0d61","title":"OpenAI Provider Guide","url":"/docs/getting-started/providers/openai","content":"OpenAI Provider Guide\n\nAccess GPT-5.4, GPT-5, GPT-4o, o-series reasoning models, and embedding models through the OpenAI API\n\nOverview\n\nOpenAI provides API access to the GPT model family, including the GPT-6 family, the GPT-5.4 series, GPT-5 series, GPT-4o multimodal models, and o-series reasoning models. NeuroLink talks to the OpenAI HTTP API directly β€” generation, streaming, tool calling, vision and embeddings are all served by NeuroLink's own client, with no third-party model SDK in the path.\n\nKey Benefits\nGPT-5.4 Series: Flagship models (March 2026) with 1.05M context (gpt-5.4, gpt-5.4-pro; mini and nano 400K)\nGPT-5 Series: Flagship models with up to 400K context windows\nGPT-4.1 Series: 1M context window models for large document processing\nGPT-4o: Multimodal model with vision support\no-Series Reasoning: o3, o3-pro, and o4-mini for deep reasoning tasks\nEmbeddings: text-embedding-3-small and other embedding models\nTool/Function Calling: Full support for agent workflows\nStreaming: Real-time streaming responses with tool execution\nProxy Support: Route requests through HTTP/HTTPS/SOCKS proxies\n\nProvider Aliases\n\nYou can reference this provider using any of the following names:\n\n| Alias | Usage |\n| --------- | --------------------------- |\n| openai | Canonical provider name |\n| gpt | Short alias for convenience |\n| chatgpt | Alternative alias |\n\nThese aliases are registered in src/lib/factories/providerRegistry.ts.\n\nQuick Start\nGet Your API Key\nVisit platform.openai.com/api-keys\nSign in or create an account\nClick Create new secret key\nCopy your new API key (starts with sk-)\nConfigure Environment\n\nAdd to your .env file:\n\nOPENAI_API_KEY also configures decisions. The same variable configures the\nOpenAI Decisions provider (openai-decisions, which\nserves decide()). So setting it for chat also lets NeuroLink's built-in\nfeatures send decision requests to OpenAI when no TypeSafe, Laya, XOR,\nPerplexity or Cloudflare Clef provider is configured, and context compaction\nneeds no other opt-in to do so. Those are paid calls, and they fail open. To\navoid that, pass the key through the SDK as credentials.openai.apiKey instead\nof the environment, and keep it out of .env too: the SDK and the CLI load that\nfile into the environment, so an OPENAI_API_KEY line like the one above would\nstill configure decisions. See\nWhat is sent to OpenAI and\nOne key, two providers.\nIf you point the chat provider at a gateway (LiteLLM, vLLM and the like) with\nOPENAI_BASE_URL, OPENAI_API_BASE or credentials.openai.baseURL, the key is the gateway's and is not\nused for decisions by default: while any of them names a host other than\nhttps://api.openai.com, NeuroLink's built-in features send nothing to OpenAI's\nDecisions API (only a call that names openai-decisions does, with that key). See\nA gateway's key.\nTest the Setup\n\nSupported Models\n\nAvailable Models (from OpenAIModels enum)\n\n| Enum Key | Model ID | Series | Context Window | Notes |\n| --------------------- | --------------------- | ------------ | -------------- | ------------------------ |\n| GPT_6_ASTRA | gpt-6-astra | GPT-6 | 1.05M | New (September 2026) |\n| GPT_6_SOL | gpt-6-sol | GPT-6 | 1.05M | New (September 2026) |\n| GPT_6_LUNA | gpt-6-luna | GPT-6 | 1.05M | New (September 2026) |\n| GPT_5_4 | gpt-5.4 | GPT-5.4 | 1.05M | New (March 2026) |\n| GPT_5_4_MINI | gpt-5.4-mini | GPT-5.4 | 400K | New (March 2026) |\n| GPT_5_4_NANO | gpt-5.4-nano | GPT-5.4 | 400K | New (March 2026) |\n| GPT_5_3_CODEX | gpt-5.3-codex | GPT-5.3 | 400K | |\n| GPT_5_2 | gpt-5.2 | GPT-5.2 | 400K | |\n| GPT_5_2_CHAT_LATEST | gpt-5.2-chat-latest | GPT-5.2 | 128K | |\n| GPT_5_2_PRO | gpt-5.2-pro | GPT-5.2 | 400K | |\n| GPT_5_2_CODEX | gpt-5.2-codex | GPT-5.2 | 400K | |\n| GPT_5_1 | gpt-5.1 | GPT-5.1 | 400K | |\n| GPT_5_1_CHAT_LATEST | gpt-5.1-chat-latest | GPT-5.1 | 128K | |\n| GPT_5_1_CODEX | gpt-5.1-codex | GPT-5.1 | 400K | |\n| GPT_5_1_CODEX_MAX | gpt-5.1-codex-max | GPT-5.1 | 400K | |\n| GPT_5_1_CODEX_MINI | gpt-5.1-codex-mini | GPT-5.1 | 400K | |\n| GPT_5 | gpt-5 | GPT-5 | 400K | |\n| GPT_5_MINI | gpt-5-mini | GPT-5 | 400K | ","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Provider Guide","lvl2":"","lvl3":""}},
6841
6866
  {"objectID":"09a56d9dc91320ff37eda19c92d08529dc6471dd3b273124ca539bf8c68cf8eb","title":"OpenAI Provider Guide","url":"/docs/getting-started/providers/openai#openai-provider-guide","content":"Access GPT-5.4, GPT-5, GPT-4o, o-series reasoning models, and embedding models through the OpenAI API","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Provider Guide","lvl2":"OpenAI Provider Guide","lvl3":""}},
6842
6867
  {"objectID":"00a9eec16078fe5bf845c9876ae67265e060b64f3150a402681173526d5f9037","title":"Overview","url":"/docs/getting-started/providers/openai#overview","content":"OpenAI provides API access to the GPT model family, including the GPT-6 family, the GPT-5.4 series, GPT-5 series, GPT-4o multimodal models, and o-series reasoning models. NeuroLink talks to the OpenAI HTTP API directly β€” generation, streaming, tool calling, vision and embeddings are all served by NeuroLink's own client, with no third-party model SDK in the path.","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Provider Guide","lvl2":"Overview","lvl3":""}},
6843
6868
  {"objectID":"7ef3ddd9cd1195ba96e4a45b2019a85d9ef0f4aa77585f4cff3f58140d40ea8e","title":"Key Benefits","url":"/docs/getting-started/providers/openai#key-benefits","content":"GPT-5.4 Series: Flagship models (March 2026) with 1.05M context (gpt-5.4, gpt-5.4-pro; mini and nano 400K)\nGPT-5 Series: Flagship models with up to 400K context windows\nGPT-4.1 Series: 1M context window models for large document processing\nGPT-4o: Multimodal model with vision support\no-Series Reasoning: o3, o3-pro, and o4-mini for deep reasoning tasks\nEmbeddings: text-embedding-3-small and other embedding models\nTool/Function Calling: Full support for agent workflows\nStreaming: Real-time streaming responses with tool execution\nProxy Support: Route requests through HTTP/HTTPS/SOCKS proxies","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Provider Guide","lvl2":"Key Benefits","lvl3":""}},
@@ -6845,7 +6870,7 @@
6845
6870
  {"objectID":"769a8aea5668e683c64e455fc484af87c547264189eaed08c2ff047dfc535167","title":"1. Get Your API Key","url":"/docs/getting-started/providers/openai#1-get-your-api-key","content":"Visit platform.openai.com/api-keys\nSign in or create an account\nClick Create new secret key\nCopy your new API key (starts with sk-)","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Provider Guide","lvl2":"1. Get Your API Key","lvl3":""}},
6846
6871
  {"objectID":"c2df7c52c3715cfca6e8c91fd43d047a5c50e2fd573e9ca5b78784aa4b98068c","title":"2. Configure Environment","url":"/docs/getting-started/providers/openai#2-configure-environment","content":"Add to your .env file:\n\n`bash","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Provider Guide","lvl2":"2. Configure Environment","lvl3":""}},
6847
6872
  {"objectID":"877d2901da12fab35c77fd0fca652f1e43e6ddea39645924dac938ef99b4463d","title":"Required: Your OpenAI API key","url":"/docs/getting-started/providers/openai#required-your-openai-api-key","content":"OPENAIAPIKEY=sk-your-key-here","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Provider Guide","lvl2":"Required: Your OpenAI API key","lvl3":""}},
6848
- {"objectID":"e1ea9f50a3405fe5b61c5bf8655daf66c0f353f33b9dff00f4181be2a1258e53","title":"Optional: Override default model (defaults to gpt-4o-mini)","url":"/docs/getting-started/providers/openai#optional-override-default-model-defaults-to-gpt-4o-mini","content":"OPENAI_MODEL=gpt-4o\n`","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Provider Guide","lvl2":"Optional: Override default model (defaults to gpt-4o-mini)","lvl3":""}},
6873
+ {"objectID":"e1ea9f50a3405fe5b61c5bf8655daf66c0f353f33b9dff00f4181be2a1258e53","title":"Optional: Override default model (defaults to gpt-4o-mini)","url":"/docs/getting-started/providers/openai#optional-override-default-model-defaults-to-gpt-4o-mini","content":"OPENAI_MODEL=gpt-4o\n\n\n> **OPENAIAPIKEY also configures decisions.** The same variable configures the\n> [OpenAI Decisions provider](/docs/getting-started/providers/openai-decisions) (openai-decisions, which\n> serves decide()). So setting it for chat also lets NeuroLink's built-in\n> features send decision requests to OpenAI when no TypeSafe, Laya, XOR,\n> Perplexity or Cloudflare Clef provider is configured, and context compaction\n> needs no other opt-in to do so. Those are paid calls, and they fail open. To\n> avoid that, pass the key through the SDK as credentials.openai.apiKey instead\n> of the environment, and keep it out of .env too: the SDK and the CLI load that\n> file into the environment, so an OPENAIAPIKEY line like the one above would\n> still configure decisions. See\n> [What is sent to OpenAI](/docs/getting-started/providers/openai-decisions#what-is-sent-to-openai) and\n> [One key, two providers](/docs/getting-started/providers/openai-decisions#one-key-two-providers).\n>\n> If you point the chat provider at a gateway (LiteLLM, vLLM and the like) with\n> OPENAIBASEURL, OPENAIAPIBASE or credentials.openai.baseURL, the key is the gateway's and is **not**\n> used for decisions by default: while any of them names a host other than\n> https://api.openai.com, NeuroLink's built-in features send nothing to OpenAI's\n> Decisions API (only a call that names openai-decisions` does, with that key). See\nA gateway's key.","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Provider Guide","lvl2":"Optional: Override default model (defaults to gpt-4o-mini)","lvl3":""}},
6849
6874
  {"objectID":"5e7e8211d2fb3a2017c349fcc7d112734942bf738f8202fcf05163a1fa3b9249","title":"3. Test the Setup","url":"/docs/getting-started/providers/openai#3-test-the-setup","content":"`bash","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Provider Guide","lvl2":"3. Test the Setup","lvl3":""}},
6850
6875
  {"objectID":"51393d2a6f860f549650441d19ba86353e5feb0d267b47894b1cd40e16d7e3d0","title":"Quick generation","url":"/docs/getting-started/providers/openai#quick-generation","content":"pnpm run cli -- generate \"Hello from GPT!\" \\\n --provider openai","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Provider Guide","lvl2":"Quick generation","lvl3":""}},
6851
6876
  {"objectID":"6102cd238f922f95762068dd3d2b3950e839a87ac388ee96bb805db79c47d00e","title":"Use specific model","url":"/docs/getting-started/providers/openai#use-specific-model","content":"pnpm run cli -- generate \"Write a haiku about AI\" \\\n --provider openai \\\n --model \"gpt-4o\"","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Provider Guide","lvl2":"Use specific model","lvl3":""}},
@@ -6880,7 +6905,7 @@
6880
6905
  {"objectID":"a86aca416aa7e75cc2d7704033668db8ec43dedebd4a1eadea56b027a3a91123","title":"Use .env file (not committed to git)","url":"/docs/getting-started/providers/openai#use-env-file-not-committed-to-git","content":"echo \"OPENAIAPIKEY=sk-...\" >> .env","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Provider Guide","lvl2":"Use .env file (not committed to git)","lvl3":""}},
6881
6906
  {"objectID":"8b74d64563fbbdc9cf013c2e60863c92df0aaa23cb1f5f0c9e0362673d7824f2","title":"Add to .gitignore","url":"/docs/getting-started/providers/openai#add-to-gitignore","content":"echo \".env\" >> .gitignore\n`","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Provider Guide","lvl2":"Add to .gitignore","lvl3":""}},
6882
6907
  {"objectID":"56923da2a8e1c4d03bd3bad6b9b821f88616cd51db72175af9fc8fee226587ba","title":"Cost Optimization","url":"/docs/getting-started/providers/openai#cost-optimization","content":"Use gpt-4o-mini for routine tasks (significantly cheaper than gpt-4o)\nUse gpt-5-nano for simple classification or extraction tasks\nReserve gpt-5.2-pro and o3-pro for tasks requiring maximum capability\nMonitor token usage via the OpenAI dashboard","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Provider Guide","lvl2":"Cost Optimization","lvl3":""}},
6883
- {"objectID":"477b6a474832b9cc2b70350407d954fbb43a26dc60feb1bba2251be372aed917","title":"Related Documentation","url":"/docs/getting-started/providers/openai#related-documentation","content":"Provider Setup Guide -- General provider configuration\nOpenAI Compatible Provider -- For OpenRouter, vLLM, and other OpenAI-compatible endpoints\nAzure OpenAI Provider -- Azure-hosted OpenAI models","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Provider Guide","lvl2":"Related Documentation","lvl3":""}},
6908
+ {"objectID":"477b6a474832b9cc2b70350407d954fbb43a26dc60feb1bba2251be372aed917","title":"Related Documentation","url":"/docs/getting-started/providers/openai#related-documentation","content":"Provider Setup Guide -- General provider configuration\nOpenAI Decisions Provider -- Typed decide() judgments on the same key\nOpenAI Compatible Provider -- For OpenRouter, vLLM, and other OpenAI-compatible endpoints\nAzure OpenAI Provider -- Azure-hosted OpenAI models","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Provider Guide","lvl2":"Related Documentation","lvl3":""}},
6884
6909
  {"objectID":"f5ddae17fd7d4defa3c0c457eaf61e1122a50d7e89cc3f06171eda10d5623de4","title":"Additional Resources","url":"/docs/getting-started/providers/openai#additional-resources","content":"OpenAI Platform -- Manage API keys and usage\nOpenAI Documentation -- Official API docs\nOpenAI Pricing -- Pricing details\nOpenAI Models -- Model specifications","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenAI Provider Guide","lvl2":"Additional Resources","lvl3":""}},
6885
6910
  {"objectID":"30e160b7189867ac421a533f3fcbdf14f7027deaeb0bfdf598a219ce3623e559","title":"OpenRouter Provider Guide","url":"/docs/getting-started/providers/openrouter","content":"OpenRouter Provider Guide\n\nAccess 300+ AI models from 60+ providers through a single unified API\n\nOverview\n\nOpenRouter is a unified gateway that provides access to 300+ AI models from 60+ providers through a single API. It automatically handles provider routing, failover, and cost optimization, making it the easiest way to access multiple AI models without managing individual provider integrations.\n\nKey Benefits\n300+ Models: Access models from Anthropic, OpenAI, Google, Meta, Mistral, and 55+ other providers\nAutomatic Failover: Built-in redundancy - if one provider is down, requests automatically route to alternatives\nCost Optimization: Competitive pricing with automatic routing to the most cost-effective providers\nZero Lock-in: Switch between models and providers instantly without code changes\nPrivacy Options: Choose between standard, moderated, or private routing modes\nUsage Dashboard: Track spending, model usage, and performance at https://openrouter.ai/activity\nFree Models: Access to free models for development and testing\n\nUse Cases\nMulti-Model Applications: Test and compare models from different providers\nCost Optimization: Automatically route to the most cost-effective model for each task\nHigh Availability: Ensure your app stays online with automatic provider failover\nModel Experimentation: Easily experiment with cutting-edge models as they're released\nPrivacy-Conscious AI: Use private routing to ensure data isn't logged or used for training\nDevelopment & Testing: Use free models during development, switch to paid in production\n\nQuick Start\nGet Your API Key\n\nSign up at https://openrouter.ai and get your API key from https://openrouter.ai/keys.\nConfigure Environment\n\nAdd your API key to .env:\nInstall NeuroLink\nStart Using OpenRouter\n\nSupported Models\n\nOpenRouter provides access to 300+ models. Here are the most popular:\n\nAnthropic Claude\n\nOpenAI\n\nGoogle\n\nMeta Llama\n\nMistral AI\n\nFree Models\n\nOpenRouter provides free access to select models:\n\nBrowse All Models\nWeb Dashboard: https://openrouter.ai/models\nAPI: Dynamically fetched via provider.getAvailableModels()\n\nModel Selection Guide\n\nBy Use Case\n\n| Use Case | Recommended Model | Why |\n| ----------------------- | ----------------------------------- | ------------------------------------------- |\n| General Chat | anthropic/claude-3-5-sonnet | Best balance of quality, speed, and cost |\n| Code Generation | openai/gpt-4o | Excellent code understanding and generation |\n| Long Documents | google/gemini-1.5-pro | 1M token context window |\n| Fast Responses | anthropic/claude-3-5-haiku | Ultra-fast with good quality |\n| Cost Optimization | openai/gpt-4o-mini | Cheapest GPT-4 class model |\n| Development/Testing | google/gemini-2.0-flash-exp:free | Free tier available |\n| Open Source | meta-llama/llama-3.1-70b-instruct | Best open source model |\n| Reasoning | anthropic/claude-3-opus | Superior reasoning capabilities |\n\nBy Performance Characteristics\n\nSpeed Priority\n\nQuality Priority\n\nCost Priority\n\nBest Practices\nModel Selection Strategy\nCost Optimization\nRate Limiting Awareness\n\nOpenRouter has rate limits based on your account tier:\nError Handling Patterns\nCaching Strategies\nProduction Deployment Tips\n\nAdvanced Features\nDynamic Model Discovery\nMulti-Model Comparison\nAttribution Tracking\nPrivacy Modes\n\nOpenRouter supports different privacy modes through model suffixes:\n\nCLI Usage\n\nBasic Commands\n\nModel Comparison via CLI\n\nPricing & Cost Management\n\nUnderstanding Costs\n\nOpenRouter charges per token with transparent pricing:\nInput tokens: Cost to process your prompt\nOutput tokens: Cost to generate the response\nCaching: Some models support prompt caching to reduce costs\n\nView current pricing at https://openrouter.ai/models\n\nCost Comparison (Approximate)\n\n| Model | Input (per 1M tokens) | Output (per 1M tokens) | Best For |\n| ----------------------------- | --------------------- | ---------------------- | ----------------- |\n| openai/gpt-4o-mini | $0.15 | $0.60 | Cost optimization |\n| google/gemini-2.0-flash | $0.075 | $0.30 | Fast & cheap |\n| anthropic/claude-3-5-haiku | $0.25 | $1.25 | Speed & value |\n| anthropic/claude-3-5-sonnet | $3.00 | $15.00 | Balanced |\n| openai/gpt-4o | $2.50 | $10.00 | Code generation |\n| anthropic/claude-3-opus | $15.00 | $75.00 | Complex reasoning |\n\nManaging Your Budget\n\nTroubleshooting\n\nCommon Issues\n\"Invalid API key\"\n\nProblem: API key not set or incorrect.\n\nSolution:\n\"Rat","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenRouter Provider Guide","lvl2":"","lvl3":""}},
6886
6911
  {"objectID":"83174925dad6f6ea35117616e75656bd78c8b4086c5d044151d67812ddce5475","title":"OpenRouter Provider Guide","url":"/docs/getting-started/providers/openrouter#openrouter-provider-guide","content":"Access 300+ AI models from 60+ providers through a single unified API","hierarchy":{"lvl0":"Getting Started","lvl1":"OpenRouter Provider Guide","lvl2":"OpenRouter Provider Guide","lvl3":""}},
@@ -6960,16 +6985,16 @@
6960
6985
  {"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":""}},
6961
6986
  {"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":""}},
6962
6987
  {"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":""}},
6963
- {"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 and\nCloudflare Clef, from Perplexity's hosted Decisions API,\nand it also reads images. It emits no text 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 measure whether i","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"","lvl3":""}},
6964
- {"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 and\nCloudflare Clef, from Perplexity's hosted Decisions API,\nand it also reads images. It emits no text 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":""}},
6988
+ {"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":""}},
6989
+ {"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":""}},
6965
6990
  {"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":""}},
6966
6991
  {"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":""}},
6967
6992
  {"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":""}},
6968
6993
  {"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":""}},
6969
6994
  {"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":""}},
6970
6995
  {"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":""}},
6971
- {"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 does\nCloudflare Clef, up to 4 of them. 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":""}},
6972
- {"objectID":"8ad813ca01099f441bbc2db40ee064d9a0294d269166c42a6f87fce2a1c1330f","title":"When NeuroLink uses it","url":"/docs/getting-started/providers/perplexity-decider#when-neurolink-uses-it","content":"Every built-in consumer of decide asks for the default decision provider. That\nis the first one that is configured, in the environment or in the credentials\npassed to the SDK, in the order TypeSafe, Laya, XOR, SubQ,\nPerplexity, then Cloudflare Clef. TypeSafe counts\nwith either of its keys, TYPESAFE_API_KEY or AI_GATEWAY_API_KEY. Laya and XOR\neach count only with both their key and their base URL. SubQ counts with its key\nalone, SUBQ_API_KEY. Perplexity counts with its key alone, a non-blank\nPERPLEXITY_API_KEY or credentials.perplexityDecider.apiKey. Cloudflare Clef\ncounts only with both CLOUDFLARE_API_KEY and CLOUDFLARE_ACCOUNT_ID. A caller\ncan always name Perplexity with provider: \"perplexity-decider\". So:\nOnly a Perplexity key: built-in features use Perplexity.\nA Perplexity key, plus TypeSafe's key, or Laya's or XOR's key and base\n URL, or SUBQ_API_KEY: built-in features use TypeSafe, Laya, XOR or SubQ,\n in that order, whichever is configured. Perplexity runs only where a caller\n asks for provider: \"perplexity-decider\".\nA Perplexity key, plus CLOUDFLARE_API_KEY and CLOUDFLARE_ACCOUNT_ID:\n built-in features use Perplexity; Cloudflare Clef runs only where a caller\n asks for provider: \"cloudflare-clef\".\nA key for the text provider only: the same as the first case. The key is\n shared, so the text provider's key also configures this one. See\n One key, two providers.\nNone of TypeSafe, Laya, XOR, SubQ, Perplexity or Cloudflare Clef\n configured: everything behaves exactly as it did without a decision model.\n\nThe classifier router's auto gate counts the credentials given to the\nNeuroLink constructor, the environment and the request's own per-call\ncredentials, so a per-call credentials.perplexityDecider can make auto pick\njev. The other consumers NeuroLink wires itself (compaction and tool routing)\nsend the surrounding request's credentials too, so they go to the caller's\naccount.","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"When NeuroLink uses it","lvl3":""}},
6996
+ {"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":""}},
6997
+ {"objectID":"8ad813ca01099f441bbc2db40ee064d9a0294d269166c42a6f87fce2a1c1330f","title":"When NeuroLink uses it","url":"/docs/getting-started/providers/perplexity-decider#when-neurolink-uses-it","content":"Every built-in consumer of decide asks for the default decision provider. That\nis the first one that is configured, in the environment or in the credentials\npassed to the SDK, in the order TypeSafe, Laya, XOR, SubQ,\nPerplexity,\nCloudflare Clef, then\nOpenAI Decisions. TypeSafe counts\nwith either of its keys, TYPESAFE_API_KEY or AI_GATEWAY_API_KEY. Laya and XOR\neach count only with both their key and their base URL. SubQ counts with its key\nalone, SUBQ_API_KEY. Perplexity counts with its key alone, a non-blank\nPERPLEXITY_API_KEY or credentials.perplexityDecider.apiKey. Cloudflare Clef\ncounts only with both CLOUDFLARE_API_KEY and CLOUDFLARE_ACCOUNT_ID. OpenAI Decisions counts with\nits key alone, OPENAI_API_KEY or credentials.openaiDecisions.apiKey. A caller\ncan always name Perplexity with provider: \"perplexity-decider\". So:\nOnly a Perplexity key: built-in features use Perplexity.\nA Perplexity key, plus TypeSafe's key, or Laya's or XOR's key and base\n URL, or SUBQ_API_KEY: built-in features use TypeSafe, Laya, XOR or SubQ,\n in that order, whichever is configured. Perplexity runs only where a caller\n asks for provider: \"perplexity-decider\".\nA Perplexity key, plus CLOUDFLARE_API_KEY and CLOUDFLARE_ACCOUNT_ID:\n built-in features use Perplexity; Cloudflare Clef runs only where a caller\n asks for provider: \"cloudflare-clef\".\nA key for the text provider only: the same as the first case. The key is\n shared, so the text provider's key also configures this one. See\n One key, two providers.\nNone of TypeSafe, Laya, XOR, SubQ, Perplexity, Cloudflare Clef or OpenAI Decisions\n configured: everything behaves exactly as it did without a decision model.\n\nThe classifier router's auto gate counts the credentials given to the\nNeuroLink constructor, the environment and the request's own per-call\ncredentials, so a per-call credentials.perplexityDecider can make auto pick\njev.","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"When NeuroLink uses it","lvl3":""}},
6973
6998
  {"objectID":"9545ac1f3da9bfc59774adf1978baa598ba4fc65670b5d0d4c96f7c10e2a1c3c","title":"What is sent to Perplexity","url":"/docs/getting-started/providers/perplexity-decider#what-is-sent-to-perplexity","content":"Perplexity receives the state and the questions of every decision made on\nyour behalf. The questions are NeuroLink's fixed wording, plus text from your own\nconversation where a consumer quotes it; the state is where your text goes.\nThis is what each built-in consumer sends and what turns it on, read from the\ncode:\nModel routing. One request behind the router, the model catalogue and the\n per-request context budget.\nSends: the first 8,000 characters of the prompt of the call being routed,\n plus whether tools are available, whether the request includes images, the\n estimated input tokens, the requested thinking level, whether a session is\n bound and how many prior messages the caller passed in. When the pool has\n more than one model, the questions carry the ids and descriptions of the\n models in it. The images, the session id and the conversation itself are not\n sent.\nTurned on by: classifierRouter.enabled with a pool: an opt-in. With\n the default classifier: \"auto\", a configured decision provider selects the\n decision strategy. classifier: \"heuristic\" or \"llm\" never calls a\n decision provider. A call that pins both provider and model is not\n routed.\nRelevance compaction. Stage 0 of context compaction.\nSends: the current request (first 4,000 characters) and, for each earlier\n user or assistant message that is plain text (not a tool call or result, a\n summary or a pinned skill), its role and its first 1,200 characters. That\n text travels twice, once in the state and once in the message's question. By\n default the six most recent messages are never sent\n (contextRelevance.protectRecent), and at most 300 are asked about.\nTurned on by: nothing beyond a configured decision provider. It runs\n inside context compaction, which starts when a conversation outgrows its\n context budget.\nSummary-quality gate. Guards the summarization stage of compaction.","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"What is sent to Perplexity","lvl3":""}},
6974
6999
  {"objectID":"01342235e59d6796c886025eea6c3dbdefc5f4420f47123db9b23eacc22955d3","title":"One key, two providers","url":"/docs/getting-started/providers/perplexity-decider#one-key-two-providers","content":"PERPLEXITY_API_KEY is the variable the\nPerplexity text provider reads to serve generate() and\nstream(). It is also the variable that configures this provider. Nothing else\nneeds to be set, so a host that set the key only to use Sonar has also\nconfigured decide:\nWith none of TypeSafe, Laya, XOR or SubQ configured, the texts listed in\n What is sent to Perplexity go to Perplexity's\n Decisions API. Context compaction needs no other opt-in, so a host with long\n conversations starts sending conversation text the first time one outgrows its\n budget. Model routing, tool routing and RAG planning do so only where you have\n turned them on. No code changes: the key is the switch.\nIt is fail-open, and TypeSafe, Laya, XOR and SubQ take precedence. If you have\n configured any of them, the shared key changes nothing for the built-in\n consumers, and a Perplexity failure leaves behaviour as it was.\nWith no decision provider configured at all, nothing is sent.\n\nAn unedited copy of .env.example does not set the key, because its\nPERPLEXITY_API_KEY line is commented out.\n\nA key in a .env file counts as a key in the environment. Importing the SDK\nloads the .env in the current working directory, and the CLI does the same at\nstart; when DOTENV_CONFIG_PATH is set, that file is loaded instead. A key that\nsits in .env therefore configures decide exactly as one exported in the\nshell does.\n\nTo keep a key that was set for Sonar from activating decisions, use one of\nthese:\nHand the key to the text provider through the SDK, not the environment, and\n keep it out of .env.\n new NeuroLink({ credentials: { perplexity: { apiKey } } }) configures the\n text provider and not this one, because NeuroLink looks for this provider's\n key in PERPLEXITY_API_KEY and in credentials.perplexityDecider, never in\n credentials.perplexity.","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"One key, two providers","lvl3":""}},
6975
7000
  {"objectID":"2c9da95e9403e04ac92a64727b9b098a3b1e626742b59f4ffebc6e24914ec316","title":"Measured on a real account, October 2026","url":"/docs/getting-started/providers/perplexity-decider#measured-on-a-real-account-october-2026","content":"NeuroLink probed the live API from an account limited to 10 requests per second.\nThese figures were observed, not taken from Perplexity's documentation:\n\n| What | Measured |\n| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| Questions per request | 128 accepted (128 answers in 8.9 s, 11,904 input tokens); 129 is refused with a 400. An extra minimal question adds about 92 input tokens, and a one-character state with one question bills 116.","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"Measured on a real account, October 2026","lvl3":""}},
@@ -6979,7 +7004,7 @@
6979
7004
  {"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":""}},
6980
7005
  {"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":""}},
6981
7006
  {"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":""}},
6982
- {"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\nPerplexity text provider\nPerplexity Decisions API reference","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Decisions Provider Guide","lvl2":"See also","lvl3":""}},
7007
+ {"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":""}},
6983
7008
  {"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":""}},
6984
7009
  {"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":""}},
6985
7010
  {"objectID":"755494265419901fd106a26a27844178614744eacb256af720b7acfdc700a22c","title":"Overview","url":"/docs/getting-started/providers/perplexity#overview","content":"Perplexity 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.","hierarchy":{"lvl0":"Getting Started","lvl1":"Perplexity Provider Guide","lvl2":"Overview","lvl3":""}},
@@ -7311,19 +7336,19 @@
7311
7336
  {"objectID":"14c8755cfa45311a2b8645d3729d760f513b4e768f4cbe6d75e1dcaaa68c7e94","title":"Configuration Reference","url":"/docs/getting-started/providers/together-ai#configuration-reference","content":"| Environment Variable | Required | Default |\n| -------------------- | -------- | ----------------------------------------- |\n| TOGETHER_API_KEY | Yes | β€” |\n| TOGETHER_MODEL | No | meta-llama/Llama-3.3-70B-Instruct-Turbo |\n| TOGETHER_BASE_URL | No | https://api.together.xyz/v1 |","hierarchy":{"lvl0":"Getting Started","lvl1":"Together AI Provider Guide","lvl2":"Configuration Reference","lvl3":""}},
7312
7337
  {"objectID":"73dacb114377509534778a0d5d1d386e64fe4e71f75f590903d6a5c3dda075c6","title":"Feature Support Matrix","url":"/docs/getting-started/providers/together-ai#feature-support-matrix","content":"| Feature | Support |\n| ----------------- | ----------------- |\n| Text generation | Yes |\n| Streaming | Yes |\n| Tool calling | Yes (model-dep.) |\n| Structured output | Yes (model-dep.) |\n| Vision | Yes (Llama 3.2 V) |\n| Embeddings | Limited |","hierarchy":{"lvl0":"Getting Started","lvl1":"Together AI Provider Guide","lvl2":"Feature Support Matrix","lvl3":""}},
7313
7338
  {"objectID":"5a31d744d2d35af19cc87e27118e0d4057ab98d14fa7be6e9acb01dcbfc29f6a","title":"See Also","url":"/docs/getting-started/providers/together-ai#see-also","content":"Fireworks Provider\nGroq Provider","hierarchy":{"lvl0":"Getting Started","lvl1":"Together AI Provider Guide","lvl2":"See Also","lvl3":""}},
7314
- {"objectID":"63e8301588e0fd846272e6b041d27fbe6a754543f38d949f07ce7e6f181a0ced","title":"TypeSafe (Jev) Provider Guide","url":"/docs/getting-started/providers/typesafe","content":"TypeSafe (Jev) Provider Guide\n\nOne of the providers that serve decide rather than generate/stream β€”\nit returns typed, calibrated judgments and emits no text at all. The others are\nLaya and XOR, open-weights models served from an endpoint\nyou configure, and SubQ, Perplexity and\nCloudflare Clef, hosted APIs. When more than one is\nconfigured, TypeSafe is tried before the others.\n\nOverview\n\nTypeSafe's Jev is a \"System One\" model. You send one state plus a map of\nnamed, typed questions; it returns one typed answer per question, all evaluated\nin a single parallel pass. Nothing has to be parsed back out of prose, and every\nchoice/score answer carries a calibrated confidence rather than a\nself-reported one.\n\nBecause it emits no text, generate() and stream() are not available and\ngetAISDKModel() throws β€” the same shape Voyage and Jina already use for\nembedding-only providers. Its descriptor declares inferenceKinds: [\"decide\"],\nwhich keeps it out of auto-select and the health sweep, so those throws are\nunreachable in normal use.\n\nThis is not neurolink.evaluate(), which\nscores an already-generated response with RAGAS scorers. Different feature,\ndifferent word.\n\nKey Facts\nProvider id: typesafe (aliases: jev, typesafe-ai)\nInference kinds: decide only β€” one of the providers that do (the others\n are Laya, XOR, SubQ,\n Perplexity and Cloudflare Clef); TypeSafe is tried before them when\n more than one is configured\nTool calling: none (toolSupport: \"none\") β€” a decision model calls nothing\nHealth check: env-only; it is never probed with a live generation\nDefault decide timeout: 5000 ms (timeouts.decideMs)\nLatency: flat in question count β€” 1 question ~393 ms, 400 questions\n ~465 ms. Concurrent requests queue instead, so batch every question into one\n call rather than fanning out.\nCost: ~$0.042 per million input tokens, output billed at zero β€” about\n $0.00002 per decision. Output tokens are reported β€” measured 21 for a\n single question, converging to ~17.5 per question in a batch of eight β€” they\n are simply not charged.\nAccuracy is the trade: 67.8% on TypeSafe's own 711-case benchmark against\n Opus 5's 73.1%. Right for decisions that are gated and reversible; wrong for\n final answers.\n\nQuick Start\nGet an API key\n\nCreate one at console.typesafe.ai/keys.\nConfigure\nUse it\n\ntryDecide() returns null on any failure. Use decide() when you want the\nfailure to surface; it throws a ProviderError whose cause carries a typed\nkind.\n\nFrom the CLI\n\nneurolink decide [state] calls decide() under the hood and reads\nTYPESAFE_API_KEY from the environment like every other CLI command. See the\nCLI command reference.\n\nThe degradation contract\n\nSetting the key is the entire switch for TypeSafe, and removing it is a\ncomplete undo while no other decision provider is configured. Every internal\nconsumer of decide fails open: with no decision provider configured, model\nrouting, context budgeting, relevance compaction, tool routing and RAG planning\nall behave exactly as they did before. Note that Perplexity's key is shared with\nits text provider, so a PERPLEXITY_API_KEY set for that provider also counts as\na configured decision provider; see\nOne key, two providers. The same\ngoes for CLOUDFLARE_API_KEY with CLOUDFLARE_ACCOUNT_ID, which the Workers AI\ntext provider reads too: set together they configure Cloudflare Clef, which ranks\nafter TypeSafe, Laya, XOR, SubQ and Perplexity; see One token, two providers. There is no\nconfiguration in which a missing, invalid, slow or unreachable decision model\nchanges NeuroLink's observable behaviour.\n\nA credential the service does not accept disables that provider instance rather\nthan paying a round trip on every later call to be told so again.\n\nTwo transports\n\nThe same model is reachable two ways, and the choice is made 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| Endpoint override | TYPESAFE_BASE_URL | TYPESAFE_GATEWAY_URL |\n| Model named in | request body | ai-model-id header |\n| Question vocabulary | noul | boolean |\n| confidence | on each answer | on providerMetadata |\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. Force\none with TYPESAFE_TRANSPORT=direct|gateway or\ncredentials.typesafe.transport. Either endpoint can be moved without a\nrelease: credentials.typesafe.baseURL / TYPESAFE_BASE_URL for the direct\none, credentials.types","hierarchy":{"lvl0":"Getting Started","lvl1":"TypeSafe (Jev) Provider Guide","lvl2":"","lvl3":""}},
7315
- {"objectID":"7320dc5177f0e320fe7887f77c01c06519bb6c0ddeb8a8b38ecfa013a9363a1f","title":"TypeSafe (Jev) Provider Guide","url":"/docs/getting-started/providers/typesafe#typesafe-jev-provider-guide","content":"One of the providers that serve decide rather than generate/stream β€”\nit returns typed, calibrated judgments and emits no text at all. The others are\nLaya and XOR, open-weights models served from an endpoint\nyou configure, and SubQ, Perplexity and\nCloudflare Clef, hosted APIs. When more than one is\nconfigured, TypeSafe is tried before the others.","hierarchy":{"lvl0":"Getting Started","lvl1":"TypeSafe (Jev) Provider Guide","lvl2":"TypeSafe (Jev) Provider Guide","lvl3":""}},
7339
+ {"objectID":"63e8301588e0fd846272e6b041d27fbe6a754543f38d949f07ce7e6f181a0ced","title":"TypeSafe (Jev) Provider Guide","url":"/docs/getting-started/providers/typesafe","content":"TypeSafe (Jev) Provider Guide\n\nOne of the providers that serve decide rather than generate/stream β€”\nit returns typed, calibrated judgments and emits no text at all. The others are\nLaya and XOR, open-weights models served from an endpoint\nyou configure, and SubQ, Perplexity,\nCloudflare Clef and OpenAI Decisions,\nhosted APIs. When more than one is configured, TypeSafe is tried before the\nothers.\n\nOverview\n\nTypeSafe's Jev is a \"System One\" model. You send one state plus a map of\nnamed, typed questions; it returns one typed answer per question, all evaluated\nin a single parallel pass. Nothing has to be parsed back out of prose, and every\nchoice/score answer carries a calibrated confidence rather than a\nself-reported one.\n\nBecause it emits no text, generate() and stream() are not available and\ngetAISDKModel() throws β€” the same shape Voyage and Jina already use for\nembedding-only providers. Its descriptor declares inferenceKinds: [\"decide\"],\nwhich keeps it out of auto-select and the health sweep, so those throws are\nunreachable in normal use.\n\nThis is not neurolink.evaluate(), which\nscores an already-generated response with RAGAS scorers. Different feature,\ndifferent word.\n\nKey Facts\nProvider id: typesafe (aliases: jev, typesafe-ai)\nInference kinds: decide only β€” one of the providers that do (the others\n are Laya, XOR, SubQ,\n Perplexity,\n Cloudflare Clef and\n OpenAI Decisions); TypeSafe is tried before them when\n more than one is configured\nTool calling: none (toolSupport: \"none\") β€” a decision model calls nothing\nHealth check: env-only; it is never probed with a live generation\nDefault decide timeout: 5000 ms (timeouts.decideMs)\nLatency: flat in question count β€” 1 question ~393 ms, 400 questions\n ~465 ms. Concurrent requests queue instead, so batch every question into one\n call rather than fanning out.\nCost: ~$0.042 per million input tokens, output billed at zero β€” about\n $0.00002 per decision. Output tokens are reported β€” measured 21 for a\n single question, converging to ~17.5 per question in a batch of eight β€” they\n are simply not charged.\nAccuracy is the trade: 67.8% on TypeSafe's own 711-case benchmark against\n Opus 5's 73.1%. Right for decisions that are gated and reversible; wrong for\n final answers.\n\nQuick Start\nGet an API key\n\nCreate one at console.typesafe.ai/keys.\nConfigure\nUse it\n\ntryDecide() returns null on any failure. Use decide() when you want the\nfailure to surface; it throws a ProviderError whose cause carries a typed\nkind.\n\nFrom the CLI\n\nneurolink decide [state] calls decide() under the hood and reads\nTYPESAFE_API_KEY from the environment like every other CLI command. See the\nCLI command reference.\n\nThe degradation contract\n\nSetting the key is the entire switch for TypeSafe, and removing it is a\ncomplete undo while no other decision provider is configured. Every internal\nconsumer of decide fails open: with no decision provider configured, model\nrouting, context budgeting, relevance compaction, tool routing and RAG planning\nall behave exactly as they did before. Note that Perplexity's key is shared with\nits text provider, so a PERPLEXITY_API_KEY set for that provider also counts as\na configured decision provider; see\nOne key, two providers. The same\ngoes for CLOUDFLARE_API_KEY with CLOUDFLARE_ACCOUNT_ID, which the Workers AI\ntext provider reads too: set together they configure Cloudflare Clef, which ranks\nafter TypeSafe, Laya, XOR, SubQ and Perplexity; see One token, two providers.\nOPENAI_API_KEY, which the OpenAI chat provider reads too, configures OpenAI\nDecisions, the last fallback; see\nOne key, two providers. There is no\nconfiguration in which a missing, invalid, slow or unreachable decision model\nchanges NeuroLink's observable behaviour.\n\nA credential the service does not accept disables that provider instance rather\nthan paying a round trip on every later call to be told so again.\n\nTwo transports\n\nThe same model is reachable two ways, and the choice is made 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| Endpoint override | TYPESAFE_BASE_URL | TYPESAFE_GATEWAY_URL |\n| Model named in | request body | ai-model-id header |\n| Question vocabulary | noul | boolean |\n| confidence | on each answer | on providerMetadata |\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. Force\none with TYPESAFE_TRANSPORT=direct|gat","hierarchy":{"lvl0":"Getting Started","lvl1":"TypeSafe (Jev) Provider Guide","lvl2":"","lvl3":""}},
7340
+ {"objectID":"7320dc5177f0e320fe7887f77c01c06519bb6c0ddeb8a8b38ecfa013a9363a1f","title":"TypeSafe (Jev) Provider Guide","url":"/docs/getting-started/providers/typesafe#typesafe-jev-provider-guide","content":"One of the providers that serve decide rather than generate/stream β€”\nit returns typed, calibrated judgments and emits no text at all. The others are\nLaya and XOR, open-weights models served from an endpoint\nyou configure, and SubQ, Perplexity,\nCloudflare Clef and OpenAI Decisions,\nhosted APIs. When more than one is configured, TypeSafe is tried before the\nothers.","hierarchy":{"lvl0":"Getting Started","lvl1":"TypeSafe (Jev) Provider Guide","lvl2":"TypeSafe (Jev) Provider Guide","lvl3":""}},
7316
7341
  {"objectID":"8cc640004e04379192695b8fcd3d49552ac0f4ebd763093bc610b4c93e823fee","title":"Overview","url":"/docs/getting-started/providers/typesafe#overview","content":"TypeSafe's Jev is a \"System One\" model. You send one state plus a map of\nnamed, typed questions; it returns one typed answer per question, all evaluated\nin a single parallel pass. Nothing has to be parsed back out of prose, and every\nchoice/score answer carries a calibrated confidence rather than a\nself-reported one.\n\nBecause it emits no text, generate() and stream() are not available and\ngetAISDKModel() throws β€” the same shape Voyage and Jina already use for\nembedding-only providers. Its descriptor declares inferenceKinds: [\"decide\"],\nwhich keeps it out of auto-select and the health sweep, so those throws are\nunreachable in normal use.\n\nThis is not neurolink.evaluate(), which\nscores an already-generated response with RAGAS scorers. Different feature,\ndifferent word.","hierarchy":{"lvl0":"Getting Started","lvl1":"TypeSafe (Jev) Provider Guide","lvl2":"Overview","lvl3":""}},
7317
- {"objectID":"4921fe7ae1c50c817be3b7742587c455084bee9d988015cf475edd5c3c196b84","title":"Key Facts","url":"/docs/getting-started/providers/typesafe#key-facts","content":"Provider id: typesafe (aliases: jev, typesafe-ai)\nInference kinds: decide only β€” one of the providers that do (the others\n are Laya, XOR, SubQ,\n Perplexity and Cloudflare Clef); TypeSafe is tried before them when\n more than one is configured\nTool calling: none (toolSupport: \"none\") β€” a decision model calls nothing\nHealth check: env-only; it is never probed with a live generation\nDefault decide timeout: 5000 ms (timeouts.decideMs)\nLatency: flat in question count β€” 1 question ~393 ms, 400 questions\n ~465 ms. Concurrent requests queue instead, so batch every question into one\n call rather than fanning out.\nCost: ~$0.042 per million input tokens, output billed at zero β€” about\n $0.00002 per decision. Output tokens are reported β€” measured 21 for a\n single question, converging to ~17.5 per question in a batch of eight β€” they\n are simply not charged.\nAccuracy is the trade: 67.8% on TypeSafe's own 711-case benchmark against\n Opus 5's 73.1%. Right for decisions that are gated and reversible; wrong for\n final answers.","hierarchy":{"lvl0":"Getting Started","lvl1":"TypeSafe (Jev) Provider Guide","lvl2":"Key Facts","lvl3":""}},
7342
+ {"objectID":"4921fe7ae1c50c817be3b7742587c455084bee9d988015cf475edd5c3c196b84","title":"Key Facts","url":"/docs/getting-started/providers/typesafe#key-facts","content":"Provider id: typesafe (aliases: jev, typesafe-ai)\nInference kinds: decide only β€” one of the providers that do (the others\n are Laya, XOR, SubQ,\n Perplexity,\n Cloudflare Clef and\n OpenAI Decisions); TypeSafe is tried before them when\n more than one is configured\nTool calling: none (toolSupport: \"none\") β€” a decision model calls nothing\nHealth check: env-only; it is never probed with a live generation\nDefault decide timeout: 5000 ms (timeouts.decideMs)\nLatency: flat in question count β€” 1 question ~393 ms, 400 questions\n ~465 ms. Concurrent requests queue instead, so batch every question into one\n call rather than fanning out.\nCost: ~$0.042 per million input tokens, output billed at zero β€” about\n $0.00002 per decision. Output tokens are reported β€” measured 21 for a\n single question, converging to ~17.5 per question in a batch of eight β€” they\n are simply not charged.\nAccuracy is the trade: 67.8% on TypeSafe's own 711-case benchmark against\n Opus 5's 73.1%. Right for decisions that are gated and reversible; wrong for\n final answers.","hierarchy":{"lvl0":"Getting Started","lvl1":"TypeSafe (Jev) Provider Guide","lvl2":"Key Facts","lvl3":""}},
7318
7343
  {"objectID":"f5f7265f7ee9ba7ead6f6016a4b9232258ffaf4256e544874d6bcca8323dbb04","title":"1. Get an API key","url":"/docs/getting-started/providers/typesafe#1-get-an-api-key","content":"Create one at console.typesafe.ai/keys.","hierarchy":{"lvl0":"Getting Started","lvl1":"TypeSafe (Jev) Provider Guide","lvl2":"1. Get an API key","lvl3":""}},
7319
7344
  {"objectID":"a7cfa6599d9458e8c4a9bfcef1bba07a4948ebe6b0f30a1352df07a713040d8e","title":"3. Use it","url":"/docs/getting-started/providers/typesafe#3-use-it","content":"tryDecide() returns null on any failure. Use decide() when you want the\nfailure to surface; it throws a ProviderError whose cause carries a typed\nkind.","hierarchy":{"lvl0":"Getting Started","lvl1":"TypeSafe (Jev) Provider Guide","lvl2":"3. Use it","lvl3":""}},
7320
7345
  {"objectID":"4ec7febf2956a104b0037472bab2e6c652e17df7f7cfdf69b73ebe2c5003f082","title":"From the CLI","url":"/docs/getting-started/providers/typesafe#from-the-cli","content":"neurolink decide [state] calls decide() under the hood and reads\nTYPESAFE_API_KEY from the environment like every other CLI command. See the\nCLI command reference.","hierarchy":{"lvl0":"Getting Started","lvl1":"TypeSafe (Jev) Provider Guide","lvl2":"From the CLI","lvl3":""}},
7321
- {"objectID":"98aafdb50791dab3469be7930897496cf4d2fb9dc57e42bacb2ee179ac0064f2","title":"The degradation contract","url":"/docs/getting-started/providers/typesafe#the-degradation-contract","content":"Setting the key is the entire switch for TypeSafe, and removing it is a\ncomplete undo while no other decision provider is configured. Every internal\nconsumer of decide fails open: with no decision provider configured, model\nrouting, context budgeting, relevance compaction, tool routing and RAG planning\nall behave exactly as they did before. Note that Perplexity's key is shared with\nits text provider, so a PERPLEXITY_API_KEY set for that provider also counts as\na configured decision provider; see\nOne key, two providers. The same\ngoes for CLOUDFLARE_API_KEY with CLOUDFLARE_ACCOUNT_ID, which the Workers AI\ntext provider reads too: set together they configure Cloudflare Clef, which ranks\nafter TypeSafe, Laya, XOR, SubQ and Perplexity; see One token, two providers. There is no\nconfiguration in which a missing, invalid, slow or unreachable decision model\nchanges NeuroLink's observable behaviour.\n\nA credential the service does not accept disables that provider instance rather\nthan paying a round trip on every later call to be told so again.","hierarchy":{"lvl0":"Getting Started","lvl1":"TypeSafe (Jev) Provider Guide","lvl2":"The degradation contract","lvl3":""}},
7346
+ {"objectID":"98aafdb50791dab3469be7930897496cf4d2fb9dc57e42bacb2ee179ac0064f2","title":"The degradation contract","url":"/docs/getting-started/providers/typesafe#the-degradation-contract","content":"Setting the key is the entire switch for TypeSafe, and removing it is a\ncomplete undo while no other decision provider is configured. Every internal\nconsumer of decide fails open: with no decision provider configured, model\nrouting, context budgeting, relevance compaction, tool routing and RAG planning\nall behave exactly as they did before. Note that Perplexity's key is shared with\nits text provider, so a PERPLEXITY_API_KEY set for that provider also counts as\na configured decision provider; see\nOne key, two providers. The same\ngoes for CLOUDFLARE_API_KEY with CLOUDFLARE_ACCOUNT_ID, which the Workers AI\ntext provider reads too: set together they configure Cloudflare Clef, which ranks\nafter TypeSafe, Laya, XOR, SubQ and Perplexity; see One token, two providers.\nOPENAI_API_KEY, which the OpenAI chat provider reads too, configures OpenAI\nDecisions, the last fallback; see\nOne key, two providers. There is no\nconfiguration in which a missing, invalid, slow or unreachable decision model\nchanges NeuroLink's observable behaviour.\n\nA credential the service does not accept disables that provider instance rather\nthan paying a round trip on every later call to be told so again.","hierarchy":{"lvl0":"Getting Started","lvl1":"TypeSafe (Jev) Provider Guide","lvl2":"The degradation contract","lvl3":""}},
7322
7347
  {"objectID":"8fd6c7607ca461fdf5e7fb3b743b1761645c1ca9a2e666330b59614acb6455fa","title":"Two transports","url":"/docs/getting-started/providers/typesafe#two-transports","content":"The same model is reachable two ways, and the choice is made 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| Endpoint override | TYPESAFE_BASE_URL | TYPESAFE_GATEWAY_URL |\n| Model named in | request body | ai-model-id header |\n| Question vocabulary | noul | boolean |\n| confidence | on each answer | on providerMetadata |\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. Force\none with TYPESAFE_TRANSPORT=direct|gateway or\ncredentials.typesafe.transport. Either endpoint can be moved without a\nrelease: credentials.typesafe.baseURL / TYPESAFE_BASE_URL for the direct\none, credentials.typesafe.gatewayURL / TYPESAFE_GATEWAY_URL for the\ngateway route.\n\n⚠️ The gateway refuses every request β€” free credits included β€” until the\nVercel team has a credit card on file, returning 403\ncustomer_verification_required. That is an account state, not a bad key, and it\narrives before the model id is validated.\n\nFull detail, including the measured error table and why the distribution peak is\nnot a substitute for the reported confidence, is in\nThe decide inference type.","hierarchy":{"lvl0":"Getting Started","lvl1":"TypeSafe (Jev) Provider Guide","lvl2":"Two transports","lvl3":""}},
7323
7348
  {"objectID":"ac6585086d9cf682e7b1a66265cacfd1c4e961588384fe3883636c5deb66588c","title":"What NeuroLink uses it for","url":"/docs/getting-started/providers/typesafe#what-neurolink-uses-it-for","content":"| Area | What the decision replaces |\n| ---------------------------------------------------------------- | --------------------------------------------------------------- |\n| Model routing | difficulty + capabilities + risk + model pick in one round trip |\n| Model catalogue | one choice over the registry ranks all N candidates at once |\n| Context budget | a rubric-placed scope reading lowers the compaction threshold |\n| Relevance compaction | per-message keep/drop, plus a gate on the generated summary |\n| Tool / MCP routing | one boolean per server, replacing a 15s LLM call at ~400 ms |\n| RAG retrieval | per-query topK / hybrid / graph / rerank planning |","hierarchy":{"lvl0":"Getting Started","lvl1":"TypeSafe (Jev) Provider Guide","lvl2":"What NeuroLink uses it for","lvl3":""}},
7324
7349
  {"objectID":"04bf675bad2aeefe749c5229a396a476273c9b463d3b81a6767b9ca9357aa36d","title":"Limits and gotchas","url":"/docs/getting-started/providers/typesafe#limits-and-gotchas","content":"Two input ceilings, both enforced by the service: state plus the longest\n single question β‰ˆ 33,000 tokens, and state plus all questions β‰ˆ\n 64,000. Exceeding either returns max_tokens_exceeded with no message\n at all β€” the provider supplies a real sentence in its place.\nBatch, never fan out. Latency is flat in question count but concurrent\n requests queue, so a second round trip costs far more than a hundred extra\n questions.\nA boolean carries no confidence of its own. Use\n decisionBooleanConfidence(p) β€” distance from a coin flip, so 0.5 β†’ 0 and\n 0/1 β†’ 1.\n403 vs 401 are inverted on the direct API, and from TypeSafe's own docs: a\n missing Authorization header returns 403, an invalid key returns\nThe gateway does not share this quirk.","hierarchy":{"lvl0":"Getting Started","lvl1":"TypeSafe (Jev) Provider Guide","lvl2":"Limits and gotchas","lvl3":""}},
7325
7350
  {"objectID":"7d7786b2749554b22a763088bb2c011be0b62bdeb53ee881e9331cf8616dffa7","title":"Troubleshooting","url":"/docs/getting-started/providers/typesafe#troubleshooting","content":"| Symptom | Cause | Fix |\n| ------------------------------------ | --------------------------------------------------------------------- | ----------------------------------------------------------------------------- |\n| tryDecide() always returns null | No key, or the key was rejected once and the instance disabled itself | Check TYPESAFE_API_KEY; construct a new instance after fixing it |\n| max_tokens_exceeded | One of the two input ceilings | Shorten state, or split questions across calls β€” but prefer shrinking state |\n| 403 customer_verification_required | Gateway transport, no card on the Vercel team | Add a payment method, or use the direct transport |\n| Routing never changes | A modelPool is configured, which owns selection outright | See Provider Orchestration |","hierarchy":{"lvl0":"Getting Started","lvl1":"TypeSafe (Jev) Provider Guide","lvl2":"Troubleshooting","lvl3":""}},
7326
- {"objectID":"6116c23ca86f351b03ac4844a1d76d9de849fb522ab4a03eb37f9e75017e567c","title":"See also","url":"/docs/getting-started/providers/typesafe#see-also","content":"The decide inference type β€” the full reference\nModel routing with a decision model\nLaya Provider Guide\nXOR Provider Guide\nPerplexity Decisions Provider Guide\nCloudflare Clef Provider Guide\nSubQ Provider Guide\nProvider setup overview","hierarchy":{"lvl0":"Getting Started","lvl1":"TypeSafe (Jev) Provider Guide","lvl2":"See also","lvl3":""}},
7351
+ {"objectID":"6116c23ca86f351b03ac4844a1d76d9de849fb522ab4a03eb37f9e75017e567c","title":"See also","url":"/docs/getting-started/providers/typesafe#see-also","content":"The decide inference type β€” the full reference\nModel routing with a decision model\nLaya Provider Guide\nXOR Provider Guide\nPerplexity Decisions Provider Guide\nCloudflare Clef Provider Guide\nSubQ Provider Guide\nOpenAI Decisions Provider Guide\nProvider setup overview","hierarchy":{"lvl0":"Getting Started","lvl1":"TypeSafe (Jev) Provider Guide","lvl2":"See also","lvl3":""}},
7327
7352
  {"objectID":"0db36dc931d978469a7ad4e6468f4b52f77cc7c0db36272c6cfe8ac11e411f42","title":"Umans AI Provider Guide","url":"/docs/getting-started/providers/umans-ai","content":"Umans AI Provider Guide\n\nUmans AI is a Tier-2 catalog provider: OpenAI-wire-compatible with no\nbehavioural quirks, so its entire integration is one JSON file\n(src/lib/providers/catalog/umans-ai.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- and roster-verified, not yet\nlive-verified. Every field below comes from Umans AI's own public pages and\nunauthenticated GET requests β€” no account was created and no API key was\nused to build it. evidence.liveMatrix is null until someone runs the live\ncapability matrix with a real key (see\nVerification status below).\n\nKey Facts\nProvider id: umans-ai (alias umans)\nProtocol: OpenAI-compatible (/chat/completions) β€” the docs say \"Umans\n Code also implements the OpenAI Chat Completions API\"\n (docs). The same gateway also\n documents an Anthropic Messages route (POST /v1/messages) and a Responses\n route (POST /v1/responses); this entry uses only /chat/completions\nBase URL: https://api.code.umans.ai/v1\nDefault model: umans-coder β€” a routing alias, not a fixed model, see\n Models\nModels in catalog: 7 (curated from a 10-model live roster; three ids are\n left out on purpose β€” umans-deepseek-v4.1-flash-lab and\n umans-mimo-v2.6-pro-lab, which /v1/models/info describes as Labs\n experiments, \"temporary, not a permanent id\", with access \"seat-gated through\n the Labs page\", and umans-qwen3.6-35b-a3b, which it describes as a\n \"Technical alias for umans-flash\")\nStreaming: supported β€” the docs' OpenAI example sends \"stream\": true to\n POST /v1/chat/completions, and the reasoning section says reasoning \"streams\n live, token by token, alongside the answer\"\nTool calling: true β€” GET /v1/models/info reports supports_tools: true\n for every roster model. The docs show no tools request example for\n /v1/chat/completions, so this rests on that field alone and has not been\n exercised\nTools while streaming: not declared (false) β€” the docs show no\n tool-call request or response on this route, streaming or otherwise\nStructured output: not declared (false) β€” no page opened mentions\n response_format, json_schema or json_object\nStructured output + tools together: not declared (false) β€” no combined\n probe was run without credentials\nEmbeddings: not declared β€” the docs describe no embeddings route\nThinking: true β€” the docs' \"Reasoning & Extended Thinking\" section\n documents reasoning_effort on /v1/chat/completions and returns reasoning\n in a reasoning_content field, separate from content. Which levels a model\n accepts varies, see Models\nBilling: no-free-tier β€” a prepaid wallet billed per token, see\n Billing below\nKey format: the Umans pages conflict, so apiKeyFormat is null and\n NeuroLink does not validate a prefix. The docs' \"Any BYOK Tool\" section says\n the key \"starts with sk-\" and their examples write it as\n sk-your-umans-api-key, while the docs' wallet-summary example shows a key\n prefix of umans_7fKq and the homepage .env example shows umans_\n\nQuick Start\nGet an API key\nVisit: https://app.umans.ai/register and create an account with Google or an email and password (already have one? sign in at https://app.umans.ai/login). Organizations are provisioned by Umans: email contact@umans.ai (https://app.umans.ai/offers/code/docs/orgs)\nOpen https://app.umans.ai/billing, go to Dashboard -> API Keys and generate a key; the docs say it is shown only once, so copy it immediately\nPrepaid wallet, no free tier stated: top up before calling the API - the docs say a wallet with no credit (no paid top-up and no active promo grant) \"does not serve until it has some\", and promo credit serves only while it lasts (https://app.umans.ai/offers/code/docs)\nSet UMANS_AI_API_KEY in your .env file\nConfigure\nUse it\n\nPer-request credentials work as they do for every provider:\n\nBilling\n\nUmans AI's pricing page (https://app.umans.ai/pricing) says \"Pay per token. Top\nup, create a key, and go.\" and \"every request debits exactly what the model\nused\". The docs (https://app.umans.ai/offers/code/docs) say a wallet with no\ncredit at all β€” no paid top-up and no active promo grant β€” \"does not serve until\nit has some\"; promo credit \"serves while it lasts\" and then the wallet suspends\nuntil a paid top-up. A funded wallet that drains to its tier's floor (a small\nnegative allowance, $5 at Tiers 0-1) also suspends, and the docs call that \"a\nstop, not a 429\". No page states a free tier or standing free credits, so the\nentry records no-free-tier. The login page's \"Sign up for free\" link is about\ncreating an account; it is not a stated free allowance. The docs document\nGET /v1/usage and a wallet-summary route on app.umans.ai for checking\nbalance and spend. Both need a key; /v1/usage was called only without one,\nfor the 401 probe under Verification status.\n\nRequest limits sit on top of the balance. The docs give each wallet tier a\nrolling five-hour request window and a concurrency cap: Tier 0 (first top-up)\n2,000 requests and 4 in flight","hierarchy":{"lvl0":"Getting Started","lvl1":"Umans AI Provider Guide","lvl2":"","lvl3":""}},
7328
7353
  {"objectID":"ff607cfd31ffc8da0d09dd8b747b2825462342a8683ab3c6cd35251b2538b0ef","title":"Umans AI Provider Guide","url":"/docs/getting-started/providers/umans-ai#umans-ai-provider-guide","content":"Umans AI is a Tier-2 catalog provider: OpenAI-wire-compatible with no\nbehavioural quirks, so its entire integration is one JSON file\n(src/lib/providers/catalog/umans-ai.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- and roster-verified, not yet\nlive-verified. Every field below comes from Umans AI's own public pages and\nunauthenticated GET requests β€” no account was created and no API key was\nused to build it. evidence.liveMatrix is null until someone runs the live\ncapability matrix with a real key (see\nVerification status below).","hierarchy":{"lvl0":"Getting Started","lvl1":"Umans AI Provider Guide","lvl2":"Umans AI Provider Guide","lvl3":""}},
7329
7354
  {"objectID":"b71e70c479a72c1b2c02508e7f57c9dc8f5bd366f7dab23c56b323d7dbb8e3ca","title":"Key Facts","url":"/docs/getting-started/providers/umans-ai#key-facts","content":"Provider id: umans-ai (alias umans)\nProtocol: OpenAI-compatible (/chat/completions) β€” the docs say \"Umans\n Code also implements the OpenAI Chat Completions API\"\n (docs). The same gateway also\n documents an Anthropic Messages route (POST /v1/messages) and a Responses\n route (POST /v1/responses); this entry uses only /chat/completions\nBase URL: https://api.code.umans.ai/v1\nDefault model: umans-coder β€” a routing alias, not a fixed model, see\n Models\nModels in catalog: 7 (curated from a 10-model live roster; three ids are\n left out on purpose β€” umans-deepseek-v4.1-flash-lab and\n umans-mimo-v2.6-pro-lab, which /v1/models/info describes as Labs\n experiments, \"temporary, not a permanent id\", with access \"seat-gated through\n the Labs page\", and umans-qwen3.6-35b-a3b, which it describes as a\n \"Technical alias for umans-flash\")\nStreaming: supported β€” the docs' OpenAI example sends \"stream\": true to\n POST /v1/chat/completions, and the reasoning section says reasoning \"streams\n live, token by token, alongside the answer\"\nTool calling: true β€” GET /v1/models/info reports supports_tools: true\n for every roster model. The docs show no tools request example for\n /v1/chat/completions, so this rests on that field alone and has not been\n exercised\nTools while streaming: not declared (false) β€” the docs show no\n tool-call request or response on this route, streaming or otherwise\nStructured output: not declared (false) β€” no page opened mentions\n response_format, json_schema or json_object\nStructured output + tools together: not declared (false) β€” no combined\n probe was run without credentials\nEmbeddings: not declared β€” the docs describe no embeddings route\nThinking: true β€” the docs' \"Reasoning & Extended Thinking\" section\n documents reasoning_effort on /v1/chat/completions and returns reasoning\n in a reasoning_content field, separate from content.","hierarchy":{"lvl0":"Getting Started","lvl1":"Umans AI Provider Guide","lvl2":"Key Facts","lvl3":""}},
@@ -7465,19 +7490,19 @@
7465
7490
  {"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":""}},
7466
7491
  {"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":""}},
7467
7492
  {"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":""}},
7468
- {"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 and\nCloudflare Clef read 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 and Cloudflare Clef refuse a\n 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, then\nCloudflare Clef.\nTypeSafe 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 pr","hierarchy":{"lvl0":"Getting Started","lvl1":"XOR Provider Guide","lvl2":"","lvl3":""}},
7493
+ {"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":""}},
7469
7494
  {"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":""}},
7470
7495
  {"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":""}},
7471
7496
  {"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":""}},
7472
7497
  {"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":""}},
7473
7498
  {"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":""}},
7474
7499
  {"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":""}},
7475
- {"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 and\nCloudflare Clef read 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 and Cloudflare Clef refuse a\n 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":""}},
7476
- {"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, then\nCloudflare Clef.\nTypeSafe 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. A caller can always name XOR with\nprovider: \"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 or Cloudflare Clef:\n everything behaves exactly as it did without a decision model.","hierarchy":{"lvl0":"Getting Started","lvl1":"XOR Provider Guide","lvl2":"When NeuroLink uses it","lvl3":""}},
7500
+ {"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":""}},
7501
+ {"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":""}},
7477
7502
  {"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":""}},
7478
7503
  {"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":""}},
7479
7504
  {"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":""}},
7480
- {"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\nThe decide inference type\nXOR on Hugging Face","hierarchy":{"lvl0":"Getting Started","lvl1":"XOR Provider Guide","lvl2":"See also","lvl3":""}},
7505
+ {"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":""}},
7481
7506
  {"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":""}},
7482
7507
  {"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":""}},
7483
7508
  {"objectID":"d509ecad3c62c73f008d7e2f88de10168c19308f90c63101973f3ae4983a7318","title":"Key Facts","url":"/docs/getting-started/providers/z-ai#key-facts","content":"Provider 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.","hierarchy":{"lvl0":"Getting Started","lvl1":"Z.AI Provider Guide","lvl2":"Key Facts","lvl3":""}},
@@ -8702,7 +8727,7 @@
8702
8727
  {"objectID":"95f574ed3e7979eee5be188ccd16efb2639e30e8258e55366d7ccd344bbc3126","title":"Related Documentation","url":"/docs/implementation-guides/14-rag-document-processing#related-documentation","content":"Vector Store Integrations\nEvaluation and Scoring\nMaster Implementation Guide","hierarchy":{"lvl0":"Implementation Guides","lvl1":"RAG Document Processing - Implementation Guide","lvl2":"Related Documentation","lvl3":""}},
8703
8728
  {"objectID":"60877eba17c1fe5c9fda2100a737f42fddb5c4c7083297e61a66884dbe5c326e","title":"NeuroLink","url":"/docs/","content":"🧠 NeuroLink\n The Pipe Layer of an AI Nervous System\n Provider Neurons Across Major AI Vendors | 3 Inference Types (generate Β· stream Β· decide) | Voice (TTS/STT/Realtime) | 58+ MCP Servers | HITL Security | Redis Persistence\n\nNeuroLink is the pipe layer of an AI nervous system: one interface connecting provider neurons β€” major AI vendors and local runtimes β€” to the applications that consume them. Built-in tooling and an opinionated factory architecture mean adding a new provider, or a new capability, never touches application code. NeuroLink ships as both a TypeScript SDK and a professional CLI so teams can build, operate, and iterate on AI features quickly.\n\n🧠 What is NeuroLink?\n\nNeuroLink is the pipe layer of an AI nervous system. Providers β€” OpenAI, Anthropic, Google, AWS, Azure, DeepSeek, NVIDIA NIM, local runtimes like Ollama and llama.cpp, and dozens more β€” are the neurons: each generates a different kind of intelligence, at a different cost and latency. NeuroLink is the vascular layer that carries that intelligence, as a stream, to the applications that consume it, across three inference types: generate and stream produce text, decide produces a calibrated boolean/choice/score judgment instead.\n\nExtracted from production systems at Juspay, NeuroLink provides a practical, TypeScript-first way to plug any application into that nervous system. Switch which neuron answers a request with a single parameter change β€” any provider you're building with, or any provider you add.\n\nWhy NeuroLink? Three genuine inference types, not one dressed up three ways β€” generate and stream produce text, while decide returns a typed, calibrated judgment (boolean / choice / score) with no text at all, for the routing and gating decisions the other two were never meant to make. Every neuron plugs into the same pipe. Switch providers with a single parameter change, leverage 64+ built-in tools and MCP servers, deploy with confidence using enterprise features like Redis memory and multi-provider failover, and optimize costs automatically with intelligent routing. Use it via our professional CLI or TypeScript SDKβ€”whichever fits your workflow.\n\nWhere we're headed: We're building for the future of AIβ€”edge-first execution and continuous streaming architectures that make AI practically free and universally available. Read our vision β†’\n\nGet Started in \\ Observability Guide\nServer Adapters -- Deploy NeuroLink as an HTTP API server with your framework of choice (Hono, Express, Fastify, Koa). Full CLI support with serve and server commands for foreground/background modes, route management, and OpenAPI generation. -> Server Adapters Guide\nTitle Generation Events -- Emit real-time events when conversation titles are auto-generated. Listen to conversation:titleGenerated for session tracking. -> Conversation Memory Guide\nCustom Title Prompts -- Customize conversation title generation with NEUROLINK_TITLE_PROMPT environment variable. Use ${userMessage} placeholder for dynamic prompts. -> Conversation Memory Guide\nVideo Generation -- Transform images into 8-second videos with synchronized audio using Google Veo 3.1 via Vertex AI. Supports 720p/1080p resolutions, portrait/landscape aspect ratios. -> Video Generation Guide\nImage Generation -- Generate images from text prompts using Gemini models via Vertex AI or Google AI Studio. Supports streaming mode with automatic file saving. -> Image Generation Guide\nHTTP/Streamable HTTP Transport for MCP -- Connect to remote MCP servers via HTTP with authentication headers, retry logic, and rate limiting. -> HTTP Transport Guide\nClaude Subscription (OAuth) Support -- Use your Claude Pro/Max/Team subscription with NeuroLink via OAuth authentication, no API key required. -> Subscription Guide\nGemini 3 Preview Support - Full support for gemini-3-flash-preview and gemini-3-pro-preview with extended thinking capabilities\nStructured Output with Zod Schemas -- Type-safe JSON generation with automatic validation using schema + output.format: \"json\" in generate(). -> Structured Output Guide\nCSV File Support -- Attach CSV files to prompts for AI-powered data analysis with auto-detection. -> CSV Guide\nPDF File Support -- Process PDF documents with native visual analysis for Vertex AI, Anthropic, Bedrock, AI Studio. -> PDF Guide\n50+ File Types -- Process Excel, Word, RTF, JSON, YAML, XML, HTML, SVG, Markdown, and 50+ code languages with intelligent content extraction. -> File Processors Guide\nLiteLLM Integration -- Access 100+ AI models across a broad range of AI providers through unified interface. -> Setup Guide\nSageMaker Integration -- Deploy and use custom trained models on AWS infrastructure. -> Setup Guide\nOpenRouter Integration -- Access 300+ models from OpenAI, Anthropic, Google, Meta, and more through a single unified API. -> Setup Guide\nHuman-in-the-loop workflows -- Pause generation for user approval/input before tool execution. -> HITL Guide\nGuardrails middleware -- Block PII, profanity, and unsafe cont","hierarchy":{"lvl0":"Docs","lvl1":"NeuroLink","lvl2":"","lvl3":""}},
8704
8729
  {"objectID":"7bd402837d03dbfbb9586674bc914cfc6ee7691e33540eeabe6555363697375e","title":"🧠 What is NeuroLink?","url":"/docs/#-what-is-neurolink","content":"NeuroLink is the pipe layer of an AI nervous system. Providers β€” OpenAI, Anthropic, Google, AWS, Azure, DeepSeek, NVIDIA NIM, local runtimes like Ollama and llama.cpp, and dozens more β€” are the neurons: each generates a different kind of intelligence, at a different cost and latency. NeuroLink is the vascular layer that carries that intelligence, as a stream, to the applications that consume it, across three inference types: generate and stream produce text, decide produces a calibrated boolean/choice/score judgment instead.\n\nExtracted from production systems at Juspay, NeuroLink provides a practical, TypeScript-first way to plug any application into that nervous system. Switch which neuron answers a request with a single parameter change β€” any provider you're building with, or any provider you add.\n\nWhy NeuroLink? Three genuine inference types, not one dressed up three ways β€” generate and stream produce text, while decide returns a typed, calibrated judgment (boolean / choice / score) with no text at all, for the routing and gating decisions the other two were never meant to make. Every neuron plugs into the same pipe. Switch providers with a single parameter change, leverage 64+ built-in tools and MCP servers, deploy with confidence using enterprise features like Redis memory and multi-provider failover, and optimize costs automatically with intelligent routing. Use it via our professional CLI or TypeScript SDKβ€”whichever fits your workflow.\n\nWhere we're headed: We're building for the future of AIβ€”edge-first execution and continuous streaming architectures that make AI practically free and universally available. Read our vision β†’\n\nGet Started in \\<5 Minutes β†’","hierarchy":{"lvl0":"Docs","lvl1":"NeuroLink","lvl2":"🧠 What is NeuroLink?","lvl3":""}},
8705
- {"objectID":"293082e7b04b9b0eb186f10fec40eefc1996d8eab9becff9e2b428731642291f","title":"What's New (Q1 2026)","url":"/docs/#whats-new-q1-2026","content":"| Feature | Version | Description | Guide |\n| ---------------------------------- | ------- |","hierarchy":{"lvl0":"Docs","lvl1":"NeuroLink","lvl2":"What's New (Q1 2026)","lvl3":""}},
8730
+ {"objectID":"293082e7b04b9b0eb186f10fec40eefc1996d8eab9becff9e2b428731642291f","title":"What's New (Q1 2026)","url":"/docs/#whats-new-q1-2026","content":"| Feature | Version | Description | Guide |\n| ---------------------------------- | ------- |","hierarchy":{"lvl0":"Docs","lvl1":"NeuroLink","lvl2":"What's New (Q1 2026)","lvl3":""}},
8706
8731
  {"objectID":"3e5ecc512d348470d92717ef33a2ff5067ffdd99c7ea212613df7986db133390","title":"Enterprise Security: Human-in-the-Loop (HITL)","url":"/docs/#enterprise-security-human-in-the-loop-hitl","content":"NeuroLink includes a HITL (Human-in-the-Loop) system for regulated industries and high-stakes AI operations:\n\n| Capability | Description | Use Case |\n| --------------------------- | ----------------------------------------------------------------------- | ------------------------------------------ |\n| Tool Approval Workflows | Require human approval before AI executes sensitive tools | Financial transactions, data modifications |\n| Output Validation | Route AI outputs through human review pipelines | Medical diagnosis, legal documents |\n| Confidence Thresholds | Automatically trigger human review below confidence level | Critical business decisions |\n| Complete Audit Trail | Audit logging to support your compliance program (HIPAA / SOC 2 / GDPR) | Regulated industries |\n\nEnterprise HITL Guide | Quick Start","hierarchy":{"lvl0":"Docs","lvl1":"NeuroLink","lvl2":"Enterprise Security: Human-in-the-Loop (HITL)","lvl3":""}},
8707
8732
  {"objectID":"c062d596f0f8940391d038563717712409b6055fdf70d92ab51cb35caf672663","title":"Get Started in Two Steps","url":"/docs/#get-started-in-two-steps","content":"`bash","hierarchy":{"lvl0":"Docs","lvl1":"NeuroLink","lvl2":"Get Started in Two Steps","lvl3":""}},
8708
8733
  {"objectID":"e9e7167316a23ea5fd5db23894b2e52405ba61f5ab57cc986d155490dd325674","title":"1. Run the interactive setup wizard (select providers, validate keys)","url":"/docs/#1-run-the-interactive-setup-wizard-select-providers-validate-keys","content":"pnpm dlx @juspay/neurolink setup","hierarchy":{"lvl0":"Docs","lvl1":"NeuroLink","lvl2":"1. Run the interactive setup wizard (select providers, validate keys)","lvl3":""}},
@@ -9738,7 +9763,7 @@
9738
9763
  {"objectID":"d7fd57b5311bed74e1ac06949abeca0fc2aab02f46c7841d85da59920aafcd61","title":"The stream-identity defect (cell 3)","url":"/docs/provider-integration/acceptance-gate#the-stream-identity-defect-cell-3","content":"Confirmed and fixed in src.\n\nStreamResult.model (the public value cell 3 asserts against) was reporting\nthe requested model, not the model the server actually served. Internally,\nneurolink.ts already captured the resolved model β€” the bug was that this\nresolved value never reached the public StreamResult.\nOpenAI-compatible protocol path (src/lib/providers/openaiChatCompletionsBase.ts,\n src/lib/types/openaiCompatible.ts) β€” the substantive fix, and the one\n cell 3 actually exercises: added StreamLoopArgs.onModelObserved?: (model:\nstring) => void, fired once per step that echoes a model field on the\n wire (SSE chunk.model, captured by parseSSEStream into\n OpenAICompatSSEResult.model). executeStream's public result.model was\n a plain data property fixed at the pre-call resolved/requested modelId;\n it is now a live getter (observedServerModel ?? modelId) so a caller\n reading .model after draining .stream sees what the server actually\n served β€” the mock's ::mock-server-resolved suffix on the STREAM cell\n is what makes this difference observable and the fix provable. It has to\n be a getter, not a reassignment after the fact: preserveLiveStreamAccessors\n spreads result into a new object at each provider boundary before the\n background loop produces its first chunk, which would freeze a plain field\n at its construction-time value.\nAnthropic path (src/lib/providers/anthropic/client.ts) β€” a narrower,\n related fix: StreamResult.model was reporting the raw constructor\n argument this.modelName, which is undefined whenever a caller relies\n on the default model rather than passing one explicitly. It now reports\n modelId, the value already resolved as this.modelName ||\ngetDefaultAnthropicModel() and actually put on the wire.","hierarchy":{"lvl0":"Provider Integration","lvl1":"Credential-free provider acceptance gate","lvl2":"The stream-identity defect (cell 3)","lvl3":""}},
9739
9764
  {"objectID":"d47c3d7913d5adb6968b60f5025f7c15472e8bbf76abe5b0b4277001a96c9691","title":"Additional src defects found and fixed by cells 4 and 8","url":"/docs/provider-integration/acceptance-gate#additional-src-defects-found-and-fixed-by-cells-4-and-8","content":"Building this gate surfaced three more real defects, all in provider-side\ntool-capability allowlists and one test-sizing constant β€” none in the mock\nitself. Each is a one-line, strictly capability-adding fix.\nollama cell 4 (tool-nonce proof) β€” OllamaProvider.supportsTools()\n checks the model name against modelConfiguration.ts's\n createOllamaConfig().modelBehavior.toolCapableModels allowlist. That list\n (OLLAMA_TOOL_CAPABLE_MODELS) included \"llama3.1\" but not \"llama3.2\" β€”\n the gate's own pinned default Ollama model\n (providerMatrix.ts's ollama.defaultModel, which declares tools:\ntrue). supportsTools() returned false for the provider's own default\n model, which silently dropped the user-supplied tool from both the\n wire tools field and the execution lookup (executeNativeGenerate()'s\n toolsRecord is built empty when supportsTools() is false), producing a\n \"Tool not found\" error instead of a real tool round-trip. Fixed in\n src/lib/core/modelConfiguration.ts by adding \"llama3.2\" to the default\n toolCapableModels array.\nopenrouter cell 4 (tool-nonce proof) β€” OpenRouterProvider.supportsTools()\n has two paths: a dynamically cached capability set (populated by\n cacheModelCapabilities(), which fetches /models and reads\n supported_parameters) and a hardcoded fallback pattern list used until\n that cache is populated. cacheModelCapabilities() is never invoked\n automatically anywhere in the real generate()/stream() code paths, so\n the fallback list is the only path ever exercised in practice. That list\n included \"meta-llama/llama-3.2\" and \"meta-llama/llama-3.3\" but not\n \"meta-llama/llama-3.1\" β€” the family of the gate's pinned default\n OpenRouter model, \"meta-llama/llama-3.1-8b-instruct\" (chosen, per an\n existing code comment, specifically because it supports every capability\n the matrix exercises). Same failure mode as the ollama defect above.\n Fixed in src/lib/providers/openRouter/client.ts by adding\n \"meta-llama/llama-3.1\" to knownToolCapablePatterns.","hierarchy":{"lvl0":"Provider Integration","lvl1":"Credential-free provider acceptance gate","lvl2":"Additional src defects found and fixed by cells 4 and 8","lvl3":""}},
9740
9765
  {"objectID":"0618b382f27d4d7ae674f8c803a793a4b1774ab7eecc3e1eb4738979361454ff","title":"Mock server","url":"/docs/provider-integration/acceptance-gate#mock-server","content":"test/helpers/acceptanceGateServer.ts is a real node:http server (not\nfetch interception) that speaks the two wire protocols the covered providers\nactually use:\nOpenAI-compatible chat completions β€” /chat/completions (including\n SSE streaming, tool calls, response_format, reasoning deltas), /models,\n /embeddings.\nAnthropic Messages API β€” /messages, for the one ANTHROPIC_BASE_URL\n row.\n\nEvery provider is redirected at it through its own documented base-URL\nenvironment override (<ID>_BASE_URL for catalog providers, each\nhand-written provider's own env var β€” see \"Coverage\" below) with a fake API\nkey (gate-fake-key-not-a-real-credential). The server enforces a\nrequest-count ceiling per instance and returns HTTP 400 past it (cell 8).\n\nEvery gate marker, exact value, and mock behavior the suite asserts against\nis exported from that file (GATE_MARKERS, GATE_EXACT_VALUE,\nGATE_STREAM_VALUE, GATE_STRUCTURED_VALUE, GATE_TOOL_NAME,\nGATE_TOOL_CONFIRM_PREFIX, GATE_THINKING_FULL, GATE_THINKING_ANSWER,\nGATE_EMBEDDING_VECTOR, GATE_SERVER_MODEL_SUFFIX, ...) so the suite and\nthe mock can never silently drift apart.","hierarchy":{"lvl0":"Provider Integration","lvl1":"Credential-free provider acceptance gate","lvl2":"Mock server","lvl3":""}},
9741
- {"objectID":"22d04d6ef0ebc06dcdcf19ccf6ce15cb208747c36ecdf33dafb495ac9c1029c1","title":"Coverage","url":"/docs/provider-integration/acceptance-gate#coverage","content":"Provider rows are derived the same way test/helpers/providerMatrix.ts\nalready does: hand-written rows are listed explicitly, catalog rows are\nderived from the built catalog (dist/providers/catalog/index.generated.js\nand dist/providers/catalog/loader.js), matching every other suite that\nconsumes providerMatrix.ts.\n\n31 providers covered β€” 9 hand-written OpenAI-compatible providers\n(openai, openai-compatible, openrouter, ollama, litellm,\nnvidia-nim, lm-studio, llamacpp, cohere), azure (OpenAI-compatible\nprotocol via its own deployment URL), anthropic (Anthropic Messages\nprotocol), and 20 catalog providers whose base URL is a plain env override\n(every catalog provider except cloudflare, which needs a\ncomputedBaseURL/account-id template the mock can't satisfy β€” see below).\n\nThe providers not covered are listed below, each for a structural reason (no silent caps β€”\nthe suite itself throws at import time if a PROVIDERS entry is in neither\nlist):\n\n| Provider | Reason |\n| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| vertex | Signed Google Cloud client (service account / ADC), not a plain bearer-token HTTP call; no base-URL override, credentials can't be faked with a static string. |\n| google-ai | Speaks Google's Gemini wire protocol β€” a third protocol family this gate's mock does not implement (only OpenAI-compatible and Anthropic Messages are). |\n| bedrock | AWS SigV4-signed requests via the AWS SDK β€” same class of problem as vertex.","hierarchy":{"lvl0":"Provider Integration","lvl1":"Credential-free provider acceptance gate","lvl2":"Coverage","lvl3":""}},
9766
+ {"objectID":"22d04d6ef0ebc06dcdcf19ccf6ce15cb208747c36ecdf33dafb495ac9c1029c1","title":"Coverage","url":"/docs/provider-integration/acceptance-gate#coverage","content":"Provider rows are derived the same way test/helpers/providerMatrix.ts\nalready does: hand-written rows are listed explicitly, catalog rows are\nderived from the built catalog (dist/providers/catalog/index.generated.js\nand dist/providers/catalog/loader.js), matching every other suite that\nconsumes providerMatrix.ts.\n\n31 providers covered β€” 9 hand-written OpenAI-compatible providers\n(openai, openai-compatible, openrouter, ollama, litellm,\nnvidia-nim, lm-studio, llamacpp, cohere), azure (OpenAI-compatible\nprotocol via its own deployment URL), anthropic (Anthropic Messages\nprotocol), and 20 catalog providers whose base URL is a plain env override\n(every catalog provider except cloudflare, which needs a\ncomputedBaseURL/account-id template the mock can't satisfy β€” see below).\n\nThe providers not covered are listed below, each for a structural reason (no silent caps β€”\nthe suite itself throws at import time if a PROVIDERS entry is in neither\nlist):\n\n| Provider | Reason |\n| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| vertex | Signed Google Cloud client (service account / ADC), not a plain bearer-token HTTP call; no base-URL override, credentials can't be faked with a static string. |\n| google-ai | Speaks Google's Gemini wire protocol β€” a third protocol family this gate's mock does not implement (only OpenAI-compatible and Anthropic Messages are).","hierarchy":{"lvl0":"Provider Integration","lvl1":"Credential-free provider acceptance gate","lvl2":"Coverage","lvl3":""}},
9742
9767
  {"objectID":"258a3149c7933854fa0749299620adb948d24476ea2c37630b2ed184ecea268d","title":"Running it","url":"/docs/provider-integration/acceptance-gate#running-it","content":"No environment variables or credentials are required, and none are used:\nreal ones are stripped at startup (see \"Known, documented gap in cell 9\"),\nand every credential the suite sets is a fake string, scoped per-row via\nwithEnv() and restored after each row.","hierarchy":{"lvl0":"Provider Integration","lvl1":"Credential-free provider acceptance gate","lvl2":"Running it","lvl3":""}},
9743
9768
  {"objectID":"2af9c7a79be94186d3044e77fe1680370e61eb985e81142a246e323fe990ef0b","title":"ADR-0001: `ProviderDescriptor` is the single source of truth for provider identity","url":"/docs/provider-integration/adr/0001-provider-descriptor-as-source-of-truth","content":"ADR-0001: ProviderDescriptor is the single source of truth for provider identity\n\nStatus: Accepted β€” 2026-08-15\nContext: Plans 00/11 (audit)\n\nContext\n\nBefore this redesign, \"what providers exist and what do they need\" was\nanswered by five independently hand-maintained places that had already\ndrifted from each other: providerRegistry.ts (registration + aliases),\ncommandFactory.ts (CLI --provider choices, re-listing every alias),\nproviderHealth.ts (hardcoded 8-of-31-provider health/auto-select list),\ncontextWindows.ts (per-model context windows), and\nproviderImageAdapter.ts (vision capability map). A sixth ad hoc identity\nmechanism existed for \"anthropic-subscription\". Google AI Studio alone\nhad five different spellings across these tables. None of this was\ntype-checked; typos were silent runtime misses (credentialKeyMap was\nalready missing a together-ai entry in production).\n\nAt 30 providers this was tolerable tech debt. At 200+ it is not: ~1,000+\nhand-authored string literals with zero compile-time linkage between them.\n\nDecision\n\nEvery provider gets exactly one ProviderDescriptor object\n(src/lib/types/providers.ts) held in one array,\nPROVIDER_DESCRIPTORS (src/lib/factories/providerDescriptors.ts), a\npure data module β€” no dynamic imports, no provider-class imports β€” so\nit is safe to import statically from anywhere, including the CLI's\ncommand-definition code (which needs --provider choices synchronously,\nbefore any provider is instantiated).\n\nEvery other subsystem that previously hardcoded its own provider list\n(CLI choices, health-check auto-selection, alias resolution) is expected\nto derive from PROVIDER_DESCRIPTORS / ProviderFactory.getAllDescriptors()\ninstead of maintaining a parallel list. ProviderFactory.normalizeProviderName\nreplaces its O(n) linear alias scan with an aliasβ†’canonical index built\nonce at registration time from the same descriptors.\n\nConsequences\nPositive: one array to review per new provider; CLI/health/alias\n tables can no longer drift because they no longer have independent\n data to drift from.\nPositive: ProviderFactory.getDescriptor(name) becomes the answer\n to \"does this provider exist and what does it need\" for every\n subsystem, including this plan's own CI gate (test:provider-structure,\n tools/verify-provider-onboarding.ts).\nNegative: PROVIDER_DESCRIPTORS becomes a single large file that\n every new provider touches β€” a predictable merge-conflict hotspot at\n high PR volume. Mitigated by keeping each entry a small, independent\n object literal (low conflict surface per line) and by the Tier 2 path\n needing only a ~10-line addition.\nNegative: subsystems that haven't yet been migrated to read from\n PROVIDER_DESCRIPTORS still need manual edits until they are. As of\n 2026-08-18, commandFactory.ts's main --provider choices and\n providerHealth.ts are already descriptor-driven, but the separate\n setup [provider] CLI subcommand still hand-hardcodes its own provider\n choices array β€” a concrete, currently-open gap, not a hypothetical one.\n The tier docs call this out explicitly rather than silently overclaiming\n that migration is complete.","hierarchy":{"lvl0":"Provider Integration","lvl1":"ADR-0001: `ProviderDescriptor` is the single source of truth for provider identity","lvl2":"","lvl3":""}},
9744
9769
  {"objectID":"3be78e1b5992c80b18e70185f4e5aaf4a714dc6e71b302cc0f46b738a8988440","title":"ADR-0001: ProviderDescriptor is the single source of truth for provider identity","url":"/docs/provider-integration/adr/0001-provider-descriptor-as-source-of-truth#adr-0001-providerdescriptor-is-the-single-source-of-truth-for-provider-identity","content":"Status: Accepted β€” 2026-08-15\nContext: Plans 00/11 (audit)","hierarchy":{"lvl0":"Provider Integration","lvl1":"ADR-0001: `ProviderDescriptor` is the single source of truth for provider identity","lvl2":"ADR-0001: ProviderDescriptor is the single source of truth for provider identity","lvl3":""}},
@@ -10039,10 +10064,10 @@
10039
10064
  {"objectID":"4578b51cac195eb59c8ac256ef9f2491197666719997b358b74e2b57b5a414fb","title":"TTS / Realtime Errors","url":"/docs/reference/error-codes#tts-realtime-errors","content":"TTSError and RealtimeError carry provider-specific messages (e.g.\nsynthesis failure, WebSocket disconnect, function-call failure). Inspect\nerror.cause for the underlying provider error.","hierarchy":{"lvl0":"Reference","lvl1":"Error Code Reference","lvl2":"TTS / Realtime Errors","lvl3":""}},
10040
10065
  {"objectID":"3e6c6ffd80fa23ecf3686bacf0db97fb3e7e6f430e82b2523745c88e257b6c45","title":"Common Triggers","url":"/docs/reference/error-codes#common-triggers","content":"STT_INVALID_AUDIO_FORMAT is thrown by STTProcessor.transcribe()\n when options.format doesn't appear in the provider's\n getSupportedFormats() list. The CLI infers the format from the\n --input-audio file extension; the SDK requires you to pass it explicitly.\n Fix: either convert the audio to a supported format, or use a different\n STT provider. See docs/getting-started/providers/azure-speech.md for the\n Azure-MP3 case.\nSTT_AUDIO_TOO_LONG is thrown when the buffer exceeds the per-call\n maxAudioBytes limit. Default is 25 MB (matches Whisper's documented\n ceiling). Override via stt.maxAudioBytes.","hierarchy":{"lvl0":"Reference","lvl1":"Error Code Reference","lvl2":"Common Triggers","lvl3":""}},
10041
10066
  {"objectID":"df1592c1b3ccdbed96fbbc998d2facc217e2652c2a3cbb2d630ed64f1c85fdb9","title":"Related Documentation","url":"/docs/reference/error-codes#related-documentation","content":"Troubleshooting Guide - Common issues and solutions\nConfiguration Reference - Environment variables and settings\nFAQ - Frequently asked questions\nProvider Feature Compatibility - Provider capabilities matrix","hierarchy":{"lvl0":"Reference","lvl1":"Error Code Reference","lvl2":"Related Documentation","lvl3":""}},
10042
- {"objectID":"4dccb885a61a05030e1eeb0b2413af7062a282bcce434d742561026c5af1d015","title":"Frequently Asked Questions","url":"/docs/reference/faq","content":"Frequently Asked Questions\n\nCommon questions and answers about NeuroLink usage, configuration, and troubleshooting.\n\nπŸš€ Getting Started\n\nQ: What is NeuroLink?\n\nA: NeuroLink is an enterprise AI development platform that provides unified access to multiple AI providers (OpenAI, Google AI, Anthropic, AWS Bedrock, etc.) through a single SDK and CLI. It includes built-in tools, analytics, evaluation capabilities, and supports the Model Context Protocol (MCP) for extended functionality.\n\nQ: Which AI providers does NeuroLink support?\n\nA: NeuroLink ships AI providers for text generation, streaming, and decision-making β€” plus separate provider systems for voice and media generation. The text and multimodal providers include:\nOpenAI (GPT-4o, GPT-4.1, o3, o4-mini)\nGoogle AI Studio (Gemini 3 Flash/Pro, Gemini 2.5 Pro/Flash)\nGoogle Vertex AI (Gemini 3, Claude via Vertex)\nAnthropic (Claude Opus 4.7, Sonnet 4.6, 4.5 Opus/Sonnet/Haiku)\nAWS Bedrock (Claude, Titan, Nova models)\nAzure OpenAI (GPT models)\nHugging Face (Open source models)\nOllama (Local AI models)\nMistral AI (Mistral models)\nLiteLLM (100+ models via proxy)\nAWS SageMaker (Custom endpoints)\nOpenAI-compatible (Any OpenAI-API-compatible endpoint)\nOpenRouter (300+ models via OpenRouter)\nDeepSeek (DeepSeek V3, R1)\nNVIDIA NIM (Llama 3.3 70B, 400+ catalog models)\nLM Studio (Local models loaded in LM Studio)\nllama.cpp (Local GGUF models via llama-server)\nGroq, Cerebras, SambaNova, Together AI, Fireworks AI, Perplexity, Cloudflare Workers AI, xAI, Baseten, GMI Cloud, Inception Labs, io.net Intelligence, Mancer, Upstage, API Route (zero-quirk OpenAI-wire-compatible catalog providers)\nCohere (chat, plus embed() and reranking)\nVoyage AI, Jina AI (embedding and/or reranking only β€” no chat completions)\nTypeSafe Jev, Laya, XOR, SubQ, Perplexity Decisions, Cloudflare Clef (decision-only β€” serve decide(), not generate()/stream(); tried in the order TypeSafe, Laya, XOR, SubQ, Perplexity, Cloudflare Clef when several are configured; Clef is configured by the same CLOUDFLARE_API_KEY and CLOUDFLARE_ACCOUNT_ID as the Cloudflare Workers AI text provider)\n\nSee Provider Setup for the complete roster with setup guides.\n\nVoice providers (a separate system from the providers above):\nOpenAI TTS (TTS-1, TTS-1-HD, GPT-4o Audio)\nElevenLabs (Multilingual v2, Turbo v2.5, Flash v2.5)\nDeepgram (Nova-3, Nova-2, Enhanced β€” STT)\nAzure Speech (Azure Cognitive Services TTS + STT)\nGoogle TTS / STT (Google Cloud Speech)\nWhisper (OpenAI Whisper β€” STT)\nFish Audio (TTS)\nCartesia (TTS)\nOpenAI Realtime + Gemini Live (realtime voice APIs)\n\nMedia generation providers (image / video / music / avatar) β€” Kling, Runway, Replicate, Beatoven, Lyria, D-ID, HeyGen. See Media Generation for the full list.\n\nQ: Do I need to install anything?\n\nA: No installation required! You can use NeuroLink directly with npx:\n\nFor frequent use, you can install globally: npm install -g @juspay/neurolink\n\nπŸ”§ Configuration\n\nQ: How do I set up API keys?\n\nA: Create a .env file in your project directory:\n\nNeuroLink automatically loads these environment variables.\n\nQ: Can I use NeuroLink behind a corporate proxy?\n\nA: Yes! NeuroLink automatically detects and uses corporate proxy settings:\n\nNo additional configuration needed.\n\nQ: How do I configure multiple environments (dev/staging/prod)?\n\nA: Use environment-specific .env files:\n\n🎯 Usage\n\nQ: What's the difference between CLI and SDK?\n\nA:\n\n| Feature | CLI | SDK |\n| -------------------- | ---------------------------- | ------------------------- |\n| Best for | Scripts, automation, testing | Applications, integration |\n| Installation | None required (npx) | npm install required |\n| Output | Text, JSON | Native JavaScript objects |\n| Batch processing | Built-in batch command | Manual implementation |\n| Learning curve | Low | Medium |\n\nQ: How do I choose the best provider for my use case?\n\nA: NeuroLink can auto-select the best provider, or you can choose based on:\nSpeed: Google AI (fastest responses)\nCoding: Anthropic Claude (best for code analysis)\nCreative: OpenAI (best for creative content)\nCost: Google AI Studio (free tier available)\nEnterprise: AWS Bedrock or Azure OpenAI\n\nQ: Can I use multiple providers in the same application?\n\nA: Yes! You can specify different providers for different requests:\n\nπŸ” Troubleshooting\n\nQ: Why am I getting \"API key not found\" errors?\n\nA: Common solutions:\nCheck .env file exists and is in the correct directory\nVerify file format: No spaces around = signs\nCheck file permissions: .env file should be readable\nVerify key format: Keys should start with provider-specific prefixes\n\nQ: Provider status shows \"Authentication failed\" - what should I do?\n\nA:\nVerify API key is correct and hasn't expired\nCheck account status - ensure billing is set up if required\nTest API key manually:\nCheck regional restrictions ","hierarchy":{"lvl0":"Reference","lvl1":"Frequently Asked Questions","lvl2":"","lvl3":""}},
10067
+ {"objectID":"4dccb885a61a05030e1eeb0b2413af7062a282bcce434d742561026c5af1d015","title":"Frequently Asked Questions","url":"/docs/reference/faq","content":"Frequently Asked Questions\n\nCommon questions and answers about NeuroLink usage, configuration, and troubleshooting.\n\nπŸš€ Getting Started\n\nQ: What is NeuroLink?\n\nA: NeuroLink is an enterprise AI development platform that provides unified access to multiple AI providers (OpenAI, Google AI, Anthropic, AWS Bedrock, etc.) through a single SDK and CLI. It includes built-in tools, analytics, evaluation capabilities, and supports the Model Context Protocol (MCP) for extended functionality.\n\nQ: Which AI providers does NeuroLink support?\n\nA: NeuroLink ships AI providers for text generation, streaming, and decision-making β€” plus separate provider systems for voice and media generation. The text and multimodal providers include:\nOpenAI (GPT-4o, GPT-4.1, o3, o4-mini)\nGoogle AI Studio (Gemini 3 Flash/Pro, Gemini 2.5 Pro/Flash)\nGoogle Vertex AI (Gemini 3, Claude via Vertex)\nAnthropic (Claude Opus 4.7, Sonnet 4.6, 4.5 Opus/Sonnet/Haiku)\nAWS Bedrock (Claude, Titan, Nova models)\nAzure OpenAI (GPT models)\nHugging Face (Open source models)\nOllama (Local AI models)\nMistral AI (Mistral models)\nLiteLLM (100+ models via proxy)\nAWS SageMaker (Custom endpoints)\nOpenAI-compatible (Any OpenAI-API-compatible endpoint)\nOpenRouter (300+ models via OpenRouter)\nDeepSeek (DeepSeek V3, R1)\nNVIDIA NIM (Llama 3.3 70B, 400+ catalog models)\nLM Studio (Local models loaded in LM Studio)\nllama.cpp (Local GGUF models via llama-server)\nGroq, Cerebras, SambaNova, Together AI, Fireworks AI, Perplexity, Cloudflare Workers AI, xAI, Baseten, GMI Cloud, Inception Labs, io.net Intelligence, Mancer, Upstage, API Route (zero-quirk OpenAI-wire-compatible catalog providers)\nCohere (chat, plus embed() and reranking)\nVoyage AI, Jina AI (embedding and/or reranking only β€” no chat completions)\nTypeSafe Jev, Laya, XOR, SubQ, Perplexity Decisions, Cloudflare Clef, OpenAI Decisions (decision-only β€” serve decide(), not generate()/stream(); tried in the order TypeSafe, Laya, XOR, SubQ, Perplexity, Cloudflare Clef, OpenAI Decisions when several are configured; Clef is configured by the same CLOUDFLARE_API_KEY and CLOUDFLARE_ACCOUNT_ID as the Cloudflare Workers AI text provider, and OpenAI Decisions by the same OPENAI_API_KEY as the OpenAI chat provider, except that this key is not used by default while OPENAI_BASE_URL, OPENAI_API_BASE or credentials.openai.baseURL names a host other than https://api.openai.com, since it is then a gateway's)\n\nSee Provider Setup for the complete roster with setup guides.\n\nVoice providers (a separate system from the providers above):\nOpenAI TTS (TTS-1, TTS-1-HD, GPT-4o Audio)\nElevenLabs (Multilingual v2, Turbo v2.5, Flash v2.5)\nDeepgram (Nova-3, Nova-2, Enhanced β€” STT)\nAzure Speech (Azure Cognitive Services TTS + STT)\nGoogle TTS / STT (Google Cloud Speech)\nWhisper (OpenAI Whisper β€” STT)\nFish Audio (TTS)\nCartesia (TTS)\nOpenAI Realtime + Gemini Live (realtime voice APIs)\n\nMedia generation providers (image / video / music / avatar) β€” Kling, Runway, Replicate, Beatoven, Lyria, D-ID, HeyGen. See Media Generation for the full list.\n\nQ: Do I need to install anything?\n\nA: No installation required! You can use NeuroLink directly with npx:\n\nFor frequent use, you can install globally: npm install -g @juspay/neurolink\n\nπŸ”§ Configuration\n\nQ: How do I set up API keys?\n\nA: Create a .env file in your project directory:\n\nNeuroLink automatically loads these environment variables.\n\nQ: Can I use NeuroLink behind a corporate proxy?\n\nA: Yes! NeuroLink automatically detects and uses corporate proxy settings:\n\nNo additional configuration needed.\n\nQ: How do I configure multiple environments (dev/staging/prod)?\n\nA: Use environment-specific .env files:\n\n🎯 Usage\n\nQ: What's the difference between CLI and SDK?\n\nA:\n\n| Feature | CLI | SDK |\n| -------------------- | ---------------------------- | ------------------------- |\n| Best for | Scripts, automation, testing | Applications, integration |\n| Installation | None required (npx) | npm install required |\n| Output | Text, JSON | Native JavaScript objects |\n| Batch processing | Built-in batch command | Manual implementation |\n| Learning curve | Low | Medium |\n\nQ: How do I choose the best provider for my use case?\n\nA: NeuroLink can auto-select the best provider, or you can choose based on:\nSpeed: Google AI (fastest responses)\nCoding: Anthropic Claude (best for code analysis)\nCreative: OpenAI (best for creative content)\nCost: Google AI Studio (free tier available)\nEnterprise: AWS Bedrock or Azure OpenAI\n\nQ: Can I use multiple providers in the same application?\n\nA: Yes! You can specify different providers for different requests:\n\nπŸ” Troubleshooting\n\nQ: Why am I getting \"API key not found\" errors?\n\nA: Common solutions:\nCheck .env file exists and is in the correct directory\nVerify file format: No spaces around = signs\nCheck file permissions: .env file should be read","hierarchy":{"lvl0":"Reference","lvl1":"Frequently Asked Questions","lvl2":"","lvl3":""}},
10043
10068
  {"objectID":"430e71707f7db7f9866d7ab0b23f14f769c4812334161d853920bf4358ad8c17","title":"Frequently Asked Questions","url":"/docs/reference/faq#frequently-asked-questions","content":"Common questions and answers about NeuroLink usage, configuration, and troubleshooting.","hierarchy":{"lvl0":"Reference","lvl1":"Frequently Asked Questions","lvl2":"Frequently Asked Questions","lvl3":""}},
10044
10069
  {"objectID":"e9218a0cd45a1960da2da4d8d664f5a8b77494352527c7b4d1e6bc12c137400f","title":"Q: What is NeuroLink?","url":"/docs/reference/faq#q-what-is-neurolink","content":"A: NeuroLink is an enterprise AI development platform that provides unified access to multiple AI providers (OpenAI, Google AI, Anthropic, AWS Bedrock, etc.) through a single SDK and CLI. It includes built-in tools, analytics, evaluation capabilities, and supports the Model Context Protocol (MCP) for extended functionality.","hierarchy":{"lvl0":"Reference","lvl1":"Frequently Asked Questions","lvl2":"Q: What is NeuroLink?","lvl3":""}},
10045
- {"objectID":"c32f5558167b5817bde6577d51c68bbce793c3118b1192fdbf6c6e5958d3faff","title":"Q: Which AI providers does NeuroLink support?","url":"/docs/reference/faq#q-which-ai-providers-does-neurolink-support","content":"A: NeuroLink ships AI providers for text generation, streaming, and decision-making β€” plus separate provider systems for voice and media generation. The text and multimodal providers include:\nOpenAI (GPT-4o, GPT-4.1, o3, o4-mini)\nGoogle AI Studio (Gemini 3 Flash/Pro, Gemini 2.5 Pro/Flash)\nGoogle Vertex AI (Gemini 3, Claude via Vertex)\nAnthropic (Claude Opus 4.7, Sonnet 4.6, 4.5 Opus/Sonnet/Haiku)\nAWS Bedrock (Claude, Titan, Nova models)\nAzure OpenAI (GPT models)\nHugging Face (Open source models)\nOllama (Local AI models)\nMistral AI (Mistral models)\nLiteLLM (100+ models via proxy)\nAWS SageMaker (Custom endpoints)\nOpenAI-compatible (Any OpenAI-API-compatible endpoint)\nOpenRouter (300+ models via OpenRouter)\nDeepSeek (DeepSeek V3, R1)\nNVIDIA NIM (Llama 3.3 70B, 400+ catalog models)\nLM Studio (Local models loaded in LM Studio)\nllama.cpp (Local GGUF models via llama-server)\nGroq, Cerebras, SambaNova, Together AI, Fireworks AI, Perplexity, Cloudflare Workers AI, xAI, Baseten, GMI Cloud, Inception Labs, io.net Intelligence, Mancer, Upstage, API Route (zero-quirk OpenAI-wire-compatible catalog providers)\nCohere (chat, plus embed() and reranking)\nVoyage AI, Jina AI (embedding and/or reranking only β€” no chat completions)\nTypeSafe Jev, Laya, XOR, SubQ, Perplexity Decisions, Cloudflare Clef (decision-only β€” serve decide(), not generate()/stream(); tried in the order TypeSafe, Laya, XOR, SubQ, Perplexity, Cloudflare Clef when several are configured; Clef is configured by the same CLOUDFLARE_API_KEY and CLOUDFLARE_ACCOUNT_ID as the Cloudflare Workers AI text provider)\n\nSee Provider Setup for the complete roster with setup guides.","hierarchy":{"lvl0":"Reference","lvl1":"Frequently Asked Questions","lvl2":"Q: Which AI providers does NeuroLink support?","lvl3":""}},
10070
+ {"objectID":"c32f5558167b5817bde6577d51c68bbce793c3118b1192fdbf6c6e5958d3faff","title":"Q: Which AI providers does NeuroLink support?","url":"/docs/reference/faq#q-which-ai-providers-does-neurolink-support","content":"A: NeuroLink ships AI providers for text generation, streaming, and decision-making β€” plus separate provider systems for voice and media generation. The text and multimodal providers include:\nOpenAI (GPT-4o, GPT-4.1, o3, o4-mini)\nGoogle AI Studio (Gemini 3 Flash/Pro, Gemini 2.5 Pro/Flash)\nGoogle Vertex AI (Gemini 3, Claude via Vertex)\nAnthropic (Claude Opus 4.7, Sonnet 4.6, 4.5 Opus/Sonnet/Haiku)\nAWS Bedrock (Claude, Titan, Nova models)\nAzure OpenAI (GPT models)\nHugging Face (Open source models)\nOllama (Local AI models)\nMistral AI (Mistral models)\nLiteLLM (100+ models via proxy)\nAWS SageMaker (Custom endpoints)\nOpenAI-compatible (Any OpenAI-API-compatible endpoint)\nOpenRouter (300+ models via OpenRouter)\nDeepSeek (DeepSeek V3, R1)\nNVIDIA NIM (Llama 3.3 70B, 400+ catalog models)\nLM Studio (Local models loaded in LM Studio)\nllama.cpp (Local GGUF models via llama-server)\nGroq, Cerebras, SambaNova, Together AI, Fireworks AI, Perplexity, Cloudflare Workers AI, xAI, Baseten, GMI Cloud, Inception Labs, io.net Intelligence, Mancer, Upstage, API Route (zero-quirk OpenAI-wire-compatible catalog providers)\nCohere (chat, plus embed() and reranking)\nVoyage AI, Jina AI (embedding and/or reranking only β€” no chat completions)\nTypeSafe Jev, Laya, XOR, SubQ, Perplexity Decisions, Cloudflare Clef, OpenAI Decisions (decision-only β€” serve decide(), not generate()/stream(); tried in the order TypeSafe, Laya, XOR, SubQ, Perplexity, Cloudflare Clef, OpenAI Decisions when several are configured; Clef is configured by the same CLOUDFLARE_API_KEY and CLOUDFLARE_ACCOUNT_ID as the Cloudflare Workers AI text provider, and OpenAI Decisions by the same OPENAI_API_KEY as the OpenAI chat provider, except that this key is not used by default while OPENAI_BASE_URL, OPENAI_API_BASE or credentials.openai.baseURL names a host other than https://api.openai.com, since it is then a gateway's)\n\nSee Provider Setup for the complete roster with setup guides.","hierarchy":{"lvl0":"Reference","lvl1":"Frequently Asked Questions","lvl2":"Q: Which AI providers does NeuroLink support?","lvl3":""}},
10046
10071
  {"objectID":"c7da7431322332ad0e9e6439acb89a8a9f6af428d15d84c94adeb886ea4fdaab","title":"Q: Do I need to install anything?","url":"/docs/reference/faq#q-do-i-need-to-install-anything","content":"A: No installation required! You can use NeuroLink directly with npx:\n\nFor frequent use, you can install globally: npm install -g @juspay/neurolink","hierarchy":{"lvl0":"Reference","lvl1":"Frequently Asked Questions","lvl2":"Q: Do I need to install anything?","lvl3":""}},
10047
10072
  {"objectID":"379b5c908063649275668a696f71c0e87923dd0d011f221a19a43f69a483acea","title":"Q: How do I set up API keys?","url":"/docs/reference/faq#q-how-do-i-set-up-api-keys","content":"A: Create a .env file in your project directory:\n\n`bash","hierarchy":{"lvl0":"Reference","lvl1":"Frequently Asked Questions","lvl2":"Q: How do I set up API keys?","lvl3":""}},
10048
10073
  {"objectID":"07c128fc6b5bcea9361ff3423a97e6a5a4e85fb14571f4a5d14bcb11eb389105","title":".env file","url":"/docs/reference/faq#env-file","content":"OPENAIAPIKEY=\"sk-your-openai-key\"\nGOOGLEAIAPI_KEY=\"AIza-your-google-ai-key\"\nANTHROPICAPIKEY=\"sk-ant-your-anthropic-key\"","hierarchy":{"lvl0":"Reference","lvl1":"Frequently Asked Questions","lvl2":".env file","lvl3":""}},
@@ -11174,8 +11199,8 @@
11174
11199
  {"objectID":"1a0933649d2e2a9e068e520585c510992a787eb886f8661e6da36cf83ce7e3eb","title":"Multiple inputs","url":"/docs/skills/neurolink-guide/multimodal#multiple-inputs","content":"neurolink generate \"Compare\" --image ./a.png --image ./b.png --pdf ./docs.pdf\n`","hierarchy":{"lvl0":"Skills","lvl1":"NeuroLink Multimodal Support","lvl2":"Multiple inputs","lvl3":""}},
11175
11200
  {"objectID":"e2858a465b5d2bc8ef1db9834500597eb845bf3b40f3a0ba4b29e54033a4b23b","title":"File Size Considerations","url":"/docs/skills/neurolink-guide/multimodal#file-size-considerations","content":"| File Type | Recommended Max | Notes |\n| --------- | --------------- | -------------------- |\n| Images | 20MB | Resized if larger |\n| PDFs | 50MB | Page limit may apply |\n| CSV | 10MB | Use maxRows option |\n| Code | 100KB | Split large files |","hierarchy":{"lvl0":"Skills","lvl1":"NeuroLink Multimodal Support","lvl2":"File Size Considerations","lvl3":""}},
11176
11201
  {"objectID":"8d5a67779513f44569761e7ea2fa399de1aafd682a08e0b14c08850f0c223cb2","title":"Next Steps","url":"/docs/skills/neurolink-guide/multimodal#next-steps","content":"MCP tools - Add external tools\nRAG integration - Document-grounded generation\nProviders - Configure vision-capable providers","hierarchy":{"lvl0":"Skills","lvl1":"NeuroLink Multimodal Support","lvl2":"Next Steps","lvl3":""}},
11177
- {"objectID":"d9e19daaa21e9512ad71f1187055c474d4b51da0c78b56a197286c6403126b9a","title":"NeuroLink Provider Configuration","url":"/docs/skills/neurolink-guide/providers","content":"NeuroLink Provider Configuration\n\nNeuroLink supports many AI providers through a unified API. This page highlights the most commonly-configured text providers β€” see the README provider table and the Provider Capabilities Audit for the full matrix, including newer text providers (DeepSeek, NVIDIA NIM, LM Studio, llama.cpp, plus the Tier-2 catalog providers β€” Groq, Cerebras, SambaNova, Together AI, Fireworks AI, Perplexity, Cloudflare Workers AI, xAI, and more), the decision-only TypeSafe Jev, Laya, XOR, SubQ, Perplexity Decisions and Cloudflare Clef providers (serve decide(), not generate()/stream(); tried in the order TypeSafe, Laya, XOR, SubQ, Perplexity, Cloudflare Clef when several are configured; Clef reads the same CLOUDFLARE_API_KEY and CLOUDFLARE_ACCOUNT_ID as the Cloudflare Workers AI text provider), and voice providers (OpenAI TTS, ElevenLabs, Deepgram, Azure Speech, Whisper, Fish Audio, Cartesia, OpenAI Realtime, Gemini Live).\n\nCommon Providers\n\n| Provider | Enum Name | Aliases | Default Model |\n| ---------------- | -------------- | -------------- | --------------------------------------- |\n| OpenAI | openai | gpt, chatgpt | gpt-4o |\n| Anthropic | anthropic | claude | claude-3-5-sonnet-20241022 |\n| Google AI Studio | google-ai | gemini, google | gemini-2.5-flash |\n| Google Vertex AI | vertex | google-vertex | gemini-2.5-flash |\n| AWS Bedrock | bedrock | aws-bedrock | anthropic.claude-3-sonnet-20240229-v1:0 |\n| Azure OpenAI | azure-openai | azure | gpt-4o |\n| Mistral AI | mistral | - | mistral-large |\n| Ollama | ollama | - | llama3 |\n| LiteLLM | litellm | - | varies |\n| AWS SageMaker | sagemaker | - | custom |\n| Hugging Face | hugging-face | hf | varies |\n| OpenRouter | openrouter | - | varies |\n| Gateway | gateway | - | varies |\n\nOpenAI\n\nAvailable Models:\ngpt-4o - Latest GPT-4 Omni\ngpt-4o-mini - Faster, cheaper\ngpt-4-turbo - GPT-4 Turbo\no1 - Reasoning model\no1-mini - Smaller reasoning model\n\nAnthropic\n\nAvailable Models:\nclaude-3-5-sonnet-20241022 - Latest Sonnet\nclaude-3-7-sonnet-20250219 - Claude 3.7 Sonnet\nclaude-3-opus-20240229 - Most capable\nclaude-3-haiku-20240307 - Fastest\n\nExtended Thinking:\n\nGoogle AI Studio\n\nAvailable Models:\ngemini-2.5-flash - Fast and capable\ngemini-2.5-pro - Most capable\ngemini-2.0-flash - Previous generation\ngemini-3-flash-preview - Preview of Gemini 3\n\nGoogle Vertex AI\n\nAvailable Models:\ngemini-3-flash - Latest Gemini 3\ngemini-3-pro - Most capable Gemini 3\ngemini-2.5-flash - Fast\ngemini-2.5-pro - Previous gen capable\n\nExtended Thinking (Gemini 3):\n\nAWS Bedrock\n\nAvailable Models:\nanthropic.claude-3-sonnet-20240229-v1:0\nanthropic.claude-3-haiku-20240307-v1:0\nanthropic.claude-3-opus-20240229-v1:0\namazon.titan-text-express-v1\namazon.nova-pro-v1:0\nmeta.llama3-70b-instruct-v1:0\n\nAzure OpenAI\n\nMistral AI\n\nAvailable Models:\nmistral-large-latest - Most capable\nmistral-small-latest - Fast\ncodestral-latest - Code specialized\nministral-8b-latest - Small\n\nOllama (Local)\n\nSetup:\n\nAvailable Models:\nllama3 - Meta Llama 3\nllama3:70b - Larger Llama 3\nmistral - Mistral 7B\ncodellama - Code specialized\nphi3 - Microsoft Phi-3\n\nLiteLLM\n\nAWS SageMaker\n\nHugging Face\n\nOpenRouter\n\nProvider Fallback\n\nConfigure automatic fallback to another provider:\n\nCheck Provider Status\n\nProvider-Specific Options\n\nTemperature and Sampling\n\nSystem Prompts\n\nVision-Capable Models\n\nNot all models support image inputs:\n\n| Provider | Vision Models |\n| --------- | --------------------- |\n| OpenAI | gpt-4o, gpt-4-turbo |\n| Anthropic | All Claude 3 models |\n| Vertex | Gemini 2.5+, Gemini 3 |\n| Google AI | Gemini 2.5+, Gemini 3 |\n| Bedrock | Claude 3 models |\n\nNext Steps\nMultimodal inputs - Work with images and documents\nMCP tools - Add external tools\nRAG integration - Document-grounded generation","hierarchy":{"lvl0":"Skills","lvl1":"NeuroLink Provider Configuration","lvl2":"","lvl3":""}},
11178
- {"objectID":"b66a3f5004ec2abbc42277973845a5485480e16a3ea54ea9f31e83978a9ee521","title":"NeuroLink Provider Configuration","url":"/docs/skills/neurolink-guide/providers#neurolink-provider-configuration","content":"NeuroLink supports many AI providers through a unified API. This page highlights the most commonly-configured text providers β€” see the README provider table and the Provider Capabilities Audit for the full matrix, including newer text providers (DeepSeek, NVIDIA NIM, LM Studio, llama.cpp, plus the Tier-2 catalog providers β€” Groq, Cerebras, SambaNova, Together AI, Fireworks AI, Perplexity, Cloudflare Workers AI, xAI, and more), the decision-only TypeSafe Jev, Laya, XOR, SubQ, Perplexity Decisions and Cloudflare Clef providers (serve decide(), not generate()/stream(); tried in the order TypeSafe, Laya, XOR, SubQ, Perplexity, Cloudflare Clef when several are configured; Clef reads the same CLOUDFLARE_API_KEY and CLOUDFLARE_ACCOUNT_ID as the Cloudflare Workers AI text provider), and voice providers (OpenAI TTS, ElevenLabs, Deepgram, Azure Speech, Whisper, Fish Audio, Cartesia, OpenAI Realtime, Gemini Live).","hierarchy":{"lvl0":"Skills","lvl1":"NeuroLink Provider Configuration","lvl2":"NeuroLink Provider Configuration","lvl3":""}},
11202
+ {"objectID":"d9e19daaa21e9512ad71f1187055c474d4b51da0c78b56a197286c6403126b9a","title":"NeuroLink Provider Configuration","url":"/docs/skills/neurolink-guide/providers","content":"NeuroLink Provider Configuration\n\nNeuroLink supports many AI providers through a unified API. This page highlights the most commonly-configured text providers β€” see the README provider table and the Provider Capabilities Audit for the full matrix, including newer text providers (DeepSeek, NVIDIA NIM, LM Studio, llama.cpp, plus the Tier-2 catalog providers β€” Groq, Cerebras, SambaNova, Together AI, Fireworks AI, Perplexity, Cloudflare Workers AI, xAI, and more), the decision-only TypeSafe Jev, Laya, XOR, SubQ, Perplexity Decisions, Cloudflare Clef and OpenAI Decisions providers (serve decide(), not generate()/stream(); tried in the order TypeSafe, Laya, XOR, SubQ, Perplexity, Cloudflare Clef, OpenAI Decisions when several are configured; Clef reads the same CLOUDFLARE_API_KEY and CLOUDFLARE_ACCOUNT_ID as the Cloudflare Workers AI text provider, and OpenAI Decisions the same OPENAI_API_KEY as the OpenAI chat provider), and voice providers (OpenAI TTS, ElevenLabs, Deepgram, Azure Speech, Whisper, Fish Audio, Cartesia, OpenAI Realtime, Gemini Live).\n\nCommon Providers\n\n| Provider | Enum Name | Aliases | Default Model |\n| ---------------- | -------------- | -------------- | --------------------------------------- |\n| OpenAI | openai | gpt, chatgpt | gpt-4o |\n| Anthropic | anthropic | claude | claude-3-5-sonnet-20241022 |\n| Google AI Studio | google-ai | gemini, google | gemini-2.5-flash |\n| Google Vertex AI | vertex | google-vertex | gemini-2.5-flash |\n| AWS Bedrock | bedrock | aws-bedrock | anthropic.claude-3-sonnet-20240229-v1:0 |\n| Azure OpenAI | azure-openai | azure | gpt-4o |\n| Mistral AI | mistral | - | mistral-large |\n| Ollama | ollama | - | llama3 |\n| LiteLLM | litellm | - | varies |\n| AWS SageMaker | sagemaker | - | custom |\n| Hugging Face | hugging-face | hf | varies |\n| OpenRouter | openrouter | - | varies |\n| Gateway | gateway | - | varies |\n\nOpenAI\n\nAvailable Models:\ngpt-4o - Latest GPT-4 Omni\ngpt-4o-mini - Faster, cheaper\ngpt-4-turbo - GPT-4 Turbo\no1 - Reasoning model\no1-mini - Smaller reasoning model\n\nAnthropic\n\nAvailable Models:\nclaude-3-5-sonnet-20241022 - Latest Sonnet\nclaude-3-7-sonnet-20250219 - Claude 3.7 Sonnet\nclaude-3-opus-20240229 - Most capable\nclaude-3-haiku-20240307 - Fastest\n\nExtended Thinking:\n\nGoogle AI Studio\n\nAvailable Models:\ngemini-2.5-flash - Fast and capable\ngemini-2.5-pro - Most capable\ngemini-2.0-flash - Previous generation\ngemini-3-flash-preview - Preview of Gemini 3\n\nGoogle Vertex AI\n\nAvailable Models:\ngemini-3-flash - Latest Gemini 3\ngemini-3-pro - Most capable Gemini 3\ngemini-2.5-flash - Fast\ngemini-2.5-pro - Previous gen capable\n\nExtended Thinking (Gemini 3):\n\nAWS Bedrock\n\nAvailable Models:\nanthropic.claude-3-sonnet-20240229-v1:0\nanthropic.claude-3-haiku-20240307-v1:0\nanthropic.claude-3-opus-20240229-v1:0\namazon.titan-text-express-v1\namazon.nova-pro-v1:0\nmeta.llama3-70b-instruct-v1:0\n\nAzure OpenAI\n\nMistral AI\n\nAvailable Models:\nmistral-large-latest - Most capable\nmistral-small-latest - Fast\ncodestral-latest - Code specialized\nministral-8b-latest - Small\n\nOllama (Local)\n\nSetup:\n\nAvailable Models:\nllama3 - Meta Llama 3\nllama3:70b - Larger Llama 3\nmistral - Mistral 7B\ncodellama - Code specialized\nphi3 - Microsoft Phi-3\n\nLiteLLM\n\nAWS SageMaker\n\nHugging Face\n\nOpenRouter\n\nProvider Fallback\n\nConfigure automatic fallback to another provider:\n\nCheck Provider Status\n\nProvider-Specific Options\n\nTemperature and Sampling\n\nSystem Prompts\n\nVision-Capable Models\n\nNot all models support image inputs:\n\n| Provider | Vision Models |\n| --------- | --------------------- |\n| OpenAI | gpt-4o, gpt-4-turbo |\n| Anthropic | All Claude 3 models |\n| Vertex | Gemini 2.5+, Gemini 3 |\n| Google AI | Gemini 2.5+, Gemini 3 |\n| Bedrock | Claude 3 models |\n\nNext Steps\nMultimodal inputs - Work with images and documents\nMCP tools - Add external tools\nRAG integration - Document-grounded generation","hierarchy":{"lvl0":"Skills","lvl1":"NeuroLink Provider Configuration","lvl2":"","lvl3":""}},
11203
+ {"objectID":"b66a3f5004ec2abbc42277973845a5485480e16a3ea54ea9f31e83978a9ee521","title":"NeuroLink Provider Configuration","url":"/docs/skills/neurolink-guide/providers#neurolink-provider-configuration","content":"NeuroLink supports many AI providers through a unified API. This page highlights the most commonly-configured text providers β€” see the README provider table and the Provider Capabilities Audit for the full matrix, including newer text providers (DeepSeek, NVIDIA NIM, LM Studio, llama.cpp, plus the Tier-2 catalog providers β€” Groq, Cerebras, SambaNova, Together AI, Fireworks AI, Perplexity, Cloudflare Workers AI, xAI, and more), the decision-only TypeSafe Jev, Laya, XOR, SubQ, Perplexity Decisions, Cloudflare Clef and OpenAI Decisions providers (serve decide(), not generate()/stream(); tried in the order TypeSafe, Laya, XOR, SubQ, Perplexity, Cloudflare Clef, OpenAI Decisions when several are configured; Clef reads the same CLOUDFLARE_API_KEY and CLOUDFLARE_ACCOUNT_ID as the Cloudflare Workers AI text provider, and OpenAI Decisions the same OPENAI_API_KEY as the OpenAI chat provider), and voice providers (OpenAI TTS, ElevenLabs, Deepgram, Azure Speech, Whisper, Fish Audio, Cartesia, OpenAI Realtime, Gemini Live).","hierarchy":{"lvl0":"Skills","lvl1":"NeuroLink Provider Configuration","lvl2":"NeuroLink Provider Configuration","lvl3":""}},
11179
11204
  {"objectID":"ca77e6781279a1e849f17c5edd76b2cc111546faa201202d3dc11820334170ce","title":"Common Providers","url":"/docs/skills/neurolink-guide/providers#common-providers","content":"| Provider | Enum Name | Aliases | Default Model |\n| ---------------- | -------------- | -------------- | --------------------------------------- |\n| OpenAI | openai | gpt, chatgpt | gpt-4o |\n| Anthropic | anthropic | claude | claude-3-5-sonnet-20241022 |\n| Google AI Studio | google-ai | gemini, google | gemini-2.5-flash |\n| Google Vertex AI | vertex | google-vertex | gemini-2.5-flash |\n| AWS Bedrock | bedrock | aws-bedrock | anthropic.claude-3-sonnet-20240229-v1:0 |\n| Azure OpenAI | azure-openai | azure | gpt-4o |\n| Mistral AI | mistral | - | mistral-large |\n| Ollama | ollama | - | llama3 |\n| LiteLLM | litellm | - | varies |\n| AWS SageMaker | sagemaker | - | custom |\n| Hugging Face | hugging-face | hf | varies |\n| OpenRouter | openrouter | - | varies |\n| Gateway | gateway | - | varies |","hierarchy":{"lvl0":"Skills","lvl1":"NeuroLink Provider Configuration","lvl2":"Common Providers","lvl3":""}},
11180
11205
  {"objectID":"9c5370e9c625cd036ee1c3c8ba7c0bea9a5b6b68ca08ccd9c710d3e65429d843","title":"OpenAI","url":"/docs/skills/neurolink-guide/providers#openai","content":"`bash","hierarchy":{"lvl0":"Skills","lvl1":"NeuroLink Provider Configuration","lvl2":"OpenAI","lvl3":""}},
11181
11206
  {"objectID":"fcc21bd062d4e7ab394bd0ad8a1257ec9ed367c205f68dab30479e6758c5cf20","title":"Environment","url":"/docs/skills/neurolink-guide/providers#environment","content":"OPENAIAPIKEY=sk-...\nOPENAIORGID=org-... # Optional\nOPENAIBASEURL=... # Optional, for proxies\ntypescript\nconst result = await neurolink.generate({\n input: { text: \"Hello\" },\n provider: \"openai\",\n model: \"gpt-4o\", // or gpt-4o-mini, gpt-4-turbo, o1, o1-mini\n});\n\n\n**Available Models:**\n\n- gpt-4o - Latest GPT-4 Omni\n- gpt-4o-mini - Faster, cheaper\n- gpt-4-turbo - GPT-4 Turbo\n- o1 - Reasoning model\n- o1-mini` - Smaller reasoning model","hierarchy":{"lvl0":"Skills","lvl1":"NeuroLink Provider Configuration","lvl2":"Environment","lvl3":""}},