@nemesis-oss/ollama-sdk 1.13.0 → 1.15.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 +43 -0
- package/README.md +170 -4
- package/dist/{anthropic-B9AFyzXI.d.ts → anthropic-DrDUfbfQ.d.ts} +1 -1
- package/dist/{anthropic-CYy_ECam.d.cts → anthropic-UeaVjLeP.d.cts} +1 -1
- package/dist/{compose-6UOPEknN.d.ts → compose-CeFbHJeO.d.ts} +1 -1
- package/dist/{compose-DhvoUrWa.d.cts → compose-DFkmtUOP.d.cts} +1 -1
- package/dist/generated-api.d.cts +5 -5
- package/dist/generated-api.d.ts +5 -5
- package/dist/generated-runtime.d.cts +2 -2
- package/dist/generated-runtime.d.ts +2 -2
- package/dist/index.cjs +140 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +185 -11
- package/dist/index.d.ts +185 -11
- package/dist/index.js +140 -3
- package/dist/index.js.map +1 -1
- package/dist/mcp-generated.d.cts +2 -2
- package/dist/mcp-generated.d.ts +2 -2
- package/dist/{runtime-CIQYCRL3.d.ts → runtime-BIjr5ME4.d.ts} +1 -1
- package/dist/{runtime-DmI1cOEq.d.cts → runtime-C4RRHqOs.d.cts} +1 -1
- package/dist/skills.d.cts +3 -3
- package/dist/skills.d.ts +3 -3
- package/dist/testing.cjs +283 -0
- package/dist/testing.cjs.map +1 -0
- package/dist/testing.d.cts +376 -0
- package/dist/testing.d.ts +376 -0
- package/dist/testing.js +277 -0
- package/dist/testing.js.map +1 -0
- package/dist/{types-B57ZZfp3.d.cts → types-DbPnfVh-.d.cts} +20 -3
- package/dist/{types-B57ZZfp3.d.ts → types-DbPnfVh-.d.ts} +20 -3
- package/package.json +14 -1
package/dist/index.js
CHANGED
|
@@ -2815,12 +2815,29 @@ var ModelsClient = class {
|
|
|
2815
2815
|
* await client.models.createModelFromGguf('my-model', '/path/to/model.gguf', {
|
|
2816
2816
|
* template: '{{ .Prompt }}',
|
|
2817
2817
|
* });
|
|
2818
|
+
*
|
|
2819
|
+
* // Speculative decoding: primary + draft shards + tuning:
|
|
2820
|
+
* await client.models.createModelFromGguf('my-model', '/path/to/model.gguf', {
|
|
2821
|
+
* draftGguf: '/path/to/draft.gguf',
|
|
2822
|
+
* draftQuantize: 'q8_0',
|
|
2823
|
+
* parameters: { draft_num_predict: 8 },
|
|
2824
|
+
* });
|
|
2818
2825
|
* ```
|
|
2819
2826
|
*
|
|
2827
|
+
* Speculative-decoding models assemble the same way: pass the draft
|
|
2828
|
+
* network's GGUF(s) as `draftGguf` (uploaded into `draft_files`), optionally
|
|
2829
|
+
* set `draft_quantize` to compress the draft weights independently of the
|
|
2830
|
+
* primary model, and set `parameters.draft_num_predict` to tune how many
|
|
2831
|
+
* tokens the draft network predicts per step (Ollama defaults separate
|
|
2832
|
+
* draft models to 4; `0` disables drafting; models with embedded MTP
|
|
2833
|
+
* tensors require setting it explicitly).
|
|
2834
|
+
*
|
|
2820
2835
|
* @param model Name for the new model (e.g. `'my-model:latest'`).
|
|
2821
2836
|
* @param gguf Path(s) to GGUF file(s) on the local filesystem.
|
|
2822
2837
|
* @param opts Everything else `/api/create` accepts (`template`, `system`,
|
|
2823
|
-
* `parameters`, `license`, `quantize`, …) except `files
|
|
2838
|
+
* `parameters`, `license`, `quantize`, `draftGguf`, …) except `files`,
|
|
2839
|
+
* `draft_files` (use `draftGguf` for path-based drafts; an explicit digest
|
|
2840
|
+
* map is still accepted and merged), `from`, and `stream`.
|
|
2824
2841
|
*/
|
|
2825
2842
|
async createModelFromGguf(model, gguf, opts) {
|
|
2826
2843
|
const paths = typeof gguf === "string" ? [gguf] : gguf;
|
|
@@ -2834,14 +2851,29 @@ var ModelsClient = class {
|
|
|
2834
2851
|
const uploaded = await this.createBlobFromFile(path, { signal: opts?.signal });
|
|
2835
2852
|
files[uploaded.fileName] = uploaded.digest;
|
|
2836
2853
|
}
|
|
2854
|
+
const draftOpt = opts?.draftGguf;
|
|
2855
|
+
const draftPaths = typeof draftOpt === "string" ? [draftOpt] : draftOpt ?? [];
|
|
2837
2856
|
const {
|
|
2838
2857
|
model: _model,
|
|
2839
2858
|
files: _files,
|
|
2840
2859
|
from: _from,
|
|
2841
2860
|
stream: _stream,
|
|
2861
|
+
draftGguf: _draftGguf,
|
|
2862
|
+
draft_files: _draftFiles,
|
|
2842
2863
|
...rest
|
|
2843
2864
|
} = opts ?? {};
|
|
2844
|
-
|
|
2865
|
+
const draftFiles = { ..._draftFiles ?? {} };
|
|
2866
|
+
for (const path of draftPaths) {
|
|
2867
|
+
const uploaded = await this.createBlobFromFile(path, { signal: opts?.signal });
|
|
2868
|
+
draftFiles[uploaded.fileName] = uploaded.digest;
|
|
2869
|
+
}
|
|
2870
|
+
return this.create({
|
|
2871
|
+
...rest,
|
|
2872
|
+
model,
|
|
2873
|
+
files,
|
|
2874
|
+
...Object.keys(draftFiles).length > 0 ? { draft_files: draftFiles } : {},
|
|
2875
|
+
stream: false
|
|
2876
|
+
});
|
|
2845
2877
|
}
|
|
2846
2878
|
};
|
|
2847
2879
|
|
|
@@ -7716,6 +7748,111 @@ var Agent = class {
|
|
|
7716
7748
|
}
|
|
7717
7749
|
};
|
|
7718
7750
|
|
|
7751
|
+
// src/draft-benchmark.ts
|
|
7752
|
+
var DEFAULT_DRAFT_TOKENS = 4;
|
|
7753
|
+
var DEFAULT_SAMPLES = 5;
|
|
7754
|
+
var DEFAULT_NUM_PREDICT = 256;
|
|
7755
|
+
var DEFAULT_SEED = 42;
|
|
7756
|
+
var DEFAULT_GAIN_THRESHOLD = 1.05;
|
|
7757
|
+
function median(values) {
|
|
7758
|
+
const sorted = [...values].sort((a, b) => a - b);
|
|
7759
|
+
const mid = Math.floor(sorted.length / 2);
|
|
7760
|
+
return sorted.length % 2 === 1 ? sorted[mid] ?? 0 : ((sorted[mid - 1] ?? 0) + (sorted[mid] ?? 0)) / 2;
|
|
7761
|
+
}
|
|
7762
|
+
function roundTo(value, decimals) {
|
|
7763
|
+
const factor = 10 ** decimals;
|
|
7764
|
+
return Math.round(value * factor) / factor;
|
|
7765
|
+
}
|
|
7766
|
+
function requirePositiveInteger(name, value) {
|
|
7767
|
+
if (!Number.isInteger(value) || value < 1) {
|
|
7768
|
+
throw new RangeError(
|
|
7769
|
+
`compareDraftPerformance: ${name} must be an integer >= 1 (got ${value}).`
|
|
7770
|
+
);
|
|
7771
|
+
}
|
|
7772
|
+
}
|
|
7773
|
+
async function runSide(client, options, draftNumPredict, samples, numPredict, seed) {
|
|
7774
|
+
const samplingOptions = {
|
|
7775
|
+
num_predict: numPredict,
|
|
7776
|
+
temperature: 0,
|
|
7777
|
+
seed,
|
|
7778
|
+
draft_num_predict: draftNumPredict
|
|
7779
|
+
};
|
|
7780
|
+
if (options.warmup ?? true) {
|
|
7781
|
+
await client.generate({
|
|
7782
|
+
model: options.model,
|
|
7783
|
+
prompt: options.prompt,
|
|
7784
|
+
options: { ...samplingOptions, num_predict: 1 },
|
|
7785
|
+
stream: false,
|
|
7786
|
+
signal: options.signal
|
|
7787
|
+
});
|
|
7788
|
+
}
|
|
7789
|
+
const tokensPerSecond = [];
|
|
7790
|
+
const generationMs = [];
|
|
7791
|
+
for (let i = 0; i < samples; i++) {
|
|
7792
|
+
options.signal?.throwIfAborted();
|
|
7793
|
+
const response = await client.generate({
|
|
7794
|
+
model: options.model,
|
|
7795
|
+
prompt: options.prompt,
|
|
7796
|
+
options: samplingOptions,
|
|
7797
|
+
stream: false,
|
|
7798
|
+
signal: options.signal
|
|
7799
|
+
});
|
|
7800
|
+
const telemetry = formatTelemetry(response);
|
|
7801
|
+
if (Number.isFinite(telemetry.tokensPerSecond) && telemetry.tokensPerSecond > 0) {
|
|
7802
|
+
tokensPerSecond.push(telemetry.tokensPerSecond);
|
|
7803
|
+
generationMs.push(telemetry.generationMs);
|
|
7804
|
+
}
|
|
7805
|
+
}
|
|
7806
|
+
if (tokensPerSecond.length === 0) {
|
|
7807
|
+
throw new OllamaClientError(
|
|
7808
|
+
`compareDraftPerformance: every draft_num_predict=${draftNumPredict} sample returned a non-positive tokens/second. The model name is likely wrong, or the server returned empty generations.`,
|
|
7809
|
+
{ code: "draft_benchmark_no_valid_samples" }
|
|
7810
|
+
);
|
|
7811
|
+
}
|
|
7812
|
+
return {
|
|
7813
|
+
draftNumPredict,
|
|
7814
|
+
medianTokensPerSecond: median(tokensPerSecond),
|
|
7815
|
+
sampleTokensPerSecond: tokensPerSecond,
|
|
7816
|
+
medianEvalDurationMs: median(generationMs)
|
|
7817
|
+
};
|
|
7818
|
+
}
|
|
7819
|
+
async function compareDraftPerformance(client, options) {
|
|
7820
|
+
const draftNumPredict = options.draftNumPredict ?? DEFAULT_DRAFT_TOKENS;
|
|
7821
|
+
requirePositiveInteger("draftNumPredict", draftNumPredict);
|
|
7822
|
+
const samples = options.samples ?? DEFAULT_SAMPLES;
|
|
7823
|
+
requirePositiveInteger("samples", samples);
|
|
7824
|
+
const numPredict = options.numPredict ?? DEFAULT_NUM_PREDICT;
|
|
7825
|
+
requirePositiveInteger("numPredict", numPredict);
|
|
7826
|
+
const seed = options.seed ?? DEFAULT_SEED;
|
|
7827
|
+
if (!Number.isInteger(seed)) {
|
|
7828
|
+
throw new RangeError(`compareDraftPerformance: seed must be an integer (got ${seed}).`);
|
|
7829
|
+
}
|
|
7830
|
+
const gainThreshold = options.gainThreshold ?? DEFAULT_GAIN_THRESHOLD;
|
|
7831
|
+
if (!Number.isFinite(gainThreshold) || gainThreshold <= 0) {
|
|
7832
|
+
throw new RangeError(
|
|
7833
|
+
`compareDraftPerformance: gainThreshold must be a positive finite number (got ${gainThreshold}).`
|
|
7834
|
+
);
|
|
7835
|
+
}
|
|
7836
|
+
options.signal?.throwIfAborted();
|
|
7837
|
+
const baseline = await runSide(client, options, 0, samples, numPredict, seed);
|
|
7838
|
+
const speculative = await runSide(client, options, draftNumPredict, samples, numPredict, seed);
|
|
7839
|
+
const baselineTokensPerSec = roundTo(baseline.medianTokensPerSecond, 1);
|
|
7840
|
+
const speculativeTokensPerSec = roundTo(speculative.medianTokensPerSecond, 1);
|
|
7841
|
+
const speedupMultiplier = baselineTokensPerSec > 0 ? roundTo(speculativeTokensPerSec / baselineTokensPerSec, 2) : 0;
|
|
7842
|
+
return {
|
|
7843
|
+
model: options.model,
|
|
7844
|
+
prompt: options.prompt,
|
|
7845
|
+
draftNumPredict,
|
|
7846
|
+
baselineTokensPerSec,
|
|
7847
|
+
speculativeTokensPerSec,
|
|
7848
|
+
speedupMultiplier,
|
|
7849
|
+
effectiveGain: speedupMultiplier > gainThreshold,
|
|
7850
|
+
gainThreshold,
|
|
7851
|
+
baseline,
|
|
7852
|
+
speculative
|
|
7853
|
+
};
|
|
7854
|
+
}
|
|
7855
|
+
|
|
7719
7856
|
// src/affinity.ts
|
|
7720
7857
|
var DEFAULT_CONCURRENT_MODELS = 1;
|
|
7721
7858
|
var DEFAULT_PER_MODEL_CONCURRENCY = 1;
|
|
@@ -7877,6 +8014,6 @@ function estimateSystemOneRequestBytes(request) {
|
|
|
7877
8014
|
return new TextEncoder().encode(JSON.stringify(request)).byteLength;
|
|
7878
8015
|
}
|
|
7879
8016
|
|
|
7880
|
-
export { ATTR_GEN_AI_OPERATION_NAME, ATTR_GEN_AI_REQUEST_MODEL, ATTR_GEN_AI_RESPONSE_MODEL, ATTR_GEN_AI_SYSTEM, ATTR_GEN_AI_TOOL_CALL_ID, ATTR_GEN_AI_TOOL_NAME, ATTR_GEN_AI_USAGE_INPUT_TOKENS, ATTR_GEN_AI_USAGE_OUTPUT_TOKENS, ATTR_HTTP_REQUEST_METHOD, ATTR_HTTP_RESPONSE_STATUS_CODE, ATTR_OLLAMA_AGENT_ITERATION, ATTR_OLLAMA_AGENT_MAX_ITERATIONS, ATTR_OLLAMA_ENDPOINT_ATTEMPT, ATTR_OLLAMA_ENDPOINT_NAME, ATTR_SERVER_ADDRESS, ATTR_SERVER_PORT, ATTR_URL_FULL, Agent, AnthropicCompatClient, AnthropicMessagesStream, ConversationSession, DEFAULT_BACKOFF, DEFAULT_BASE_URL, DEFAULT_CONTEXT_WARNING_THRESHOLD, DEFAULT_EMBED_BATCH_SIZE, DEFAULT_EMBED_CONCURRENCY, DEFAULT_FAILOVER_CODES, DEFAULT_FETCH_BACKOFF_CONFIG, DEFAULT_RETRY_CONFIG, DEFAULT_TIMEOUT_MS, EndpointRegistry, GEN_AI_SYSTEM_OLLAMA, HttpClient, IMAGE_TOKEN_ESTIMATE, KEEP_ALIVE_INDEFINITE, KEEP_ALIVE_UNLOAD, KNOWN_DONE_REASONS, MAX_SYSTEM_ONE_IMAGES_BYTES, MAX_SYSTEM_ONE_REQUEST_BYTES, MESSAGE_OVERHEAD_TOKENS, McpBridge, ModelAffinityRouter, ModelAffinityScheduler, ModelsClient, NANOS_PER_MS, NANOS_PER_SECOND, NOOP_LOGGER, OLLAMA_CLOUD_BASE_URL, OLLAMA_FALLBACK_CONTEXT_LENGTH, OllamaAbortError, OllamaAgentMaxIterationsError, OllamaAgentMaxToolCallsError, OllamaAgentToolLoopError, OllamaAuthError, OllamaBadGatewayError, OllamaClient, OllamaClientError, OllamaGenericClientError, OllamaIncompatibleModelError, OllamaMcpError, OllamaModelRoutingError, OllamaNetworkError, OllamaNotFoundError, OllamaOverloadedError, OllamaQuotaExceededError, OllamaRateLimitError, OllamaRequestTooLargeError, OllamaRequestValidationError, OllamaResponseValidationError, OllamaServerError, OllamaServerVersionUnknownError, OllamaSkillInvalidError, OllamaSkillNotFoundError, OllamaStream, OllamaStreamError, OllamaTimeoutError, OllamaToolTimeoutError, OllamaToolValidationError, OllamaUnsupportedCapabilityError, OpenAIChatCompletionStream, OpenAICompatClient, OpenAICompletionStream, OpenAIResponsesStream, OpenAIResponsesStreamError, QuotaManager, RETRYABLE_STATUS_CODES, ResponsesModule, ToolCallAccumulator, ToolRegistry, WEB_FETCH_TOOL_NAME, WEB_SEARCH_TOOL_NAME, addSpanEvent, applySkill, batchEmbed, calculateBackoff, canonicalToolCallSignature, checkChatContext, checkEndpointHealth, checkGenerateContext, compactConversationHistory, composeMiddleware, contextWarningMessage, createConsoleLogger, createDecision, createModelAffinityScheduler, createOllamaCloudFreeTierQuota, createTimeoutSignal, createWebFetchTool, createWebSearchTool, createWebTools, defineTool, detectModelCapabilities, embedBatchOverflowMessage, encodeImage, estimateChatRequestTokens, estimateGenerateRequestTokens, estimateMessageTokens, estimateSystemOneRequestBytes, estimateTokens, extractContextLength as extractNativeContextLength, extractParameterNumCtx, extractUsage, fetchWithBackoff, findOversizedEmbedInputs, findRunningModelContextLength, formatTelemetry, formatWebFetchResult, formatWebSearchResult, imageStringNeedsResolution, inferRuntimeMode, isKeepAliveSugar, isKnownDoneReason, isModelResident, isSameToolCall, listAllMcpTools, listAvailableModels, loadMcpTools, mapError, mergeToolCall, mergeToolCallArgumentsString, mergeToolCallArrays, normalizeChatStream, normalizeGenerateStream, normalizeKeepAlive, normalizeProgressStream, parseFrontmatter, parseNdjsonStream, parseSseStream, parseStructuredOutput, registerMcpTools, resolveContextLength, resolveCredentialEndpoints, resolveImageInput, sanitizeHistoryForNextTurn, setSpanError, toDataStream, toResponse, toTextStream, withRetry, withSpan, zodToJsonSchema };
|
|
8017
|
+
export { ATTR_GEN_AI_OPERATION_NAME, ATTR_GEN_AI_REQUEST_MODEL, ATTR_GEN_AI_RESPONSE_MODEL, ATTR_GEN_AI_SYSTEM, ATTR_GEN_AI_TOOL_CALL_ID, ATTR_GEN_AI_TOOL_NAME, ATTR_GEN_AI_USAGE_INPUT_TOKENS, ATTR_GEN_AI_USAGE_OUTPUT_TOKENS, ATTR_HTTP_REQUEST_METHOD, ATTR_HTTP_RESPONSE_STATUS_CODE, ATTR_OLLAMA_AGENT_ITERATION, ATTR_OLLAMA_AGENT_MAX_ITERATIONS, ATTR_OLLAMA_ENDPOINT_ATTEMPT, ATTR_OLLAMA_ENDPOINT_NAME, ATTR_SERVER_ADDRESS, ATTR_SERVER_PORT, ATTR_URL_FULL, Agent, AnthropicCompatClient, AnthropicMessagesStream, ConversationSession, DEFAULT_BACKOFF, DEFAULT_BASE_URL, DEFAULT_CONTEXT_WARNING_THRESHOLD, DEFAULT_EMBED_BATCH_SIZE, DEFAULT_EMBED_CONCURRENCY, DEFAULT_FAILOVER_CODES, DEFAULT_FETCH_BACKOFF_CONFIG, DEFAULT_RETRY_CONFIG, DEFAULT_TIMEOUT_MS, EndpointRegistry, GEN_AI_SYSTEM_OLLAMA, HttpClient, IMAGE_TOKEN_ESTIMATE, KEEP_ALIVE_INDEFINITE, KEEP_ALIVE_UNLOAD, KNOWN_DONE_REASONS, MAX_SYSTEM_ONE_IMAGES_BYTES, MAX_SYSTEM_ONE_REQUEST_BYTES, MESSAGE_OVERHEAD_TOKENS, McpBridge, ModelAffinityRouter, ModelAffinityScheduler, ModelsClient, NANOS_PER_MS, NANOS_PER_SECOND, NOOP_LOGGER, OLLAMA_CLOUD_BASE_URL, OLLAMA_FALLBACK_CONTEXT_LENGTH, OllamaAbortError, OllamaAgentMaxIterationsError, OllamaAgentMaxToolCallsError, OllamaAgentToolLoopError, OllamaAuthError, OllamaBadGatewayError, OllamaClient, OllamaClientError, OllamaGenericClientError, OllamaIncompatibleModelError, OllamaMcpError, OllamaModelRoutingError, OllamaNetworkError, OllamaNotFoundError, OllamaOverloadedError, OllamaQuotaExceededError, OllamaRateLimitError, OllamaRequestTooLargeError, OllamaRequestValidationError, OllamaResponseValidationError, OllamaServerError, OllamaServerVersionUnknownError, OllamaSkillInvalidError, OllamaSkillNotFoundError, OllamaStream, OllamaStreamError, OllamaTimeoutError, OllamaToolTimeoutError, OllamaToolValidationError, OllamaUnsupportedCapabilityError, OpenAIChatCompletionStream, OpenAICompatClient, OpenAICompletionStream, OpenAIResponsesStream, OpenAIResponsesStreamError, QuotaManager, RETRYABLE_STATUS_CODES, ResponsesModule, ToolCallAccumulator, ToolRegistry, WEB_FETCH_TOOL_NAME, WEB_SEARCH_TOOL_NAME, addSpanEvent, applySkill, batchEmbed, calculateBackoff, canonicalToolCallSignature, checkChatContext, checkEndpointHealth, checkGenerateContext, compactConversationHistory, compareDraftPerformance, composeMiddleware, contextWarningMessage, createConsoleLogger, createDecision, createModelAffinityScheduler, createOllamaCloudFreeTierQuota, createTimeoutSignal, createWebFetchTool, createWebSearchTool, createWebTools, defineTool, detectModelCapabilities, embedBatchOverflowMessage, encodeImage, estimateChatRequestTokens, estimateGenerateRequestTokens, estimateMessageTokens, estimateSystemOneRequestBytes, estimateTokens, extractContextLength as extractNativeContextLength, extractParameterNumCtx, extractUsage, fetchWithBackoff, findOversizedEmbedInputs, findRunningModelContextLength, formatTelemetry, formatWebFetchResult, formatWebSearchResult, imageStringNeedsResolution, inferRuntimeMode, isKeepAliveSugar, isKnownDoneReason, isModelResident, isSameToolCall, listAllMcpTools, listAvailableModels, loadMcpTools, mapError, mergeToolCall, mergeToolCallArgumentsString, mergeToolCallArrays, normalizeChatStream, normalizeGenerateStream, normalizeKeepAlive, normalizeProgressStream, parseFrontmatter, parseNdjsonStream, parseSseStream, parseStructuredOutput, registerMcpTools, resolveContextLength, resolveCredentialEndpoints, resolveImageInput, sanitizeHistoryForNextTurn, setSpanError, toDataStream, toResponse, toTextStream, withRetry, withSpan, zodToJsonSchema };
|
|
7881
8018
|
//# sourceMappingURL=index.js.map
|
|
7882
8019
|
//# sourceMappingURL=index.js.map
|