@contractspec/module.ai-chat 4.1.5 → 4.3.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/README.md +29 -3
- package/dist/browser/core/index.js +53 -17
- package/dist/browser/index.js +982 -426
- package/dist/browser/presentation/components/index.js +975 -419
- package/dist/browser/presentation/hooks/index.js +8 -1
- package/dist/browser/presentation/index.js +983 -427
- package/dist/core/create-chat-route.d.ts +14 -3
- package/dist/core/index.js +53 -17
- package/dist/core/message-types.d.ts +4 -0
- package/dist/index.js +982 -426
- package/dist/node/core/index.js +53 -17
- package/dist/node/index.js +982 -426
- package/dist/node/presentation/components/index.js +975 -419
- package/dist/node/presentation/hooks/index.js +8 -1
- package/dist/node/presentation/index.js +983 -427
- package/dist/presentation/components/ChainOfThought.d.ts +30 -0
- package/dist/presentation/components/ChatInput.d.ts +3 -4
- package/dist/presentation/components/ChatMessage.d.ts +6 -4
- package/dist/presentation/components/ChatWithExport.d.ts +14 -1
- package/dist/presentation/components/ChatWithSidebar.d.ts +12 -1
- package/dist/presentation/components/Reasoning.d.ts +24 -0
- package/dist/presentation/components/Sources.d.ts +22 -0
- package/dist/presentation/components/Suggestion.d.ts +12 -0
- package/dist/presentation/components/ToolResultRenderer.d.ts +20 -3
- package/dist/presentation/components/component-types.d.ts +52 -0
- package/dist/presentation/components/index.d.ts +6 -1
- package/dist/presentation/components/index.js +975 -419
- package/dist/presentation/hooks/index.js +8 -1
- package/dist/presentation/index.js +983 -427
- package/package.json +15 -15
package/README.md
CHANGED
|
@@ -162,7 +162,10 @@ For full AI SDK compatibility including tool approval, use `createChatRoute` wit
|
|
|
162
162
|
|
|
163
163
|
```ts
|
|
164
164
|
// app/api/chat/route.ts (Next.js App Router)
|
|
165
|
-
import {
|
|
165
|
+
import {
|
|
166
|
+
createChatRoute,
|
|
167
|
+
CHAT_ROUTE_MAX_DURATION,
|
|
168
|
+
} from '@contractspec/module.ai-chat/core';
|
|
166
169
|
import { createProvider } from '@contractspec/lib.ai-providers';
|
|
167
170
|
|
|
168
171
|
const provider = createProvider({
|
|
@@ -172,8 +175,11 @@ const provider = createProvider({
|
|
|
172
175
|
});
|
|
173
176
|
|
|
174
177
|
export const POST = createChatRoute({ provider });
|
|
178
|
+
export const maxDuration = CHAT_ROUTE_MAX_DURATION;
|
|
175
179
|
```
|
|
176
180
|
|
|
181
|
+
`maxDuration` is required for long-running streaming on Vercel/serverless. The route sends sources and reasoning by default (AI Elements parity). Override with `sendSources` and `sendReasoning` in options. Use `getModel` to support a model picker from the request body.
|
|
182
|
+
|
|
177
183
|
```tsx
|
|
178
184
|
// Client: use @ai-sdk/react useChat with DefaultChatTransport
|
|
179
185
|
import { useChat } from '@ai-sdk/react';
|
|
@@ -229,9 +235,29 @@ const chatService = new ChatService({
|
|
|
229
235
|
// based on thinking level when modelSelector is set
|
|
230
236
|
```
|
|
231
237
|
|
|
232
|
-
###
|
|
238
|
+
### AI Elements-Style Components
|
|
239
|
+
|
|
240
|
+
The module includes native implementations of [Reasoning](https://elements.ai-sdk.dev/components/reasoning), [Sources](https://elements.ai-sdk.dev/components/sources), [Suggestion](https://elements.ai-sdk.dev/components/suggestion), and [Chain of Thought](https://elements.ai-sdk.dev/components/chain-of-thought) patterns. Pass `components` to `ChatMessage` or `ChatWithExport` to override with ai-elements when installed:
|
|
241
|
+
|
|
242
|
+
```tsx
|
|
243
|
+
import { ChatWithSidebar, type ChatMessageComponents } from '@contractspec/module.ai-chat';
|
|
244
|
+
// When using ai-elements: import { Reasoning, Sources, ... } from '@/components/ai-elements/...';
|
|
245
|
+
|
|
246
|
+
<ChatWithSidebar
|
|
247
|
+
components={{
|
|
248
|
+
Reasoning: AiElementsReasoning,
|
|
249
|
+
Sources: AiElementsSources,
|
|
250
|
+
SourcesTrigger: AiElementsSourcesTrigger,
|
|
251
|
+
Source: AiElementsSource,
|
|
252
|
+
ChainOfThought: AiElementsChainOfThought,
|
|
253
|
+
ChainOfThoughtStep: AiElementsChainOfThoughtStep,
|
|
254
|
+
}}
|
|
255
|
+
suggestions={['Explain how X works', 'What is Y?']}
|
|
256
|
+
showSuggestionsWhenEmpty
|
|
257
|
+
/>
|
|
258
|
+
```
|
|
233
259
|
|
|
234
|
-
Apps can optionally use [AI Elements](https://elements.ai-sdk.dev) for UI
|
|
260
|
+
Use `suggestions` and `onSuggestionClick` for clickable prompt chips. Apps can optionally use [AI Elements](https://elements.ai-sdk.dev) for enhanced UI; provide an adapter from `ChatMessage` to `UIMessage` when integrating.
|
|
235
261
|
|
|
236
262
|
### useCompletion (Non-Chat Completion)
|
|
237
263
|
|
|
@@ -1089,39 +1089,74 @@ import {
|
|
|
1089
1089
|
convertToModelMessages,
|
|
1090
1090
|
streamText as streamText2
|
|
1091
1091
|
} from "ai";
|
|
1092
|
+
import { z as z4 } from "zod";
|
|
1093
|
+
var CHAT_ROUTE_MAX_DURATION = 30;
|
|
1094
|
+
var REQUEST_BODY_SCHEMA = z4.object({
|
|
1095
|
+
messages: z4.array(z4.unknown()).min(1, "messages array required"),
|
|
1096
|
+
thinkingLevel: z4.enum(["instant", "thinking", "extra_thinking", "max"]).optional(),
|
|
1097
|
+
model: z4.string().optional()
|
|
1098
|
+
});
|
|
1092
1099
|
var DEFAULT_SYSTEM_PROMPT2 = `You are a helpful AI assistant.`;
|
|
1100
|
+
function defaultSendReasoning(thinkingLevel) {
|
|
1101
|
+
return Boolean(thinkingLevel && thinkingLevel !== "instant");
|
|
1102
|
+
}
|
|
1103
|
+
function defaultSendSources() {
|
|
1104
|
+
return true;
|
|
1105
|
+
}
|
|
1093
1106
|
function createChatRoute(options) {
|
|
1094
1107
|
const {
|
|
1095
1108
|
provider,
|
|
1096
1109
|
systemPrompt = DEFAULT_SYSTEM_PROMPT2,
|
|
1097
1110
|
tools,
|
|
1098
|
-
thinkingLevel: defaultThinkingLevel
|
|
1111
|
+
thinkingLevel: defaultThinkingLevel,
|
|
1112
|
+
sendSources = defaultSendSources(),
|
|
1113
|
+
sendReasoning = defaultSendReasoning(defaultThinkingLevel),
|
|
1114
|
+
getModel
|
|
1099
1115
|
} = options;
|
|
1100
1116
|
return async (req) => {
|
|
1101
1117
|
if (req.method !== "POST") {
|
|
1102
1118
|
return new Response("Method not allowed", { status: 405 });
|
|
1103
1119
|
}
|
|
1104
|
-
let
|
|
1120
|
+
let rawBody;
|
|
1105
1121
|
try {
|
|
1106
|
-
|
|
1122
|
+
rawBody = await req.json();
|
|
1107
1123
|
} catch {
|
|
1108
|
-
return new Response("Invalid JSON body", {
|
|
1124
|
+
return new Response(JSON.stringify({ error: "Invalid JSON body" }), {
|
|
1125
|
+
status: 400,
|
|
1126
|
+
headers: { "Content-Type": "application/json" }
|
|
1127
|
+
});
|
|
1109
1128
|
}
|
|
1110
|
-
const
|
|
1111
|
-
if (!
|
|
1112
|
-
|
|
1129
|
+
const parsed = REQUEST_BODY_SCHEMA.safeParse(rawBody);
|
|
1130
|
+
if (!parsed.success) {
|
|
1131
|
+
const message = parsed.error.issues[0]?.message ?? "Invalid request body";
|
|
1132
|
+
return new Response(JSON.stringify({ error: message }), {
|
|
1133
|
+
status: 400,
|
|
1134
|
+
headers: { "Content-Type": "application/json" }
|
|
1135
|
+
});
|
|
1113
1136
|
}
|
|
1137
|
+
const body = parsed.data;
|
|
1114
1138
|
const thinkingLevel = body.thinkingLevel ?? defaultThinkingLevel;
|
|
1115
1139
|
const providerOptions = getProviderOptions(thinkingLevel, provider.name);
|
|
1116
|
-
const model = provider.getModel();
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1140
|
+
const model = getModel ? getModel(body) : provider.getModel();
|
|
1141
|
+
try {
|
|
1142
|
+
const result = streamText2({
|
|
1143
|
+
model,
|
|
1144
|
+
messages: await convertToModelMessages(body.messages),
|
|
1145
|
+
system: systemPrompt,
|
|
1146
|
+
tools,
|
|
1147
|
+
providerOptions: Object.keys(providerOptions).length > 0 ? providerOptions : undefined
|
|
1148
|
+
});
|
|
1149
|
+
return result.toUIMessageStreamResponse({
|
|
1150
|
+
sendSources,
|
|
1151
|
+
sendReasoning
|
|
1152
|
+
});
|
|
1153
|
+
} catch (error) {
|
|
1154
|
+
const message = error instanceof Error ? error.message : "An error occurred";
|
|
1155
|
+
return new Response(JSON.stringify({ error: message }), {
|
|
1156
|
+
status: 500,
|
|
1157
|
+
headers: { "Content-Type": "application/json" }
|
|
1158
|
+
});
|
|
1159
|
+
}
|
|
1125
1160
|
};
|
|
1126
1161
|
}
|
|
1127
1162
|
// src/core/create-completion-route.ts
|
|
@@ -1614,5 +1649,6 @@ export {
|
|
|
1614
1649
|
THINKING_LEVEL_DESCRIPTIONS,
|
|
1615
1650
|
LocalStorageConversationStore,
|
|
1616
1651
|
InMemoryConversationStore,
|
|
1617
|
-
ChatService
|
|
1652
|
+
ChatService,
|
|
1653
|
+
CHAT_ROUTE_MAX_DURATION
|
|
1618
1654
|
};
|