Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion packages/smartquote/src/ai-sdk/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* to test our transform with realistic AI streaming patterns.
*/
import { describe, expect, it } from 'vitest';
import { streamText } from 'ai';
import { streamText, type StreamTextTransform, type ToolSet } from 'ai';
import { MockLanguageModelV3, simulateReadableStream } from 'ai/test';

import { smartQuoteTransform, SmartQuote } from './index.js';
Expand Down Expand Up @@ -294,4 +294,31 @@ describe('smartQuoteTransform with AI SDK', () => {
expect(text).toContain(RightDouble);
});
});

describe('type compatibility', () => {
it('is compatible with streamText tools parameter', () => {
// Define a typed tools object - we intersect with ToolSet to satisfy
// the constraint since our simplified type is missing required Tool properties
type MyToolSet = {
myTool: { description: string; parameters: unknown };
};
// Create a transform with the specific tool type
const transform = smartQuoteTransform<MyToolSet & ToolSet>();
// This should compile without type errors - the transform should be assignable
// to experimental_transform when tools are specified
const config: { experimental_transform: StreamTextTransform<MyToolSet & ToolSet> } = {
experimental_transform: transform,
};
expect(config.experimental_transform).toBe(transform);
});

it('works with default ToolSet when no type parameter is specified', () => {
// When calling without type params, it defaults to ToolSet
const transform = smartQuoteTransform();
const config: { experimental_transform: StreamTextTransform<ToolSet> } = {
experimental_transform: transform,
};
expect(config.experimental_transform).toBe(transform);
});
});
});
15 changes: 12 additions & 3 deletions packages/smartquote/src/ai-sdk/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,25 @@ export { SmartQuote, smartQuotes } from '../index.js';
*
* Converts straight quotes to typographically correct smart quotes
* in streaming AI responses. See module documentation for examples.
*
* @remarks
* The function is generic over the tools type parameter, allowing it to be
* compatible with any tool configuration in `streamText()`. The transform
* only processes `text-delta` stream parts and passes through all other
* parts unchanged, including tool-related stream parts.
*
* @typeParam TOOLS - The tools type from the streamText configuration.
* Defaults to ToolSet for compatibility when no tools are specified.
*/
export function smartQuoteTransform(
export function smartQuoteTransform<TOOLS extends ToolSet = ToolSet>(
options?: SmartQuoteTransformOptions,
): StreamTextTransform<ToolSet> {
): StreamTextTransform<TOOLS> {
return () => {
const transform = options?.disableMarkdown
? createTextTransform()
: createMarkdownTextTransform();

return new TransformStream<TextStreamPart<ToolSet>, TextStreamPart<ToolSet>>({
return new TransformStream<TextStreamPart<TOOLS>, TextStreamPart<TOOLS>>({
transform(part, controller) {
if (part.type === 'text-delta') {
const converted = transform(part.text);
Expand Down
Loading