@juspay/neurolink 12.43.2 → 12.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +3 -3
- package/README.md +94 -71
- package/dist/browser/neurolink.min.js +408 -408
- package/dist/cli/commands/decide.d.ts +1 -1
- package/dist/cli/commands/decide.js +3 -3
- package/dist/cli/commands/setup.js +2 -1
- package/dist/cli/factories/commandFactory.js +1 -1
- package/dist/constants/enums.d.ts +13 -0
- package/dist/constants/enums.js +14 -0
- package/dist/factories/providerDescriptors.d.ts +8 -2
- package/dist/factories/providerDescriptors.js +75 -5
- package/dist/factories/providerRegistry.js +11 -1
- package/dist/models/manifestRegistry.js +2 -0
- package/dist/models/manifests/perplexityDecider.d.ts +14 -0
- package/dist/models/manifests/perplexityDecider.js +32 -0
- package/dist/providers/anthropic/client.js +20 -6
- package/dist/providers/perplexityDecider.d.ts +50 -0
- package/dist/providers/perplexityDecider.js +373 -0
- package/dist/providers/systemOneDecision.d.ts +12 -0
- package/dist/providers/systemOneDecision.js +48 -4
- package/dist/types/classifierRouter.d.ts +7 -5
- package/dist/types/cli.d.ts +2 -1
- package/dist/types/decision.d.ts +5 -0
- package/dist/types/providers.d.ts +11 -0
- package/dist/utils/modelChoices.js +9 -1
- package/dist/utils/pricing.js +8 -0
- package/dist/utils/providerConfig.d.ts +6 -0
- package/dist/utils/providerConfig.js +18 -0
- package/docs-site/static/search-index.json +83 -59
- package/package.json +3 -1
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*
|
|
10
10
|
* Credentials are env-only here, exactly as every other CLI command: the
|
|
11
11
|
* decision provider reads its own settings (TYPESAFE_API_KEY, LAYA_API_KEY and
|
|
12
|
-
* LAYA_BASE_URL,
|
|
12
|
+
* LAYA_BASE_URL, XOR_API_KEY and XOR_BASE_URL, or PERPLEXITY_API_KEY) itself.
|
|
13
13
|
*/
|
|
14
14
|
import type { CommandModule } from "yargs";
|
|
15
15
|
import type { CliDecideArgs } from "../../types/index.js";
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*
|
|
10
10
|
* Credentials are env-only here, exactly as every other CLI command: the
|
|
11
11
|
* decision provider reads its own settings (TYPESAFE_API_KEY, LAYA_API_KEY and
|
|
12
|
-
* LAYA_BASE_URL,
|
|
12
|
+
* LAYA_BASE_URL, XOR_API_KEY and XOR_BASE_URL, or PERPLEXITY_API_KEY) itself.
|
|
13
13
|
*/
|
|
14
14
|
import chalk from "chalk";
|
|
15
15
|
import ora from "ora";
|
|
@@ -191,7 +191,7 @@ export const decideCommand = {
|
|
|
191
191
|
type: "string",
|
|
192
192
|
array: true,
|
|
193
193
|
nargs: 1,
|
|
194
|
-
describe: "Image for the model to read: a file path or a data: URL. Repeat for several (XOR
|
|
194
|
+
describe: "Image for the model to read: a file path or a data: URL. Repeat for several (XOR and Perplexity take up to 8)",
|
|
195
195
|
})
|
|
196
196
|
.option("video", {
|
|
197
197
|
type: "string",
|
|
@@ -217,7 +217,7 @@ export const decideCommand = {
|
|
|
217
217
|
})
|
|
218
218
|
.example('$0 decide "Refund request for a damaged item" --questions \'{"urgent":{"type":"boolean","instructions":"Is this urgent?"}}\'', "Ask a single yes/no question")
|
|
219
219
|
.example("$0 decide --state-file ticket.json --questions-file questions.json --format json", "Read state and questions from files, emit raw JSON")
|
|
220
|
-
.example('$0 decide "What color is this?" --provider xor --image ./photo.png --questions \'{"color":{"type":"choice","instructions":"What color is the image?","criteria":{"red":"red","blue":"blue"}}}\'', "Ask about an image (XOR
|
|
220
|
+
.example('$0 decide "What color is this?" --provider xor --image ./photo.png --questions \'{"color":{"type":"choice","instructions":"What color is the image?","criteria":{"red":"red","blue":"blue"}}}\'', "Ask about an image (XOR and Perplexity read images)"),
|
|
221
221
|
handler: async (argv) => {
|
|
222
222
|
const outputFormat = argv.format ?? "text";
|
|
223
223
|
// --- Validate before any provider work ---------------------------------
|
|
@@ -20,7 +20,7 @@ import { handleGCPSetup } from "./setup-gcp.js";
|
|
|
20
20
|
import { handleHuggingFaceSetup } from "./setup-huggingface.js";
|
|
21
21
|
import { handleMistralSetup } from "./setup-mistral.js";
|
|
22
22
|
import { PROVIDER_DESCRIPTORS_BY_NAME } from "../../factories/providerDescriptors.js";
|
|
23
|
-
import { createCohereConfig, createDeepSeekConfig, createIdeogramConfig, createJinaConfig, createNvidiaNimConfig, createOpenAICompatibleConfig, createRecraftConfig, createReplicateConfig, createStabilityConfig, createVoyageConfig, createTypeSafeConfig, createLayaConfig, createXorConfig, satisfiesFallbacks, } from "../../utils/providerConfig.js";
|
|
23
|
+
import { createCohereConfig, createDeepSeekConfig, createIdeogramConfig, createJinaConfig, createNvidiaNimConfig, createOpenAICompatibleConfig, createRecraftConfig, createReplicateConfig, createStabilityConfig, createVoyageConfig, createTypeSafeConfig, createLayaConfig, createXorConfig, createPerplexityDeciderConfig, satisfiesFallbacks, } from "../../utils/providerConfig.js";
|
|
24
24
|
import { getCatalogJsonEntries, buildCatalogConfigOptions, } from "../../providers/catalog/loader.js";
|
|
25
25
|
// Provider information database
|
|
26
26
|
const PROVIDERS = [
|
|
@@ -171,6 +171,7 @@ export const EXTRA_PROVIDER_CONFIGS = {
|
|
|
171
171
|
typesafe: createTypeSafeConfig(),
|
|
172
172
|
laya: createLayaConfig(),
|
|
173
173
|
xor: createXorConfig(),
|
|
174
|
+
"perplexity-decider": createPerplexityDeciderConfig(),
|
|
174
175
|
...Object.fromEntries(getCatalogJsonEntries()
|
|
175
176
|
.filter((e) => e.id !== "mistral")
|
|
176
177
|
.map((e) => [e.id, buildCatalogConfigOptions(e)])),
|
|
@@ -616,7 +616,7 @@ export class CLICommandFactory {
|
|
|
616
616
|
},
|
|
617
617
|
classifierStrategy: {
|
|
618
618
|
type: "string",
|
|
619
|
-
description: "Classifier strategy: 'auto' (default — 'jev' when a decision provider is configured, such as TYPESAFE_API_KEY, LAYA_API_KEY with LAYA_BASE_URL,
|
|
619
|
+
description: "Classifier strategy: 'auto' (default — 'jev' when a decision provider is configured, such as TYPESAFE_API_KEY, LAYA_API_KEY with LAYA_BASE_URL, XOR_API_KEY with XOR_BASE_URL, or PERPLEXITY_API_KEY, else 'heuristic'), 'heuristic' (no LLM), 'llm' (a cheap model picks per prompt), or 'jev' (a System One decision model — TypeSafe Jev, Laya, XOR or Perplexity — with calibrated confidence).",
|
|
620
620
|
choices: ["auto", "heuristic", "llm", "jev"],
|
|
621
621
|
alias: "classifier-strategy",
|
|
622
622
|
},
|
|
@@ -109,6 +109,11 @@ export declare enum AIProviderName {
|
|
|
109
109
|
LAYA = "laya",
|
|
110
110
|
/** XOR (Juspay, open weights) — serves the `decide` inference type only. */
|
|
111
111
|
XOR = "xor",
|
|
112
|
+
/**
|
|
113
|
+
* Perplexity Decisions API (`pplx-decider-v1-27b`) — serves the `decide`
|
|
114
|
+
* inference type only. Distinct from `PERPLEXITY`, the Sonar text provider.
|
|
115
|
+
*/
|
|
116
|
+
PERPLEXITY_DECIDER = "perplexity-decider",
|
|
112
117
|
AUTO = "auto"
|
|
113
118
|
}
|
|
114
119
|
/**
|
|
@@ -1764,3 +1769,11 @@ export declare enum LayaModels {
|
|
|
1764
1769
|
export declare enum XorModels {
|
|
1765
1770
|
XOR_1_1 = "xor-1.1"
|
|
1766
1771
|
}
|
|
1772
|
+
/**
|
|
1773
|
+
* Perplexity decision models. Hand-written: the Decisions API is a Tier-3
|
|
1774
|
+
* provider, so it is not in the provider catalog and codegen never touches
|
|
1775
|
+
* this. The API serves one model and answers 400 to a missing or unknown one.
|
|
1776
|
+
*/
|
|
1777
|
+
export declare enum PerplexityDeciderModels {
|
|
1778
|
+
PPLX_DECIDER_V1_27B = "pplx-decider-v1-27b"
|
|
1779
|
+
}
|
package/dist/constants/enums.js
CHANGED
|
@@ -115,6 +115,11 @@ export var AIProviderName;
|
|
|
115
115
|
AIProviderName["LAYA"] = "laya";
|
|
116
116
|
/** XOR (Juspay, open weights) — serves the `decide` inference type only. */
|
|
117
117
|
AIProviderName["XOR"] = "xor";
|
|
118
|
+
/**
|
|
119
|
+
* Perplexity Decisions API (`pplx-decider-v1-27b`) — serves the `decide`
|
|
120
|
+
* inference type only. Distinct from `PERPLEXITY`, the Sonar text provider.
|
|
121
|
+
*/
|
|
122
|
+
AIProviderName["PERPLEXITY_DECIDER"] = "perplexity-decider";
|
|
118
123
|
AIProviderName["AUTO"] = "auto";
|
|
119
124
|
})(AIProviderName || (AIProviderName = {}));
|
|
120
125
|
/**
|
|
@@ -2084,3 +2089,12 @@ export var XorModels;
|
|
|
2084
2089
|
(function (XorModels) {
|
|
2085
2090
|
XorModels["XOR_1_1"] = "xor-1.1";
|
|
2086
2091
|
})(XorModels || (XorModels = {}));
|
|
2092
|
+
/**
|
|
2093
|
+
* Perplexity decision models. Hand-written: the Decisions API is a Tier-3
|
|
2094
|
+
* provider, so it is not in the provider catalog and codegen never touches
|
|
2095
|
+
* this. The API serves one model and answers 400 to a missing or unknown one.
|
|
2096
|
+
*/
|
|
2097
|
+
export var PerplexityDeciderModels;
|
|
2098
|
+
(function (PerplexityDeciderModels) {
|
|
2099
|
+
PerplexityDeciderModels["PPLX_DECIDER_V1_27B"] = "pplx-decider-v1-27b";
|
|
2100
|
+
})(PerplexityDeciderModels || (PerplexityDeciderModels = {}));
|
|
@@ -30,8 +30,14 @@ export declare const DECISION_PROVIDERS: readonly ProviderDescriptor[];
|
|
|
30
30
|
* internal consumer treats as "carry on exactly as before".
|
|
31
31
|
*/
|
|
32
32
|
export declare function resolveDefaultDecisionProvider(credentials?: NeurolinkCredentials): string | undefined;
|
|
33
|
-
/**
|
|
34
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Names of the decision providers that accept images, or, with `video`, the
|
|
35
|
+
* ones that accept video too: a hint that names a provider which would refuse
|
|
36
|
+
* the same request is worse than none.
|
|
37
|
+
*/
|
|
38
|
+
export declare function listMediaDecisionProviders(needs?: {
|
|
39
|
+
video?: boolean;
|
|
40
|
+
}): string[];
|
|
35
41
|
/**
|
|
36
42
|
* The variables that would configure each decision provider, one clause per
|
|
37
43
|
* provider in precedence order, e.g. "TYPESAFE_API_KEY or AI_GATEWAY_API_KEY
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AIProviderName } from "../constants/enums.js";
|
|
2
|
-
import { GoogleAIModels, OpenAIModels, AnthropicModels, VertexModels, OllamaModels, LiteLLMModels, NvidiaNimModels, OpenRouterModels, CohereModels, VoyageModels, TypeSafeModels, LayaModels, XorModels, JinaModels, StabilityModels, IdeogramModels, RecraftModels, ReplicateModels, } from "../constants/enums.js";
|
|
2
|
+
import { GoogleAIModels, OpenAIModels, AnthropicModels, VertexModels, OllamaModels, LiteLLMModels, NvidiaNimModels, OpenRouterModels, CohereModels, VoyageModels, TypeSafeModels, LayaModels, XorModels, PerplexityDeciderModels, JinaModels, StabilityModels, IdeogramModels, RecraftModels, ReplicateModels, } from "../constants/enums.js";
|
|
3
3
|
import { API_KEY_FORMATS } from "../utils/providerConfig.js";
|
|
4
4
|
import { getCatalogJsonEntries, catalogCredentialsKey, catalogEnvVar, } from "../providers/catalog/loader.js";
|
|
5
5
|
import { DEFAULT_INFERENCE_KINDS } from "../types/index.js";
|
|
@@ -451,7 +451,7 @@ const HAND_DESCRIPTORS = [
|
|
|
451
451
|
timeouts: { decideMs: 5000 },
|
|
452
452
|
setupUrl: "https://console.typesafe.ai/keys",
|
|
453
453
|
},
|
|
454
|
-
// Laya MUST stay after TypeSafe, and
|
|
454
|
+
// Laya MUST stay after TypeSafe, XOR after Laya, and Perplexity after XOR.
|
|
455
455
|
// resolveDefaultDecisionProvider() returns the first configured
|
|
456
456
|
// DECISION_PROVIDERS entry, in this order, so a host configured for several
|
|
457
457
|
// keeps Jev for every built-in consumer and reaches the others only by
|
|
@@ -543,6 +543,69 @@ const HAND_DESCRIPTORS = [
|
|
|
543
543
|
},
|
|
544
544
|
setupUrl: "https://huggingface.co/juspay/xor",
|
|
545
545
|
},
|
|
546
|
+
{
|
|
547
|
+
name: AIProviderName.PERPLEXITY_DECIDER,
|
|
548
|
+
aliases: [],
|
|
549
|
+
credentialsKey: "perplexityDecider",
|
|
550
|
+
envVars: {
|
|
551
|
+
// The same key the `perplexity` text provider reads, so an ambient
|
|
552
|
+
// PERPLEXITY_API_KEY configures this provider too. It sits after XOR in
|
|
553
|
+
// this list, which is what keeps that from displacing any other decision
|
|
554
|
+
// provider a host has configured.
|
|
555
|
+
apiKey: "PERPLEXITY_API_KEY",
|
|
556
|
+
// Optional: the API is hosted at a public endpoint, so a key alone is
|
|
557
|
+
// enough and there is no extraRequired.
|
|
558
|
+
baseURL: "PERPLEXITY_DECIDER_BASE_URL",
|
|
559
|
+
model: "PERPLEXITY_DECIDER_MODEL",
|
|
560
|
+
},
|
|
561
|
+
defaultModel: PerplexityDeciderModels.PPLX_DECIDER_V1_27B,
|
|
562
|
+
// Serves only `decide`, like the other decision providers — the one
|
|
563
|
+
// declaration that keeps it out of every generation code path, and out of
|
|
564
|
+
// the way of the `perplexity` text provider.
|
|
565
|
+
inferenceKinds: ["decide"],
|
|
566
|
+
toolSupport: "none",
|
|
567
|
+
localRuntime: false,
|
|
568
|
+
healthCheck: "env-only",
|
|
569
|
+
// Deliberately NO autoSelectPriority / autoSelectPreference /
|
|
570
|
+
// defaultHealthSweepPriority, for the same reason as TypeSafe above.
|
|
571
|
+
//
|
|
572
|
+
// Measured live: 4s at 65,000 input tokens, 10s at 146,000 and 23s at
|
|
573
|
+
// 251,000 (faster than linear: about 17,000, 15,000 and 11,000 tokens a
|
|
574
|
+
// second), plus about 65 ms for each question after the first (128 minimal
|
|
575
|
+
// questions took 8.9s). 10s is the allowance for the state and covers every
|
|
576
|
+
// one the window below admits except log text or number arrays close to it;
|
|
577
|
+
// the provider adds 100 ms a question on top, so a request at the
|
|
578
|
+
// 128-question cap waits about 22.8s. A larger state passes a per-call
|
|
579
|
+
// `timeoutMs`.
|
|
580
|
+
timeouts: { decideMs: 10_000 },
|
|
581
|
+
// The server reads 262,144 input tokens in all and answers an over-long
|
|
582
|
+
// request with an explicit 400, never a silent truncation. The state and the
|
|
583
|
+
// questions were measured to count toward it; images are billed as input
|
|
584
|
+
// tokens and presumably count too. The window below is deliberately lower: a
|
|
585
|
+
// state of 100,000 tokens takes about 7s of the 10s above (interpolated from
|
|
586
|
+
// those points), and a much larger one would outlast it and be retried into
|
|
587
|
+
// the same wait. The estimate is about four characters per token. Measured
|
|
588
|
+
// on 40,000-character samples: English prose 4.3, TypeScript 3.8, a minified
|
|
589
|
+
// JSON catalog 3.4, log lines with timestamps and ids 1.35 and arrays of
|
|
590
|
+
// numbers 1.2. Only the last two run low enough to pass the window and still
|
|
591
|
+
// be refused by the server; JSON is under-counted by about 13%. A request
|
|
592
|
+
// over the window fails locally as max_tokens_exceeded, which every consumer
|
|
593
|
+
// treats as "carry on as before". 128 questions is the documented cap,
|
|
594
|
+
// confirmed live.
|
|
595
|
+
// Non-ASCII text is charged at the measured rate for CJK (0.46 tokens per
|
|
596
|
+
// code point) and Devanagari (0.44), not for emoji (2.6), because an
|
|
597
|
+
// over-charge silently shuts every non-Latin caller out while an
|
|
598
|
+
// under-charge is caught by that 400.
|
|
599
|
+
decisionLimits: {
|
|
600
|
+
maxStateTokens: 100_000,
|
|
601
|
+
maxQuestions: 128,
|
|
602
|
+
nonAsciiTokensPerChar: 0.5,
|
|
603
|
+
// Images only; the API has no video input. A ninth image in one request
|
|
604
|
+
// is refused with a 400, and the 32 MiB body is the documented cap.
|
|
605
|
+
media: { maxImages: 8, video: false, maxRequestBytes: 32 * 1024 * 1024 },
|
|
606
|
+
},
|
|
607
|
+
setupUrl: "https://console.perplexity.ai",
|
|
608
|
+
},
|
|
546
609
|
];
|
|
547
610
|
/**
|
|
548
611
|
* Builds a ProviderDescriptor for every JSON-catalog provider. Every field
|
|
@@ -678,9 +741,16 @@ function isDecisionProviderConfigured(descriptor, credentials) {
|
|
|
678
741
|
export function resolveDefaultDecisionProvider(credentials) {
|
|
679
742
|
return DECISION_PROVIDERS.find((descriptor) => isDecisionProviderConfigured(descriptor, credentials))?.name;
|
|
680
743
|
}
|
|
681
|
-
/**
|
|
682
|
-
|
|
683
|
-
|
|
744
|
+
/**
|
|
745
|
+
* Names of the decision providers that accept images, or, with `video`, the
|
|
746
|
+
* ones that accept video too: a hint that names a provider which would refuse
|
|
747
|
+
* the same request is worse than none.
|
|
748
|
+
*/
|
|
749
|
+
export function listMediaDecisionProviders(needs) {
|
|
750
|
+
return DECISION_PROVIDERS.filter((descriptor) => {
|
|
751
|
+
const media = descriptor.decisionLimits?.media;
|
|
752
|
+
return media !== undefined && (!needs?.video || media.video);
|
|
753
|
+
}).map((descriptor) => descriptor.name);
|
|
684
754
|
}
|
|
685
755
|
/**
|
|
686
756
|
* The variables that would configure each decision provider, one clause per
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ProviderFactory } from "./providerFactory.js";
|
|
2
2
|
import { logger } from "../utils/logger.js";
|
|
3
|
-
import { AIProviderName, GoogleAIModels, OpenAIModels, AnthropicModels, VertexModels, OllamaModels, LiteLLMModels, NvidiaNimModels, OpenRouterModels, CohereModels, VoyageModels, JinaModels, StabilityModels, IdeogramModels, RecraftModels, TypeSafeModels, LayaModels, XorModels, ReplicateModels, } from "../constants/enums.js";
|
|
3
|
+
import { AIProviderName, GoogleAIModels, OpenAIModels, AnthropicModels, VertexModels, OllamaModels, LiteLLMModels, NvidiaNimModels, OpenRouterModels, CohereModels, VoyageModels, JinaModels, StabilityModels, IdeogramModels, RecraftModels, TypeSafeModels, LayaModels, XorModels, PerplexityDeciderModels, ReplicateModels, } from "../constants/enums.js";
|
|
4
4
|
import { PROVIDER_DESCRIPTORS_BY_NAME } from "./providerDescriptors.js";
|
|
5
5
|
import { OPENAI_COMPAT_CATALOG } from "../providers/openaiCompatCatalog.js";
|
|
6
6
|
import { providerChoicesFor } from "./mediaHandlerCatalog.js";
|
|
@@ -250,6 +250,16 @@ export class ProviderRegistry {
|
|
|
250
250
|
const { XorProvider } = await import("../providers/xor.js");
|
|
251
251
|
return new XorProvider(modelName, sdk, undefined, xorCreds);
|
|
252
252
|
}, process.env.XOR_MODEL || XorModels.XOR_1_1, [], PROVIDER_DESCRIPTORS_BY_NAME.get(AIProviderName.XOR));
|
|
253
|
+
// Register the Perplexity Decisions API — a `decide` provider reached at
|
|
254
|
+
// Perplexity's public endpoint. Its descriptor declares inferenceKinds:
|
|
255
|
+
// ["decide"], so nothing in the generation fallback chain can reach it,
|
|
256
|
+
// and it is registered apart from the `perplexity` text provider.
|
|
257
|
+
ProviderFactory.registerProvider(AIProviderName.PERPLEXITY_DECIDER, async (modelName, _providerName, sdk, _region, credentials) => {
|
|
258
|
+
const perplexityDeciderCreds = credentials;
|
|
259
|
+
const { PerplexityDeciderProvider } = await import("../providers/perplexityDecider.js");
|
|
260
|
+
return new PerplexityDeciderProvider(modelName, sdk, undefined, perplexityDeciderCreds);
|
|
261
|
+
}, process.env.PERPLEXITY_DECIDER_MODEL ||
|
|
262
|
+
PerplexityDeciderModels.PPLX_DECIDER_V1_27B, [], PROVIDER_DESCRIPTORS_BY_NAME.get(AIProviderName.PERPLEXITY_DECIDER));
|
|
253
263
|
logger.debug("All AI providers registered successfully");
|
|
254
264
|
// ===== MEDIA HANDLER REGISTRATION =====
|
|
255
265
|
// Single registration path (Task 11): each ecosystem barrel (voice,
|
|
@@ -22,6 +22,7 @@ import { groqManifest } from "./manifests/groq.js";
|
|
|
22
22
|
import { typesafeManifest } from "./manifests/typesafe.js";
|
|
23
23
|
import { layaManifest } from "./manifests/laya.js";
|
|
24
24
|
import { xorManifest } from "./manifests/xor.js";
|
|
25
|
+
import { perplexityDeciderManifest } from "./manifests/perplexityDecider.js";
|
|
25
26
|
import { cohereManifest } from "./manifests/cohere.js";
|
|
26
27
|
import { togetherAiManifest } from "./manifests/together-ai.js";
|
|
27
28
|
import { fireworksManifest } from "./manifests/fireworks.js";
|
|
@@ -122,6 +123,7 @@ export const MANIFEST_REGISTRY = {
|
|
|
122
123
|
typesafe: typesafeManifest,
|
|
123
124
|
laya: layaManifest,
|
|
124
125
|
xor: xorManifest,
|
|
126
|
+
"perplexity-decider": perplexityDeciderManifest,
|
|
125
127
|
cerebras: catalogManifest("cerebras"),
|
|
126
128
|
sambanova: catalogManifest("sambanova"),
|
|
127
129
|
cohere: cohereManifest,
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ProviderModelManifest } from "../../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Perplexity Decisions API — the `decide` inference type, not text generation,
|
|
4
|
+
* and not the Sonar models of the `perplexity` text provider.
|
|
5
|
+
*
|
|
6
|
+
* `contextWindow` is the documented ceiling on input tokens per request,
|
|
7
|
+
* shared by the state, every question and every image. `vision` describes
|
|
8
|
+
* `generate()` input, which this provider does not serve; its image input is
|
|
9
|
+
* `DecisionRequest.images`.
|
|
10
|
+
*
|
|
11
|
+
* `maxOutputTokens` is required by the manifest type but has no honest value
|
|
12
|
+
* for a model that emits no text, so a small non-zero figure is used.
|
|
13
|
+
*/
|
|
14
|
+
export declare const perplexityDeciderManifest: ProviderModelManifest;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Perplexity Decisions API — the `decide` inference type, not text generation,
|
|
3
|
+
* and not the Sonar models of the `perplexity` text provider.
|
|
4
|
+
*
|
|
5
|
+
* `contextWindow` is the documented ceiling on input tokens per request,
|
|
6
|
+
* shared by the state, every question and every image. `vision` describes
|
|
7
|
+
* `generate()` input, which this provider does not serve; its image input is
|
|
8
|
+
* `DecisionRequest.images`.
|
|
9
|
+
*
|
|
10
|
+
* `maxOutputTokens` is required by the manifest type but has no honest value
|
|
11
|
+
* for a model that emits no text, so a small non-zero figure is used.
|
|
12
|
+
*/
|
|
13
|
+
export const perplexityDeciderManifest = {
|
|
14
|
+
defaultContextWindow: 262_144,
|
|
15
|
+
models: {
|
|
16
|
+
_default: {
|
|
17
|
+
aliases: [],
|
|
18
|
+
contextWindow: 262_144,
|
|
19
|
+
maxOutputTokens: 256,
|
|
20
|
+
vision: false,
|
|
21
|
+
functionCalling: false,
|
|
22
|
+
},
|
|
23
|
+
"pplx-decider-v1-27b": {
|
|
24
|
+
aliases: [],
|
|
25
|
+
displayName: "Perplexity Decider v1 27B",
|
|
26
|
+
contextWindow: 262_144,
|
|
27
|
+
maxOutputTokens: 256,
|
|
28
|
+
vision: false,
|
|
29
|
+
functionCalling: false,
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
};
|
|
@@ -1153,6 +1153,10 @@ export class AnthropicProvider extends BaseProvider {
|
|
|
1153
1153
|
}
|
|
1154
1154
|
// Extended thinking passthrough (providerOptions.anthropic.thinking).
|
|
1155
1155
|
const thinking = options.providerOptions?.anthropic?.thinking;
|
|
1156
|
+
// `disabled` is sent so a model that thinks by default (claude-sonnet-5
|
|
1157
|
+
// does, unasked) is told not to, but it fixes nothing about sampling: only a
|
|
1158
|
+
// block that turns thinking ON makes Anthropic reject temperature.
|
|
1159
|
+
const thinkingOn = thinking?.type === "enabled";
|
|
1156
1160
|
// Close the stable prefix with a breakpoint on the last tool. The
|
|
1157
1161
|
// stream path does the same, just before its own marker count.
|
|
1158
1162
|
tools = withLastToolCacheBreakpoint(tools);
|
|
@@ -1184,7 +1188,7 @@ export class AnthropicProvider extends BaseProvider {
|
|
|
1184
1188
|
}, "anthropic.doGenerate");
|
|
1185
1189
|
// Dropping a caller's explicit sampling parameters is exactly the
|
|
1186
1190
|
// kind of silent discard this change fixes elsewhere, so say so.
|
|
1187
|
-
if (
|
|
1191
|
+
if (thinkingOn &&
|
|
1188
1192
|
(samplingParams.temperature !== undefined ||
|
|
1189
1193
|
samplingParams.topP !== undefined)) {
|
|
1190
1194
|
logger.debug("[anthropic] extended thinking is enabled, so temperature/top_p are omitted — Anthropic rejects any temperature but 1 while thinking is set");
|
|
@@ -1200,10 +1204,10 @@ export class AnthropicProvider extends BaseProvider {
|
|
|
1200
1204
|
// forwarding it alongside thinking turns a call that used to work
|
|
1201
1205
|
// into a 400. Drop the sampling knobs for exactly those turns and
|
|
1202
1206
|
// let Anthropic's thinking defaults stand.
|
|
1203
|
-
...(!
|
|
1207
|
+
...(!thinkingOn && samplingParams.temperature !== undefined
|
|
1204
1208
|
? { temperature: samplingParams.temperature }
|
|
1205
1209
|
: {}),
|
|
1206
|
-
...(!
|
|
1210
|
+
...(!thinkingOn && samplingParams.topP !== undefined
|
|
1207
1211
|
? { top_p: samplingParams.topP }
|
|
1208
1212
|
: {}),
|
|
1209
1213
|
...(options.stopSequences && options.stopSequences.length > 0
|
|
@@ -1534,6 +1538,12 @@ export class AnthropicProvider extends BaseProvider {
|
|
|
1534
1538
|
budget_tokens: options.thinkingConfig.budgetTokens,
|
|
1535
1539
|
};
|
|
1536
1540
|
}
|
|
1541
|
+
else if (options.thinkingConfig?.type === "disabled") {
|
|
1542
|
+
// Without this the request carries no `thinking` field at all, which on
|
|
1543
|
+
// a model that thinks by default means "think" — the explicit
|
|
1544
|
+
// `type: "disabled"` the type already offered was silently dropped.
|
|
1545
|
+
anthropicNamespace.thinking = { type: "disabled" };
|
|
1546
|
+
}
|
|
1537
1547
|
// The per-call `timeout` keeps its per-MODEL-CALL meaning once
|
|
1538
1548
|
// `turnTimeoutMs` owns the whole-turn deadline, and it reaches the model
|
|
1539
1549
|
// layer only through providerOptions.neurolink. Without it each step fell
|
|
@@ -1751,7 +1761,11 @@ export class AnthropicProvider extends BaseProvider {
|
|
|
1751
1761
|
type: "enabled",
|
|
1752
1762
|
budget_tokens: options.thinkingConfig.budgetTokens,
|
|
1753
1763
|
}
|
|
1754
|
-
:
|
|
1764
|
+
: options.thinkingConfig?.type === "disabled"
|
|
1765
|
+
? { type: "disabled" }
|
|
1766
|
+
: undefined;
|
|
1767
|
+
// See the generate path: `disabled` is sent, but only ON constrains sampling.
|
|
1768
|
+
const thinkingOn = thinking?.type === "enabled";
|
|
1755
1769
|
// Wrap the native stream in an OTel span to capture provider-level
|
|
1756
1770
|
// latency and token usage (same span name as the pre-migration path so
|
|
1757
1771
|
// dashboards stay continuous).
|
|
@@ -1956,7 +1970,7 @@ export class AnthropicProvider extends BaseProvider {
|
|
|
1956
1970
|
const streamSamplingParams = resolveSamplingParams("anthropic", modelId, options.temperature !== undefined && options.temperature !== null
|
|
1957
1971
|
? { temperature: options.temperature }
|
|
1958
1972
|
: {}, "anthropic.executeStream");
|
|
1959
|
-
if (
|
|
1973
|
+
if (thinkingOn && streamSamplingParams.temperature !== undefined) {
|
|
1960
1974
|
logger.debug("[anthropic] extended thinking is enabled, so temperature is omitted on the stream path — Anthropic rejects any temperature but 1 while thinking is set");
|
|
1961
1975
|
}
|
|
1962
1976
|
return {
|
|
@@ -1970,7 +1984,7 @@ export class AnthropicProvider extends BaseProvider {
|
|
|
1970
1984
|
...(payload.system ? { system: payload.system } : {}),
|
|
1971
1985
|
// Same constraint on the streaming path: a temperature alongside
|
|
1972
1986
|
// `thinking` is rejected outright.
|
|
1973
|
-
...(!
|
|
1987
|
+
...(!thinkingOn && streamSamplingParams.temperature !== undefined
|
|
1974
1988
|
? { temperature: streamSamplingParams.temperature }
|
|
1975
1989
|
: {}),
|
|
1976
1990
|
...(cachedTools && cachedTools.length > 0
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { DecisionError, DecisionPreparedMedia, DecisionState, NeurolinkCredentials } from "../types/index.js";
|
|
2
|
+
import { SystemOneDecisionProvider } from "./systemOneDecision.js";
|
|
3
|
+
/**
|
|
4
|
+
* Perplexity Provider — the `decide` inference type only.
|
|
5
|
+
*
|
|
6
|
+
* `pplx-decider-v1-27b` answers the same typed `noul` / `choice` / `score`
|
|
7
|
+
* questions as the other decision providers, in one batched pass, and also reads
|
|
8
|
+
* images. It is a hosted API with a public endpoint, so unlike the self-hosted
|
|
9
|
+
* providers it needs only a key. The request loop, retries, auth circuit
|
|
10
|
+
* breaker and answer parsing are shared with every decision provider in
|
|
11
|
+
* {@link SystemOneDecisionProvider}.
|
|
12
|
+
*
|
|
13
|
+
* The key is the same `PERPLEXITY_API_KEY` the Sonar text provider reads, so a
|
|
14
|
+
* host that has configured that provider has also configured this one.
|
|
15
|
+
*
|
|
16
|
+
* @see https://docs.perplexity.ai/api-reference/decisions-post
|
|
17
|
+
*/
|
|
18
|
+
export declare class PerplexityDeciderProvider extends SystemOneDecisionProvider {
|
|
19
|
+
private readonly apiKey;
|
|
20
|
+
private readonly baseURL;
|
|
21
|
+
constructor(modelName?: string, sdk?: unknown, _region?: string, credentials?: NeurolinkCredentials["perplexityDecider"]);
|
|
22
|
+
protected getDefaultModel(): string;
|
|
23
|
+
protected vendorLabel(): string;
|
|
24
|
+
protected vendorDisplayName(): string;
|
|
25
|
+
protected decisionApiKey(): string;
|
|
26
|
+
protected missingKeyMessage(): string;
|
|
27
|
+
protected missingConfigMessage(): string | undefined;
|
|
28
|
+
protected decisionEndpoint(): string;
|
|
29
|
+
protected decisionHeaders(): Record<string, string>;
|
|
30
|
+
/**
|
|
31
|
+
* `model` is always sent: the API answers 400 to a request that names none.
|
|
32
|
+
* Images travel inside `state`, which becomes an array of the caller's state
|
|
33
|
+
* followed by one OpenAI-style `image_url` part per image; the API has no
|
|
34
|
+
* separate images field and rejects unknown ones.
|
|
35
|
+
*/
|
|
36
|
+
protected buildDecisionBody(state: DecisionState, questions: Record<string, Record<string, unknown>>, model: string, media?: DecisionPreparedMedia): Record<string, unknown>;
|
|
37
|
+
protected parseDecisionError(status: number, payload: unknown, requestId: string | undefined): DecisionError;
|
|
38
|
+
/**
|
|
39
|
+
* A 401, a 404 and a 504 carry no request id, so this is undefined for them.
|
|
40
|
+
*/
|
|
41
|
+
protected readRequestId(headers: Headers): string | undefined;
|
|
42
|
+
protected defaultTimeoutMs(questionCount: number): number | undefined;
|
|
43
|
+
/**
|
|
44
|
+
* `Retry-After` is whole seconds on a 429, or an HTTP date. Anything else, a
|
|
45
|
+
* zero and a date already past all read as undefined, so the retry takes the
|
|
46
|
+
* default backoff instead of going out at once. `Number()` is not used: it
|
|
47
|
+
* reads "0x10" as 16 and "1e3" as 1,000.
|
|
48
|
+
*/
|
|
49
|
+
protected readRetryAfterMs(headers: Headers): number | undefined;
|
|
50
|
+
}
|