ai 6.0.33 → 6.0.34
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 +10 -0
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/internal/index.js +1 -1
- package/dist/internal/index.mjs +1 -1
- package/docs/02-foundations/03-prompts.mdx +2 -2
- package/docs/03-ai-sdk-core/15-tools-and-tool-calling.mdx +1 -1
- package/docs/07-reference/01-ai-sdk-core/28-output.mdx +1 -1
- package/package.json +6 -4
- package/src/agent/agent.ts +116 -0
- package/src/agent/create-agent-ui-stream-response.test.ts +258 -0
- package/src/agent/create-agent-ui-stream-response.ts +50 -0
- package/src/agent/create-agent-ui-stream.ts +73 -0
- package/src/agent/index.ts +33 -0
- package/src/agent/infer-agent-tools.ts +7 -0
- package/src/agent/infer-agent-ui-message.test-d.ts +54 -0
- package/src/agent/infer-agent-ui-message.ts +11 -0
- package/src/agent/pipe-agent-ui-stream-to-response.ts +52 -0
- package/src/agent/tool-loop-agent-on-finish-callback.ts +31 -0
- package/src/agent/tool-loop-agent-on-step-finish-callback.ts +11 -0
- package/src/agent/tool-loop-agent-settings.ts +182 -0
- package/src/agent/tool-loop-agent.test-d.ts +114 -0
- package/src/agent/tool-loop-agent.test.ts +442 -0
- package/src/agent/tool-loop-agent.ts +114 -0
- package/src/embed/__snapshots__/embed-many.test.ts.snap +191 -0
- package/src/embed/__snapshots__/embed.test.ts.snap +81 -0
- package/src/embed/embed-many-result.ts +53 -0
- package/src/embed/embed-many.test.ts +653 -0
- package/src/embed/embed-many.ts +378 -0
- package/src/embed/embed-result.ts +50 -0
- package/src/embed/embed.test.ts +298 -0
- package/src/embed/embed.ts +211 -0
- package/src/embed/index.ts +4 -0
- package/src/error/index.ts +34 -0
- package/src/error/invalid-argument-error.ts +34 -0
- package/src/error/invalid-stream-part-error.ts +28 -0
- package/src/error/invalid-tool-approval-error.ts +26 -0
- package/src/error/invalid-tool-input-error.ts +33 -0
- package/src/error/no-image-generated-error.ts +39 -0
- package/src/error/no-object-generated-error.ts +70 -0
- package/src/error/no-output-generated-error.ts +26 -0
- package/src/error/no-speech-generated-error.ts +18 -0
- package/src/error/no-such-tool-error.ts +35 -0
- package/src/error/no-transcript-generated-error.ts +20 -0
- package/src/error/tool-call-not-found-for-approval-error.ts +32 -0
- package/src/error/tool-call-repair-error.ts +30 -0
- package/src/error/unsupported-model-version-error.ts +23 -0
- package/src/error/verify-no-object-generated-error.ts +27 -0
- package/src/generate-image/generate-image-result.ts +42 -0
- package/src/generate-image/generate-image.test.ts +1420 -0
- package/src/generate-image/generate-image.ts +360 -0
- package/src/generate-image/index.ts +18 -0
- package/src/generate-object/__snapshots__/generate-object.test.ts.snap +133 -0
- package/src/generate-object/__snapshots__/stream-object.test.ts.snap +297 -0
- package/src/generate-object/generate-object-result.ts +67 -0
- package/src/generate-object/generate-object.test-d.ts +49 -0
- package/src/generate-object/generate-object.test.ts +1191 -0
- package/src/generate-object/generate-object.ts +518 -0
- package/src/generate-object/index.ts +9 -0
- package/src/generate-object/inject-json-instruction.test.ts +181 -0
- package/src/generate-object/inject-json-instruction.ts +30 -0
- package/src/generate-object/output-strategy.ts +415 -0
- package/src/generate-object/parse-and-validate-object-result.ts +111 -0
- package/src/generate-object/repair-text.ts +12 -0
- package/src/generate-object/stream-object-result.ts +120 -0
- package/src/generate-object/stream-object.test-d.ts +74 -0
- package/src/generate-object/stream-object.test.ts +1950 -0
- package/src/generate-object/stream-object.ts +986 -0
- package/src/generate-object/validate-object-generation-input.ts +144 -0
- package/src/generate-speech/generate-speech-result.ts +30 -0
- package/src/generate-speech/generate-speech.test.ts +300 -0
- package/src/generate-speech/generate-speech.ts +190 -0
- package/src/generate-speech/generated-audio-file.ts +65 -0
- package/src/generate-speech/index.ts +3 -0
- package/src/generate-text/__snapshots__/generate-text.test.ts.snap +1872 -0
- package/src/generate-text/__snapshots__/stream-text.test.ts.snap +1255 -0
- package/src/generate-text/collect-tool-approvals.test.ts +553 -0
- package/src/generate-text/collect-tool-approvals.ts +116 -0
- package/src/generate-text/content-part.ts +25 -0
- package/src/generate-text/execute-tool-call.ts +129 -0
- package/src/generate-text/extract-reasoning-content.ts +17 -0
- package/src/generate-text/extract-text-content.ts +15 -0
- package/src/generate-text/generate-text-result.ts +168 -0
- package/src/generate-text/generate-text.test-d.ts +68 -0
- package/src/generate-text/generate-text.test.ts +7011 -0
- package/src/generate-text/generate-text.ts +1223 -0
- package/src/generate-text/generated-file.ts +70 -0
- package/src/generate-text/index.ts +57 -0
- package/src/generate-text/is-approval-needed.ts +29 -0
- package/src/generate-text/output-utils.ts +23 -0
- package/src/generate-text/output.test.ts +698 -0
- package/src/generate-text/output.ts +590 -0
- package/src/generate-text/parse-tool-call.test.ts +570 -0
- package/src/generate-text/parse-tool-call.ts +188 -0
- package/src/generate-text/prepare-step.ts +103 -0
- package/src/generate-text/prune-messages.test.ts +720 -0
- package/src/generate-text/prune-messages.ts +167 -0
- package/src/generate-text/reasoning-output.ts +20 -0
- package/src/generate-text/reasoning.ts +8 -0
- package/src/generate-text/response-message.ts +10 -0
- package/src/generate-text/run-tools-transformation.test.ts +1143 -0
- package/src/generate-text/run-tools-transformation.ts +420 -0
- package/src/generate-text/smooth-stream.test.ts +2101 -0
- package/src/generate-text/smooth-stream.ts +162 -0
- package/src/generate-text/step-result.ts +238 -0
- package/src/generate-text/stop-condition.ts +29 -0
- package/src/generate-text/stream-text-result.ts +463 -0
- package/src/generate-text/stream-text.test-d.ts +200 -0
- package/src/generate-text/stream-text.test.ts +19979 -0
- package/src/generate-text/stream-text.ts +2505 -0
- package/src/generate-text/to-response-messages.test.ts +922 -0
- package/src/generate-text/to-response-messages.ts +163 -0
- package/src/generate-text/tool-approval-request-output.ts +21 -0
- package/src/generate-text/tool-call-repair-function.ts +27 -0
- package/src/generate-text/tool-call.ts +47 -0
- package/src/generate-text/tool-error.ts +34 -0
- package/src/generate-text/tool-output-denied.ts +21 -0
- package/src/generate-text/tool-output.ts +7 -0
- package/src/generate-text/tool-result.ts +36 -0
- package/src/generate-text/tool-set.ts +14 -0
- package/src/global.ts +24 -0
- package/src/index.ts +50 -0
- package/src/logger/index.ts +6 -0
- package/src/logger/log-warnings.test.ts +351 -0
- package/src/logger/log-warnings.ts +119 -0
- package/src/middleware/__snapshots__/simulate-streaming-middleware.test.ts.snap +64 -0
- package/src/middleware/add-tool-input-examples-middleware.test.ts +476 -0
- package/src/middleware/add-tool-input-examples-middleware.ts +90 -0
- package/src/middleware/default-embedding-settings-middleware.test.ts +126 -0
- package/src/middleware/default-embedding-settings-middleware.ts +22 -0
- package/src/middleware/default-settings-middleware.test.ts +388 -0
- package/src/middleware/default-settings-middleware.ts +33 -0
- package/src/middleware/extract-json-middleware.test.ts +827 -0
- package/src/middleware/extract-json-middleware.ts +197 -0
- package/src/middleware/extract-reasoning-middleware.test.ts +1028 -0
- package/src/middleware/extract-reasoning-middleware.ts +238 -0
- package/src/middleware/index.ts +10 -0
- package/src/middleware/simulate-streaming-middleware.test.ts +911 -0
- package/src/middleware/simulate-streaming-middleware.ts +79 -0
- package/src/middleware/wrap-embedding-model.test.ts +358 -0
- package/src/middleware/wrap-embedding-model.ts +86 -0
- package/src/middleware/wrap-image-model.test.ts +423 -0
- package/src/middleware/wrap-image-model.ts +85 -0
- package/src/middleware/wrap-language-model.test.ts +518 -0
- package/src/middleware/wrap-language-model.ts +104 -0
- package/src/middleware/wrap-provider.test.ts +120 -0
- package/src/middleware/wrap-provider.ts +51 -0
- package/src/model/as-embedding-model-v3.test.ts +319 -0
- package/src/model/as-embedding-model-v3.ts +24 -0
- package/src/model/as-image-model-v3.test.ts +409 -0
- package/src/model/as-image-model-v3.ts +24 -0
- package/src/model/as-language-model-v3.test.ts +508 -0
- package/src/model/as-language-model-v3.ts +103 -0
- package/src/model/as-provider-v3.ts +36 -0
- package/src/model/as-speech-model-v3.test.ts +356 -0
- package/src/model/as-speech-model-v3.ts +24 -0
- package/src/model/as-transcription-model-v3.test.ts +529 -0
- package/src/model/as-transcription-model-v3.ts +24 -0
- package/src/model/resolve-model.test.ts +244 -0
- package/src/model/resolve-model.ts +126 -0
- package/src/prompt/call-settings.ts +148 -0
- package/src/prompt/content-part.ts +209 -0
- package/src/prompt/convert-to-language-model-prompt.test.ts +2018 -0
- package/src/prompt/convert-to-language-model-prompt.ts +442 -0
- package/src/prompt/create-tool-model-output.test.ts +508 -0
- package/src/prompt/create-tool-model-output.ts +34 -0
- package/src/prompt/data-content.test.ts +15 -0
- package/src/prompt/data-content.ts +134 -0
- package/src/prompt/index.ts +27 -0
- package/src/prompt/invalid-data-content-error.ts +29 -0
- package/src/prompt/invalid-message-role-error.ts +27 -0
- package/src/prompt/message-conversion-error.ts +28 -0
- package/src/prompt/message.ts +68 -0
- package/src/prompt/prepare-call-settings.test.ts +159 -0
- package/src/prompt/prepare-call-settings.ts +108 -0
- package/src/prompt/prepare-tools-and-tool-choice.test.ts +461 -0
- package/src/prompt/prepare-tools-and-tool-choice.ts +86 -0
- package/src/prompt/prompt.ts +43 -0
- package/src/prompt/split-data-url.ts +17 -0
- package/src/prompt/standardize-prompt.test.ts +82 -0
- package/src/prompt/standardize-prompt.ts +99 -0
- package/src/prompt/wrap-gateway-error.ts +29 -0
- package/src/registry/custom-provider.test.ts +211 -0
- package/src/registry/custom-provider.ts +155 -0
- package/src/registry/index.ts +7 -0
- package/src/registry/no-such-provider-error.ts +41 -0
- package/src/registry/provider-registry.test.ts +691 -0
- package/src/registry/provider-registry.ts +328 -0
- package/src/rerank/index.ts +2 -0
- package/src/rerank/rerank-result.ts +70 -0
- package/src/rerank/rerank.test.ts +516 -0
- package/src/rerank/rerank.ts +237 -0
- package/src/telemetry/assemble-operation-name.ts +21 -0
- package/src/telemetry/get-base-telemetry-attributes.ts +53 -0
- package/src/telemetry/get-tracer.ts +20 -0
- package/src/telemetry/noop-tracer.ts +69 -0
- package/src/telemetry/record-span.ts +63 -0
- package/src/telemetry/select-telemetry-attributes.ts +78 -0
- package/src/telemetry/select-temetry-attributes.test.ts +114 -0
- package/src/telemetry/stringify-for-telemetry.test.ts +114 -0
- package/src/telemetry/stringify-for-telemetry.ts +33 -0
- package/src/telemetry/telemetry-settings.ts +44 -0
- package/src/test/mock-embedding-model-v2.ts +35 -0
- package/src/test/mock-embedding-model-v3.ts +48 -0
- package/src/test/mock-image-model-v2.ts +28 -0
- package/src/test/mock-image-model-v3.ts +28 -0
- package/src/test/mock-language-model-v2.ts +72 -0
- package/src/test/mock-language-model-v3.ts +77 -0
- package/src/test/mock-provider-v2.ts +68 -0
- package/src/test/mock-provider-v3.ts +80 -0
- package/src/test/mock-reranking-model-v3.ts +25 -0
- package/src/test/mock-server-response.ts +69 -0
- package/src/test/mock-speech-model-v2.ts +24 -0
- package/src/test/mock-speech-model-v3.ts +24 -0
- package/src/test/mock-tracer.ts +156 -0
- package/src/test/mock-transcription-model-v2.ts +24 -0
- package/src/test/mock-transcription-model-v3.ts +24 -0
- package/src/test/mock-values.ts +4 -0
- package/src/test/not-implemented.ts +3 -0
- package/src/text-stream/create-text-stream-response.test.ts +38 -0
- package/src/text-stream/create-text-stream-response.ts +18 -0
- package/src/text-stream/index.ts +2 -0
- package/src/text-stream/pipe-text-stream-to-response.test.ts +38 -0
- package/src/text-stream/pipe-text-stream-to-response.ts +26 -0
- package/src/transcribe/index.ts +2 -0
- package/src/transcribe/transcribe-result.ts +60 -0
- package/src/transcribe/transcribe.test.ts +313 -0
- package/src/transcribe/transcribe.ts +173 -0
- package/src/types/embedding-model-middleware.ts +3 -0
- package/src/types/embedding-model.ts +18 -0
- package/src/types/image-model-middleware.ts +3 -0
- package/src/types/image-model-response-metadata.ts +16 -0
- package/src/types/image-model.ts +19 -0
- package/src/types/index.ts +29 -0
- package/src/types/json-value.ts +15 -0
- package/src/types/language-model-middleware.ts +3 -0
- package/src/types/language-model-request-metadata.ts +6 -0
- package/src/types/language-model-response-metadata.ts +21 -0
- package/src/types/language-model.ts +104 -0
- package/src/types/provider-metadata.ts +16 -0
- package/src/types/provider.ts +55 -0
- package/src/types/reranking-model.ts +6 -0
- package/src/types/speech-model-response-metadata.ts +21 -0
- package/src/types/speech-model.ts +6 -0
- package/src/types/transcription-model-response-metadata.ts +16 -0
- package/src/types/transcription-model.ts +9 -0
- package/src/types/usage.ts +200 -0
- package/src/types/warning.ts +7 -0
- package/src/ui/__snapshots__/append-response-messages.test.ts.snap +416 -0
- package/src/ui/__snapshots__/convert-to-model-messages.test.ts.snap +419 -0
- package/src/ui/__snapshots__/process-chat-text-response.test.ts.snap +142 -0
- package/src/ui/call-completion-api.ts +157 -0
- package/src/ui/chat-transport.ts +83 -0
- package/src/ui/chat.test-d.ts +233 -0
- package/src/ui/chat.test.ts +2695 -0
- package/src/ui/chat.ts +716 -0
- package/src/ui/convert-file-list-to-file-ui-parts.ts +36 -0
- package/src/ui/convert-to-model-messages.test.ts +2775 -0
- package/src/ui/convert-to-model-messages.ts +373 -0
- package/src/ui/default-chat-transport.ts +36 -0
- package/src/ui/direct-chat-transport.test.ts +446 -0
- package/src/ui/direct-chat-transport.ts +118 -0
- package/src/ui/http-chat-transport.test.ts +185 -0
- package/src/ui/http-chat-transport.ts +292 -0
- package/src/ui/index.ts +71 -0
- package/src/ui/last-assistant-message-is-complete-with-approval-responses.ts +44 -0
- package/src/ui/last-assistant-message-is-complete-with-tool-calls.test.ts +371 -0
- package/src/ui/last-assistant-message-is-complete-with-tool-calls.ts +39 -0
- package/src/ui/process-text-stream.test.ts +38 -0
- package/src/ui/process-text-stream.ts +16 -0
- package/src/ui/process-ui-message-stream.test.ts +8052 -0
- package/src/ui/process-ui-message-stream.ts +713 -0
- package/src/ui/text-stream-chat-transport.ts +23 -0
- package/src/ui/transform-text-to-ui-message-stream.test.ts +124 -0
- package/src/ui/transform-text-to-ui-message-stream.ts +27 -0
- package/src/ui/ui-messages.test.ts +48 -0
- package/src/ui/ui-messages.ts +534 -0
- package/src/ui/use-completion.ts +84 -0
- package/src/ui/validate-ui-messages.test.ts +1428 -0
- package/src/ui/validate-ui-messages.ts +476 -0
- package/src/ui-message-stream/create-ui-message-stream-response.test.ts +266 -0
- package/src/ui-message-stream/create-ui-message-stream-response.ts +32 -0
- package/src/ui-message-stream/create-ui-message-stream.test.ts +639 -0
- package/src/ui-message-stream/create-ui-message-stream.ts +124 -0
- package/src/ui-message-stream/get-response-ui-message-id.test.ts +55 -0
- package/src/ui-message-stream/get-response-ui-message-id.ts +24 -0
- package/src/ui-message-stream/handle-ui-message-stream-finish.test.ts +429 -0
- package/src/ui-message-stream/handle-ui-message-stream-finish.ts +135 -0
- package/src/ui-message-stream/index.ts +13 -0
- package/src/ui-message-stream/json-to-sse-transform-stream.ts +12 -0
- package/src/ui-message-stream/pipe-ui-message-stream-to-response.test.ts +90 -0
- package/src/ui-message-stream/pipe-ui-message-stream-to-response.ts +40 -0
- package/src/ui-message-stream/read-ui-message-stream.test.ts +122 -0
- package/src/ui-message-stream/read-ui-message-stream.ts +87 -0
- package/src/ui-message-stream/ui-message-chunks.test-d.ts +18 -0
- package/src/ui-message-stream/ui-message-chunks.ts +344 -0
- package/src/ui-message-stream/ui-message-stream-headers.ts +7 -0
- package/src/ui-message-stream/ui-message-stream-on-finish-callback.ts +32 -0
- package/src/ui-message-stream/ui-message-stream-response-init.ts +5 -0
- package/src/ui-message-stream/ui-message-stream-writer.ts +24 -0
- package/src/util/as-array.ts +3 -0
- package/src/util/async-iterable-stream.test.ts +241 -0
- package/src/util/async-iterable-stream.ts +94 -0
- package/src/util/consume-stream.ts +29 -0
- package/src/util/cosine-similarity.test.ts +57 -0
- package/src/util/cosine-similarity.ts +47 -0
- package/src/util/create-resolvable-promise.ts +30 -0
- package/src/util/create-stitchable-stream.test.ts +239 -0
- package/src/util/create-stitchable-stream.ts +112 -0
- package/src/util/data-url.ts +17 -0
- package/src/util/deep-partial.ts +84 -0
- package/src/util/detect-media-type.test.ts +670 -0
- package/src/util/detect-media-type.ts +184 -0
- package/src/util/download/download-function.ts +45 -0
- package/src/util/download/download.test.ts +69 -0
- package/src/util/download/download.ts +46 -0
- package/src/util/error-handler.ts +1 -0
- package/src/util/fix-json.test.ts +279 -0
- package/src/util/fix-json.ts +401 -0
- package/src/util/get-potential-start-index.test.ts +34 -0
- package/src/util/get-potential-start-index.ts +30 -0
- package/src/util/index.ts +11 -0
- package/src/util/is-deep-equal-data.test.ts +119 -0
- package/src/util/is-deep-equal-data.ts +48 -0
- package/src/util/is-non-empty-object.ts +5 -0
- package/src/util/job.ts +1 -0
- package/src/util/log-v2-compatibility-warning.ts +21 -0
- package/src/util/merge-abort-signals.test.ts +155 -0
- package/src/util/merge-abort-signals.ts +43 -0
- package/src/util/merge-objects.test.ts +118 -0
- package/src/util/merge-objects.ts +79 -0
- package/src/util/now.ts +4 -0
- package/src/util/parse-partial-json.test.ts +80 -0
- package/src/util/parse-partial-json.ts +30 -0
- package/src/util/prepare-headers.test.ts +51 -0
- package/src/util/prepare-headers.ts +14 -0
- package/src/util/prepare-retries.test.ts +10 -0
- package/src/util/prepare-retries.ts +47 -0
- package/src/util/retry-error.ts +41 -0
- package/src/util/retry-with-exponential-backoff.test.ts +446 -0
- package/src/util/retry-with-exponential-backoff.ts +154 -0
- package/src/util/serial-job-executor.test.ts +162 -0
- package/src/util/serial-job-executor.ts +36 -0
- package/src/util/simulate-readable-stream.test.ts +98 -0
- package/src/util/simulate-readable-stream.ts +39 -0
- package/src/util/split-array.test.ts +60 -0
- package/src/util/split-array.ts +20 -0
- package/src/util/value-of.ts +65 -0
- package/src/util/write-to-server-response.test.ts +266 -0
- package/src/util/write-to-server-response.ts +49 -0
- package/src/version.ts +5 -0
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
import {
|
|
2
|
+
LanguageModelV3,
|
|
3
|
+
LanguageModelV3CallOptions,
|
|
4
|
+
LanguageModelV3Middleware,
|
|
5
|
+
} from '@ai-sdk/provider';
|
|
6
|
+
import { wrapLanguageModel } from '../middleware/wrap-language-model';
|
|
7
|
+
import { MockLanguageModelV3 } from '../test/mock-language-model-v3';
|
|
8
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
9
|
+
|
|
10
|
+
describe('wrapLanguageModel', () => {
|
|
11
|
+
describe('model property', () => {
|
|
12
|
+
it('should pass through by default', () => {
|
|
13
|
+
const wrappedModel = wrapLanguageModel({
|
|
14
|
+
model: new MockLanguageModelV3({
|
|
15
|
+
modelId: 'test-model',
|
|
16
|
+
}),
|
|
17
|
+
middleware: {
|
|
18
|
+
specificationVersion: 'v3',
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
expect(wrappedModel.modelId).toBe('test-model');
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('should use middleware overrideModelId if provided', () => {
|
|
26
|
+
const wrappedModel = wrapLanguageModel({
|
|
27
|
+
model: new MockLanguageModelV3({
|
|
28
|
+
modelId: 'test-model',
|
|
29
|
+
}),
|
|
30
|
+
middleware: {
|
|
31
|
+
specificationVersion: 'v3',
|
|
32
|
+
overrideModelId: ({ model }) => 'override-model',
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
expect(wrappedModel.modelId).toBe('override-model');
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('should use modelId parameter if provided', () => {
|
|
40
|
+
const wrappedModel = wrapLanguageModel({
|
|
41
|
+
model: new MockLanguageModelV3({
|
|
42
|
+
modelId: 'test-model',
|
|
43
|
+
}),
|
|
44
|
+
middleware: {
|
|
45
|
+
specificationVersion: 'v3',
|
|
46
|
+
},
|
|
47
|
+
modelId: 'override-model',
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
expect(wrappedModel.modelId).toBe('override-model');
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
describe('provider property', () => {
|
|
55
|
+
it('should pass through by default', () => {
|
|
56
|
+
const wrappedModel = wrapLanguageModel({
|
|
57
|
+
model: new MockLanguageModelV3({
|
|
58
|
+
provider: 'test-provider',
|
|
59
|
+
}),
|
|
60
|
+
middleware: {
|
|
61
|
+
specificationVersion: 'v3',
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
expect(wrappedModel.provider).toBe('test-provider');
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('should use middleware overrideProvider if provided', () => {
|
|
69
|
+
const wrappedModel = wrapLanguageModel({
|
|
70
|
+
model: new MockLanguageModelV3({
|
|
71
|
+
provider: 'test-provider',
|
|
72
|
+
}),
|
|
73
|
+
middleware: {
|
|
74
|
+
specificationVersion: 'v3',
|
|
75
|
+
overrideProvider: ({ model }) => 'override-provider',
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
expect(wrappedModel.provider).toBe('override-provider');
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('should use providerId parameter if provided', () => {
|
|
83
|
+
const wrappedModel = wrapLanguageModel({
|
|
84
|
+
model: new MockLanguageModelV3({
|
|
85
|
+
provider: 'test-provider',
|
|
86
|
+
}),
|
|
87
|
+
middleware: {
|
|
88
|
+
specificationVersion: 'v3',
|
|
89
|
+
},
|
|
90
|
+
providerId: 'override-provider',
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
expect(wrappedModel.provider).toBe('override-provider');
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
describe('supportedUrls property', () => {
|
|
98
|
+
it('should pass through by default', async () => {
|
|
99
|
+
const supportedUrls = {
|
|
100
|
+
'original/*': [/^https:\/\/.*$/],
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const wrappedModel = wrapLanguageModel({
|
|
104
|
+
model: new MockLanguageModelV3({ supportedUrls }),
|
|
105
|
+
middleware: {
|
|
106
|
+
specificationVersion: 'v3',
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
expect(await wrappedModel.supportedUrls).toStrictEqual(supportedUrls);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it('should use middleware overrideSupportedUrls if provided', () => {
|
|
114
|
+
const wrappedModel = wrapLanguageModel({
|
|
115
|
+
model: new MockLanguageModelV3({
|
|
116
|
+
supportedUrls: {
|
|
117
|
+
'original/*': [/^https:\/\/.*$/],
|
|
118
|
+
},
|
|
119
|
+
}),
|
|
120
|
+
middleware: {
|
|
121
|
+
specificationVersion: 'v3',
|
|
122
|
+
overrideSupportedUrls: ({ model }) => ({
|
|
123
|
+
'override/*': [/^https:\/\/.*$/],
|
|
124
|
+
}),
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
expect(wrappedModel.supportedUrls).toStrictEqual({
|
|
129
|
+
'override/*': [/^https:\/\/.*$/],
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it('should call transformParams middleware for doGenerate', async () => {
|
|
135
|
+
const mockModel = new MockLanguageModelV3({
|
|
136
|
+
doGenerate: [],
|
|
137
|
+
});
|
|
138
|
+
const transformParams = vi.fn().mockImplementation(({ params }) => ({
|
|
139
|
+
...params,
|
|
140
|
+
transformed: true,
|
|
141
|
+
}));
|
|
142
|
+
|
|
143
|
+
const wrappedModel = wrapLanguageModel({
|
|
144
|
+
model: mockModel,
|
|
145
|
+
middleware: {
|
|
146
|
+
specificationVersion: 'v3',
|
|
147
|
+
transformParams,
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
const params: LanguageModelV3CallOptions = {
|
|
152
|
+
prompt: [{ role: 'user', content: [{ type: 'text', text: 'Hello' }] }],
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
await wrappedModel.doGenerate(params);
|
|
156
|
+
|
|
157
|
+
expect(transformParams).toHaveBeenCalledWith({
|
|
158
|
+
params,
|
|
159
|
+
type: 'generate',
|
|
160
|
+
model: expect.any(Object),
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
expect(mockModel.doGenerateCalls[0]).toStrictEqual({
|
|
164
|
+
...params,
|
|
165
|
+
transformed: true,
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it('should call wrapGenerate middleware', async () => {
|
|
170
|
+
const mockModel = new MockLanguageModelV3({
|
|
171
|
+
doGenerate: vi.fn().mockResolvedValue('mock result'),
|
|
172
|
+
});
|
|
173
|
+
const wrapGenerate = vi
|
|
174
|
+
.fn()
|
|
175
|
+
.mockImplementation(({ doGenerate }) => doGenerate());
|
|
176
|
+
|
|
177
|
+
const wrappedModel = wrapLanguageModel({
|
|
178
|
+
model: mockModel,
|
|
179
|
+
middleware: {
|
|
180
|
+
specificationVersion: 'v3',
|
|
181
|
+
wrapGenerate,
|
|
182
|
+
},
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
const params: LanguageModelV3CallOptions = {
|
|
186
|
+
prompt: [{ role: 'user', content: [{ type: 'text', text: 'Hello' }] }],
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
await wrappedModel.doGenerate(params);
|
|
190
|
+
|
|
191
|
+
expect(wrapGenerate).toHaveBeenCalledWith({
|
|
192
|
+
doGenerate: expect.any(Function),
|
|
193
|
+
doStream: expect.any(Function),
|
|
194
|
+
params,
|
|
195
|
+
model: mockModel,
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it('should call transformParams middleware for doStream', async () => {
|
|
200
|
+
const mockModel = new MockLanguageModelV3({
|
|
201
|
+
doStream: [],
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
const transformParams = vi.fn().mockImplementation(({ params }) => ({
|
|
205
|
+
...params,
|
|
206
|
+
transformed: true,
|
|
207
|
+
}));
|
|
208
|
+
|
|
209
|
+
const wrappedModel = wrapLanguageModel({
|
|
210
|
+
model: mockModel,
|
|
211
|
+
middleware: {
|
|
212
|
+
specificationVersion: 'v3',
|
|
213
|
+
transformParams,
|
|
214
|
+
},
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
const params: LanguageModelV3CallOptions = {
|
|
218
|
+
prompt: [{ role: 'user', content: [{ type: 'text', text: 'Hello' }] }],
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
await wrappedModel.doStream(params);
|
|
222
|
+
|
|
223
|
+
expect(transformParams).toHaveBeenCalledWith({
|
|
224
|
+
params,
|
|
225
|
+
type: 'stream',
|
|
226
|
+
model: expect.any(Object),
|
|
227
|
+
});
|
|
228
|
+
expect(mockModel.doStreamCalls[0]).toStrictEqual({
|
|
229
|
+
...params,
|
|
230
|
+
transformed: true,
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
it('should call wrapStream middleware', async () => {
|
|
235
|
+
const mockModel = new MockLanguageModelV3({
|
|
236
|
+
doStream: vi.fn().mockResolvedValue('mock stream'),
|
|
237
|
+
});
|
|
238
|
+
const wrapStream = vi.fn().mockImplementation(({ doStream }) => doStream());
|
|
239
|
+
|
|
240
|
+
const wrappedModel = wrapLanguageModel({
|
|
241
|
+
model: mockModel,
|
|
242
|
+
middleware: {
|
|
243
|
+
specificationVersion: 'v3',
|
|
244
|
+
wrapStream,
|
|
245
|
+
},
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
const params: LanguageModelV3CallOptions = {
|
|
249
|
+
prompt: [{ role: 'user', content: [{ type: 'text', text: 'Hello' }] }],
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
await wrappedModel.doStream(params);
|
|
253
|
+
|
|
254
|
+
expect(wrapStream).toHaveBeenCalledWith({
|
|
255
|
+
doGenerate: expect.any(Function),
|
|
256
|
+
doStream: expect.any(Function),
|
|
257
|
+
params,
|
|
258
|
+
model: mockModel,
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
it('should support models that use "this" context in supportedUrls', async () => {
|
|
263
|
+
let supportedUrlsCalled = false;
|
|
264
|
+
|
|
265
|
+
class MockLanguageModelWithImageSupport implements LanguageModelV3 {
|
|
266
|
+
readonly specificationVersion = 'v3';
|
|
267
|
+
readonly provider = 'test-provider';
|
|
268
|
+
readonly modelId = 'test-model';
|
|
269
|
+
|
|
270
|
+
readonly doGenerate: LanguageModelV3['doGenerate'] = vi.fn();
|
|
271
|
+
readonly doStream: LanguageModelV3['doStream'] = vi.fn();
|
|
272
|
+
|
|
273
|
+
readonly value = {
|
|
274
|
+
'image/*': [/^https:\/\/.*$/],
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
get supportedUrls() {
|
|
278
|
+
supportedUrlsCalled = true;
|
|
279
|
+
// Reference 'this' to verify context
|
|
280
|
+
return this.value;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
const model = new MockLanguageModelWithImageSupport();
|
|
285
|
+
|
|
286
|
+
const wrappedModel = wrapLanguageModel({
|
|
287
|
+
model,
|
|
288
|
+
middleware: { specificationVersion: 'v3' },
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
expect(await wrappedModel.supportedUrls).toStrictEqual(model.value);
|
|
292
|
+
expect(supportedUrlsCalled).toBe(true);
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
describe('multiple middlewares', () => {
|
|
296
|
+
it('should call multiple transformParams middlewares in sequence for doGenerate', async () => {
|
|
297
|
+
const mockModel = new MockLanguageModelV3({
|
|
298
|
+
doGenerate: [],
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
const transformParams1 = vi.fn().mockImplementation(({ params }) => ({
|
|
302
|
+
...params,
|
|
303
|
+
transformationStep1: true,
|
|
304
|
+
}));
|
|
305
|
+
const transformParams2 = vi.fn().mockImplementation(({ params }) => ({
|
|
306
|
+
...params,
|
|
307
|
+
transformationStep2: true,
|
|
308
|
+
}));
|
|
309
|
+
|
|
310
|
+
const wrappedModel = wrapLanguageModel({
|
|
311
|
+
model: mockModel,
|
|
312
|
+
middleware: [
|
|
313
|
+
{
|
|
314
|
+
specificationVersion: 'v3',
|
|
315
|
+
transformParams: transformParams1,
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
specificationVersion: 'v3',
|
|
319
|
+
transformParams: transformParams2,
|
|
320
|
+
},
|
|
321
|
+
],
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
const params: LanguageModelV3CallOptions = {
|
|
325
|
+
prompt: [{ role: 'user', content: [{ type: 'text', text: 'Hello' }] }],
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
await wrappedModel.doGenerate(params);
|
|
329
|
+
|
|
330
|
+
expect(transformParams1).toHaveBeenCalledWith({
|
|
331
|
+
params,
|
|
332
|
+
type: 'generate',
|
|
333
|
+
model: expect.any(Object),
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
expect(transformParams2).toHaveBeenCalledWith({
|
|
337
|
+
params: { ...params, transformationStep1: true },
|
|
338
|
+
type: 'generate',
|
|
339
|
+
model: expect.any(Object),
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
expect(mockModel.doGenerateCalls[0]).toStrictEqual(
|
|
343
|
+
expect.objectContaining({
|
|
344
|
+
transformationStep1: true,
|
|
345
|
+
transformationStep2: true,
|
|
346
|
+
}),
|
|
347
|
+
);
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
it('should call multiple transformParams middlewares in sequence for doStream', async () => {
|
|
351
|
+
const mockModel = new MockLanguageModelV3({
|
|
352
|
+
doStream: [],
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
const transformParams1 = vi.fn().mockImplementation(({ params }) => ({
|
|
356
|
+
...params,
|
|
357
|
+
transformationStep1: true,
|
|
358
|
+
}));
|
|
359
|
+
const transformParams2 = vi.fn().mockImplementation(({ params }) => ({
|
|
360
|
+
...params,
|
|
361
|
+
transformationStep2: true,
|
|
362
|
+
}));
|
|
363
|
+
|
|
364
|
+
const wrappedModel = wrapLanguageModel({
|
|
365
|
+
model: mockModel,
|
|
366
|
+
middleware: [
|
|
367
|
+
{
|
|
368
|
+
specificationVersion: 'v3',
|
|
369
|
+
transformParams: transformParams1,
|
|
370
|
+
},
|
|
371
|
+
{
|
|
372
|
+
specificationVersion: 'v3',
|
|
373
|
+
transformParams: transformParams2,
|
|
374
|
+
},
|
|
375
|
+
],
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
const params: LanguageModelV3CallOptions = {
|
|
379
|
+
prompt: [{ role: 'user', content: [{ type: 'text', text: 'Hello' }] }],
|
|
380
|
+
};
|
|
381
|
+
|
|
382
|
+
await wrappedModel.doStream(params);
|
|
383
|
+
|
|
384
|
+
expect(transformParams1).toHaveBeenCalledWith({
|
|
385
|
+
params,
|
|
386
|
+
type: 'stream',
|
|
387
|
+
model: expect.any(Object),
|
|
388
|
+
});
|
|
389
|
+
expect(transformParams2).toHaveBeenCalledWith({
|
|
390
|
+
params: expect.objectContaining({ transformationStep1: true }),
|
|
391
|
+
type: 'stream',
|
|
392
|
+
model: mockModel,
|
|
393
|
+
});
|
|
394
|
+
expect(mockModel.doStreamCalls[0]).toStrictEqual(
|
|
395
|
+
expect.objectContaining({
|
|
396
|
+
transformationStep1: true,
|
|
397
|
+
transformationStep2: true,
|
|
398
|
+
}),
|
|
399
|
+
);
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
it('should chain multiple wrapGenerate middlewares in the correct order', async () => {
|
|
403
|
+
const mockModel = new MockLanguageModelV3({
|
|
404
|
+
doGenerate: vi.fn().mockResolvedValue('final generate result'),
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
const wrapGenerate1 = vi
|
|
408
|
+
.fn()
|
|
409
|
+
.mockImplementation(async ({ doGenerate, params, model }) => {
|
|
410
|
+
const result = await doGenerate();
|
|
411
|
+
return `wrapGenerate1(${result})`;
|
|
412
|
+
});
|
|
413
|
+
const wrapGenerate2 = vi
|
|
414
|
+
.fn()
|
|
415
|
+
.mockImplementation(async ({ doGenerate, params, model }) => {
|
|
416
|
+
const result = await doGenerate();
|
|
417
|
+
return `wrapGenerate2(${result})`;
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
const wrappedModel = wrapLanguageModel({
|
|
421
|
+
model: mockModel,
|
|
422
|
+
middleware: [
|
|
423
|
+
{
|
|
424
|
+
specificationVersion: 'v3',
|
|
425
|
+
wrapGenerate: wrapGenerate1,
|
|
426
|
+
},
|
|
427
|
+
{
|
|
428
|
+
specificationVersion: 'v3',
|
|
429
|
+
wrapGenerate: wrapGenerate2,
|
|
430
|
+
},
|
|
431
|
+
],
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
const params: LanguageModelV3CallOptions = {
|
|
435
|
+
prompt: [{ role: 'user', content: [{ type: 'text', text: 'Hello' }] }],
|
|
436
|
+
};
|
|
437
|
+
|
|
438
|
+
const result = await wrappedModel.doGenerate(params);
|
|
439
|
+
|
|
440
|
+
// The middlewares should wrap in order, applying wrapGenerate2 last
|
|
441
|
+
expect(result).toBe(
|
|
442
|
+
'wrapGenerate1(wrapGenerate2(final generate result))',
|
|
443
|
+
);
|
|
444
|
+
expect(wrapGenerate1).toHaveBeenCalled();
|
|
445
|
+
expect(wrapGenerate2).toHaveBeenCalled();
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
it('should chain multiple wrapStream middlewares in the correct order', async () => {
|
|
449
|
+
const mockModel = new MockLanguageModelV3({
|
|
450
|
+
doStream: vi.fn().mockResolvedValue('final stream result'),
|
|
451
|
+
});
|
|
452
|
+
|
|
453
|
+
const wrapStream1 = vi
|
|
454
|
+
.fn()
|
|
455
|
+
.mockImplementation(async ({ doStream, params, model }) => {
|
|
456
|
+
const result = await doStream();
|
|
457
|
+
return `wrapStream1(${result})`;
|
|
458
|
+
});
|
|
459
|
+
const wrapStream2 = vi
|
|
460
|
+
.fn()
|
|
461
|
+
.mockImplementation(async ({ doStream, params, model }) => {
|
|
462
|
+
const result = await doStream();
|
|
463
|
+
return `wrapStream2(${result})`;
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
const wrappedModel = wrapLanguageModel({
|
|
467
|
+
model: mockModel,
|
|
468
|
+
middleware: [
|
|
469
|
+
{
|
|
470
|
+
specificationVersion: 'v3',
|
|
471
|
+
wrapStream: wrapStream1,
|
|
472
|
+
},
|
|
473
|
+
{
|
|
474
|
+
specificationVersion: 'v3',
|
|
475
|
+
wrapStream: wrapStream2,
|
|
476
|
+
},
|
|
477
|
+
],
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
const params: LanguageModelV3CallOptions = {
|
|
481
|
+
prompt: [{ role: 'user', content: [{ type: 'text', text: 'Hello' }] }],
|
|
482
|
+
};
|
|
483
|
+
|
|
484
|
+
const result = await wrappedModel.doStream(params);
|
|
485
|
+
|
|
486
|
+
// The middlewares should wrap in order, applying wrapStream2 last
|
|
487
|
+
expect(result).toBe('wrapStream1(wrapStream2(final stream result))');
|
|
488
|
+
expect(wrapStream1).toHaveBeenCalled();
|
|
489
|
+
expect(wrapStream2).toHaveBeenCalled();
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
it('should not mutate the middleware array argument', async () => {
|
|
493
|
+
const middleware1 = {
|
|
494
|
+
specificationVersion: 'v3',
|
|
495
|
+
wrapStream: vi.fn(),
|
|
496
|
+
};
|
|
497
|
+
|
|
498
|
+
const middleware2 = {
|
|
499
|
+
specificationVersion: 'v3',
|
|
500
|
+
wrapStream: vi.fn(),
|
|
501
|
+
};
|
|
502
|
+
|
|
503
|
+
const middlewares = [
|
|
504
|
+
middleware1,
|
|
505
|
+
middleware2,
|
|
506
|
+
] as LanguageModelV3Middleware[];
|
|
507
|
+
|
|
508
|
+
wrapLanguageModel({
|
|
509
|
+
model: new MockLanguageModelV3(),
|
|
510
|
+
middleware: middlewares,
|
|
511
|
+
});
|
|
512
|
+
|
|
513
|
+
expect(middlewares.length).toBe(2);
|
|
514
|
+
expect(middlewares[0]).toBe(middleware1);
|
|
515
|
+
expect(middlewares[1]).toBe(middleware2);
|
|
516
|
+
});
|
|
517
|
+
});
|
|
518
|
+
});
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import {
|
|
2
|
+
LanguageModelV3,
|
|
3
|
+
LanguageModelV3CallOptions,
|
|
4
|
+
LanguageModelV3GenerateResult,
|
|
5
|
+
LanguageModelV3StreamResult,
|
|
6
|
+
} from '@ai-sdk/provider';
|
|
7
|
+
import { LanguageModelMiddleware } from '../types';
|
|
8
|
+
import { asArray } from '../util/as-array';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Wraps a LanguageModelV3 instance with middleware functionality.
|
|
12
|
+
* This function allows you to apply middleware to transform parameters,
|
|
13
|
+
* wrap generate operations, and wrap stream operations of a language model.
|
|
14
|
+
*
|
|
15
|
+
* @param options - Configuration options for wrapping the language model.
|
|
16
|
+
* @param options.model - The original LanguageModelV3 instance to be wrapped.
|
|
17
|
+
* @param options.middleware - The middleware to be applied to the language model. When multiple middlewares are provided, the first middleware will transform the input first, and the last middleware will be wrapped directly around the model.
|
|
18
|
+
* @param options.modelId - Optional custom model ID to override the original model's ID.
|
|
19
|
+
* @param options.providerId - Optional custom provider ID to override the original model's provider ID.
|
|
20
|
+
* @returns A new LanguageModelV3 instance with middleware applied.
|
|
21
|
+
*/
|
|
22
|
+
export const wrapLanguageModel = ({
|
|
23
|
+
model,
|
|
24
|
+
middleware: middlewareArg,
|
|
25
|
+
modelId,
|
|
26
|
+
providerId,
|
|
27
|
+
}: {
|
|
28
|
+
model: LanguageModelV3;
|
|
29
|
+
middleware: LanguageModelMiddleware | LanguageModelMiddleware[];
|
|
30
|
+
modelId?: string;
|
|
31
|
+
providerId?: string;
|
|
32
|
+
}): LanguageModelV3 => {
|
|
33
|
+
return [...asArray(middlewareArg)]
|
|
34
|
+
.reverse()
|
|
35
|
+
.reduce((wrappedModel, middleware) => {
|
|
36
|
+
return doWrap({ model: wrappedModel, middleware, modelId, providerId });
|
|
37
|
+
}, model);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const doWrap = ({
|
|
41
|
+
model,
|
|
42
|
+
middleware: {
|
|
43
|
+
transformParams,
|
|
44
|
+
wrapGenerate,
|
|
45
|
+
wrapStream,
|
|
46
|
+
overrideProvider,
|
|
47
|
+
overrideModelId,
|
|
48
|
+
overrideSupportedUrls,
|
|
49
|
+
},
|
|
50
|
+
modelId,
|
|
51
|
+
providerId,
|
|
52
|
+
}: {
|
|
53
|
+
model: LanguageModelV3;
|
|
54
|
+
middleware: LanguageModelMiddleware;
|
|
55
|
+
modelId?: string;
|
|
56
|
+
providerId?: string;
|
|
57
|
+
}): LanguageModelV3 => {
|
|
58
|
+
async function doTransform({
|
|
59
|
+
params,
|
|
60
|
+
type,
|
|
61
|
+
}: {
|
|
62
|
+
params: LanguageModelV3CallOptions;
|
|
63
|
+
type: 'generate' | 'stream';
|
|
64
|
+
}) {
|
|
65
|
+
return transformParams
|
|
66
|
+
? await transformParams({ params, type, model })
|
|
67
|
+
: params;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
specificationVersion: 'v3',
|
|
72
|
+
|
|
73
|
+
provider: providerId ?? overrideProvider?.({ model }) ?? model.provider,
|
|
74
|
+
modelId: modelId ?? overrideModelId?.({ model }) ?? model.modelId,
|
|
75
|
+
supportedUrls: overrideSupportedUrls?.({ model }) ?? model.supportedUrls,
|
|
76
|
+
|
|
77
|
+
async doGenerate(
|
|
78
|
+
params: LanguageModelV3CallOptions,
|
|
79
|
+
): Promise<LanguageModelV3GenerateResult> {
|
|
80
|
+
const transformedParams = await doTransform({ params, type: 'generate' });
|
|
81
|
+
const doGenerate = async () => model.doGenerate(transformedParams);
|
|
82
|
+
const doStream = async () => model.doStream(transformedParams);
|
|
83
|
+
return wrapGenerate
|
|
84
|
+
? wrapGenerate({
|
|
85
|
+
doGenerate,
|
|
86
|
+
doStream,
|
|
87
|
+
params: transformedParams,
|
|
88
|
+
model,
|
|
89
|
+
})
|
|
90
|
+
: doGenerate();
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
async doStream(
|
|
94
|
+
params: LanguageModelV3CallOptions,
|
|
95
|
+
): Promise<LanguageModelV3StreamResult> {
|
|
96
|
+
const transformedParams = await doTransform({ params, type: 'stream' });
|
|
97
|
+
const doGenerate = async () => model.doGenerate(transformedParams);
|
|
98
|
+
const doStream = async () => model.doStream(transformedParams);
|
|
99
|
+
return wrapStream
|
|
100
|
+
? wrapStream({ doGenerate, doStream, params: transformedParams, model })
|
|
101
|
+
: doStream();
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
};
|