@juspay/neurolink 12.46.1 → 12.47.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 +75 -50
- package/dist/browser/neurolink.min.js +409 -409
- package/dist/cli/commands/decide.js +2 -2
- package/dist/cli/commands/setup.js +2 -1
- package/dist/cli/factories/commandFactory.js +1 -1
- package/dist/constants/enums.d.ts +16 -0
- package/dist/constants/enums.js +17 -0
- package/dist/factories/providerDescriptors.js +84 -5
- package/dist/factories/providerRegistry.js +10 -1
- package/dist/models/manifestRegistry.js +2 -0
- package/dist/models/manifests/cloudflareClef.d.ts +16 -0
- package/dist/models/manifests/cloudflareClef.js +42 -0
- package/dist/providers/cloudflareClef.d.ts +52 -0
- package/dist/providers/cloudflareClef.js +331 -0
- package/dist/providers/systemOneDecision.d.ts +12 -1
- package/dist/providers/systemOneDecision.js +70 -18
- package/dist/types/decision.d.ts +22 -0
- package/dist/types/providers.d.ts +15 -0
- package/dist/utils/modelChoices.js +13 -1
- package/dist/utils/pricing.js +12 -0
- package/dist/utils/providerConfig.d.ts +7 -0
- package/dist/utils/providerConfig.js +19 -0
- package/docs-site/static/search-index.json +78 -56
- package/package.json +2 -1
|
@@ -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 and Perplexity take 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, Cloudflare Clef up to 4)",
|
|
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 and
|
|
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, Perplexity and Cloudflare Clef 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, createPerplexityDeciderConfig, satisfiesFallbacks, } from "../../utils/providerConfig.js";
|
|
23
|
+
import { createCohereConfig, createDeepSeekConfig, createIdeogramConfig, createJinaConfig, createNvidiaNimConfig, createOpenAICompatibleConfig, createRecraftConfig, createReplicateConfig, createStabilityConfig, createVoyageConfig, createTypeSafeConfig, createLayaConfig, createXorConfig, createPerplexityDeciderConfig, createCloudflareClefConfig, satisfiesFallbacks, } from "../../utils/providerConfig.js";
|
|
24
24
|
import { getCatalogJsonEntries, buildCatalogConfigOptions, } from "../../providers/catalog/loader.js";
|
|
25
25
|
// Provider information database
|
|
26
26
|
const PROVIDERS = [
|
|
@@ -172,6 +172,7 @@ export const EXTRA_PROVIDER_CONFIGS = {
|
|
|
172
172
|
laya: createLayaConfig(),
|
|
173
173
|
xor: createXorConfig(),
|
|
174
174
|
"perplexity-decider": createPerplexityDeciderConfig(),
|
|
175
|
+
"cloudflare-clef": createCloudflareClefConfig(),
|
|
175
176
|
...Object.fromEntries(getCatalogJsonEntries()
|
|
176
177
|
.filter((e) => e.id !== "mistral")
|
|
177
178
|
.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, XOR_API_KEY with XOR_BASE_URL, or
|
|
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, PERPLEXITY_API_KEY, or CLOUDFLARE_API_KEY with CLOUDFLARE_ACCOUNT_ID, else 'heuristic'), 'heuristic' (no LLM), 'llm' (a cheap model picks per prompt), or 'jev' (a System One decision model — TypeSafe Jev, Laya, XOR, Perplexity or Cloudflare Clef — with calibrated confidence).",
|
|
620
620
|
choices: ["auto", "heuristic", "llm", "jev"],
|
|
621
621
|
alias: "classifier-strategy",
|
|
622
622
|
},
|
|
@@ -115,6 +115,12 @@ export declare enum AIProviderName {
|
|
|
115
115
|
* inference type only. Distinct from `PERPLEXITY`, the Sonar text provider.
|
|
116
116
|
*/
|
|
117
117
|
PERPLEXITY_DECIDER = "perplexity-decider",
|
|
118
|
+
/**
|
|
119
|
+
* Cloudflare Clef (`@cf/cloudflare/clef`, `@cf/cloudflare/clef-flash`) on
|
|
120
|
+
* Workers AI — serves the `decide` inference type only. Distinct from
|
|
121
|
+
* `CLOUDFLARE`, the Workers AI text provider.
|
|
122
|
+
*/
|
|
123
|
+
CLOUDFLARE_CLEF = "cloudflare-clef",
|
|
118
124
|
AUTO = "auto"
|
|
119
125
|
}
|
|
120
126
|
/**
|
|
@@ -1781,3 +1787,13 @@ export declare enum XorModels {
|
|
|
1781
1787
|
export declare enum PerplexityDeciderModels {
|
|
1782
1788
|
PPLX_DECIDER_V1_27B = "pplx-decider-v1-27b"
|
|
1783
1789
|
}
|
|
1790
|
+
/**
|
|
1791
|
+
* Cloudflare Clef decision models, named as the Workers AI API names them in
|
|
1792
|
+
* the request body (the path adds the `@cf/cloudflare/` prefix). Hand-written:
|
|
1793
|
+
* Clef is a Tier-3 provider, so it is not in the provider catalog and codegen
|
|
1794
|
+
* never touches this. `CLEF` is the 27B model, `CLEF_FLASH` the 9B one.
|
|
1795
|
+
*/
|
|
1796
|
+
export declare enum CloudflareClefModels {
|
|
1797
|
+
CLEF = "clef",
|
|
1798
|
+
CLEF_FLASH = "clef-flash"
|
|
1799
|
+
}
|
package/dist/constants/enums.js
CHANGED
|
@@ -121,6 +121,12 @@ export var AIProviderName;
|
|
|
121
121
|
* inference type only. Distinct from `PERPLEXITY`, the Sonar text provider.
|
|
122
122
|
*/
|
|
123
123
|
AIProviderName["PERPLEXITY_DECIDER"] = "perplexity-decider";
|
|
124
|
+
/**
|
|
125
|
+
* Cloudflare Clef (`@cf/cloudflare/clef`, `@cf/cloudflare/clef-flash`) on
|
|
126
|
+
* Workers AI — serves the `decide` inference type only. Distinct from
|
|
127
|
+
* `CLOUDFLARE`, the Workers AI text provider.
|
|
128
|
+
*/
|
|
129
|
+
AIProviderName["CLOUDFLARE_CLEF"] = "cloudflare-clef";
|
|
124
130
|
AIProviderName["AUTO"] = "auto";
|
|
125
131
|
})(AIProviderName || (AIProviderName = {}));
|
|
126
132
|
/**
|
|
@@ -2103,3 +2109,14 @@ export var PerplexityDeciderModels;
|
|
|
2103
2109
|
(function (PerplexityDeciderModels) {
|
|
2104
2110
|
PerplexityDeciderModels["PPLX_DECIDER_V1_27B"] = "pplx-decider-v1-27b";
|
|
2105
2111
|
})(PerplexityDeciderModels || (PerplexityDeciderModels = {}));
|
|
2112
|
+
/**
|
|
2113
|
+
* Cloudflare Clef decision models, named as the Workers AI API names them in
|
|
2114
|
+
* the request body (the path adds the `@cf/cloudflare/` prefix). Hand-written:
|
|
2115
|
+
* Clef is a Tier-3 provider, so it is not in the provider catalog and codegen
|
|
2116
|
+
* never touches this. `CLEF` is the 27B model, `CLEF_FLASH` the 9B one.
|
|
2117
|
+
*/
|
|
2118
|
+
export var CloudflareClefModels;
|
|
2119
|
+
(function (CloudflareClefModels) {
|
|
2120
|
+
CloudflareClefModels["CLEF"] = "clef";
|
|
2121
|
+
CloudflareClefModels["CLEF_FLASH"] = "clef-flash";
|
|
2122
|
+
})(CloudflareClefModels || (CloudflareClefModels = {}));
|
|
@@ -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, PerplexityDeciderModels, 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, CloudflareClefModels, 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,8 @@ const HAND_DESCRIPTORS = [
|
|
|
451
451
|
timeouts: { decideMs: 5000 },
|
|
452
452
|
setupUrl: "https://console.typesafe.ai/keys",
|
|
453
453
|
},
|
|
454
|
-
// Laya MUST stay after TypeSafe, XOR after Laya,
|
|
454
|
+
// Laya MUST stay after TypeSafe, XOR after Laya, Perplexity after XOR, and
|
|
455
|
+
// Cloudflare Clef after Perplexity.
|
|
455
456
|
// resolveDefaultDecisionProvider() returns the first configured
|
|
456
457
|
// DECISION_PROVIDERS entry, in this order, so a host configured for several
|
|
457
458
|
// keeps Jev for every built-in consumer and reaches the others only by
|
|
@@ -606,6 +607,79 @@ const HAND_DESCRIPTORS = [
|
|
|
606
607
|
},
|
|
607
608
|
setupUrl: "https://console.perplexity.ai",
|
|
608
609
|
},
|
|
610
|
+
{
|
|
611
|
+
name: AIProviderName.CLOUDFLARE_CLEF,
|
|
612
|
+
aliases: [],
|
|
613
|
+
credentialsKey: "cloudflareClef",
|
|
614
|
+
envVars: {
|
|
615
|
+
// The same token and account id the `cloudflare` text provider reads, so
|
|
616
|
+
// ambient Workers AI settings configure this provider too. It sits last
|
|
617
|
+
// in this list, which is what keeps that from displacing any other
|
|
618
|
+
// decision provider a host has configured.
|
|
619
|
+
apiKey: "CLOUDFLARE_API_KEY",
|
|
620
|
+
// Cloudflare's own API is the endpoint, so a base URL is optional; but
|
|
621
|
+
// the path carries the account id, so a token alone is useless. Both are
|
|
622
|
+
// required for it to count as configured, from the environment or from
|
|
623
|
+
// credentials.cloudflareClef.
|
|
624
|
+
extraRequired: ["CLOUDFLARE_ACCOUNT_ID"],
|
|
625
|
+
extraRequiredCredentialFields: { CLOUDFLARE_ACCOUNT_ID: "accountId" },
|
|
626
|
+
baseURL: "CLOUDFLARE_CLEF_BASE_URL",
|
|
627
|
+
model: "CLOUDFLARE_CLEF_MODEL",
|
|
628
|
+
},
|
|
629
|
+
defaultModel: CloudflareClefModels.CLEF,
|
|
630
|
+
// Serves only `decide`, like the other decision providers — the one
|
|
631
|
+
// declaration that keeps it out of every generation code path, and out of
|
|
632
|
+
// the way of the `cloudflare` text provider.
|
|
633
|
+
inferenceKinds: ["decide"],
|
|
634
|
+
toolSupport: "none",
|
|
635
|
+
localRuntime: false,
|
|
636
|
+
healthCheck: "env-only",
|
|
637
|
+
// Deliberately NO autoSelectPriority / autoSelectPreference /
|
|
638
|
+
// defaultHealthSweepPriority, for the same reason as TypeSafe above.
|
|
639
|
+
//
|
|
640
|
+
// Measured 2026-10-03: 0.3 to 1.0 s for a small request, 1.1 s for 64 questions on
|
|
641
|
+
// clef-flash and 1.3 s on clef, and 2.2 s at most for any of 60 requests
|
|
642
|
+
// sent at once. On 2026-10-04, 64 questions took 1.5 s (flash) / 2.3 s (clef).
|
|
643
|
+
// 5s covers those observations and keeps a fail-open consumer
|
|
644
|
+
// from waiting on a stuck call.
|
|
645
|
+
timeouts: { decideMs: 5_000 },
|
|
646
|
+
// The Workers AI endpoint ignores state text past about 2,048 tokens
|
|
647
|
+
// (hosted service or model: unknown), despite the documented 64K. The local
|
|
648
|
+
// 1,500-token estimate refuses before every measured cut. On 2026-10-04,
|
|
649
|
+
// both models read facts at the original clef-flash lower bounds for logs,
|
|
650
|
+
// number lists, digit arrays and compact JSON, but not about 2.5% further on;
|
|
651
|
+
// English prose and random CJK already matched on both. Digits cost 1,
|
|
652
|
+
// ASCII symbols 0.75, BMP non-ASCII 1.5 and astral characters 3 tokens.
|
|
653
|
+
// Natural Chinese, Japanese, Korean and Hindi prose and emoji-rich English
|
|
654
|
+
// were also safe under those rates on clef. A many-key object cut between
|
|
655
|
+
// 128 and 134 preceding keys on both models: its lower bound was 4,883
|
|
656
|
+
// compact-JSON characters, estimated at 2,299 tokens. The probe used an
|
|
657
|
+
// explicit field-name question and zero-padded keys together after the
|
|
658
|
+
// control failed three times. It then passed; necessity was not established.
|
|
659
|
+
// Other object shapes and Unicode sequences may differ.
|
|
660
|
+
decisionLimits: {
|
|
661
|
+
maxStateTokens: 1_500,
|
|
662
|
+
maxQuestions: 64,
|
|
663
|
+
nonAsciiTokensPerChar: 1.5,
|
|
664
|
+
digitTokensPerChar: 1,
|
|
665
|
+
symbolTokensPerChar: 0.75,
|
|
666
|
+
astralTokensPerChar: 3,
|
|
667
|
+
// Images only. Exactly four tiny images succeeded and five were refused
|
|
668
|
+
// on both models. image/jpg also succeeded and is normalized to JPEG.
|
|
669
|
+
// Retain the conservative 256,000-byte encoded-body cap: on 2026-10-04
|
|
670
|
+
// both models accepted 520,000 text characters and refused 525,000 with
|
|
671
|
+
// 413/code 5021. On 2026-10-03, clef-flash accepted 262,000 and refused
|
|
672
|
+
// 270,000. Estimates match encoded body characters / 4, rounded up. The
|
|
673
|
+
// threshold moved from 65,527 accepted / 67,527 refused to 130,026 /
|
|
674
|
+
// 131,276 (clef) and 130,027 / 131,277 (flash); errors still print 65,536.
|
|
675
|
+
// Inference: the new interval contains 131,072 (twice the printed
|
|
676
|
+
// figure); reason unknown.
|
|
677
|
+
// The new image-byte ceiling was not measured; the old 195/202 KB PNG boundary
|
|
678
|
+
// is historical. See the guide for exact model and date coverage.
|
|
679
|
+
media: { maxImages: 4, video: false, maxRequestBytes: 256_000 },
|
|
680
|
+
},
|
|
681
|
+
setupUrl: "https://dash.cloudflare.com/profile/api-tokens",
|
|
682
|
+
},
|
|
609
683
|
];
|
|
610
684
|
/**
|
|
611
685
|
* Builds a ProviderDescriptor for every JSON-catalog provider. Every field
|
|
@@ -724,9 +798,14 @@ function isDecisionProviderConfigured(descriptor, credentials) {
|
|
|
724
798
|
const hasKey = [descriptor.envVars.apiKey, ...(descriptor.envVars.fallbacks ?? [])].some(inEnv) ||
|
|
725
799
|
isSet(slice?.apiKey) ||
|
|
726
800
|
isSet(slice?.gatewayApiKey);
|
|
727
|
-
// A required base URL can also come from credentials.<key>.baseURL
|
|
728
|
-
|
|
729
|
-
|
|
801
|
+
// A required base URL can also come from credentials.<key>.baseURL, and any
|
|
802
|
+
// other required value the descriptor maps to a field of that slice.
|
|
803
|
+
const hasRequired = (descriptor.envVars.extraRequired ?? []).every((name) => {
|
|
804
|
+
const field = descriptor.envVars.extraRequiredCredentialFields?.[name];
|
|
805
|
+
return (inEnv(name) ||
|
|
806
|
+
(name === descriptor.envVars.baseURL && isSet(slice?.baseURL)) ||
|
|
807
|
+
(field !== undefined && isSet(slice?.[field])));
|
|
808
|
+
});
|
|
730
809
|
return hasKey && hasRequired;
|
|
731
810
|
}
|
|
732
811
|
/**
|
|
@@ -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, PerplexityDeciderModels, 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, CloudflareClefModels, 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";
|
|
@@ -260,6 +260,15 @@ export class ProviderRegistry {
|
|
|
260
260
|
return new PerplexityDeciderProvider(modelName, sdk, undefined, perplexityDeciderCreds);
|
|
261
261
|
}, process.env.PERPLEXITY_DECIDER_MODEL ||
|
|
262
262
|
PerplexityDeciderModels.PPLX_DECIDER_V1_27B, [], PROVIDER_DESCRIPTORS_BY_NAME.get(AIProviderName.PERPLEXITY_DECIDER));
|
|
263
|
+
// Register Cloudflare Clef — a `decide` provider reached through the
|
|
264
|
+
// Workers AI REST API. Its descriptor declares inferenceKinds:
|
|
265
|
+
// ["decide"], so nothing in the generation fallback chain can reach it,
|
|
266
|
+
// and it is registered apart from the `cloudflare` text provider.
|
|
267
|
+
ProviderFactory.registerProvider(AIProviderName.CLOUDFLARE_CLEF, async (modelName, _providerName, sdk, _region, credentials) => {
|
|
268
|
+
const cloudflareClefCreds = credentials;
|
|
269
|
+
const { CloudflareClefProvider } = await import("../providers/cloudflareClef.js");
|
|
270
|
+
return new CloudflareClefProvider(modelName, sdk, undefined, cloudflareClefCreds);
|
|
271
|
+
}, process.env.CLOUDFLARE_CLEF_MODEL || CloudflareClefModels.CLEF, [], PROVIDER_DESCRIPTORS_BY_NAME.get(AIProviderName.CLOUDFLARE_CLEF));
|
|
263
272
|
logger.debug("All AI providers registered successfully");
|
|
264
273
|
// ===== MEDIA HANDLER REGISTRATION =====
|
|
265
274
|
// Single registration path (Task 11): each ecosystem barrel (voice,
|
|
@@ -23,6 +23,7 @@ import { typesafeManifest } from "./manifests/typesafe.js";
|
|
|
23
23
|
import { layaManifest } from "./manifests/laya.js";
|
|
24
24
|
import { xorManifest } from "./manifests/xor.js";
|
|
25
25
|
import { perplexityDeciderManifest } from "./manifests/perplexityDecider.js";
|
|
26
|
+
import { cloudflareClefManifest } from "./manifests/cloudflareClef.js";
|
|
26
27
|
import { cohereManifest } from "./manifests/cohere.js";
|
|
27
28
|
import { togetherAiManifest } from "./manifests/together-ai.js";
|
|
28
29
|
import { fireworksManifest } from "./manifests/fireworks.js";
|
|
@@ -124,6 +125,7 @@ export const MANIFEST_REGISTRY = {
|
|
|
124
125
|
laya: layaManifest,
|
|
125
126
|
xor: xorManifest,
|
|
126
127
|
"perplexity-decider": perplexityDeciderManifest,
|
|
128
|
+
"cloudflare-clef": cloudflareClefManifest,
|
|
127
129
|
cerebras: catalogManifest("cerebras"),
|
|
128
130
|
sambanova: catalogManifest("sambanova"),
|
|
129
131
|
cohere: cohereManifest,
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ProviderModelManifest } from "../../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Cloudflare Clef on Workers AI — the `decide` inference type, not text
|
|
4
|
+
* generation, and not the Workers AI text models of the `cloudflare` provider.
|
|
5
|
+
*
|
|
6
|
+
* `contextWindow` is the figure Cloudflare documents (65,536 tokens). The
|
|
7
|
+
* Workers AI endpoint ignores state text past about 2,048 tokens without an
|
|
8
|
+
* error (hosted service or model: unknown), so NeuroLink enforces the limit on
|
|
9
|
+
* the descriptor's `decisionLimits`, not this. `vision` describes `generate()`
|
|
10
|
+
* input, which this provider does not serve; its image input is
|
|
11
|
+
* `DecisionRequest.images`.
|
|
12
|
+
*
|
|
13
|
+
* `maxOutputTokens` is required by the manifest type but has no honest value
|
|
14
|
+
* for a model that emits no text, so a small non-zero figure is used.
|
|
15
|
+
*/
|
|
16
|
+
export declare const cloudflareClefManifest: ProviderModelManifest;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloudflare Clef on Workers AI — the `decide` inference type, not text
|
|
3
|
+
* generation, and not the Workers AI text models of the `cloudflare` provider.
|
|
4
|
+
*
|
|
5
|
+
* `contextWindow` is the figure Cloudflare documents (65,536 tokens). The
|
|
6
|
+
* Workers AI endpoint ignores state text past about 2,048 tokens without an
|
|
7
|
+
* error (hosted service or model: unknown), so NeuroLink enforces the limit on
|
|
8
|
+
* the descriptor's `decisionLimits`, not this. `vision` describes `generate()`
|
|
9
|
+
* input, which this provider does not serve; its image input is
|
|
10
|
+
* `DecisionRequest.images`.
|
|
11
|
+
*
|
|
12
|
+
* `maxOutputTokens` is required by the manifest type but has no honest value
|
|
13
|
+
* for a model that emits no text, so a small non-zero figure is used.
|
|
14
|
+
*/
|
|
15
|
+
export const cloudflareClefManifest = {
|
|
16
|
+
defaultContextWindow: 65_536,
|
|
17
|
+
models: {
|
|
18
|
+
_default: {
|
|
19
|
+
aliases: [],
|
|
20
|
+
contextWindow: 65_536,
|
|
21
|
+
maxOutputTokens: 256,
|
|
22
|
+
vision: false,
|
|
23
|
+
functionCalling: false,
|
|
24
|
+
},
|
|
25
|
+
clef: {
|
|
26
|
+
aliases: ["@cf/cloudflare/clef"],
|
|
27
|
+
displayName: "Cloudflare Clef (27B)",
|
|
28
|
+
contextWindow: 65_536,
|
|
29
|
+
maxOutputTokens: 256,
|
|
30
|
+
vision: false,
|
|
31
|
+
functionCalling: false,
|
|
32
|
+
},
|
|
33
|
+
"clef-flash": {
|
|
34
|
+
aliases: ["@cf/cloudflare/clef-flash"],
|
|
35
|
+
displayName: "Cloudflare Clef-flash (9B)",
|
|
36
|
+
contextWindow: 65_536,
|
|
37
|
+
maxOutputTokens: 256,
|
|
38
|
+
vision: false,
|
|
39
|
+
functionCalling: false,
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { DecisionError, DecisionPreparedMedia, DecisionState, NeurolinkCredentials } from "../types/index.js";
|
|
2
|
+
import { SystemOneDecisionProvider } from "./systemOneDecision.js";
|
|
3
|
+
/**
|
|
4
|
+
* Cloudflare Clef — the `decide` inference type only.
|
|
5
|
+
*
|
|
6
|
+
* `@cf/cloudflare/clef` (27B) and `@cf/cloudflare/clef-flash` (9B) answer the
|
|
7
|
+
* same typed `noul` / `choice` / `score` questions as the other decision
|
|
8
|
+
* providers, follow the System One wire, and read images. They are reached
|
|
9
|
+
* through the Workers AI REST API, which wraps every answer in Cloudflare's own
|
|
10
|
+
* `{ result, success, errors }` envelope and puts the model in the URL path.
|
|
11
|
+
*
|
|
12
|
+
* The token and account id are the ones the Cloudflare Workers AI text provider
|
|
13
|
+
* reads (`CLOUDFLARE_API_KEY`, `CLOUDFLARE_ACCOUNT_ID`), so a host that has
|
|
14
|
+
* configured that provider has also configured this one.
|
|
15
|
+
*
|
|
16
|
+
* The Workers AI endpoint ignores text past about 2,048 tokens, far below
|
|
17
|
+
* the documented 64K (hosted service or model: unknown). See `decisionLimits`
|
|
18
|
+
* on the descriptor for the measured figures.
|
|
19
|
+
*
|
|
20
|
+
* @see https://developers.cloudflare.com/workers-ai/models/clef/
|
|
21
|
+
*/
|
|
22
|
+
export declare class CloudflareClefProvider extends SystemOneDecisionProvider {
|
|
23
|
+
private readonly apiKey;
|
|
24
|
+
private readonly accountId;
|
|
25
|
+
private readonly baseURL;
|
|
26
|
+
constructor(modelName?: string, sdk?: unknown, _region?: string, credentials?: NeurolinkCredentials["cloudflareClef"]);
|
|
27
|
+
protected getDefaultModel(): string;
|
|
28
|
+
protected vendorLabel(): string;
|
|
29
|
+
protected vendorDisplayName(): string;
|
|
30
|
+
protected decisionApiKey(): string;
|
|
31
|
+
protected missingKeyMessage(): string;
|
|
32
|
+
protected missingConfigMessage(): string | undefined;
|
|
33
|
+
/** The model is part of the path, so the endpoint depends on the model asked for. */
|
|
34
|
+
protected decisionEndpoint(model: string): string;
|
|
35
|
+
protected decisionHeaders(): Record<string, string>;
|
|
36
|
+
/**
|
|
37
|
+
* Images travel in their own `images` array, as `data:` URLs, placed before
|
|
38
|
+
* the state by the server. `model` is sent although the path already names
|
|
39
|
+
* it: the API documents it as required, and refuses a body whose `model`
|
|
40
|
+
* differs from the path.
|
|
41
|
+
*/
|
|
42
|
+
protected buildDecisionBody(state: DecisionState, questions: Record<string, Record<string, unknown>>, model: string, media?: DecisionPreparedMedia): Record<string, unknown>;
|
|
43
|
+
/** A success is `{ result: { model, answers, usage }, success: true }`. */
|
|
44
|
+
protected readDecisionPayload(payload: unknown): unknown;
|
|
45
|
+
protected parseDecisionError(status: number, payload: unknown, requestId: string | undefined): DecisionError;
|
|
46
|
+
/**
|
|
47
|
+
* `cf-ai-req-id` is on every answer that reached the model, success or
|
|
48
|
+
* refusal. A 401 and a wrong-path 400 never reach it, so they carry only the
|
|
49
|
+
* edge's `cf-ray`.
|
|
50
|
+
*/
|
|
51
|
+
protected readRequestId(headers: Headers): string | undefined;
|
|
52
|
+
}
|