@cerebriline/llms 0.0.0-stage → 4.100.240
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/LICENSE +201 -0
- package/README.md +15 -2
- package/dist/catalog/catalog-cline-recommended.d.ts +14 -0
- package/dist/catalog/catalog-cline-recommended.d.ts.map +1 -0
- package/dist/catalog/catalog-live.d.ts +64 -0
- package/dist/catalog/catalog-live.d.ts.map +1 -0
- package/dist/catalog/catalog.generated-access.d.ts +5 -0
- package/dist/catalog/catalog.generated-access.d.ts.map +1 -0
- package/dist/catalog/catalog.generated.d.ts +17 -0
- package/dist/catalog/catalog.generated.d.ts.map +1 -0
- package/dist/catalog/model-filters.d.ts +9 -0
- package/dist/catalog/model-filters.d.ts.map +1 -0
- package/dist/catalog/model-id-aliases.d.ts +11 -0
- package/dist/catalog/model-id-aliases.d.ts.map +1 -0
- package/dist/catalog/model-operation.d.ts +27 -0
- package/dist/catalog/model-operation.d.ts.map +1 -0
- package/dist/catalog/types.d.ts +367 -0
- package/dist/catalog/types.d.ts.map +1 -0
- package/dist/index.browser.d.ts +12 -0
- package/dist/index.browser.d.ts.map +1 -0
- package/dist/index.browser.js +16 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +272 -0
- package/dist/models.d.ts +10 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +241 -0
- package/dist/providers/agent-slots.d.ts +100 -0
- package/dist/providers/agent-slots.d.ts.map +1 -0
- package/dist/providers/ai-sdk.d.ts +158 -0
- package/dist/providers/ai-sdk.d.ts.map +1 -0
- package/dist/providers/async.d.ts +2 -0
- package/dist/providers/async.d.ts.map +1 -0
- package/dist/providers/billing.d.ts +5 -0
- package/dist/providers/billing.d.ts.map +1 -0
- package/dist/providers/builtin-types.d.ts +34 -0
- package/dist/providers/builtin-types.d.ts.map +1 -0
- package/dist/providers/builtins-runtime.d.ts +3 -0
- package/dist/providers/builtins-runtime.d.ts.map +1 -0
- package/dist/providers/builtins.d.ts +30 -0
- package/dist/providers/builtins.d.ts.map +1 -0
- package/dist/providers/compat.d.ts +75 -0
- package/dist/providers/compat.d.ts.map +1 -0
- package/dist/providers/config.d.ts +521 -0
- package/dist/providers/config.d.ts.map +1 -0
- package/dist/providers/error-classification.d.ts +23 -0
- package/dist/providers/error-classification.d.ts.map +1 -0
- package/dist/providers/errors.d.ts +33 -0
- package/dist/providers/errors.d.ts.map +1 -0
- package/dist/providers/factory-registry.d.ts +92 -0
- package/dist/providers/factory-registry.d.ts.map +1 -0
- package/dist/providers/format.d.ts +2 -0
- package/dist/providers/format.d.ts.map +1 -0
- package/dist/providers/gateway.d.ts +123 -0
- package/dist/providers/gateway.d.ts.map +1 -0
- package/dist/providers/handler.d.ts +75 -0
- package/dist/providers/handler.d.ts.map +1 -0
- package/dist/providers/http.d.ts +10 -0
- package/dist/providers/http.d.ts.map +1 -0
- package/dist/providers/ids.d.ts +77 -0
- package/dist/providers/ids.d.ts.map +1 -0
- package/dist/providers/messages.d.ts +5 -0
- package/dist/providers/messages.d.ts.map +1 -0
- package/dist/providers/middleware/backoff.d.ts +11 -0
- package/dist/providers/middleware/backoff.d.ts.map +1 -0
- package/dist/providers/middleware/retry-empty-response.d.ts +74 -0
- package/dist/providers/middleware/retry-empty-response.d.ts.map +1 -0
- package/dist/providers/middleware/retry-rate-limit.d.ts +49 -0
- package/dist/providers/middleware/retry-rate-limit.d.ts.map +1 -0
- package/dist/providers/middleware/split-tool-images.d.ts +32 -0
- package/dist/providers/middleware/split-tool-images.d.ts.map +1 -0
- package/dist/providers/middleware/stream-part-classification.d.ts +33 -0
- package/dist/providers/middleware/stream-part-classification.d.ts.map +1 -0
- package/dist/providers/model-capabilities.d.ts +15 -0
- package/dist/providers/model-capabilities.d.ts.map +1 -0
- package/dist/providers/model-facts.d.ts +115 -0
- package/dist/providers/model-facts.d.ts.map +1 -0
- package/dist/providers/model-operations.d.ts +78 -0
- package/dist/providers/model-operations.d.ts.map +1 -0
- package/dist/providers/model-registry.d.ts +25 -0
- package/dist/providers/model-registry.d.ts.map +1 -0
- package/dist/providers/model-tools.d.ts +22 -0
- package/dist/providers/model-tools.d.ts.map +1 -0
- package/dist/providers/openai-codex-models.d.ts +11 -0
- package/dist/providers/openai-codex-models.d.ts.map +1 -0
- package/dist/providers/provider-ids.generated.d.ts +13 -0
- package/dist/providers/provider-ids.generated.d.ts.map +1 -0
- package/dist/providers/provider-keys.d.ts +13 -0
- package/dist/providers/provider-keys.d.ts.map +1 -0
- package/dist/providers/provider-request-capture.d.ts +10 -0
- package/dist/providers/provider-request-capture.d.ts.map +1 -0
- package/dist/providers/providers.generated.d.ts +19 -0
- package/dist/providers/providers.generated.d.ts.map +1 -0
- package/dist/providers/reasoning-history.d.ts +140 -0
- package/dist/providers/reasoning-history.d.ts.map +1 -0
- package/dist/providers/registry.d.ts +19 -0
- package/dist/providers/registry.d.ts.map +1 -0
- package/dist/providers/request-headers.d.ts +30 -0
- package/dist/providers/request-headers.d.ts.map +1 -0
- package/dist/providers/request-timings.d.ts +20 -0
- package/dist/providers/request-timings.d.ts.map +1 -0
- package/dist/providers/routing/anthropic-compatible.d.ts +35 -0
- package/dist/providers/routing/anthropic-compatible.d.ts.map +1 -0
- package/dist/providers/routing/bedrock-cache-point.d.ts +26 -0
- package/dist/providers/routing/bedrock-cache-point.d.ts.map +1 -0
- package/dist/providers/routing/generic-compatible.d.ts +10 -0
- package/dist/providers/routing/generic-compatible.d.ts.map +1 -0
- package/dist/providers/routing/glm-thinking.d.ts +16 -0
- package/dist/providers/routing/glm-thinking.d.ts.map +1 -0
- package/dist/providers/routing/minimax-thinking.d.ts +6 -0
- package/dist/providers/routing/minimax-thinking.d.ts.map +1 -0
- package/dist/providers/routing/portable-reasoning.d.ts +11 -0
- package/dist/providers/routing/portable-reasoning.d.ts.map +1 -0
- package/dist/providers/routing/provider-option-rules.d.ts +13 -0
- package/dist/providers/routing/provider-option-rules.d.ts.map +1 -0
- package/dist/providers/routing/provider-options-types.d.ts +57 -0
- package/dist/providers/routing/provider-options-types.d.ts.map +1 -0
- package/dist/providers/routing/provider-options.d.ts +27 -0
- package/dist/providers/routing/provider-options.d.ts.map +1 -0
- package/dist/providers/routing/reasoning-codecs.d.ts +4 -0
- package/dist/providers/routing/reasoning-codecs.d.ts.map +1 -0
- package/dist/providers/routing/reasoning-options.d.ts +8 -0
- package/dist/providers/routing/reasoning-options.d.ts.map +1 -0
- package/dist/providers/routing/utils.d.ts +31 -0
- package/dist/providers/routing/utils.d.ts.map +1 -0
- package/dist/providers/sdk-warnings.d.ts +14 -0
- package/dist/providers/sdk-warnings.d.ts.map +1 -0
- package/dist/providers/server-health.d.ts +66 -0
- package/dist/providers/server-health.d.ts.map +1 -0
- package/dist/providers/stream.d.ts +124 -0
- package/dist/providers/stream.d.ts.map +1 -0
- package/dist/providers/types.d.ts +10 -0
- package/dist/providers/types.d.ts.map +1 -0
- package/dist/providers/url.d.ts +3 -0
- package/dist/providers/url.d.ts.map +1 -0
- package/dist/providers/utils.d.ts +2 -0
- package/dist/providers/utils.d.ts.map +1 -0
- package/dist/providers/vendors/anthropic.d.ts +4 -0
- package/dist/providers/vendors/anthropic.d.ts.map +1 -0
- package/dist/providers/vendors/bedrock.d.ts +24 -0
- package/dist/providers/vendors/bedrock.d.ts.map +1 -0
- package/dist/providers/vendors/cline.d.ts +37 -0
- package/dist/providers/vendors/cline.d.ts.map +1 -0
- package/dist/providers/vendors/community.d.ts +8 -0
- package/dist/providers/vendors/community.d.ts.map +1 -0
- package/dist/providers/vendors/google.d.ts +12 -0
- package/dist/providers/vendors/google.d.ts.map +1 -0
- package/dist/providers/vendors/llamacpp-sampling.d.ts +130 -0
- package/dist/providers/vendors/llamacpp-sampling.d.ts.map +1 -0
- package/dist/providers/vendors/llamacpp-timings.d.ts +33 -0
- package/dist/providers/vendors/llamacpp-timings.d.ts.map +1 -0
- package/dist/providers/vendors/minimax-thinking.d.ts +5 -0
- package/dist/providers/vendors/minimax-thinking.d.ts.map +1 -0
- package/dist/providers/vendors/mistral.d.ts +4 -0
- package/dist/providers/vendors/mistral.d.ts.map +1 -0
- package/dist/providers/vendors/ollama-account.d.ts +128 -0
- package/dist/providers/vendors/ollama-account.d.ts.map +1 -0
- package/dist/providers/vendors/ollama-reachability.d.ts +42 -0
- package/dist/providers/vendors/ollama-reachability.d.ts.map +1 -0
- package/dist/providers/vendors/ollama-stall-watchdog.d.ts +86 -0
- package/dist/providers/vendors/ollama-stall-watchdog.d.ts.map +1 -0
- package/dist/providers/vendors/ollama-tool-images.d.ts +67 -0
- package/dist/providers/vendors/ollama-tool-images.d.ts.map +1 -0
- package/dist/providers/vendors/ollama.d.ts +256 -0
- package/dist/providers/vendors/ollama.d.ts.map +1 -0
- package/dist/providers/vendors/openai-compatible.d.ts +16 -0
- package/dist/providers/vendors/openai-compatible.d.ts.map +1 -0
- package/dist/providers/vendors/openai.d.ts +4 -0
- package/dist/providers/vendors/openai.d.ts.map +1 -0
- package/dist/providers/vendors/opencoti-agent-window.d.ts +44 -0
- package/dist/providers/vendors/opencoti-agent-window.d.ts.map +1 -0
- package/dist/providers/vendors/opencoti-kv-pressure.d.ts +322 -0
- package/dist/providers/vendors/opencoti-kv-pressure.d.ts.map +1 -0
- package/dist/providers/vendors/opencoti-liveness.d.ts +177 -0
- package/dist/providers/vendors/opencoti-liveness.d.ts.map +1 -0
- package/dist/providers/vendors/opencoti-window.d.ts +56 -0
- package/dist/providers/vendors/opencoti-window.d.ts.map +1 -0
- package/dist/providers/vendors/opencoti.d.ts +335 -0
- package/dist/providers/vendors/opencoti.d.ts.map +1 -0
- package/dist/providers/vendors/polykv-lead.d.ts +94 -0
- package/dist/providers/vendors/polykv-lead.d.ts.map +1 -0
- package/dist/providers/vendors/polykv-swarm.d.ts +705 -0
- package/dist/providers/vendors/polykv-swarm.d.ts.map +1 -0
- package/dist/providers/vendors/polykv.d.ts +958 -0
- package/dist/providers/vendors/polykv.d.ts.map +1 -0
- package/dist/providers/vendors/types.d.ts +176 -0
- package/dist/providers/vendors/types.d.ts.map +1 -0
- package/dist/providers/vendors/vertex.d.ts +4 -0
- package/dist/providers/vendors/vertex.d.ts.map +1 -0
- package/dist/providers/vendors/xollama-engine.d.ts +57 -0
- package/dist/providers/vendors/xollama-engine.d.ts.map +1 -0
- package/dist/providers/vendors/xollama.d.ts +188 -0
- package/dist/providers/vendors/xollama.d.ts.map +1 -0
- package/dist/providers.browser.d.ts +3 -0
- package/dist/providers.browser.d.ts.map +1 -0
- package/dist/providers.browser.js +16 -0
- package/dist/providers.d.ts +12 -0
- package/dist/providers.d.ts.map +1 -0
- package/dist/providers.js +272 -0
- package/dist/services/langfuse-telemetry.d.ts +19 -0
- package/dist/services/langfuse-telemetry.d.ts.map +1 -0
- package/dist/transcription.d.ts +53 -0
- package/dist/transcription.d.ts.map +1 -0
- package/package.json +84 -5
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { LanguageModelV4 } from "@ai-sdk/provider";
|
|
2
|
+
import type { GatewayProviderContext, GatewayResolvedProviderConfig } from "@cerebriline/shared";
|
|
3
|
+
import type { ProviderFactoryResult } from "./types";
|
|
4
|
+
export interface ClineWebSearchInput {
|
|
5
|
+
query: string;
|
|
6
|
+
allowed_domains?: string[];
|
|
7
|
+
blocked_domains?: string[];
|
|
8
|
+
}
|
|
9
|
+
export interface ClineWebSearchResult {
|
|
10
|
+
results: Array<{
|
|
11
|
+
title?: string;
|
|
12
|
+
url?: string;
|
|
13
|
+
}>;
|
|
14
|
+
}
|
|
15
|
+
export interface ClineWebSearchOptions {
|
|
16
|
+
allowedDomains?: string[];
|
|
17
|
+
blockedDomains?: string[];
|
|
18
|
+
}
|
|
19
|
+
export interface ClineProviderOptions {
|
|
20
|
+
apiKey?: string;
|
|
21
|
+
baseURL: string;
|
|
22
|
+
headers?: Record<string, string>;
|
|
23
|
+
fetch?: typeof fetch;
|
|
24
|
+
onResponseError?: (response: Response) => Promise<void> | void;
|
|
25
|
+
}
|
|
26
|
+
declare const webSearchFactory: import("@ai-sdk/provider-utils").ProviderDefinedToolFactory<ClineWebSearchInput, ClineWebSearchOptions, {}>;
|
|
27
|
+
export interface ClineProvider {
|
|
28
|
+
(modelId: string): LanguageModelV4;
|
|
29
|
+
tools: {
|
|
30
|
+
webSearch(options?: ClineWebSearchOptions): ReturnType<typeof webSearchFactory<ClineWebSearchResult>>;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/** Create the Cline AI SDK provider, including Cline-native client tools. */
|
|
34
|
+
export declare function createCline(options: ClineProviderOptions): ClineProvider;
|
|
35
|
+
export declare function createClineProviderModule(config: GatewayResolvedProviderConfig, context: GatewayProviderContext): Promise<ProviderFactoryResult>;
|
|
36
|
+
export {};
|
|
37
|
+
//# sourceMappingURL=cline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cline.d.ts","sourceRoot":"","sources":["../../../src/providers/vendors/cline.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACX,eAAe,EAGf,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EACX,sBAAsB,EACtB,6BAA6B,EAC7B,MAAM,eAAe,CAAC;AAcvB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAErD,MAAM,WAAW,mBAAmB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,oBAAoB;IACpC,OAAO,EAAE,KAAK,CAAC;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjD;AAED,MAAM,WAAW,qBAAqB;IACrC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC/D;AA+BD,QAAA,MAAM,gBAAgB,6GAMpB,CAAC;AA8FH,MAAM,WAAW,aAAa;IAC7B,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,CAAC;IACnC,KAAK,EAAE;QACN,SAAS,CACR,OAAO,CAAC,EAAE,qBAAqB,GAC7B,UAAU,CAAC,OAAO,gBAAgB,CAAC,oBAAoB,CAAC,CAAC,CAAC;KAC7D,CAAC;CACF;AAED,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAgCxE;AAWD,wBAAsB,yBAAyB,CAC9C,MAAM,EAAE,6BAA6B,EACrC,OAAO,EAAE,sBAAsB,GAC7B,OAAO,CAAC,qBAAqB,CAAC,CAsDhC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { GatewayResolvedProviderConfig } from "@cerebriline/shared";
|
|
2
|
+
import type { ProviderFactoryResult } from "./types";
|
|
3
|
+
export declare function createClaudeCodeProviderModule(config: GatewayResolvedProviderConfig): Promise<ProviderFactoryResult>;
|
|
4
|
+
export declare function createOpenAICodexProviderModule(config: GatewayResolvedProviderConfig): Promise<ProviderFactoryResult>;
|
|
5
|
+
export declare function createOpenCodeProviderModule(config: GatewayResolvedProviderConfig): Promise<ProviderFactoryResult>;
|
|
6
|
+
export declare function createDifyProviderModule(config: GatewayResolvedProviderConfig): Promise<ProviderFactoryResult>;
|
|
7
|
+
export declare function createSapAiCoreProviderModule(config: GatewayResolvedProviderConfig): Promise<ProviderFactoryResult>;
|
|
8
|
+
//# sourceMappingURL=community.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"community.d.ts","sourceRoot":"","sources":["../../../src/providers/vendors/community.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,eAAe,CAAC;AAQnE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAsErD,wBAAsB,8BAA8B,CACnD,MAAM,EAAE,6BAA6B,GACnC,OAAO,CAAC,qBAAqB,CAAC,CAyDhC;AAED,wBAAsB,+BAA+B,CACpD,MAAM,EAAE,6BAA6B,GACnC,OAAO,CAAC,qBAAqB,CAAC,CAmBhC;AA+BD,wBAAsB,4BAA4B,CACjD,MAAM,EAAE,6BAA6B,GACnC,OAAO,CAAC,qBAAqB,CAAC,CAgBhC;AAED,wBAAsB,wBAAwB,CAC7C,MAAM,EAAE,6BAA6B,GACnC,OAAO,CAAC,qBAAqB,CAAC,CAgBhC;AAuID,wBAAsB,6BAA6B,CAClD,MAAM,EAAE,6BAA6B,GACnC,OAAO,CAAC,qBAAqB,CAAC,CA+BhC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { GatewayProviderContext, GatewayResolvedProviderConfig } from "@cerebriline/shared";
|
|
2
|
+
import type { ProviderFactoryResult } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* The legacy Gemini base-URL setting (and Google's own `@google/genai`
|
|
5
|
+
* client) treat the base URL as a host root and append the API version
|
|
6
|
+
* themselves, while `@ai-sdk/google` expects the version segment to be part
|
|
7
|
+
* of `baseURL` (its default is `.../v1beta`). Preserve the legacy semantics:
|
|
8
|
+
* append `/v1beta` unless the URL already ends with a version segment.
|
|
9
|
+
*/
|
|
10
|
+
export declare function normalizeGeminiBaseUrl(baseUrl: string | undefined): string | undefined;
|
|
11
|
+
export declare function createGoogleProviderModule(config: GatewayResolvedProviderConfig, context: GatewayProviderContext): Promise<ProviderFactoryResult>;
|
|
12
|
+
//# sourceMappingURL=google.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"google.d.ts","sourceRoot":"","sources":["../../../src/providers/vendors/google.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACX,sBAAsB,EACtB,6BAA6B,EAC7B,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAIrD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACrC,OAAO,EAAE,MAAM,GAAG,SAAS,GACzB,MAAM,GAAG,SAAS,CAOpB;AAED,wBAAsB,0BAA0B,CAC/C,MAAM,EAAE,6BAA6B,EACrC,OAAO,EAAE,sBAAsB,GAC7B,OAAO,CAAC,qBAAqB,CAAC,CA0BhC"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import type { GatewayResolvedProviderConfig } from "@cerebriline/shared";
|
|
2
|
+
import type { ProviderSamplingOptions } from "../config";
|
|
3
|
+
/**
|
|
4
|
+
* The per-request sampler and thinking budget a llama.cpp server accepts.
|
|
5
|
+
*
|
|
6
|
+
* llama.cpp is reached through the generic `openai-compatible` vendor — there
|
|
7
|
+
* is no provider id for it, and nothing identifies one before a response comes
|
|
8
|
+
* back (`request-timings.ts` recognises it only by the `timings` object on the
|
|
9
|
+
* final frame). So everything here is written to be inert unless the user
|
|
10
|
+
* configured it: an unset field is never sent, and a hosted OpenAI-style
|
|
11
|
+
* endpoint on this same path therefore sees a request byte-identical to the one
|
|
12
|
+
* it saw before. That is the same rule the Ollama vendor states for the same
|
|
13
|
+
* reason — a local model carries a sampler that was tuned against that quant,
|
|
14
|
+
* and a client sending a complete set on every request silently replaces it.
|
|
15
|
+
*
|
|
16
|
+
* Both this and `opencoti` are llama.cpp underneath, which is why one table
|
|
17
|
+
* serves both.
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* Configured sampler field to the name llama.cpp's request schema uses.
|
|
21
|
+
*
|
|
22
|
+
* Verified against `tools/server/server-schema.cpp`. Deliberately absent:
|
|
23
|
+
* `numGpu`, which is Ollama's `num_gpu` and has no per-request form here —
|
|
24
|
+
* llama.cpp decides layer placement with `-ngl` at startup, so sending it would
|
|
25
|
+
* be a field the server does not read, which is the shape of bug this table
|
|
26
|
+
* exists to avoid.
|
|
27
|
+
*/
|
|
28
|
+
export declare const LLAMACPP_SAMPLING_WIRE_NAMES: {
|
|
29
|
+
readonly temperature: "temperature";
|
|
30
|
+
readonly topK: "top_k";
|
|
31
|
+
readonly topP: "top_p";
|
|
32
|
+
readonly minP: "min_p";
|
|
33
|
+
readonly typicalP: "typical_p";
|
|
34
|
+
readonly repeatLastN: "repeat_last_n";
|
|
35
|
+
readonly repeatPenalty: "repeat_penalty";
|
|
36
|
+
readonly presencePenalty: "presence_penalty";
|
|
37
|
+
readonly frequencyPenalty: "frequency_penalty";
|
|
38
|
+
readonly seed: "seed";
|
|
39
|
+
readonly numPredict: "n_predict";
|
|
40
|
+
readonly numKeep: "n_keep";
|
|
41
|
+
readonly stop: "stop";
|
|
42
|
+
readonly thinkBudgetMessage: "reasoning_budget_message";
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* The share of the window an effort level is allowed to spend thinking.
|
|
46
|
+
*
|
|
47
|
+
* Ported verbatim from the Ollama server's own table (`api/types.go`,
|
|
48
|
+
* `thinkBudgetFraction`) so that `high` means the same thing on both engines.
|
|
49
|
+
* llama.cpp has no notion of an effort level — `reasoning_budget_tokens` is an
|
|
50
|
+
* absolute count — so the level has to be resolved to a number on this side,
|
|
51
|
+
* and resolving it with different arithmetic would make the same setting mean
|
|
52
|
+
* two different budgets depending on which server answered.
|
|
53
|
+
*
|
|
54
|
+
* The steps halve rather than crowding the top of the range: how long a model
|
|
55
|
+
* thinks depends on the prompt, not on how much room it was given, so shares
|
|
56
|
+
* near the whole window stop bounding anything once the window is large.
|
|
57
|
+
*/
|
|
58
|
+
export declare const LLAMACPP_THINK_BUDGET_FRACTION: Readonly<Record<string, readonly [number, number]>>;
|
|
59
|
+
/**
|
|
60
|
+
* The room a level is a share of.
|
|
61
|
+
*
|
|
62
|
+
* Ported from the Ollama server's `ThinkBudgetWindow`. A level bounds thinking
|
|
63
|
+
* so the model still has room left to answer, which makes the response length
|
|
64
|
+
* the thing to divide: when the caller caps it with `n_predict`, a share of the
|
|
65
|
+
* context length can equal or exceed that cap and then bounds nothing — the
|
|
66
|
+
* model spends the whole response thinking and stops at the cap with no answer.
|
|
67
|
+
* So prefer the output cap when it is set, and never exceed the context.
|
|
68
|
+
*/
|
|
69
|
+
export declare function resolveLlamaCppThinkBudgetWindow(contextWindow: number | undefined, numPredict: number | undefined): number;
|
|
70
|
+
/**
|
|
71
|
+
* Resolve a configured `thinkBudget` to the absolute token count llama.cpp
|
|
72
|
+
* wants, or `undefined` when it does not resolve to one.
|
|
73
|
+
*
|
|
74
|
+
* The field is tri-valued by design, matching Ollama's: a bare token count, an
|
|
75
|
+
* effort level, or absent. A level with no window to take a share of yields
|
|
76
|
+
* nothing rather than a guess — sending `0` would read as "no thinking at all"
|
|
77
|
+
* to the server, which is the opposite of what an effort level asks for.
|
|
78
|
+
*/
|
|
79
|
+
export declare function resolveLlamaCppThinkBudgetTokens(thinkBudget: string | undefined, window: number): number | undefined;
|
|
80
|
+
/**
|
|
81
|
+
* Translate the configured sampler onto llama.cpp's request body.
|
|
82
|
+
*
|
|
83
|
+
* Only fields the user actually set are sent; see the note at the top of this
|
|
84
|
+
* file for why that matters on a shared code path. An empty `stop` list is
|
|
85
|
+
* dropped for the same reason — it is not an instruction to clear the server's.
|
|
86
|
+
*/
|
|
87
|
+
export declare function buildLlamaCppSamplingOptions(sampling: ProviderSamplingOptions | undefined, budget?: {
|
|
88
|
+
contextWindow?: number;
|
|
89
|
+
numPredict?: number;
|
|
90
|
+
/**
|
|
91
|
+
* The level the request asks for, which is what the provider panel's
|
|
92
|
+
* dropdown actually writes.
|
|
93
|
+
*
|
|
94
|
+
* This used to be missing, and the omission is the whole defect: the
|
|
95
|
+
* builder bailed out above when no *sampler* was configured, so a user
|
|
96
|
+
* who set nothing but an effort level sent no budget at all. Measured
|
|
97
|
+
* live on an opencoti server 2026-09-18, `reasoning_effort` -- the field
|
|
98
|
+
* the AI SDK emits for the level -- is discarded outright, so the
|
|
99
|
+
* thinking was unbounded for every one of those requests.
|
|
100
|
+
*/
|
|
101
|
+
effort?: string;
|
|
102
|
+
/** `false` means reason as little as possible, which here is a budget of 0. */
|
|
103
|
+
enabled?: boolean;
|
|
104
|
+
}): Record<string, unknown>;
|
|
105
|
+
/**
|
|
106
|
+
* The one budget this provider will be sent, from the two places it can come
|
|
107
|
+
* from.
|
|
108
|
+
*
|
|
109
|
+
* Precedence mirrors what the panel makes mutually exclusive: an explicit count
|
|
110
|
+
* is "Custom (reasoning_budget_tokens)" and is the number the user typed, so it
|
|
111
|
+
* outranks a level, which is only ever a share. Neither set means **unbounded**
|
|
112
|
+
* -- and unlike Ollama, where an absent budget hands the decision to the model's
|
|
113
|
+
* own `think_budget`, absent here means the engine bounds nothing at all. So
|
|
114
|
+
* nothing is sent rather than a computed default, and a budget then comes only
|
|
115
|
+
* from the server's own command-line flag if one was given.
|
|
116
|
+
*/
|
|
117
|
+
export declare function resolveLlamaCppReasoningBudget(source: {
|
|
118
|
+
thinkBudget?: string;
|
|
119
|
+
effort?: string;
|
|
120
|
+
enabled?: boolean;
|
|
121
|
+
}, window: number): number | undefined;
|
|
122
|
+
/**
|
|
123
|
+
* The sampler the user configured for this provider entry.
|
|
124
|
+
*
|
|
125
|
+
* Read from the same place every vendor reads it — `providers.json`'s
|
|
126
|
+
* `sampling` — so a value typed into the settings panel reaches a llama.cpp
|
|
127
|
+
* server by the same route it reaches Ollama.
|
|
128
|
+
*/
|
|
129
|
+
export declare function readLlamaCppSamplingOptions(config: GatewayResolvedProviderConfig | undefined): ProviderSamplingOptions | undefined;
|
|
130
|
+
//# sourceMappingURL=llamacpp-sampling.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llamacpp-sampling.d.ts","sourceRoot":"","sources":["../../../src/providers/vendors/llamacpp-sampling.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AAEzD;;;;;;;;;;;;;;;GAeG;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;CAekC,CAAC;AAE5E;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,8BAA8B,EAAE,QAAQ,CACpD,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAOzC,CAAC;AAkBF;;;;;;;;;GASG;AACH,wBAAgB,gCAAgC,CAC/C,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,UAAU,EAAE,MAAM,GAAG,SAAS,GAC5B,MAAM,CAOR;AAMD;;;;;;;;GAQG;AACH,wBAAgB,gCAAgC,CAC/C,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,MAAM,EAAE,MAAM,GACZ,MAAM,GAAG,SAAS,CAmBpB;AAED;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAC3C,QAAQ,EAAE,uBAAuB,GAAG,SAAS,EAC7C,MAAM,CAAC,EAAE;IACR,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;;;;OAUG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB,GACC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAiDzB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,8BAA8B,CAC7C,MAAM,EAAE;IACP,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB,EACD,MAAM,EAAE,MAAM,GACZ,MAAM,GAAG,SAAS,CAYpB;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAC1C,MAAM,EAAE,6BAA6B,GAAG,SAAS,GAC/C,uBAAuB,GAAG,SAAS,CAKrC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keep llama.cpp's `timings` object, which the compatible provider drops.
|
|
3
|
+
*
|
|
4
|
+
* The server puts it on the last frame of every streamed response --
|
|
5
|
+
* `prompt_n`/`prompt_ms`, `predicted_n`/`predicted_ms`, the rates it computed
|
|
6
|
+
* itself, `cache_n` for the prefix it did not have to re-read, and the
|
|
7
|
+
* speculative-decoding counters when a draft model is attached. None of that
|
|
8
|
+
* is standard OpenAI, so `@ai-sdk/openai-compatible` parses past it; a metadata
|
|
9
|
+
* extractor is that package's supported way to keep a field it does not know,
|
|
10
|
+
* which is why this path needs no patched dependency the way Ollama's does.
|
|
11
|
+
*
|
|
12
|
+
* Its own module rather than opencoti's because both the PolyKV vendor and the
|
|
13
|
+
* generic OpenAI-compatible one use it, and the generic path must not pull in
|
|
14
|
+
* opencoti's pool bookkeeping to get a timings reader.
|
|
15
|
+
*
|
|
16
|
+
* Keyed `llamacpp` because the shape belongs to the engine: llama.cpp's own
|
|
17
|
+
* server answers with exactly this, so anything built on it is read by the
|
|
18
|
+
* same code.
|
|
19
|
+
*/
|
|
20
|
+
export declare const llamaCppTimingsMetadataExtractor: {
|
|
21
|
+
extractMetadata: ({ parsedBody }: {
|
|
22
|
+
parsedBody: unknown;
|
|
23
|
+
}) => Promise<{
|
|
24
|
+
llamacpp: Record<string, unknown>;
|
|
25
|
+
} | undefined>;
|
|
26
|
+
createStreamExtractor: () => {
|
|
27
|
+
processChunk(parsedChunk: unknown): void;
|
|
28
|
+
buildMetadata: () => {
|
|
29
|
+
llamacpp: Record<string, unknown>;
|
|
30
|
+
} | undefined;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=llamacpp-timings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llamacpp-timings.d.ts","sourceRoot":"","sources":["../../../src/providers/vendors/llamacpp-timings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAeH,eAAO,MAAM,gCAAgC;sCACJ;QAAE,UAAU,EAAE,OAAO,CAAA;KAAE;kBAZjD,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;kCAiBT,OAAO;;;;;CAYnC,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { LanguageModelV4Middleware } from "@ai-sdk/provider";
|
|
2
|
+
export declare const MINIMAX_THINKING_DISABLED_HEADER = "x-cline-minimax-thinking-disabled";
|
|
3
|
+
export declare const miniMaxThinkingDisabledMiddleware: LanguageModelV4Middleware;
|
|
4
|
+
export declare function createMiniMaxThinkingFetch(baseFetch?: typeof fetch): typeof fetch;
|
|
5
|
+
//# sourceMappingURL=minimax-thinking.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"minimax-thinking.d.ts","sourceRoot":"","sources":["../../../src/providers/vendors/minimax-thinking.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEX,yBAAyB,EACzB,MAAM,kBAAkB,CAAC;AAE1B,eAAO,MAAM,gCAAgC,sCACT,CAAC;AAsBrC,eAAO,MAAM,iCAAiC,EAAE,yBAe/C,CAAC;AAqBF,wBAAgB,0BAA0B,CAAC,SAAS,GAAE,OAAO,KAAa,gBAsCzE"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { GatewayResolvedProviderConfig } from "@cerebriline/shared";
|
|
2
|
+
import type { ProviderFactoryResult } from "./types";
|
|
3
|
+
export declare function createMistralProviderModule(config: GatewayResolvedProviderConfig): Promise<ProviderFactoryResult>;
|
|
4
|
+
//# sourceMappingURL=mistral.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mistral.d.ts","sourceRoot":"","sources":["../../../src/providers/vendors/mistral.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,eAAe,CAAC;AAInE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAErD,wBAAsB,2BAA2B,CAChD,MAAM,EAAE,6BAA6B,GACnC,OAAO,CAAC,qBAAqB,CAAC,CAsBhC"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import type { BasicLogger } from "@cerebriline/shared";
|
|
2
|
+
/** The plan an account is on, or a model requires. Open-ended on purpose: the
|
|
3
|
+
* server sends a string and a plan tier this build has never heard of must
|
|
4
|
+
* still render. */
|
|
5
|
+
export type OllamaPlan = string;
|
|
6
|
+
export interface OllamaAccount {
|
|
7
|
+
/** Whether `/api/me` answered at all. Not signed in and not reachable are
|
|
8
|
+
* different conditions and the panel says which. */
|
|
9
|
+
readonly reachable: boolean;
|
|
10
|
+
readonly signedIn: boolean;
|
|
11
|
+
readonly plan?: OllamaPlan;
|
|
12
|
+
readonly name?: string;
|
|
13
|
+
readonly email?: string;
|
|
14
|
+
/** Where to sign in, as the server itself computed it. */
|
|
15
|
+
readonly signinUrl?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface OllamaRecommendation {
|
|
18
|
+
readonly model: string;
|
|
19
|
+
readonly description?: string;
|
|
20
|
+
readonly contextLength?: number;
|
|
21
|
+
readonly maxOutputTokens?: number;
|
|
22
|
+
readonly requiredPlan?: OllamaPlan;
|
|
23
|
+
/**
|
|
24
|
+
* The thinking settings the model accepts, normalized to strings.
|
|
25
|
+
*
|
|
26
|
+
* The wire mixes booleans and levels in one array -- `[false, "low",
|
|
27
|
+
* "high", "max"]` for one model and `[false, true]` for another -- so
|
|
28
|
+
* `false` renders as `off` and `true` as `on`. A model whose values are
|
|
29
|
+
* `off`/`on` has a switch; one with levels has a picker.
|
|
30
|
+
*/
|
|
31
|
+
readonly thinkingValues?: readonly string[];
|
|
32
|
+
readonly thinkingDefault?: string;
|
|
33
|
+
/** Present on local recommendations only; the cloud ones carry no size. */
|
|
34
|
+
readonly vramBytes?: number;
|
|
35
|
+
}
|
|
36
|
+
export interface OllamaCatalogEntry {
|
|
37
|
+
readonly name: string;
|
|
38
|
+
/** True when `/api/tags` gave it a `remote_host` or a `remote_model`. */
|
|
39
|
+
readonly cloud: boolean;
|
|
40
|
+
readonly remoteHost?: string;
|
|
41
|
+
readonly remoteModel?: string;
|
|
42
|
+
readonly family?: string;
|
|
43
|
+
readonly capabilities: readonly string[];
|
|
44
|
+
/**
|
|
45
|
+
* `false` for a cloud model the server offers but has not pulled: listed
|
|
46
|
+
* by its recommendations and absent from `/api/tags`. Ollama fetches its
|
|
47
|
+
* manifest on the first request, so it is as usable as a pulled one.
|
|
48
|
+
* Absent for every entry `/api/tags` itself lists.
|
|
49
|
+
*/
|
|
50
|
+
readonly pulled?: false;
|
|
51
|
+
}
|
|
52
|
+
export interface OllamaAccountStatus {
|
|
53
|
+
/** Whether the server answered `/api/tags`. */
|
|
54
|
+
readonly reachable: boolean;
|
|
55
|
+
readonly account: OllamaAccount;
|
|
56
|
+
readonly recommendations: readonly OllamaRecommendation[];
|
|
57
|
+
readonly models: readonly OllamaCatalogEntry[];
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Read `POST /api/me`.
|
|
61
|
+
*
|
|
62
|
+
* The response uses Go's exported field names (`Name`, `Plan`, `Email`), not
|
|
63
|
+
* the snake_case every other Ollama endpoint uses; both spellings are accepted
|
|
64
|
+
* so a future rename does not silently empty the strip.
|
|
65
|
+
*/
|
|
66
|
+
export declare function parseOllamaWhoami(status: number, payload: unknown): OllamaAccount;
|
|
67
|
+
/** Read `GET /api/experimental/model-recommendations`. */
|
|
68
|
+
export declare function parseOllamaRecommendations(payload: unknown): OllamaRecommendation[];
|
|
69
|
+
/**
|
|
70
|
+
* The cloud models a server offers without having pulled them.
|
|
71
|
+
*
|
|
72
|
+
* pandorum, 2026-09-30: `glm-5.3-flash:cloud` headed the recommendations, ran
|
|
73
|
+
* a session with its 1M window, and was not among the 166 tags -- so the chat
|
|
74
|
+
* box said the server did not have it, the settings strip had nothing to say
|
|
75
|
+
* about it, and the picker could not offer it. A cloud recommendation needs no
|
|
76
|
+
* pull: the server fetches its manifest on first use.
|
|
77
|
+
*
|
|
78
|
+
* Cloud recommendations only. A local one (it carries a `vram_bytes`) does
|
|
79
|
+
* need a pull, and its absence from the tags is the truth. The name suffix is
|
|
80
|
+
* the only mark a recommendation has, so it decides here; `remote_host`, the
|
|
81
|
+
* real discriminator, exists only once a model is pulled.
|
|
82
|
+
*/
|
|
83
|
+
export declare function unpulledCloudModels(recommendations: readonly OllamaRecommendation[], catalog: readonly OllamaCatalogEntry[]): OllamaCatalogEntry[];
|
|
84
|
+
/** Read `GET /api/tags`. */
|
|
85
|
+
export declare function parseOllamaCatalog(payload: unknown): OllamaCatalogEntry[];
|
|
86
|
+
/**
|
|
87
|
+
* The fallback when the catalog could not be read.
|
|
88
|
+
*
|
|
89
|
+
* Deliberately last-resort: it is right about `kimi-k2.6:cloud` and wrong about
|
|
90
|
+
* `glm-5.3-flash-tpl2:latest`, and a `-cloud` in the middle of a name is not a
|
|
91
|
+
* suffix.
|
|
92
|
+
*/
|
|
93
|
+
export declare function looksLikeCloudName(modelId: string): boolean;
|
|
94
|
+
/**
|
|
95
|
+
* Find the recommendation that describes a tag.
|
|
96
|
+
*
|
|
97
|
+
* A tag built FROM a cloud model keeps its own name — `glm-5.3-flash-tpl2:latest`
|
|
98
|
+
* is `glm-5.3-flash` underneath — so `remote_model` is tried before the tag's
|
|
99
|
+
* own name. Without that, every re-templated cloud model reads as unlisted.
|
|
100
|
+
*/
|
|
101
|
+
export declare function matchOllamaRecommendation(recommendations: readonly OllamaRecommendation[], model: {
|
|
102
|
+
readonly name: string;
|
|
103
|
+
readonly remoteModel?: string;
|
|
104
|
+
}): OllamaRecommendation | undefined;
|
|
105
|
+
/**
|
|
106
|
+
* Read everything the settings panel shows about an Ollama endpoint.
|
|
107
|
+
*
|
|
108
|
+
* Nothing here may fail a caller. Each read stands alone: a server that does
|
|
109
|
+
* not proxy `/api/me` still reports its models, and an account read that says
|
|
110
|
+
* "not signed in" does not suppress the recommendations, which need no auth.
|
|
111
|
+
*/
|
|
112
|
+
export declare function readOllamaAccountStatus(baseUrl: string | undefined, fetchImpl?: typeof fetch): Promise<OllamaAccountStatus>;
|
|
113
|
+
/** Test seam, and the reset a base-URL change needs. */
|
|
114
|
+
export declare function resetOllamaAccountStatus(): void;
|
|
115
|
+
/** What has been primed for this server, if anything. */
|
|
116
|
+
export declare function readOllamaAccountCache(baseUrl: string | undefined): OllamaAccountStatus | undefined;
|
|
117
|
+
/** Prime {@link readOllamaAccountCache} for a server, at most once. */
|
|
118
|
+
export declare function primeOllamaAccountStatus(baseUrl: string | undefined, fetchImpl?: typeof fetch, logger?: BasicLogger): Promise<void>;
|
|
119
|
+
/**
|
|
120
|
+
* Whether a model is served from the cloud.
|
|
121
|
+
*
|
|
122
|
+
* `undefined` when the catalog has not been primed — which is not the same as
|
|
123
|
+
* `false`, and callers that care about the difference must ask for it.
|
|
124
|
+
*/
|
|
125
|
+
export declare function readOllamaCloudFlag(baseUrl: string | undefined, modelId: string | undefined): boolean | undefined;
|
|
126
|
+
/** The recommendation describing a model on a primed server, if it has one. */
|
|
127
|
+
export declare function readOllamaRecommendation(baseUrl: string | undefined, modelId: string | undefined): OllamaRecommendation | undefined;
|
|
128
|
+
//# sourceMappingURL=ollama-account.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ollama-account.d.ts","sourceRoot":"","sources":["../../../src/providers/vendors/ollama-account.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether an Ollama or xOllama endpoint answers, for the chat input.
|
|
3
|
+
*
|
|
4
|
+
* The chat box is where a dead server is found out, and until now it was found
|
|
5
|
+
* out by sending a message and reading the error. This is one `GET /api/tags`
|
|
6
|
+
* with a short bound: cheap enough to repeat while the panel is open, and the
|
|
7
|
+
* one read that also says whether the selected model is there at all.
|
|
8
|
+
*
|
|
9
|
+
* Deliberately not {@link readOllamaAccountStatus}: that one also asks
|
|
10
|
+
* ollama.com who the host is signed in as, a signed round trip that has no
|
|
11
|
+
* business on a poll.
|
|
12
|
+
*
|
|
13
|
+
* An unset base URL is resolved the way the chat request resolves it -- the
|
|
14
|
+
* package's own default for Ollama, {@link XOLLAMA_DEFAULT_BASE_URL} for
|
|
15
|
+
* xOllama -- so the probe asks the server the chat would have asked.
|
|
16
|
+
*/
|
|
17
|
+
/** Where `ollama-ai-provider-v2` sends a request with no base URL. */
|
|
18
|
+
export declare const OLLAMA_PACKAGE_DEFAULT_BASE_URL = "http://127.0.0.1:11434";
|
|
19
|
+
/** Long enough for a busy server's `/api/tags`, short enough to say "down" promptly. */
|
|
20
|
+
export declare const OLLAMA_REACHABILITY_TIMEOUT_MS = 4000;
|
|
21
|
+
export interface OllamaReachability {
|
|
22
|
+
readonly reachable: boolean;
|
|
23
|
+
/** The origin asked, as the user would type it. */
|
|
24
|
+
readonly baseUrl: string;
|
|
25
|
+
/** Why it did not answer: an HTTP status, a timeout, or the network's word. */
|
|
26
|
+
readonly error?: string;
|
|
27
|
+
/**
|
|
28
|
+
* It answered, and refused the request for want of a key (401). xOllama
|
|
29
|
+
* with a local key set answers every route so; the server is up and the
|
|
30
|
+
* fix is in the provider's settings, not on the server.
|
|
31
|
+
*/
|
|
32
|
+
readonly unauthorized?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Whether the model is in `/api/tags`. Absent when no model was named or
|
|
35
|
+
* the server did not answer -- not the same as `false`.
|
|
36
|
+
*/
|
|
37
|
+
readonly modelFound?: boolean;
|
|
38
|
+
}
|
|
39
|
+
/** The origin a chat request on this provider goes to. */
|
|
40
|
+
export declare function resolveOllamaOrigin(providerId: string, baseUrl: string | undefined): string;
|
|
41
|
+
export declare function probeOllamaReachability(providerId: string, baseUrl: string | undefined, modelId?: string, fetchImpl?: typeof fetch): Promise<OllamaReachability>;
|
|
42
|
+
//# sourceMappingURL=ollama-reachability.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ollama-reachability.d.ts","sourceRoot":"","sources":["../../../src/providers/vendors/ollama-reachability.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAQH,sEAAsE;AACtE,eAAO,MAAM,+BAA+B,2BAA2B,CAAC;AAExE,wFAAwF;AACxF,eAAO,MAAM,8BAA8B,OAAO,CAAC;AAEnD,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,mDAAmD;IACnD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,+EAA+E;IAC/E,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;IAChC;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,0DAA0D;AAC1D,wBAAgB,mBAAmB,CAClC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GAAG,SAAS,GACzB,MAAM,CAQR;AA2CD,wBAAsB,uBAAuB,CAC5C,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,CAAC,EAAE,MAAM,EAChB,SAAS,GAAE,OAAO,KAAa,GAC7B,OAAO,CAAC,kBAAkB,CAAC,CAgD7B"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A stall bound that asks the server before it gives up.
|
|
3
|
+
*
|
|
4
|
+
* Every fixed timeout on a local model is a guess about hardware. undici's
|
|
5
|
+
* five-minute `bodyTimeout` is the one that keeps ending runs, but replacing it
|
|
6
|
+
* with a bigger constant only moves the guess: prompt prefill at a hundred
|
|
7
|
+
* thousand tokens is minutes of silence on a healthy socket, and the same
|
|
8
|
+
* silence is what a crashed server looks like from the client side. The two are
|
|
9
|
+
* indistinguishable from the stream alone — but not from the server, which will
|
|
10
|
+
* answer a second connection in milliseconds if it is alive.
|
|
11
|
+
*
|
|
12
|
+
* So silence is not the failure condition here; silence *from a server that has
|
|
13
|
+
* stopped answering* is. On each quiet interval this asks Ollama whether it is
|
|
14
|
+
* up, and a server that answers buys the request another interval, from zero,
|
|
15
|
+
* as many times as it keeps answering. What is left is a real bound — the
|
|
16
|
+
* request dies when the server does, and only then.
|
|
17
|
+
*
|
|
18
|
+
* The interval is therefore a polling period rather than a patience budget, and
|
|
19
|
+
* is set short enough to notice a dead server quickly rather than long enough
|
|
20
|
+
* to outlast a slow one.
|
|
21
|
+
*/
|
|
22
|
+
import type { BasicLogger } from "@cerebriline/shared";
|
|
23
|
+
/** How long a quiet stream may stay quiet before the server is asked about it. */
|
|
24
|
+
export declare const OLLAMA_STALL_PROBE_INTERVAL_MS = 30000;
|
|
25
|
+
/** How long the health probe itself may take before it counts as no answer. */
|
|
26
|
+
export declare const OLLAMA_HEALTH_PROBE_TIMEOUT_MS = 10000;
|
|
27
|
+
/**
|
|
28
|
+
* How many probes in a row must go unanswered before the request is failed.
|
|
29
|
+
*
|
|
30
|
+
* More than one because a single refused connection is not yet evidence: a
|
|
31
|
+
* server under a heavy generation can drop a probe, and killing a run that was
|
|
32
|
+
* about to produce its first token is worse than waiting one more interval.
|
|
33
|
+
*/
|
|
34
|
+
export declare const OLLAMA_HEALTH_PROBE_FAILURES_BEFORE_GIVING_UP = 3;
|
|
35
|
+
export type OllamaHealthProbe = () => Promise<boolean>;
|
|
36
|
+
/**
|
|
37
|
+
* Ask an Ollama server whether it is alive.
|
|
38
|
+
*
|
|
39
|
+
* `/api/ps` rather than `/api/version` because the answer carries something
|
|
40
|
+
* worth logging — whether the model this request is for is still resident. That
|
|
41
|
+
* does not decide the verdict: a model evicted mid-queue will be reloaded and
|
|
42
|
+
* the request still completes, so treating eviction as death would fail
|
|
43
|
+
* requests that were going to succeed. It is the difference between "the
|
|
44
|
+
* server is busy with us" and "the server is busy with something else", which
|
|
45
|
+
* is exactly what someone reading the log after a stall wants to know.
|
|
46
|
+
*/
|
|
47
|
+
export declare function createOllamaHealthProbe(options: {
|
|
48
|
+
url: string;
|
|
49
|
+
fetch: typeof fetch;
|
|
50
|
+
model?: string;
|
|
51
|
+
dispatcher?: unknown;
|
|
52
|
+
timeoutMs?: number;
|
|
53
|
+
logger?: BasicLogger;
|
|
54
|
+
}): OllamaHealthProbe;
|
|
55
|
+
export interface StallWatchdogOptions {
|
|
56
|
+
probe: OllamaHealthProbe;
|
|
57
|
+
intervalMs?: number;
|
|
58
|
+
failuresBeforeGivingUp?: number;
|
|
59
|
+
logger?: BasicLogger;
|
|
60
|
+
/** Names the thing being watched in logs and in the failure message. */
|
|
61
|
+
label: string;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Run `probe` every quiet interval until something else finishes.
|
|
65
|
+
*
|
|
66
|
+
* Returns a stop function and calls `onDead` once, with the elapsed time, when
|
|
67
|
+
* the server has failed enough probes in a row to be called dead. Restarting
|
|
68
|
+
* the interval after a successful probe is the whole point: a live server
|
|
69
|
+
* resets the clock rather than spending a budget.
|
|
70
|
+
*/
|
|
71
|
+
export declare function watchForStall(options: StallWatchdogOptions & {
|
|
72
|
+
onDead: (elapsedMs: number) => void;
|
|
73
|
+
}): {
|
|
74
|
+
stop: () => void;
|
|
75
|
+
noteActivity: () => void;
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Wrap a streaming response so a stalled body is measured against the server
|
|
79
|
+
* rather than against a stopwatch.
|
|
80
|
+
*
|
|
81
|
+
* The reader's pending read is kept and re-raced rather than re-issued: a
|
|
82
|
+
* `ReadableStreamDefaultReader` allows one outstanding `read()`, so the timeout
|
|
83
|
+
* has to lose the race without cancelling the thing it raced.
|
|
84
|
+
*/
|
|
85
|
+
export declare function withStallWatchdog(response: Response, options: StallWatchdogOptions): Response;
|
|
86
|
+
//# sourceMappingURL=ollama-stall-watchdog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ollama-stall-watchdog.d.ts","sourceRoot":"","sources":["../../../src/providers/vendors/ollama-stall-watchdog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,kFAAkF;AAClF,eAAO,MAAM,8BAA8B,QAAS,CAAC;AAErD,+EAA+E;AAC/E,eAAO,MAAM,8BAA8B,QAAS,CAAC;AAErD;;;;;;GAMG;AACH,eAAO,MAAM,6CAA6C,IAAI,CAAC;AAE/D,MAAM,MAAM,iBAAiB,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;AAWvD;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE;IAChD,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,WAAW,CAAC;CACrB,GAAG,iBAAiB,CA0CpB;AA0BD,MAAM,WAAW,oBAAoB;IACpC,KAAK,EAAE,iBAAiB,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,wEAAwE;IACxE,KAAK,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC5B,OAAO,EAAE,oBAAoB,GAAG;IAAE,MAAM,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,GACrE;IAAE,IAAI,EAAE,MAAM,IAAI,CAAC;IAAC,YAAY,EAAE,MAAM,IAAI,CAAA;CAAE,CAwDhD;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAChC,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,oBAAoB,GAC3B,QAAQ,CAiEV"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Put tool-result images back on the tool message, on the way out.
|
|
3
|
+
*
|
|
4
|
+
* `splitToolImagesMiddleware` moves image bytes out of a `role:"tool"` message
|
|
5
|
+
* and into a synthetic `role:"user"` message placed immediately after it. That
|
|
6
|
+
* is the only shape chat-completions can carry, and for those wire formats it
|
|
7
|
+
* is correct. Ollama's native `/api/chat` is not one of them: `images` is a
|
|
8
|
+
* field on every message, tool messages included, and every renderer that
|
|
9
|
+
* handles images at all routes tool responses through the same content path.
|
|
10
|
+
*
|
|
11
|
+
* Leaving the synthetic user message in place is not merely redundant there —
|
|
12
|
+
* it is destructive. Chat templates decide how much of the assistant's own
|
|
13
|
+
* reasoning to replay from the position of the last user turn:
|
|
14
|
+
*
|
|
15
|
+
* if message.Role == "assistant" && message.Thinking != "" && i > lastUserIdx
|
|
16
|
+
* (ollama, model/renderers/gemma4.go)
|
|
17
|
+
*
|
|
18
|
+
* A user message injected after every screenshot moves `lastUserIdx` to the end
|
|
19
|
+
* of the conversation, so *every* thinking block before it stops being
|
|
20
|
+
* rendered. Measured on a live session: 209,028 characters of prompt became
|
|
21
|
+
* 104,026 — the model's entire reasoning history, three blocks of it over
|
|
22
|
+
* 20,000 characters each, gone from a request that otherwise looked fine. The
|
|
23
|
+
* model then reads fourteen turns of assistants that did not think, and stops
|
|
24
|
+
* thinking. It recovers only when compaction happens to drop the screenshots.
|
|
25
|
+
*
|
|
26
|
+
* So this runs at the wire layer rather than as another middleware: the
|
|
27
|
+
* conversion that loses the images (`convertToOllamaChatMessages`, whose `tool`
|
|
28
|
+
* branch writes `content` and nothing else) sits between the typed prompt and
|
|
29
|
+
* here, and this is the first point where the images and the tool message they
|
|
30
|
+
* belong to exist in the same object again.
|
|
31
|
+
*/
|
|
32
|
+
/** What the splitting middleware leaves behind in the tool result. */
|
|
33
|
+
export declare const OLLAMA_SPLIT_IMAGE_PLACEHOLDER = "(see following user message for image)";
|
|
34
|
+
export interface MergeToolImagesResult {
|
|
35
|
+
messages: unknown[];
|
|
36
|
+
/** How many synthetic user messages were folded away. */
|
|
37
|
+
merged: number;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Fold each synthetic image message into the tool message it follows.
|
|
41
|
+
*
|
|
42
|
+
* A synthetic message that does not follow a tool message is left exactly
|
|
43
|
+
* where it is: that is either a real user turn or a shape this function does
|
|
44
|
+
* not recognise, and dropping an image is worse than the prompt cost of one
|
|
45
|
+
* extra message.
|
|
46
|
+
*/
|
|
47
|
+
export declare function mergeOllamaToolImages(messages: unknown): MergeToolImagesResult;
|
|
48
|
+
export interface RewrittenOllamaBody {
|
|
49
|
+
/** The body to send, unchanged when there was nothing to do. */
|
|
50
|
+
body: string;
|
|
51
|
+
/** The model this request is for, when the body names one. */
|
|
52
|
+
model?: string;
|
|
53
|
+
merged: number;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Rewrite a serialized `/api/chat` body, and read the model name while it is
|
|
57
|
+
* parsed.
|
|
58
|
+
*
|
|
59
|
+
* Both callers want something out of the same parse, and a request body at
|
|
60
|
+
* these sizes is not something to parse twice: the transcripts that trigger
|
|
61
|
+
* this are a quarter of a megabyte, most of it base64.
|
|
62
|
+
*
|
|
63
|
+
* Never throws. A body that is not JSON, or not a chat body, is something this
|
|
64
|
+
* has no opinion about — it goes out as it came in.
|
|
65
|
+
*/
|
|
66
|
+
export declare function rewriteOllamaChatBody(body: unknown): RewrittenOllamaBody | undefined;
|
|
67
|
+
//# sourceMappingURL=ollama-tool-images.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ollama-tool-images.d.ts","sourceRoot":"","sources":["../../../src/providers/vendors/ollama-tool-images.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,sEAAsE;AACtE,eAAO,MAAM,8BAA8B,2CACF,CAAC;AA6C1C,MAAM,WAAW,qBAAqB;IACrC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACpC,QAAQ,EAAE,OAAO,GACf,qBAAqB,CA4BvB;AAED,MAAM,WAAW,mBAAmB;IACnC,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACpC,IAAI,EAAE,OAAO,GACX,mBAAmB,GAAG,SAAS,CAuBjC"}
|