@contractspec/module.ai-chat 4.1.5 → 4.2.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 +13 -13
|
@@ -6,16 +6,19 @@
|
|
|
6
6
|
* @example
|
|
7
7
|
* ```ts
|
|
8
8
|
* // app/api/chat/route.ts (Next.js App Router)
|
|
9
|
-
* import { createChatRoute } from '@contractspec/module.ai-chat/core';
|
|
9
|
+
* import { createChatRoute, CHAT_ROUTE_MAX_DURATION } from '@contractspec/module.ai-chat/core';
|
|
10
10
|
* import { createProvider } from '@contractspec/lib.ai-providers';
|
|
11
11
|
*
|
|
12
12
|
* const provider = createProvider({ provider: 'openai', apiKey: process.env.OPENAI_API_KEY });
|
|
13
13
|
* export const POST = createChatRoute({ provider });
|
|
14
|
+
* export const maxDuration = CHAT_ROUTE_MAX_DURATION;
|
|
14
15
|
* ```
|
|
15
16
|
*/
|
|
16
|
-
import { type ToolSet } from 'ai';
|
|
17
|
+
import { type LanguageModel, type ToolSet } from 'ai';
|
|
17
18
|
import type { Provider as ChatProvider } from '@contractspec/lib.ai-providers';
|
|
18
19
|
import type { ThinkingLevel } from './thinking-levels';
|
|
20
|
+
/** Recommended maxDuration for Next.js route handlers (Vercel/serverless). */
|
|
21
|
+
export declare const CHAT_ROUTE_MAX_DURATION = 30;
|
|
19
22
|
export interface CreateChatRouteOptions {
|
|
20
23
|
/** LLM provider (from createProvider) */
|
|
21
24
|
provider: ChatProvider;
|
|
@@ -25,6 +28,14 @@ export interface CreateChatRouteOptions {
|
|
|
25
28
|
tools?: ToolSet;
|
|
26
29
|
/** Default thinking level (can be overridden by request body) */
|
|
27
30
|
thinkingLevel?: ThinkingLevel;
|
|
31
|
+
/** Send source citations to client (e.g. Perplexity). Default: true when thinkingLevel is set. */
|
|
32
|
+
sendSources?: boolean;
|
|
33
|
+
/** Send reasoning parts to client (extended thinking). Default: true when thinkingLevel is set and not instant. */
|
|
34
|
+
sendReasoning?: boolean;
|
|
35
|
+
/** Resolve model from request body (for model picker). If not provided, uses provider.getModel(). */
|
|
36
|
+
getModel?: (body: {
|
|
37
|
+
model?: string;
|
|
38
|
+
}) => LanguageModel;
|
|
28
39
|
}
|
|
29
40
|
/**
|
|
30
41
|
* Create a route handler that streams chat using streamText + toUIMessageStreamResponse.
|
|
@@ -32,7 +43,7 @@ export interface CreateChatRouteOptions {
|
|
|
32
43
|
* Compatible with @ai-sdk/react useChat when used as the API endpoint.
|
|
33
44
|
* Supports tool approval when tools have needsApproval.
|
|
34
45
|
*
|
|
35
|
-
* @param options - Provider, system prompt,
|
|
46
|
+
* @param options - Provider, system prompt, optional tools, sendSources, sendReasoning
|
|
36
47
|
* @returns A function (req: Request) => Promise<Response> suitable for Next.js route handlers
|
|
37
48
|
*/
|
|
38
49
|
export declare function createChatRoute(options: CreateChatRouteOptions): (req: Request) => Promise<Response>;
|
package/dist/core/index.js
CHANGED
|
@@ -1084,39 +1084,74 @@ import {
|
|
|
1084
1084
|
convertToModelMessages,
|
|
1085
1085
|
streamText as streamText2
|
|
1086
1086
|
} from "ai";
|
|
1087
|
+
import { z as z4 } from "zod";
|
|
1088
|
+
var CHAT_ROUTE_MAX_DURATION = 30;
|
|
1089
|
+
var REQUEST_BODY_SCHEMA = z4.object({
|
|
1090
|
+
messages: z4.array(z4.unknown()).min(1, "messages array required"),
|
|
1091
|
+
thinkingLevel: z4.enum(["instant", "thinking", "extra_thinking", "max"]).optional(),
|
|
1092
|
+
model: z4.string().optional()
|
|
1093
|
+
});
|
|
1087
1094
|
var DEFAULT_SYSTEM_PROMPT2 = `You are a helpful AI assistant.`;
|
|
1095
|
+
function defaultSendReasoning(thinkingLevel) {
|
|
1096
|
+
return Boolean(thinkingLevel && thinkingLevel !== "instant");
|
|
1097
|
+
}
|
|
1098
|
+
function defaultSendSources() {
|
|
1099
|
+
return true;
|
|
1100
|
+
}
|
|
1088
1101
|
function createChatRoute(options) {
|
|
1089
1102
|
const {
|
|
1090
1103
|
provider,
|
|
1091
1104
|
systemPrompt = DEFAULT_SYSTEM_PROMPT2,
|
|
1092
1105
|
tools,
|
|
1093
|
-
thinkingLevel: defaultThinkingLevel
|
|
1106
|
+
thinkingLevel: defaultThinkingLevel,
|
|
1107
|
+
sendSources = defaultSendSources(),
|
|
1108
|
+
sendReasoning = defaultSendReasoning(defaultThinkingLevel),
|
|
1109
|
+
getModel
|
|
1094
1110
|
} = options;
|
|
1095
1111
|
return async (req) => {
|
|
1096
1112
|
if (req.method !== "POST") {
|
|
1097
1113
|
return new Response("Method not allowed", { status: 405 });
|
|
1098
1114
|
}
|
|
1099
|
-
let
|
|
1115
|
+
let rawBody;
|
|
1100
1116
|
try {
|
|
1101
|
-
|
|
1117
|
+
rawBody = await req.json();
|
|
1102
1118
|
} catch {
|
|
1103
|
-
return new Response("Invalid JSON body", {
|
|
1119
|
+
return new Response(JSON.stringify({ error: "Invalid JSON body" }), {
|
|
1120
|
+
status: 400,
|
|
1121
|
+
headers: { "Content-Type": "application/json" }
|
|
1122
|
+
});
|
|
1104
1123
|
}
|
|
1105
|
-
const
|
|
1106
|
-
if (!
|
|
1107
|
-
|
|
1124
|
+
const parsed = REQUEST_BODY_SCHEMA.safeParse(rawBody);
|
|
1125
|
+
if (!parsed.success) {
|
|
1126
|
+
const message = parsed.error.issues[0]?.message ?? "Invalid request body";
|
|
1127
|
+
return new Response(JSON.stringify({ error: message }), {
|
|
1128
|
+
status: 400,
|
|
1129
|
+
headers: { "Content-Type": "application/json" }
|
|
1130
|
+
});
|
|
1108
1131
|
}
|
|
1132
|
+
const body = parsed.data;
|
|
1109
1133
|
const thinkingLevel = body.thinkingLevel ?? defaultThinkingLevel;
|
|
1110
1134
|
const providerOptions = getProviderOptions(thinkingLevel, provider.name);
|
|
1111
|
-
const model = provider.getModel();
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1135
|
+
const model = getModel ? getModel(body) : provider.getModel();
|
|
1136
|
+
try {
|
|
1137
|
+
const result = streamText2({
|
|
1138
|
+
model,
|
|
1139
|
+
messages: await convertToModelMessages(body.messages),
|
|
1140
|
+
system: systemPrompt,
|
|
1141
|
+
tools,
|
|
1142
|
+
providerOptions: Object.keys(providerOptions).length > 0 ? providerOptions : undefined
|
|
1143
|
+
});
|
|
1144
|
+
return result.toUIMessageStreamResponse({
|
|
1145
|
+
sendSources,
|
|
1146
|
+
sendReasoning
|
|
1147
|
+
});
|
|
1148
|
+
} catch (error) {
|
|
1149
|
+
const message = error instanceof Error ? error.message : "An error occurred";
|
|
1150
|
+
return new Response(JSON.stringify({ error: message }), {
|
|
1151
|
+
status: 500,
|
|
1152
|
+
headers: { "Content-Type": "application/json" }
|
|
1153
|
+
});
|
|
1154
|
+
}
|
|
1120
1155
|
};
|
|
1121
1156
|
}
|
|
1122
1157
|
// src/core/create-completion-route.ts
|
|
@@ -1609,5 +1644,6 @@ export {
|
|
|
1609
1644
|
THINKING_LEVEL_DESCRIPTIONS,
|
|
1610
1645
|
LocalStorageConversationStore,
|
|
1611
1646
|
InMemoryConversationStore,
|
|
1612
|
-
ChatService
|
|
1647
|
+
ChatService,
|
|
1648
|
+
CHAT_ROUTE_MAX_DURATION
|
|
1613
1649
|
};
|
|
@@ -42,6 +42,10 @@ export interface ChatToolCall {
|
|
|
42
42
|
result?: unknown;
|
|
43
43
|
status: 'pending' | 'running' | 'completed' | 'error';
|
|
44
44
|
error?: string;
|
|
45
|
+
/** When true, result is streaming (preliminary) */
|
|
46
|
+
preliminary?: boolean;
|
|
47
|
+
/** Nested UIMessage parts (subagent output) */
|
|
48
|
+
nestedParts?: unknown[];
|
|
45
49
|
}
|
|
46
50
|
/**
|
|
47
51
|
* Source/citation in a message
|