@juspay/neurolink 13.8.10 → 13.8.12

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.
@@ -2257,10 +2257,10 @@
2257
2257
  {"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":""}},
2258
2258
  {"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":""}},
2259
2259
  {"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":""}},
2260
- {"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, OPENAI_API_KEY, or SCALEDOWN_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, the default decision provider when none ahead of it is configured (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. SCALEDOWN_API_KEY is ScaleDown's own key and counts by itself: with only that key auto resolves to jev, answered by ScaleDown (also a paid call, with the same fallback). 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, credentials.scaledown 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, ScaleDown) 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 ","hierarchy":{"lvl0":"Features","lvl1":"Classifier Router","lvl2":"","lvl3":""}},
2260
+ {"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, OPENAI_API_KEY, or SCALEDOWN_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, the default decision provider when none ahead of it is configured (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. SCALEDOWN_API_KEY is ScaleDown's own key and counts by itself: with only that key auto resolves to jev, answered by ScaleDown (also a paid call, with the same fallback). 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, credentials.scaledown and the other decision providers' slices) passed on a single call can make auto pick jev rather than heuristic, but it adds a provider and does not pin one. The decision goes to that account only when no decision provider ahead of it in the order is configured; otherwise it goes to the first one that is.\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, ScaleDown) 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| --- | ---------------------- | -------------------------------------------------------------------------------","hierarchy":{"lvl0":"Features","lvl1":"Classifier Router","lvl2":"","lvl3":""}},
2261
2261
  {"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":""}},
2262
2262
  {"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":""}},
2263
- {"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, OPENAI_API_KEY, or SCALEDOWN_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, the default decision provider when none ahead of it is configured (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. SCALEDOWN_API_KEY is ScaleDown's own key and counts by itself: with only that key auto resolves to jev, answered by ScaleDown (also a paid call, with the same fallback). 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, credentials.scaledown 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.","hierarchy":{"lvl0":"Features","lvl1":"Classifier Router","lvl2":"How it works","lvl3":""}},
2263
+ {"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, OPENAI_API_KEY, or SCALEDOWN_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, the default decision provider when none ahead of it is configured (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. SCALEDOWN_API_KEY is ScaleDown's own key and counts by itself: with only that key auto resolves to jev, answered by ScaleDown (also a paid call, with the same fallback). 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, credentials.scaledown and the other decision providers' slices) passed on a single call can make auto pick jev rather than heuristic, but it adds a provider and does not pin one.","hierarchy":{"lvl0":"Features","lvl1":"Classifier Router","lvl2":"How it works","lvl3":""}},
2264
2264
  {"objectID":"69f1dc84af676af8d2dd086916cc99bf8c9351dee3213dbc4aaf3e2a513f515f","title":"Quick start (heuristic, SDK)","url":"/docs/features/classifier-router#quick-start-heuristic-sdk","content":"Quick start (heuristic, SDK)","hierarchy":{"lvl0":"Features","lvl1":"Classifier Router","lvl2":"Quick start (heuristic, SDK)","lvl3":""}},
2265
2265
  {"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":""}},
2266
2266
  {"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":""}},
@@ -2338,6 +2338,7 @@
2338
2338
  {"objectID":"f1d10e310dd6cdd2e1ec76e8fb228e48f343eec841772b564c22357e7ea8f64f","title":"Validation Rules","url":"/docs/features/claude-proxy-config-reference#validation-rules","content":"The config loader validates the following:\naccounts must be present and be a non-array object.\nEach provider key in accounts must map to an array.\nEach account must have a non-empty string apiKey.\nIf version is present, it must be a number.\nrouting.account-allowlist must be an array of non-empty strings when present. An explicit null counts as present and is rejected, whichever spelling carries it, including when the other spelling holds an array.\nrouting.quota-routing must be a boolean when present.\nrouting.auto-fallback must be a boolean when present.\nrouting.max-inflight-per-account must be an integer from 1 through 20 when present.\nrouting.session-soft-limit must be a number in (0, 1] when present.\nrouting.session-reset-tolerance-ms must be a positive integer when present.\nrouting.use-overage must be auto, always, or never (case-insensitive)\n when present.\nrouting.account-ranking must be expiry-first or headroom-first when\n present.\nrouting.prefer-primary must be a boolean when present.\nrouting.session-affinity must be a boolean when present.\nrouting.session-affinity-idle-ttl-ms must be an integer from 60000 through\n 86400000 when present.\nrouting.spill-inflight must be an integer from 0 through 100 when present.\nFor those five routing policy keys, an explicit null counts as present\n and is rejected, whichever spelling (kebab-case or camelCase) carries it.\nPlaintext API keys (not using ${ENV_VAR} references) trigger a warning.\n\nAn absent default config is optional. An existing config that cannot be read or\nvalidated fails proxy startup; it is never ignored in favor of unrestricted\nrouting. A value that fails any check above rejects the whole config, never\njust that key: at startup the proxy does not start, and on a hot reload the\nlast-known-good generation stays active.","hierarchy":{"lvl0":"Features","lvl1":"Claude Proxy Configuration Reference","lvl2":"Validation Rules","lvl3":""}},
2339
2339
  {"objectID":"c8450374b1fc8e0a0f5fb47d3bef0cab242c75e17bfebe6e943ef17b22c10227","title":"Account Routing Policies","url":"/docs/features/claude-proxy-config-reference#account-routing-policies","content":"The five keys above (account-ranking, prefer-primary, session-affinity,\nsession-affinity-idle-ttl-ms, spill-inflight) all default to today's exact\nbehavior — expiry-first ranking, no affinity, no primary preference, no\nspill — and are validated and hot-reloaded through the same runtime config\nsnapshot as every other routing key.\n\nstrategy: round-robin ignores all five keys. They apply only under\nfill-first with more than one enabled account.\n\nNEUROLINK_PROXY_QUOTA_ROUTING=off disables quota-based ranking, but\nsession-affinity, prefer-primary and spill-inflight still apply.\nTurning off quota routing removes the expiry/headroom ordering step, so\naccount-ranking has no effect; it does not disable sticky sessions, the\nprimary preference or spill, which then work on the configured account\norder.\n\nPrecedence. After unusable accounts are removed, the order a request\ntries is:\nthe session's bound account, when session-affinity is on and that\n account is usable and not session-saturated;\nthe configured primary-account, when prefer-primary is on and it is\n usable and not session-saturated;\nthe remaining accounts in account-ranking order.\n\nSpill only changes which account is tried first, and only for requests\nwithout an active session-affinity binding — it never re-orders or moves a\nrequest that is already bound to an account. Its target must be usable and\nnot session-saturated, like every step above; when no account under the\nthreshold qualifies, nothing spills.\n\nBinding. A served request binds its session to the Anthropic account\nthat served it. The existing binding is kept only when that request never\ntried the bound account and the bound account is still usable and not\nsession-saturated — a request that overflowed the bound account's\nmax-inflight-per-account cap onto another account keeps the session on its\nwarm prompt cache.","hierarchy":{"lvl0":"Features","lvl1":"Claude Proxy Configuration Reference","lvl2":"Account Routing Policies","lvl3":""}},
2340
2340
  {"objectID":"2b5d2865be217ed908e64f9d07acbe019108e95f210f6c14f031cf8cb99ece6f","title":"3. Environment Variables","url":"/docs/features/claude-proxy-config-reference#3-environment-variables","content":"| Variable | Purpose | Used By |\n| -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ |\n| ANTHROPIC_API_KEY | Anthropic API key. Used as a fallback credential when no OAuth accounts are found. | Proxy routes, Anthropic provider |\n| ANTHROPIC_OAUTH_TOKEN | OAuth access token for Anthropic (alternative to stored tokens). | Anthropic provider, providerConfig |\n| CLAUDE_OAUTH_TOKEN | Alias for ANTHROPIC_OAUTH_TOKEN. Checked as a fallback.","hierarchy":{"lvl0":"Features","lvl1":"Claude Proxy Configuration Reference","lvl2":"3. Environment Variables","lvl3":""}},
2341
+ {"objectID":"80c3f3761c75b9ade9789621570e067d9a631ce027171eba652da6eeb2db3dce","title":"Request body limits","url":"/docs/features/claude-proxy-config-reference#request-body-limits","content":"The proxy reads a POST body before it can parse the model or check a share token, so the body is bounded first. Each route has a request size limit, taken from its API's documentation where the API states one; a larger body is answered 413 with error.type request_too_large, before the body is parsed and before the share gate runs. Limits are binary megabytes, a little above the documented figures, so the upstream stays the one to refuse a borderline request.\n\n| Route | Limit | Source |\n| -------------------------------------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| POST /v1/messages, POST /v1/messages/count_tokens, /peer/* endpoints | 32 MiB | Messages API and Token Counting API maximum request size, 32 MB: platform.claude.com/docs/en/api/errors#request-size-limits. The peer endpoints have no upstream and use the same value.","hierarchy":{"lvl0":"Features","lvl1":"Claude Proxy Configuration Reference","lvl2":"Request body limits","lvl3":""}},
2341
2342
  {"objectID":"3f1a3fc9d7711064037deec5635e85b2dc713d3d9c019df22c659f47215812b8","title":"Proxy Env File Resolution Order","url":"/docs/features/claude-proxy-config-reference#proxy-env-file-resolution-order","content":"When the proxy starts, it loads env vars from a .env file using this priority:\n--env-file <path> CLI flag — explicit path, required to exist.\nNEUROLINK_ENV_FILE=<path> environment variable — explicit path, required to exist.\n~/.neurolink/.env — loaded automatically if the file exists (created by neurolink proxy telemetry setup).\nNothing — proxy starts without extra env vars; telemetry remains disabled unless env vars are already set in the shell, and the proxy emits a startup log explaining how to enable it unless output is suppressed.\n\nThe --env-file flag is baked into the launchd plist by proxy install, so the service always loads from the same file across reboots. The three runtime routing variables above and routing interpolation are reread transactionally; other env settings remain startup-only.\n\nPriority for Anthropic credentials (checked in order by the proxy routes):\nTokenStore compound keys -- anthropic:<label> entries in ~/.neurolink/tokens.json.\nLegacy credentials file -- ~/.neurolink/anthropic-credentials.json (only if no compound keys exist).\nANTHROPIC_API_KEY env var -- Only if no Anthropic TokenStore entries or legacy credential are present.\n\nrouting.account-allowlist filters these sources before loading or refresh. Legacy and environment fallbacks are never activated merely because existing TokenStore accounts are disabled, cooling, or unavailable.","hierarchy":{"lvl0":"Features","lvl1":"Claude Proxy Configuration Reference","lvl2":"Proxy Env File Resolution Order","lvl3":""}},
2342
2343
  {"objectID":"80e1b4619dc934235aae772511dd334605525b9512cb0a98374bc61d27f8903a","title":"4. Claude Code Settings","url":"/docs/features/claude-proxy-config-reference#4-claude-code-settings","content":"When the proxy starts, it automatically writes to ~/.claude/settings.json:\n\n| Key | Value | Description |\n| -------------------- | ---------------------- | --------------------------------------------------------------------------- |\n| ANTHROPIC_BASE_URL | http://<host>:<port> | Tells Claude Code to route all Anthropic API requests through the proxy. |\n| ENABLE_TOOL_SEARCH | \"true\" | Enables tool search in Claude Code (required for full proxy compatibility). |\n\nLifecycle:\nOn proxy start -- Both keys are written (or merged into existing settings).\nOn proxy stop (Ctrl+C / SIGTERM) -- Both keys are removed. Other env keys in the settings file are preserved.\nFail-open guard -- A foreground proxy's detached guard removes stale settings only after confirming its parent died and no replacement is healthy. launchd-managed proxies do not spawn this cleanup guard; they use a separate updater-only worker.\nSafety -- If the ANTHROPIC_BASE_URL has been changed to a different value (e.g., another proxy), the cleanup will not overwrite it.\n\nAfter starting the proxy, restart Claude Code for the new settings to take effect.","hierarchy":{"lvl0":"Features","lvl1":"Claude Proxy Configuration Reference","lvl2":"4. Claude Code Settings","lvl3":""}},
2343
2344
  {"objectID":"33854e3aed0df3989e054a61d15916e33189a47dbc13b68719a4d2b9ba8b4bca","title":"5. File Locations","url":"/docs/features/claude-proxy-config-reference#5-file-locations","content":"All NeuroLink proxy files are stored under ~/.neurolink/ (with 0o700 directory permissions).\n\n| File | Permissions | Description |\n| ------------------------------------------------------------ | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| ~/.neurolink/tokens.json | 0o600 | TokenStore -- Multi-provider OAuth token storage. Stores tokens keyed by provider:label (e.g., anthropic:personal). XOR-obfuscated by default (not plaintext). |\n| ~/.neurolink/anthropic-credentials.json | 0o600 | Legacy credentials -- Single-account OAuth tokens. Used as a fallback when no compound keys exist in tokens.json. Updated on token refresh (pre-request or on-401). |\n| ~/.neurolink/proxy-config.yaml | user default | Proxy config -- YAML/JSON configuration file. Loaded and watched by proxy start (default path, overridable with --config). Valid routing changes publish a new runtime generation. |\n| ~/.neurolink/.env | 0o600 | Proxy env file — Auto-loaded and watched by the proxy.","hierarchy":{"lvl0":"Features","lvl1":"Claude Proxy Configuration Reference","lvl2":"5. File Locations","lvl3":""}},
@@ -5085,7 +5086,7 @@
5085
5086
  {"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":""}},
5086
5087
  {"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":""}},
5087
5088
  {"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":""}},
5088
- {"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,\nSubQ, Perplexity,\nOpenAI Decisions and ScaleDown,\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 | sixth of eight: after TypeSafe, Laya, XOR, SubQ and Perplexity, before OpenAI Decisions and ScaleDown |\n| Verified live | 2026-10-03 and 2026-10-04, with a real account (see Limits) |\n\nQuick Start\nGet a token and your account id\n\nCreate an API token with the Workers AI: Read + Write permission at\ndash.cloudflare.com/profile/api-tokens, and copy your account id from\nthe dashboard URL or the \"Account ID\" panel.\nConfigure\n\nThe base URL must be https://; http:// is accepted only for localhost,\n127.0.0.1 and [::1], because","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Clef Provider Guide","lvl2":"","lvl3":""}},
5089
+ {"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,\nSubQ, Perplexity,\nOpenAI Decisions and ScaleDown,\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; the text alone is held to 195,584 characters on clef-flash |\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 | sixth of eight: after TypeSafe, Laya, XOR, SubQ and Perplexity, before OpenAI Decisions and ScaleDown |\n| Verified live | 2026-10-03 and 2026-10-04, with a real account (see Limits) |\n\nQuick Start\nGet a token and your account id\n\nCreate an API token with the Workers AI: Read + Write permission at\ndash.cloudflare.com/profile/api-tokens, and copy your account id from\nthe dashboard URL or the \"Account ID\" panel.\nConfigure\n\nThe base URL must be https://; http:// is accepted only for localhost,\n127.0.0.1 and [::1], because e","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Clef Provider Guide","lvl2":"","lvl3":""}},
5089
5090
  {"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,\nSubQ, Perplexity,\nOpenAI Decisions and ScaleDown,\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":""}},
5090
5091
  {"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":""}},
5091
5092
  {"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":""}},
@@ -5098,12 +5099,13 @@
5098
5099
  {"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":""}},
5099
5100
  {"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":""}},
5100
5101
  {"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":""}},
5102
+ {"objectID":"d037c352a1fe4919ca99ec7f802ad178e960f28da494088ad0702c93867c6a67","title":"What the 413 counts","url":"/docs/getting-started/providers/cloudflare-clef#what-the-413-counts","content":"The paragraph above gives the edges for plain text. What the estimate is made of\nwas measured on 2026-10-23 and 2026-10-24, one request at a time and with the daily\nallocation spent. That does not hide the size gate: it answers 413 before the\nallocation check answers 429/code 4006, so a 413 means refused by the gate and a\n429 means the request passed it (these probes read no answer).\nThe estimate is the characters of the request's JSON without its images\n array (the key included), over four, rounded half up. A text of 196,609\n characters got 429 on clef-flash and 196,610 got 5021 (estimate 49,153; twice\n 24,576 is 49,152); on clef, 524,288 got 429 and 524,292 got 5021.\nThe images are not in it. Bodies of 396,820 and 517,199 bytes (one and four\n images, the text at the edge) and 632,380 and 1,168,636 bytes (one image of\n about 0.5 and 1.1 MB, a text of 100,000 characters) got 429 on clef-flash,\n not 5021, while a text of 196,612 characters got 5021 with the same 200 KB image\n beside it. That is an inference from the order of the two refusals; no answer\n was read from these bodies. Live case 19.14, which sends about 253 KB with an\n image, is answered. On 2026-10-05 the estimate was the whole body over four\n (133,126 for 532,505 bytes); it no longer is.\nIt counts characters, not bytes. 98,252 \"é\" (196,612 bytes in UTF-8) got 429;\n 98,252 newlines, which JSON writes as two characters each, got 5021.\n\nNeuroLink therefore holds the text of a Clef request (the body without images) to\n195,584 characters on clef-flash and 523,264 on clef, which is eight characters\nper window token less 1,024, and refuses more locally as max_tokens_exceeded,\nthe kind Cloudflare's own 413 gets. A model it does not know has no such limit.\nReaching it takes a text that its state limit above does not allow except through\nthe questions or control characters, which JSON writes as up to six characters each.","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Clef Provider Guide","lvl2":"What the 413 counts","lvl3":""}},
5101
5103
  {"objectID":"26bf07373276f11bf9e656e74cd4a5cbdeeed0e8b4bfa1c057f362b55a3ad959","title":"The state window changed on 2026-10-07","url":"/docs/getting-started/providers/cloudflare-clef#the-state-window-changed-on-2026-10-07","content":"The window described above no longer applies. On 2026-10-07 the Workers AI\nendpoint read the whole state. This section records what was measured; the\nnumbers above stay as the record of 2026-10-03 and 2026-10-04.\n\nMeasured with one request at a time between 07:24 and 08:12 UTC, with a fact\nplaced at the end of the state (the part a cut would drop) and the question \"what\ncolour does the text say the vault code is?\". A fact counts as read when the\nanswer's probability for its colour is at least 0.8.\n\n| State | Model | Characters | Input tokens billed | Fact read (probability) | Time |\n| --------------------------------- | ------------ | ---------- | ------------------- | ----------------------- | ------ |\n| Prose, fact at 55,000 | clef-flash | 60,032 | 10,555 | yes (0.980) | 0.8 s |\n| Prose, fact at 55,000 | clef | 60,032 | 10,555 | yes (0.996) | 2.0 s |\n| Prose, no fact (control) | clef-flash | 60,000 | 10,547 | no (0.297) | 1.1 s |\n| Prose, no fact (control) | clef | 60,000 | 10,547 | no (0.170) | 2.0 s |\n| Prose, fact at 200,000 | clef-flash | 240,032 | 41,755 | yes (0.978) | 3.0 s |\n| Prose, fact at the end | clef-flash | 300,031 | 52,154 | yes (0.984) | 4.9 s |\n| Prose, fact at the end | clef | 300,031 | 52,154 | yes (0.996) | 11.8 s |\n| Prose, fact at the end | clef-flash | 500,031 | 86,819 | yes (0.985) | 19.2 s |\n| JSON array of digits, fact at end | clef-flash | 115,031 | 115,153 | yes (0.986) | 11.3 s |\n| JSON array of digits, fact at end | clef-flash | 158,031 | 158,153 | yes (0.987) | 30.9 s |\n| JSON array of digits, fact at end |","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Clef Provider Guide","lvl2":"The state window changed on 2026-10-07","lvl3":""}},
5102
- {"objectID":"39c1f7ffec3b0df62b067ce9d778c3752d09cb8fdecce80b4e64028655048470","title":"What NeuroLink refuses before any request","url":"/docs/getting-started/providers/cloudflare-clef#what-neurolink-refuses-before-any-request","content":"| Refused | Limit | Error kind |\n| --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | ------------------------------------- |\n| A state estimated over 16,000 tokens | digits 1 token each, punctuation 0.75, emoji 3, other non-ASCII text 1.5, letters about 4 characters a token | max_tokens_exceeded |\n| More than 64 questions in one decide() | 64 | max_tokens_exceeded |\n| A request body over 256,000 bytes | 256,000 | invalid_request |\n| More than 4 images, a video, or a format other than PNG, JPEG or WebP | | invalid_request |\n| A model name that is not a plain name, such as clef/../x | | invalid_request |\n| A missing token or account id, or a base URL that cannot work | | authentication or invalid_request |\n\nNeuroLink.tryDecide(), which every built-in feature calls, splits a question\nmap at 64 and runs up to four batches at once, so only a direct decide() meets\nthe 64-question refusal.\n\nWhy 16,000.","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Clef Provider Guide","lvl2":"What NeuroLink refuses before any request","lvl3":""}},
5103
- {"objectID":"bb0d1df2801529da652fbd15360879d9b2ccce53dfdf4d825a7a00f4e19d8d15","title":"What is not verified","url":"/docs/getting-started/providers/cloudflare-clef#what-is-not-verified","content":"The status Cloudflare returns for a token without Workers AI permission. No\n such token was available. A 403 is treated as an ordinary invalid_request,\n not authentication, so that if it does mean a missing permission, fixing it\n in the dashboard works at once, without restarting the process.\nAny 5xx other than one 529. Cloudflare answered a single server error, HTTP 529\n with code 5012 (\"Clef inference failed\"), to a 190,153-token state on clef on\n 2026-10-07; the retry and classification of 500, 502, 503 and 504 rest on\n ordinary HTTP conventions.\nWhat a Workers Paid account that has run out of credit gets. Only the Free plan's\n daily allocation running out was seen (HTTP 429, code 4006, 2026-10-05); it is\n not retried. Cloudflare documents a reset at 00:00 UTC, but this account was\n still refused at 02:38 and 04:12 UTC on 2026-10-06 and answered again at\n 07:24 UTC on 2026-10-07, so when the allowance returns here is not verified.\nThe 27B TypeScript, minified-JSON and synthetic Devanagari/emoji cuts; see the\n model coverage above.\nThe rate limit. Only a burst of 60 was tried.\nWhether Cloudflare's service is generally available or in beta.\nWhether the state window (about 2,048 tokens until 2026-10-04, none found by\n 2026-10-07) and the changing request-size limit belong to the hosted service or\n to the model itself. The open weights on Hugging Face\n were not run.\nWhether either limit changes again. The live decide suite carries three canary\n cases that fail with an instruction to re-measure: 19.10 and 19.10b send a\n prose state and a digit array just under NeuroLink's own limit, with a fact at\n the very end, to both models, and fail if the service stops reading below that\n limit; 19.11 checks both sides of the text-only request ceiling on clef-flash.\n None of them notices a service that reads more than the limit allows.","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Clef Provider Guide","lvl2":"What is not verified","lvl3":""}},
5104
+ {"objectID":"39c1f7ffec3b0df62b067ce9d778c3752d09cb8fdecce80b4e64028655048470","title":"What NeuroLink refuses before any request","url":"/docs/getting-started/providers/cloudflare-clef#what-neurolink-refuses-before-any-request","content":"| Refused | Limit | Error kind |\n| --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | ------------------------------------- |\n| A state estimated over 16,000 tokens | digits 1 token each, punctuation 0.75, emoji 3, other non-ASCII text 1.5, letters about 4 characters a token | max_tokens_exceeded |\n| More than 64 questions in one decide() | 64 | max_tokens_exceeded |\n| A request body over 256,000 bytes | 256,000 | invalid_request |\n| clef-flash: text without images over 195,584 characters | 195,584 (clef: 523,264) | max_tokens_exceeded |\n| More than 4 images, a video, or a format other than PNG, JPEG or WebP | | invalid_request |\n| A model name that is not a plain name, such as clef/../x | | invalid_request |\n| A missing token or account id, or a base URL that cannot work | | authentication or invalid_request |","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Clef Provider Guide","lvl2":"What NeuroLink refuses before any request","lvl3":""}},
5105
+ {"objectID":"bb0d1df2801529da652fbd15360879d9b2ccce53dfdf4d825a7a00f4e19d8d15","title":"What is not verified","url":"/docs/getting-started/providers/cloudflare-clef#what-is-not-verified","content":"The status Cloudflare returns for a token without Workers AI permission. No\n such token was available. A 403 is treated as an ordinary invalid_request,\n not authentication, so that if it does mean a missing permission, fixing it\n in the dashboard works at once, without restarting the process.\nAny 5xx other than one 529. Cloudflare answered a single server error, HTTP 529\n with code 5012 (\"Clef inference failed\"), to a 190,153-token state on clef on\n 2026-10-07; the retry and classification of 500, 502, 503 and 504 rest on\n ordinary HTTP conventions.\nWhat a Workers Paid account that has run out of credit gets. Only the Free plan's\n daily allocation running out was seen (HTTP 429, code 4006, 2026-10-05); it is\n not retried. Cloudflare documents a reset at 00:00 UTC, but this account was\n still refused at 02:38 and 04:12 UTC on 2026-10-06 and answered again at\n 07:24 UTC on 2026-10-07, so when the allowance returns here is not verified.\nThe 27B TypeScript, minified-JSON and synthetic Devanagari/emoji cuts; see the\n model coverage above.\nThe rate limit. Only a burst of 60 was tried.\nWhether Cloudflare's service is generally available or in beta.\nWhether the state window (about 2,048 tokens until 2026-10-04, none found by\n 2026-10-07) and the changing request-size limit belong to the hosted service or\n to the model itself. The open weights on Hugging Face\n were not run.\nWhether either limit changes again. The live decide suite carries four canary\n cases that fail with an instruction to re-measure: 19.10 and 19.10b send a\n prose state and a digit array just under NeuroLink's own limit, with a fact at\n the very end, to both models, and fail if the service stops reading below that\n limit; 19.11 and 19.11b check both sides of the text-only request ceiling on\n clef-flash and clef.\n None of them notices a service that reads more than the limit allows.","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Clef Provider Guide","lvl2":"What is not verified","lvl3":""}},
5104
5106
  {"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":""}},
5105
5107
  {"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":""}},
5106
- {"objectID":"ce05a3d9d2ab15b8867c8e721fbfa0f8e1248520e2413765fa7d70bd835e3f85","title":"Troubleshooting","url":"/docs/getting-started/providers/cloudflare-clef#troubleshooting","content":"\"requires the account id\" — set CLOUDFLARE_ACCOUNT_ID or\n credentials.cloudflareClef.accountId.\n\"The state is ~N tokens; Cloudflare's … model reads at most 1500\" — shorten\n the state, or send only the part the question is about. Cloudflare would have\n cut the rest without telling you.\n\"No route for that URI\" — the model name or the base URL is wrong. Clef is\n served as clef and clef-flash, and the base URL must end in /client/v4.\n\"The Cloudflare base URL must use https:// unless it points at this machine\" —\n the override is an http:// URL whose host is not localhost, 127.0.0.1 or\n [::1]. A plain-http request would send the token unencrypted. Use https://,\n or reach the server through a port-forward to localhost.\n\"Cloudflare answered with a redirect\" — the endpoint replied 301, 302, 307 or 308. The provider does not follow it and does not retry. Set the base URL to the\n address the redirect leads to.\nA 429 \"Capacity temporarily exceeded\" — retried for you; if it keeps\n happening, send fewer requests at once.\nA 429 \"you have used up your daily free allocation of 10,000 neurons\" — the\n Free plan's allowance for the day is gone. It is not retried, because nothing\n changes until the allowance returns (Cloudflare documents a reset at 00:00 UTC; on\n this account it came back later, see \"What is not verified\"); upgrade to Workers Paid or wait.\n Built-in features that use Clef as their default fall back as on any failure.\nAn image is refused as \"The request is N bytes; Cloudflare accepts at most\n 256000\" — Cloudflare counts the base64 text of the image, so NeuroLink\n refuses it locally under the retained conservative cap. Resize or compress it\n to well under 190 KB; a 195 KB PNG, which Cloudflare accepted, is about 260,000\n characters in base64 and is refused here.\ndecide() uses Clef although you never chose it — you have the Workers AI\n token and account id set and no other decision provider; see\n When NeuroLink uses it.","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Clef Provider Guide","lvl2":"Troubleshooting","lvl3":""}},
5108
+ {"objectID":"ce05a3d9d2ab15b8867c8e721fbfa0f8e1248520e2413765fa7d70bd835e3f85","title":"Troubleshooting","url":"/docs/getting-started/providers/cloudflare-clef#troubleshooting","content":"\"requires the account id\" — set CLOUDFLARE_ACCOUNT_ID or\n credentials.cloudflareClef.accountId.\n\"The state is ~N tokens; Cloudflare's … model reads at most 1500\" — shorten\n the state, or send only the part the question is about. Cloudflare would have\n cut the rest without telling you.\n\"No route for that URI\" — the model name or the base URL is wrong. Clef is\n served as clef and clef-flash, and the base URL must end in /client/v4.\n\"The Cloudflare base URL must use https:// unless it points at this machine\" —\n the override is an http:// URL whose host is not localhost, 127.0.0.1 or\n [::1]. A plain-http request would send the token unencrypted. Use https://,\n or reach the server through a port-forward to localhost.\n\"Cloudflare answered with a redirect\" — the endpoint replied 301, 302, 307 or 308. The provider does not follow it and does not retry. Set the base URL to the\n address the redirect leads to.\nA 429 \"Capacity temporarily exceeded\" — retried for you; if it keeps\n happening, send fewer requests at once.\nA 429 \"you have used up your daily free allocation of 10,000 neurons\" — the\n Free plan's allowance for the day is gone. It is not retried, because nothing\n changes until the allowance returns (Cloudflare documents a reset at 00:00 UTC; on\n this account it came back later, see \"What is not verified\"); upgrade to Workers Paid or wait.\n Built-in features that use Clef as their default fall back as on any failure.\nAn image is refused as \"The request is N bytes; Cloudflare accepts at most\n 256000\" — that is NeuroLink's own cap on the whole encoded body, base64\n included. Cloudflare's 413 gate does not count the images, so it would take\n more. Resize or compress the image to well under 190 KB; a 195 KB PNG, which\n Cloudflare accepted, is about 260,000 characters in base64 and is refused here.","hierarchy":{"lvl0":"Getting Started","lvl1":"Cloudflare Clef Provider Guide","lvl2":"Troubleshooting","lvl3":""}},
5107
5109
  {"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\nScaleDown 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":""}},
5108
5110
  {"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 sixth of the eight decision\nproviders NeuroLink falls back to: built-in features that call decide() use the\nfirst one configured, in the order TypeSafe, Laya, XOR, SubQ, Perplexity, Clef,\nOpenAI Decisions, then ScaleDown. 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":""}},
5109
5111
  {"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":""}},
@@ -7856,7 +7858,7 @@
7856
7858
  {"objectID":"ce64f640074b8e60ee4bd472c5c1e5a246d0c373e06b5c046eae0db635733ba5","title":"Production Checklist","url":"/docs/guides/server-adapters/fastify#production-checklist","content":"[ ] Configure environment variables securely\n[ ] Set appropriate CORS origins (not *)\n[ ] Enable rate limiting with reasonable limits\n[ ] Add authentication middleware\n[ ] Configure request timeouts\n[ ] Set body size limits\n[ ] Enable compression (@fastify/compress)\n[ ] Add security headers (@fastify/helmet)\n[ ] Configure logging with appropriate level\n[ ] Set up health check monitoring\n[ ] Configure error tracking (Sentry, etc.)\n[ ] Use schema validation for all routes\n[ ] Enable JSON schema compilation caching","hierarchy":{"lvl0":"Guides","lvl1":"Fastify Adapter","lvl2":"Production Checklist","lvl3":""}},
7857
7859
  {"objectID":"96060a0ae3f9dfb112daf783ff1f49d405316b318d40fdb38c9e9b3a3f4dc377","title":"Related Documentation","url":"/docs/guides/server-adapters/fastify#related-documentation","content":"Server Adapters Overview - Getting started with server adapters\nConfiguration Reference - Full configuration options\nHono Adapter - Compare with Hono adapter\nExpress Adapter - Compare with Express adapter\nSecurity Best Practices - Authentication patterns","hierarchy":{"lvl0":"Guides","lvl1":"Fastify Adapter","lvl2":"Related Documentation","lvl3":""}},
7858
7860
  {"objectID":"84a68aab0ea6da1d4500a0e89cffad25af13dfb8f7c11c0466d2a5cc2160f2c2","title":"Additional Resources","url":"/docs/guides/server-adapters/fastify#additional-resources","content":"Fastify Documentation - Official Fastify documentation\nFastify Plugins - Official and community plugins\nFastify Performance - Performance tuning\n\nNeed Help? Join our GitHub Discussions or open an issue.","hierarchy":{"lvl0":"Guides","lvl1":"Fastify Adapter","lvl2":"Additional Resources","lvl3":""}},
7859
- {"objectID":"cd85d95041216458a7ff86a558a33685239f0e7c062584b10c910a1071c70385","title":"Hono Adapter","url":"/docs/guides/server-adapters/hono","content":"Hono Adapter\n\nThe recommended framework for NeuroLink server adapters\n\nHono is a lightweight, ultrafast web framework designed for the edge. It runs on virtually any JavaScript runtime including Node.js, Deno, Bun, Cloudflare Workers, and more.\n\nWhy Hono?\n\n| Feature | Benefit |\n| ----------------------- | ------------------------------------------------------------------------- |\n| Multi-runtime | Deploy to Node.js, Deno, Bun, Cloudflare Workers, Vercel Edge, AWS Lambda |\n| Ultrafast | Minimal overhead, optimized router with RegExpRouter |\n| TypeScript-first | Full type safety out of the box |\n| Tiny footprint | ~14KB minified, no dependencies |\n| Built-in middleware | CORS, compression, ETag, secure headers included |\n| Web Standards | Uses Fetch API, Request/Response objects |\n\nHono is the default and recommended framework for NeuroLink server adapters.\n\nCLI Usage\n\nStart a Hono server via CLI:\n\nQuick Start\n\nInstallation\n\nHono is included with NeuroLink - no additional installation required.\n\nBasic Usage\n\nTest the Server\n\nAccessing the Hono App\n\nFor advanced customization, you can access the underlying Hono instance:\n\nConfiguration Options\n\nFull Configuration Example\n\nMiddleware Integration\n\nUsing NeuroLink Middleware\n\nUsing Hono Built-in Middleware\n\nStreaming Responses\n\nHono has excellent streaming support, which NeuroLink leverages for real-time AI responses:\n\nCustom Streaming Route\n\nError Handling\n\nCustom Error Handler\n\nPerformance Tips\nUse the RegExpRouter (Default)\n\nHono uses RegExpRouter by default, which is the fastest router. No configuration needed.\nEnable Compression\nUse ETag for Caching\nMinimize Middleware Chain\n\nOnly use middleware where needed:\nUse Streaming for Long Responses\n\nAlways use the streaming endpoint for AI generation to avoid timeouts:\n\nEdge Runtime Deployment\n\nCloudflare Workers\n\nVercel Edge Functions\n\nDeno Deploy\n\nTesting\n\nUnit Testing with Hono Test Client\n\nProduction Checklist\n[ ] Configure environment variables securely\n[ ] Set appropriate CORS origins (not *)\n[ ] Enable rate limiting with reasonable limits\n[ ] Add authentication middleware\n[ ] Configure request timeouts\n[ ] Set body size limits\n[ ] Enable compression\n[ ] Add security headers\n[ ] Configure logging with appropriate level\n[ ] Set up health check monitoring\n[ ] Configure error tracking (Sentry, etc.)\n\nRelated Documentation\nServer Adapters Overview - Getting started with server adapters\nConfiguration Reference - Full configuration options\nExpress Adapter - Compare with Express adapter\nSecurity Best Practices - Authentication patterns\nStreaming Guide - Real-time streaming with SSE and NDJSON\n\nAdditional Resources\nHono Documentation - Official Hono documentation\nHono Middleware - Built-in middleware\nHono Examples - Example applications\n\nNeed Help? Join our GitHub Discussions or open an issue.","hierarchy":{"lvl0":"Guides","lvl1":"Hono Adapter","lvl2":"","lvl3":""}},
7861
+ {"objectID":"cd85d95041216458a7ff86a558a33685239f0e7c062584b10c910a1071c70385","title":"Hono Adapter","url":"/docs/guides/server-adapters/hono","content":"Hono Adapter\n\nThe recommended framework for NeuroLink server adapters\n\nHono is a lightweight, ultrafast web framework designed for the edge. It runs on virtually any JavaScript runtime including Node.js, Deno, Bun, Cloudflare Workers, and more.\n\nWhy Hono?\n\n| Feature | Benefit |\n| ----------------------- | ------------------------------------------------------------------------- |\n| Multi-runtime | Deploy to Node.js, Deno, Bun, Cloudflare Workers, Vercel Edge, AWS Lambda |\n| Ultrafast | Minimal overhead, optimized router with RegExpRouter |\n| TypeScript-first | Full type safety out of the box |\n| Tiny footprint | ~14KB minified, no dependencies |\n| Built-in middleware | CORS, compression, ETag, secure headers included |\n| Web Standards | Uses Fetch API, Request/Response objects |\n\nHono is the default and recommended framework for NeuroLink server adapters.\n\nCLI Usage\n\nStart a Hono server via CLI:\n\nQuick Start\n\nInstallation\n\nHono is included with NeuroLink - no additional installation required.\n\nBasic Usage\n\nTest the Server\n\nAccessing the Hono App\n\nFor advanced customization, you can access the underlying Hono instance:\n\nConfiguration Options\n\nFull Configuration Example\n\nRequest body limits\n\nbodyParser.jsonLimit bounds JSON bodies and bodyParser.maxSize bounds url-encoded forms. Both default to 10mb, as on the Express, Fastify and Koa adapters, and raising either one is honoured. Uploads (multipart/form-data, application/octet-stream, audio/*) are bounded by bodyParser.rawMaxSize, which defaults to maxSize when that is set and to 64mb otherwise.\n\nA JSON or url-encoded form body over its limit is answered 413 with error.code set to PAYLOAD_TOO_LARGE, before any middleware or route runs. A declared Content-Length over the limit is refused without reading the body, and a body sent without one is read only as far as the limit. An upload over the limit still reaches its route, which answers in its own wire format.\n\nMiddleware Integration\n\nUsing NeuroLink Middleware\n\nUsing Hono Built-in Middleware\n\nStreaming Responses\n\nHono has excellent streaming support, which NeuroLink leverages for real-time AI responses:\n\nCustom Streaming Route\n\nError Handling\n\nCustom Error Handler\n\nPerformance Tips\nUse the RegExpRouter (Default)\n\nHono uses RegExpRouter by default, which is the fastest router. No configuration needed.\nEnable Compression\nUse ETag for Caching\nMinimize Middleware Chain\n\nOnly use middleware where needed:\nUse Streaming for Long Responses\n\nAlways use the streaming endpoint for AI generation to avoid timeouts:\n\nEdge Runtime Deployment\n\nCloudflare Workers\n\nVercel Edge Functions\n\nDeno Deploy\n\nTesting\n\nUnit Testing with Hono Test Client\n\nProduction Checklist\n[ ] Configure environment variables securely\n[ ] Set appropriate CORS origins (not *)\n[ ] Enable rate limiting with reasonable limits\n[ ] Add authentication middleware\n[ ] Configure request timeouts\n[ ] Set body size limits\n[ ] Enable compression\n[ ] Add security headers\n[ ] Configure logging with appropriate level\n[ ] Set up health check monitoring\n[ ] Configure error tracking (Sentry, etc.)\n\nRelated Documentation\nServer Adapters Overview - Getting started with server adapters\nConfiguration Reference - Full configuration options\nExpress Adapter - Compare with Express adapter\nSecurity Best Practices - Authentication patterns\nStreaming Guide - Real-time streaming with SSE and NDJSON\n\nAdditional Resources\nHono Documentation - Official Hono documentation\nHono Middleware - Built-in middleware\nHono Examples - Example applications\n\nNeed Help? Join our GitHub Discussions or open an issue.","hierarchy":{"lvl0":"Guides","lvl1":"Hono Adapter","lvl2":"","lvl3":""}},
7860
7862
  {"objectID":"4f52a63fa59e73e486b75c6e70853fb82c660686cdf13261394fc63c32c40a66","title":"Hono Adapter","url":"/docs/guides/server-adapters/hono#hono-adapter","content":"The recommended framework for NeuroLink server adapters\n\nHono is a lightweight, ultrafast web framework designed for the edge. It runs on virtually any JavaScript runtime including Node.js, Deno, Bun, Cloudflare Workers, and more.","hierarchy":{"lvl0":"Guides","lvl1":"Hono Adapter","lvl2":"Hono Adapter","lvl3":""}},
7861
7863
  {"objectID":"c53bb661bf4d428d1292350b9eae21f7c2d881f171414cc705135e3e360d3521","title":"Why Hono?","url":"/docs/guides/server-adapters/hono#why-hono","content":"| Feature | Benefit |\n| ----------------------- | ------------------------------------------------------------------------- |\n| Multi-runtime | Deploy to Node.js, Deno, Bun, Cloudflare Workers, Vercel Edge, AWS Lambda |\n| Ultrafast | Minimal overhead, optimized router with RegExpRouter |\n| TypeScript-first | Full type safety out of the box |\n| Tiny footprint | ~14KB minified, no dependencies |\n| Built-in middleware | CORS, compression, ETag, secure headers included |\n| Web Standards | Uses Fetch API, Request/Response objects |\n\nHono is the default and recommended framework for NeuroLink server adapters.","hierarchy":{"lvl0":"Guides","lvl1":"Hono Adapter","lvl2":"Why Hono?","lvl3":""}},
7862
7864
  {"objectID":"4a6a19f4b89aa1306c9c1c381201916f7a706160c87f5e8dbf11e7f2cc60764f","title":"CLI Usage","url":"/docs/guides/server-adapters/hono#cli-usage","content":"Start a Hono server via CLI:","hierarchy":{"lvl0":"Guides","lvl1":"Hono Adapter","lvl2":"CLI Usage","lvl3":""}},
@@ -7865,6 +7867,7 @@
7865
7867
  {"objectID":"ac05717bef2259e66cdf32c6288f05234f2bcfdb7368a47650ed142a0a388a55","title":"Test the Server","url":"/docs/guides/server-adapters/hono#test-the-server","content":"Test the Server","hierarchy":{"lvl0":"Guides","lvl1":"Hono Adapter","lvl2":"Test the Server","lvl3":""}},
7866
7868
  {"objectID":"65a842ab7e90d7989760c8a34c85e7567c556472b5b3d94a0c62ccc93a613156","title":"Accessing the Hono App","url":"/docs/guides/server-adapters/hono#accessing-the-hono-app","content":"For advanced customization, you can access the underlying Hono instance:","hierarchy":{"lvl0":"Guides","lvl1":"Hono Adapter","lvl2":"Accessing the Hono App","lvl3":""}},
7867
7869
  {"objectID":"0f064fccc3e1e74bc76e8e15f3bf58fc0a6fb19c5287de8d9477a3c660a1b562","title":"Full Configuration Example","url":"/docs/guides/server-adapters/hono#full-configuration-example","content":"Full Configuration Example","hierarchy":{"lvl0":"Guides","lvl1":"Hono Adapter","lvl2":"Full Configuration Example","lvl3":""}},
7870
+ {"objectID":"f2750d8ff58dea504fb6e6d82dd41be7772022260c0badf9be197729e5921f1c","title":"Request body limits","url":"/docs/guides/server-adapters/hono#request-body-limits","content":"bodyParser.jsonLimit bounds JSON bodies and bodyParser.maxSize bounds url-encoded forms. Both default to 10mb, as on the Express, Fastify and Koa adapters, and raising either one is honoured. Uploads (multipart/form-data, application/octet-stream, audio/*) are bounded by bodyParser.rawMaxSize, which defaults to maxSize when that is set and to 64mb otherwise.\n\nA JSON or url-encoded form body over its limit is answered 413 with error.code set to PAYLOAD_TOO_LARGE, before any middleware or route runs. A declared Content-Length over the limit is refused without reading the body, and a body sent without one is read only as far as the limit. An upload over the limit still reaches its route, which answers in its own wire format.","hierarchy":{"lvl0":"Guides","lvl1":"Hono Adapter","lvl2":"Request body limits","lvl3":""}},
7868
7871
  {"objectID":"821ac3bdd68d125a2aef04f014beab93f8b62f2148bcece2ccc375cd2d09925b","title":"Using NeuroLink Middleware","url":"/docs/guides/server-adapters/hono#using-neurolink-middleware","content":"Using NeuroLink Middleware","hierarchy":{"lvl0":"Guides","lvl1":"Hono Adapter","lvl2":"Using NeuroLink Middleware","lvl3":""}},
7869
7872
  {"objectID":"354e2b56d0fe0720a8dadeb912ee44e5412ff034874daf270f8c96ce6a011b54","title":"Using Hono Built-in Middleware","url":"/docs/guides/server-adapters/hono#using-hono-built-in-middleware","content":"Using Hono Built-in Middleware","hierarchy":{"lvl0":"Guides","lvl1":"Hono Adapter","lvl2":"Using Hono Built-in Middleware","lvl3":""}},
7870
7873
  {"objectID":"87222251107cdbe1386180da56d88d17b161d2b7b2aafc76f031006fa81fc0dd","title":"Streaming Responses","url":"/docs/guides/server-adapters/hono#streaming-responses","content":"Hono has excellent streaming support, which NeuroLink leverages for real-time AI responses:","hierarchy":{"lvl0":"Guides","lvl1":"Hono Adapter","lvl2":"Streaming Responses","lvl3":""}},
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juspay/neurolink",
3
- "version": "13.8.10",
3
+ "version": "13.8.12",
4
4
  "packageManager": "pnpm@10.15.1",
5
5
  "description": "The pipe layer of an AI nervous system: one interface connecting provider neurons to your application, across three inference types — generate, stream and decide. `decide` returns typed, calibrated judgements from a non-generative model (~400ms, ~$0.00002/call) for routing, tool selection and context budgeting. MCP-native (4 transports), voice TTS/STT/realtime, RAG, agents, memory, compaction, 9 observability exporters. OpenAI · Anthropic · Gemini · Bedrock · Azure · Ollama · TypeSafe Jev and more.",
6
6
  "author": {
@@ -73,7 +73,9 @@
73
73
  "convert:specific": "tsx tools/automation/shellConverter.ts --specific",
74
74
  "// Testing (Continuous Test Suites)": "",
75
75
  "test": "pnpm exec tsx test/continuous-test-suite.ts",
76
- "test:agent-delegation": "pnpm exec tsx test/continuous-test-suite-agent-delegation.ts",
76
+ "test:agent-delegation": "pnpm run test:agent-delegation-offline && pnpm run test:agent-delegation-live",
77
+ "test:agent-delegation-offline": "pnpm exec tsx test/continuous-test-suite-agent-delegation.ts",
78
+ "test:agent-delegation-live": "pnpm exec tsx test/continuous-test-suite-agent-delegation-live.ts",
77
79
  "test:agent-tasks": "pnpm exec tsx test/continuous-test-suite-agent-tasks.ts",
78
80
  "test:agent:session-stream": "pnpm exec tsx test/continuous-test-suite-agent-session-stream.ts",
79
81
  "test:agent:platform-router": "pnpm exec tsx test/continuous-test-suite-agent-platform-router.ts",
@@ -203,12 +205,15 @@
203
205
  "test:rag-html-markup": "pnpm exec tsx test/continuous-test-suite-rag-html-markup.ts",
204
206
  "test:rag-bounds": "pnpm exec tsx test/continuous-test-suite-rag-bounds.ts",
205
207
  "test:skills": "pnpm exec tsx test/continuous-test-suite-skills.ts",
206
- "test:decide": "pnpm exec tsx test/continuous-test-suite-decide.ts",
208
+ "test:decide": "pnpm run test:decide-offline && pnpm run test:decide-live",
209
+ "test:decide-offline": "pnpm exec tsx test/continuous-test-suite-decide.ts",
210
+ "test:decide-live": "pnpm exec tsx test/continuous-test-suite-decide-live.ts",
207
211
  "test:decide-catalog": "pnpm exec tsx test/continuous-test-suite-decide-catalog.ts",
208
212
  "test:agent-mode": "pnpm exec tsx test/continuous-test-suite-agent-mode.ts",
209
213
  "test:servers": "pnpm exec tsx test/continuous-test-suite-servers.ts",
210
214
  "test:server-boundaries": "pnpm exec tsx test/continuous-test-suite-server-boundaries.ts",
211
215
  "test:agent-input-guard": "pnpm exec tsx test/continuous-test-suite-agent-input-guard.ts",
216
+ "test:body-limits": "pnpm exec tsx test/continuous-test-suite-body-limits.ts",
212
217
  "test:websocket-agent-handler": "pnpm exec tsx test/continuous-test-suite-websocket-agent-handler.ts",
213
218
  "test:tool-reliability": "pnpm exec tsx test/continuous-test-suite-tool-reliability.ts",
214
219
  "test:video-abort": "pnpm exec tsx test/continuous-test-suite-video-abort.ts",
@@ -336,7 +341,9 @@
336
341
  "test:office:security": "pnpm exec tsx test/continuous-test-suite-office-security.ts",
337
342
  "test:vision-image-format": "pnpm exec tsx test/continuous-test-suite-vision-image-format.ts",
338
343
  "test:image-exif": "pnpm exec tsx test/continuous-test-suite-image-exif.ts",
339
- "test:model-pool": "pnpm exec tsx test/continuous-test-suite-model-pool.ts",
344
+ "test:model-pool": "pnpm run test:model-pool-offline && pnpm run test:model-pool-live",
345
+ "test:model-pool-offline": "pnpm exec tsx test/continuous-test-suite-model-pool.ts",
346
+ "test:model-pool-live": "pnpm exec tsx test/continuous-test-suite-model-pool-live.ts",
340
347
  "test:agents": "pnpm exec tsx test/continuous-test-suite-agents.ts",
341
348
  "test:classifier-router": "pnpm exec tsx test/continuous-test-suite-classifier-router.ts",
342
349
  "test:vector-chroma": "pnpm exec tsx test/continuous-test-suite-vector-chroma.ts",