@juspay/neurolink 12.43.3 → 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.
@@ -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, or XOR_API_KEY and XOR_BASE_URL) itself.
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, or XOR_API_KEY and XOR_BASE_URL) itself.
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 takes up to 8)",
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 only)"),
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, or XOR_API_KEY with XOR_BASE_URL, else 'heuristic'), 'heuristic' (no LLM), 'llm' (a cheap model picks per prompt), or 'jev' (a System One decision model — TypeSafe Jev, Laya or XOR — with calibrated confidence).",
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
+ }
@@ -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
- /** Names of the decision providers that accept images or video. */
34
- export declare function listMediaDecisionProviders(): string[];
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 XOR after Laya.
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
- /** Names of the decision providers that accept images or video. */
682
- export function listMediaDecisionProviders() {
683
- return DECISION_PROVIDERS.filter((descriptor) => descriptor.decisionLimits?.media !== undefined).map((descriptor) => descriptor.name);
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
+ };
@@ -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
+ }