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,162 @@
|
|
|
1
|
+
import { delay as originalDelay } from '@ai-sdk/provider-utils';
|
|
2
|
+
import { SharedV3ProviderMetadata } from '@ai-sdk/provider';
|
|
3
|
+
import { TextStreamPart } from './stream-text-result';
|
|
4
|
+
import { ToolSet } from './tool-set';
|
|
5
|
+
import { InvalidArgumentError } from '@ai-sdk/provider';
|
|
6
|
+
|
|
7
|
+
const CHUNKING_REGEXPS = {
|
|
8
|
+
word: /\S+\s+/m,
|
|
9
|
+
line: /\n+/m,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Detects the first chunk in a buffer.
|
|
14
|
+
*
|
|
15
|
+
* @param buffer - The buffer to detect the first chunk in.
|
|
16
|
+
*
|
|
17
|
+
* @returns The first detected chunk, or `undefined` if no chunk was detected.
|
|
18
|
+
*/
|
|
19
|
+
export type ChunkDetector = (buffer: string) => string | undefined | null;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Smooths text and reasoning streaming output.
|
|
23
|
+
*
|
|
24
|
+
* @param delayInMs - The delay in milliseconds between each chunk. Defaults to 10ms. Can be set to `null` to skip the delay.
|
|
25
|
+
* @param chunking - Controls how the text is chunked for streaming. Use "word" to stream word by word (default), "line" to stream line by line, provide a custom RegExp pattern for custom chunking, provide an Intl.Segmenter for locale-aware word segmentation (recommended for CJK languages), or provide a custom ChunkDetector function.
|
|
26
|
+
*
|
|
27
|
+
* @returns A transform stream that smooths text streaming output.
|
|
28
|
+
*/
|
|
29
|
+
export function smoothStream<TOOLS extends ToolSet>({
|
|
30
|
+
delayInMs = 10,
|
|
31
|
+
chunking = 'word',
|
|
32
|
+
_internal: { delay = originalDelay } = {},
|
|
33
|
+
}: {
|
|
34
|
+
delayInMs?: number | null;
|
|
35
|
+
chunking?: 'word' | 'line' | RegExp | ChunkDetector | Intl.Segmenter;
|
|
36
|
+
/**
|
|
37
|
+
* Internal. For test use only. May change without notice.
|
|
38
|
+
*/
|
|
39
|
+
_internal?: {
|
|
40
|
+
delay?: (delayInMs: number | null) => Promise<void>;
|
|
41
|
+
};
|
|
42
|
+
} = {}): (options: {
|
|
43
|
+
tools: TOOLS;
|
|
44
|
+
}) => TransformStream<TextStreamPart<TOOLS>, TextStreamPart<TOOLS>> {
|
|
45
|
+
let detectChunk: ChunkDetector;
|
|
46
|
+
|
|
47
|
+
// Check if chunking is an Intl.Segmenter (duck-typing for segment method)
|
|
48
|
+
if (
|
|
49
|
+
chunking != null &&
|
|
50
|
+
typeof chunking === 'object' &&
|
|
51
|
+
'segment' in chunking &&
|
|
52
|
+
typeof chunking.segment === 'function'
|
|
53
|
+
) {
|
|
54
|
+
const segmenter = chunking as Intl.Segmenter;
|
|
55
|
+
detectChunk = (buffer: string) => {
|
|
56
|
+
if (buffer.length === 0) return null;
|
|
57
|
+
const iterator = segmenter.segment(buffer)[Symbol.iterator]();
|
|
58
|
+
const first = iterator.next().value;
|
|
59
|
+
return first?.segment || null;
|
|
60
|
+
};
|
|
61
|
+
} else if (typeof chunking === 'function') {
|
|
62
|
+
detectChunk = buffer => {
|
|
63
|
+
const match = chunking(buffer);
|
|
64
|
+
|
|
65
|
+
if (match == null) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (!match.length) {
|
|
70
|
+
throw new Error(`Chunking function must return a non-empty string.`);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (!buffer.startsWith(match)) {
|
|
74
|
+
throw new Error(
|
|
75
|
+
`Chunking function must return a match that is a prefix of the buffer. Received: "${match}" expected to start with "${buffer}"`,
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return match;
|
|
80
|
+
};
|
|
81
|
+
} else {
|
|
82
|
+
const chunkingRegex =
|
|
83
|
+
typeof chunking === 'string'
|
|
84
|
+
? CHUNKING_REGEXPS[chunking]
|
|
85
|
+
: chunking instanceof RegExp
|
|
86
|
+
? chunking
|
|
87
|
+
: undefined;
|
|
88
|
+
|
|
89
|
+
if (chunkingRegex == null) {
|
|
90
|
+
throw new InvalidArgumentError({
|
|
91
|
+
argument: 'chunking',
|
|
92
|
+
message: `Chunking must be "word", "line", a RegExp, an Intl.Segmenter, or a ChunkDetector function. Received: ${chunking}`,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
detectChunk = buffer => {
|
|
97
|
+
const match = chunkingRegex.exec(buffer);
|
|
98
|
+
|
|
99
|
+
if (!match) {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return buffer.slice(0, match.index) + match?.[0];
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return () => {
|
|
108
|
+
let buffer = '';
|
|
109
|
+
let id = '';
|
|
110
|
+
let type: 'text-delta' | 'reasoning-delta' | undefined = undefined;
|
|
111
|
+
let providerMetadata: SharedV3ProviderMetadata | undefined = undefined;
|
|
112
|
+
|
|
113
|
+
function flushBuffer(
|
|
114
|
+
controller: TransformStreamDefaultController<TextStreamPart<TOOLS>>,
|
|
115
|
+
) {
|
|
116
|
+
if (buffer.length > 0 && type !== undefined) {
|
|
117
|
+
controller.enqueue({
|
|
118
|
+
type,
|
|
119
|
+
text: buffer,
|
|
120
|
+
id,
|
|
121
|
+
...(providerMetadata != null ? { providerMetadata } : {}),
|
|
122
|
+
});
|
|
123
|
+
buffer = '';
|
|
124
|
+
providerMetadata = undefined;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return new TransformStream<TextStreamPart<TOOLS>, TextStreamPart<TOOLS>>({
|
|
129
|
+
async transform(chunk, controller) {
|
|
130
|
+
// Handle non-smoothable chunks: flush buffer and pass through
|
|
131
|
+
if (chunk.type !== 'text-delta' && chunk.type !== 'reasoning-delta') {
|
|
132
|
+
flushBuffer(controller);
|
|
133
|
+
controller.enqueue(chunk);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Flush buffer when type or id changes
|
|
138
|
+
if ((chunk.type !== type || chunk.id !== id) && buffer.length > 0) {
|
|
139
|
+
flushBuffer(controller);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
buffer += chunk.text;
|
|
143
|
+
id = chunk.id;
|
|
144
|
+
type = chunk.type;
|
|
145
|
+
|
|
146
|
+
// Preserve providerMetadata (e.g., Anthropic thinking signatures)
|
|
147
|
+
if (chunk.providerMetadata != null) {
|
|
148
|
+
providerMetadata = chunk.providerMetadata;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
let match;
|
|
152
|
+
|
|
153
|
+
while ((match = detectChunk(buffer)) != null) {
|
|
154
|
+
controller.enqueue({ type, text: match, id });
|
|
155
|
+
buffer = buffer.slice(match.length);
|
|
156
|
+
|
|
157
|
+
await delay(delayInMs);
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
};
|
|
162
|
+
}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { ReasoningPart } from '@ai-sdk/provider-utils';
|
|
2
|
+
import {
|
|
3
|
+
CallWarning,
|
|
4
|
+
FinishReason,
|
|
5
|
+
LanguageModelRequestMetadata,
|
|
6
|
+
LanguageModelResponseMetadata,
|
|
7
|
+
ProviderMetadata,
|
|
8
|
+
} from '../types';
|
|
9
|
+
import { Source } from '../types/language-model';
|
|
10
|
+
import { LanguageModelUsage } from '../types/usage';
|
|
11
|
+
import { ContentPart } from './content-part';
|
|
12
|
+
import { GeneratedFile } from './generated-file';
|
|
13
|
+
import { ResponseMessage } from './response-message';
|
|
14
|
+
import { DynamicToolCall, StaticToolCall, TypedToolCall } from './tool-call';
|
|
15
|
+
import {
|
|
16
|
+
DynamicToolResult,
|
|
17
|
+
StaticToolResult,
|
|
18
|
+
TypedToolResult,
|
|
19
|
+
} from './tool-result';
|
|
20
|
+
import { ToolSet } from './tool-set';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The result of a single step in the generation process.
|
|
24
|
+
*/
|
|
25
|
+
export type StepResult<TOOLS extends ToolSet> = {
|
|
26
|
+
/**
|
|
27
|
+
The content that was generated in the last step.
|
|
28
|
+
*/
|
|
29
|
+
readonly content: Array<ContentPart<TOOLS>>;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
The generated text.
|
|
33
|
+
*/
|
|
34
|
+
readonly text: string;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
The reasoning that was generated during the generation.
|
|
38
|
+
*/
|
|
39
|
+
readonly reasoning: Array<ReasoningPart>;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
The reasoning text that was generated during the generation.
|
|
43
|
+
*/
|
|
44
|
+
readonly reasoningText: string | undefined;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
The files that were generated during the generation.
|
|
48
|
+
*/
|
|
49
|
+
readonly files: Array<GeneratedFile>;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
The sources that were used to generate the text.
|
|
53
|
+
*/
|
|
54
|
+
readonly sources: Array<Source>;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
The tool calls that were made during the generation.
|
|
58
|
+
*/
|
|
59
|
+
readonly toolCalls: Array<TypedToolCall<TOOLS>>;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
The static tool calls that were made in the last step.
|
|
63
|
+
*/
|
|
64
|
+
readonly staticToolCalls: Array<StaticToolCall<TOOLS>>;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
The dynamic tool calls that were made in the last step.
|
|
68
|
+
*/
|
|
69
|
+
readonly dynamicToolCalls: Array<DynamicToolCall>;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
The results of the tool calls.
|
|
73
|
+
*/
|
|
74
|
+
readonly toolResults: Array<TypedToolResult<TOOLS>>;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
The static tool results that were made in the last step.
|
|
78
|
+
*/
|
|
79
|
+
readonly staticToolResults: Array<StaticToolResult<TOOLS>>;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
The dynamic tool results that were made in the last step.
|
|
83
|
+
*/
|
|
84
|
+
readonly dynamicToolResults: Array<DynamicToolResult>;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* The unified reason why the generation finished.
|
|
88
|
+
*/
|
|
89
|
+
readonly finishReason: FinishReason;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* The raw reason why the generation finished (from the provider).
|
|
93
|
+
*/
|
|
94
|
+
readonly rawFinishReason: string | undefined;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
The token usage of the generated text.
|
|
98
|
+
*/
|
|
99
|
+
readonly usage: LanguageModelUsage;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
Warnings from the model provider (e.g. unsupported settings).
|
|
103
|
+
*/
|
|
104
|
+
readonly warnings: CallWarning[] | undefined;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
Additional request information.
|
|
108
|
+
*/
|
|
109
|
+
readonly request: LanguageModelRequestMetadata;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
Additional response information.
|
|
113
|
+
*/
|
|
114
|
+
readonly response: LanguageModelResponseMetadata & {
|
|
115
|
+
/**
|
|
116
|
+
The response messages that were generated during the call.
|
|
117
|
+
Response messages can be either assistant messages or tool messages.
|
|
118
|
+
They contain a generated id.
|
|
119
|
+
*/
|
|
120
|
+
readonly messages: Array<ResponseMessage>;
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
Response body (available only for providers that use HTTP requests).
|
|
124
|
+
*/
|
|
125
|
+
body?: unknown;
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
Additional provider-specific metadata. They are passed through
|
|
130
|
+
from the provider to the AI SDK and enable provider-specific
|
|
131
|
+
results that can be fully encapsulated in the provider.
|
|
132
|
+
*/
|
|
133
|
+
readonly providerMetadata: ProviderMetadata | undefined;
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
export class DefaultStepResult<TOOLS extends ToolSet>
|
|
137
|
+
implements StepResult<TOOLS>
|
|
138
|
+
{
|
|
139
|
+
readonly content: StepResult<TOOLS>['content'];
|
|
140
|
+
readonly finishReason: StepResult<TOOLS>['finishReason'];
|
|
141
|
+
readonly rawFinishReason: StepResult<TOOLS>['rawFinishReason'];
|
|
142
|
+
readonly usage: StepResult<TOOLS>['usage'];
|
|
143
|
+
readonly warnings: StepResult<TOOLS>['warnings'];
|
|
144
|
+
readonly request: StepResult<TOOLS>['request'];
|
|
145
|
+
readonly response: StepResult<TOOLS>['response'];
|
|
146
|
+
readonly providerMetadata: StepResult<TOOLS>['providerMetadata'];
|
|
147
|
+
|
|
148
|
+
constructor({
|
|
149
|
+
content,
|
|
150
|
+
finishReason,
|
|
151
|
+
rawFinishReason,
|
|
152
|
+
usage,
|
|
153
|
+
warnings,
|
|
154
|
+
request,
|
|
155
|
+
response,
|
|
156
|
+
providerMetadata,
|
|
157
|
+
}: {
|
|
158
|
+
content: StepResult<TOOLS>['content'];
|
|
159
|
+
finishReason: StepResult<TOOLS>['finishReason'];
|
|
160
|
+
rawFinishReason: StepResult<TOOLS>['rawFinishReason'];
|
|
161
|
+
usage: StepResult<TOOLS>['usage'];
|
|
162
|
+
warnings: StepResult<TOOLS>['warnings'];
|
|
163
|
+
request: StepResult<TOOLS>['request'];
|
|
164
|
+
response: StepResult<TOOLS>['response'];
|
|
165
|
+
providerMetadata: StepResult<TOOLS>['providerMetadata'];
|
|
166
|
+
}) {
|
|
167
|
+
this.content = content;
|
|
168
|
+
this.finishReason = finishReason;
|
|
169
|
+
this.rawFinishReason = rawFinishReason;
|
|
170
|
+
this.usage = usage;
|
|
171
|
+
this.warnings = warnings;
|
|
172
|
+
this.request = request;
|
|
173
|
+
this.response = response;
|
|
174
|
+
this.providerMetadata = providerMetadata;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
get text() {
|
|
178
|
+
return this.content
|
|
179
|
+
.filter(part => part.type === 'text')
|
|
180
|
+
.map(part => part.text)
|
|
181
|
+
.join('');
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
get reasoning() {
|
|
185
|
+
return this.content.filter(part => part.type === 'reasoning');
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
get reasoningText() {
|
|
189
|
+
return this.reasoning.length === 0
|
|
190
|
+
? undefined
|
|
191
|
+
: this.reasoning.map(part => part.text).join('');
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
get files() {
|
|
195
|
+
return this.content
|
|
196
|
+
.filter(part => part.type === 'file')
|
|
197
|
+
.map(part => part.file);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
get sources() {
|
|
201
|
+
return this.content.filter(part => part.type === 'source');
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
get toolCalls() {
|
|
205
|
+
return this.content.filter(part => part.type === 'tool-call');
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
get staticToolCalls() {
|
|
209
|
+
return this.toolCalls.filter(
|
|
210
|
+
(toolCall): toolCall is StaticToolCall<TOOLS> =>
|
|
211
|
+
toolCall.dynamic !== true,
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
get dynamicToolCalls() {
|
|
216
|
+
return this.toolCalls.filter(
|
|
217
|
+
(toolCall): toolCall is DynamicToolCall => toolCall.dynamic === true,
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
get toolResults() {
|
|
222
|
+
return this.content.filter(part => part.type === 'tool-result');
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
get staticToolResults() {
|
|
226
|
+
return this.toolResults.filter(
|
|
227
|
+
(toolResult): toolResult is StaticToolResult<TOOLS> =>
|
|
228
|
+
toolResult.dynamic !== true,
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
get dynamicToolResults() {
|
|
233
|
+
return this.toolResults.filter(
|
|
234
|
+
(toolResult): toolResult is DynamicToolResult =>
|
|
235
|
+
toolResult.dynamic === true,
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { StepResult } from './step-result';
|
|
2
|
+
import { ToolSet } from './tool-set';
|
|
3
|
+
|
|
4
|
+
export type StopCondition<TOOLS extends ToolSet> = (options: {
|
|
5
|
+
steps: Array<StepResult<TOOLS>>;
|
|
6
|
+
}) => PromiseLike<boolean> | boolean;
|
|
7
|
+
|
|
8
|
+
export function stepCountIs(stepCount: number): StopCondition<any> {
|
|
9
|
+
return ({ steps }) => steps.length === stepCount;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function hasToolCall(toolName: string): StopCondition<any> {
|
|
13
|
+
return ({ steps }) =>
|
|
14
|
+
steps[steps.length - 1]?.toolCalls?.some(
|
|
15
|
+
toolCall => toolCall.toolName === toolName,
|
|
16
|
+
) ?? false;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export async function isStopConditionMet<TOOLS extends ToolSet>({
|
|
20
|
+
stopConditions,
|
|
21
|
+
steps,
|
|
22
|
+
}: {
|
|
23
|
+
stopConditions: Array<StopCondition<TOOLS>>;
|
|
24
|
+
steps: Array<StepResult<TOOLS>>;
|
|
25
|
+
}): Promise<boolean> {
|
|
26
|
+
return (
|
|
27
|
+
await Promise.all(stopConditions.map(condition => condition({ steps })))
|
|
28
|
+
).some(result => result);
|
|
29
|
+
}
|