ai-sdk-ollama 3.7.1 → 3.8.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 CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.8.0
4
+
5
+ ### Minor Changes
6
+
7
+ - ed617f1: - **Fix:** Make `OllamaProviderOptions`, `OllamaChatProviderOptions`, and `OllamaEmbeddingProviderOptions` compatible with the AI SDK's `providerOptions` (`Record<string, JSONObject>`). They are now defined as type aliases from Zod schemas (`z.infer`), so passing e.g. `providerOptions: { ollama: { structuredOutputs: true } }` into `streamText`, `generateText`, or `ToolLoopAgent` type-checks correctly (fixes #548).
8
+ - **New:** Export provider option Zod schemas: `ollamaProviderOptionsSchema`, `ollamaChatProviderOptionsSchema`, `ollamaEmbeddingProviderOptionsSchema`, and `ollamaRerankingProviderOptionsSchema` for validation or parsing.
9
+ - **New:** Image generation support via `ollama.imageModel(modelId)` and `OllamaImageModel`, using the AI SDK's `generateImage()` and experimental Ollama image models (e.g. `x/z-image-turbo`, `x/flux2-klein`). Supports `providerOptions.ollama` (e.g. `steps`, `negative_prompt`).
10
+ - **Change:** Reranking model now uses `parseProviderOptions` from `@ai-sdk/provider-utils` for `providerOptions.ollama`; `OllamaRerankingProviderOptions` is now a type inferred from the exported schema.
11
+
3
12
  ## 3.7.1
4
13
 
5
14
  ### Patch Changes
@@ -35,7 +35,6 @@ __export(index_browser_exports, {
35
35
  module.exports = __toCommonJS(index_browser_exports);
36
36
 
37
37
  // src/provider.browser.ts
38
- var import_provider = require("@ai-sdk/provider");
39
38
  var import_browser = require("ollama/browser");
40
39
 
41
40
  // src/utils/tool-calling-reliability.ts
@@ -16423,6 +16422,7 @@ var ollamaRerankingResponseSchema = external_exports.object({
16423
16422
  )
16424
16423
  });
16425
16424
  var ollamaRerankingProviderOptionsSchema = external_exports.object({
16425
+ /** Custom instruction for this specific reranking call. Overrides the instruction set in model settings. */
16426
16426
  instruction: external_exports.string().optional()
16427
16427
  });
16428
16428
  var ollamaErrorSchema = external_exports.object({
@@ -16455,15 +16455,11 @@ var OllamaRerankingModel = class {
16455
16455
  providerOptions
16456
16456
  }) {
16457
16457
  const warnings = [];
16458
- let rerankingOptions;
16459
- if (providerOptions?.ollama) {
16460
- const parsed = ollamaRerankingProviderOptionsSchema.safeParse(
16461
- providerOptions.ollama
16462
- );
16463
- if (parsed.success) {
16464
- rerankingOptions = parsed.data;
16465
- }
16466
- }
16458
+ const rerankingOptions = await (0, import_provider_utils2.parseProviderOptions)({
16459
+ provider: "ollama",
16460
+ providerOptions,
16461
+ schema: ollamaRerankingProviderOptionsSchema
16462
+ });
16467
16463
  let documentValues;
16468
16464
  if (documents.type === "object") {
16469
16465
  warnings.push({
@@ -16657,6 +16653,115 @@ var OllamaEmbeddingRerankingModel = class {
16657
16653
  }
16658
16654
  };
16659
16655
 
16656
+ // src/models/image-model.ts
16657
+ var import_provider_utils3 = require("@ai-sdk/provider-utils");
16658
+ var ollamaImageProviderOptionsSchema = external_exports.object({
16659
+ steps: external_exports.number().optional(),
16660
+ negative_prompt: external_exports.string().optional()
16661
+ });
16662
+ var OllamaImageModel = class {
16663
+ constructor(modelId, config2) {
16664
+ this.config = config2;
16665
+ __publicField(this, "specificationVersion", "v3");
16666
+ __publicField(this, "provider");
16667
+ __publicField(this, "modelId");
16668
+ __publicField(this, "maxImagesPerCall", 1);
16669
+ this.modelId = modelId;
16670
+ this.provider = config2.provider;
16671
+ }
16672
+ async doGenerate(options) {
16673
+ const {
16674
+ prompt,
16675
+ size,
16676
+ aspectRatio,
16677
+ seed,
16678
+ providerOptions,
16679
+ abortSignal,
16680
+ headers: optHeaders
16681
+ } = options;
16682
+ if (prompt == null || prompt === "") {
16683
+ throw new OllamaError({ message: "Image generation requires a prompt" });
16684
+ }
16685
+ const url2 = `${this.config.baseURL.replace(/\/$/, "")}/api/generate`;
16686
+ const body = {
16687
+ model: this.modelId,
16688
+ prompt,
16689
+ stream: false
16690
+ };
16691
+ if (size) {
16692
+ const [w, h] = size.split("x").map(Number);
16693
+ if (!Number.isNaN(w)) body.width = w;
16694
+ if (!Number.isNaN(h)) body.height = h;
16695
+ }
16696
+ if (aspectRatio && body.width == null && body.height == null) {
16697
+ const [ratioW, ratioH] = aspectRatio.split(":").map(Number);
16698
+ if (ratioW != null && ratioH != null && !Number.isNaN(ratioW) && !Number.isNaN(ratioH) && ratioW > 0 && ratioH > 0) {
16699
+ const target = 1024;
16700
+ body.width = Math.round(target * Math.sqrt(ratioW / ratioH));
16701
+ body.height = Math.round(target * Math.sqrt(ratioH / ratioW));
16702
+ }
16703
+ }
16704
+ if (seed != null) {
16705
+ const opts = typeof body.options === "object" && body.options ? body.options : {};
16706
+ body.options = { ...opts, seed };
16707
+ }
16708
+ const po = await (0, import_provider_utils3.parseProviderOptions)({
16709
+ provider: "ollama",
16710
+ providerOptions,
16711
+ schema: ollamaImageProviderOptionsSchema
16712
+ });
16713
+ if (po?.steps != null) body.steps = po.steps;
16714
+ if (po?.negative_prompt != null) body.negative_prompt = po.negative_prompt;
16715
+ const headers = {
16716
+ "Content-Type": "application/json",
16717
+ ...this.config.headers(),
16718
+ ...optHeaders
16719
+ };
16720
+ const res = await (this.config.fetch ?? fetch)(url2, {
16721
+ method: "POST",
16722
+ headers,
16723
+ body: JSON.stringify(body),
16724
+ signal: abortSignal
16725
+ });
16726
+ if (!res.ok) {
16727
+ const errBody = await res.json().catch(() => ({}));
16728
+ throw new OllamaError({
16729
+ message: errBody.error ?? `Ollama API error: ${res.status} ${res.statusText}`
16730
+ });
16731
+ }
16732
+ const data = await res.json();
16733
+ const images = [];
16734
+ if (Array.isArray(data.images) && data.images.length > 0) {
16735
+ images.push(...data.images);
16736
+ } else if (typeof data.image === "string" && data.image.trim().length > 0) {
16737
+ images.push(data.image.trim());
16738
+ } else if (typeof data.response === "string" && data.response.trim().length > 0) {
16739
+ const trimmed = data.response.trim();
16740
+ if (/^[A-Za-z0-9+/=]+$/.test(trimmed) && trimmed.length > 100) {
16741
+ images.push(trimmed);
16742
+ }
16743
+ }
16744
+ const responseHeaders = {};
16745
+ for (const [key, value] of res.headers.entries()) {
16746
+ responseHeaders[key] = value;
16747
+ }
16748
+ return {
16749
+ images,
16750
+ warnings: [],
16751
+ response: {
16752
+ timestamp: /* @__PURE__ */ new Date(),
16753
+ modelId: data.model ?? this.modelId,
16754
+ headers: Object.keys(responseHeaders).length > 0 ? responseHeaders : void 0
16755
+ },
16756
+ usage: data.eval_count == null ? void 0 : {
16757
+ inputTokens: void 0,
16758
+ outputTokens: data.eval_count,
16759
+ totalTokens: data.eval_count
16760
+ }
16761
+ };
16762
+ }
16763
+ };
16764
+
16660
16765
  // src/tool/web-search.ts
16661
16766
  var import_ai = require("ai");
16662
16767
  var webSearchInputSchema = external_exports.object({
@@ -16909,10 +17014,10 @@ function createOllama(options = {}) {
16909
17014
  });
16910
17015
  };
16911
17016
  const createRerankingModel = (modelId, settings = {}) => {
16912
- const baseURL = options.baseURL ?? "http://127.0.0.1:11434";
17017
+ const baseURL2 = options.baseURL ?? "http://127.0.0.1:11434";
16913
17018
  return new OllamaRerankingModel(modelId, settings, {
16914
17019
  provider: "ollama.reranking",
16915
- baseURL,
17020
+ baseURL: baseURL2,
16916
17021
  headers: () => normalizedHeaders,
16917
17022
  fetch: options.fetch
16918
17023
  });
@@ -16939,13 +17044,15 @@ function createOllama(options = {}) {
16939
17044
  provider.reranking = createRerankingModel;
16940
17045
  provider.rerankingModel = createRerankingModel;
16941
17046
  provider.embeddingReranking = createEmbeddingRerankingModel;
16942
- provider.imageModel = (modelId) => {
16943
- throw new import_provider.NoSuchModelError({
16944
- modelId,
16945
- modelType: "imageModel",
16946
- message: "Image generation is not supported by Ollama"
16947
- });
16948
- };
17047
+ const baseURL = options.baseURL ?? "http://127.0.0.1:11434";
17048
+ const createImageModel = (modelId) => new OllamaImageModel(modelId, {
17049
+ provider: "ollama",
17050
+ modelId,
17051
+ baseURL,
17052
+ headers: () => normalizedHeaders,
17053
+ fetch: options.fetch
17054
+ });
17055
+ provider.imageModel = createImageModel;
16949
17056
  const toolsWithClient = {
16950
17057
  webSearch: (options2 = {}) => ollamaTools.webSearch({ ...options2, client }),
16951
17058
  webFetch: (options2 = {}) => ollamaTools.webFetch({ ...options2, client })