Skip to content

Commit efe3b0f

Browse files
committed
feat: Supports adjusting text output effects, output by word by default (most efficient)
feat: Supports HTML element rendering, making it possible to output complex tables, charts, videos and other elements. refactor: Optimize table output prompt fix: Fixed the issue where the search task unexpectedly turned to completed status when the information collection content was empty.
1 parent 0afbe5e commit efe3b0f

14 files changed

Lines changed: 182 additions & 12806 deletions

File tree

package-lock.json

Lines changed: 0 additions & 12764 deletions
This file was deleted.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "deep-research",
33
"description": "Use any LLMs (Large Language Models) for Deep Research. Support SSE API and MCP server.",
4-
"version": "0.9.15",
4+
"version": "0.9.16",
55
"license": "MIT",
66
"repository": {
77
"url": "https://github.com/u14app/deep-research"
@@ -75,6 +75,7 @@
7575
"react-zoom-pan-pinch": "^3.7.0",
7676
"rehype-highlight": "^7.0.2",
7777
"rehype-katex": "^7.0.1",
78+
"rehype-raw": "^7.0.0",
7879
"remark-breaks": "^4.0.0",
7980
"remark-gfm": "^4.0.1",
8081
"remark-math": "^6.0.0",

pnpm-lock.yaml

Lines changed: 54 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/MagicDown/View.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import dynamic from "next/dynamic";
22
import { useMemo, memo } from "react";
33
import ReactMarkdown, { type Options, type Components } from "react-markdown";
4+
import rehypeRaw from "rehype-raw";
45
import remarkGfm from "remark-gfm";
56
import remarkMath from "remark-math";
67
import remarkBreaks from "remark-breaks";
@@ -38,10 +39,12 @@ function MarkdownBlock({ children: content, ...rest }: Options) {
3839
{...rest}
3940
remarkPlugins={[remarkGfm, remarkMath, remarkBreaks, ...remarkPlugins]}
4041
rehypePlugins={[
42+
rehypeRaw,
4143
[rehypeHighlight, { detect: true, ignoreMissing: true }],
4244
rehypeKatex,
4345
...rehypePlugins,
4446
]}
47+
disallowedElements={["script", "form"]}
4548
components={{
4649
pre: (props) => {
4750
const { children, className, ...rest } = props;

src/components/Setting.tsx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ const formSchema = z.object({
162162
debug: z.string().optional(),
163163
references: z.string().optional(),
164164
citationImage: z.string().optional(),
165+
smoothTextStreamType: z.enum(["character", "word", "line"]).optional(),
165166
});
166167

167168
function convertModelName(name: string) {
@@ -3432,6 +3433,37 @@ function Setting({ open, onClose }: SettingProps) {
34323433
</FormItem>
34333434
)}
34343435
/>
3436+
<FormField
3437+
control={form.control}
3438+
name="smoothTextStreamType"
3439+
render={({ field }) => (
3440+
<FormItem className="from-item">
3441+
<FormLabel className="from-label">
3442+
<HelpTip tip={t("setting.textOutputModeTip")}>
3443+
{t("setting.textOutputMode")}
3444+
</HelpTip>
3445+
</FormLabel>
3446+
<FormControl>
3447+
<Select {...field} onValueChange={field.onChange}>
3448+
<SelectTrigger className="form-field">
3449+
<SelectValue />
3450+
</SelectTrigger>
3451+
<SelectContent>
3452+
<SelectItem value="character">
3453+
{t("setting.character")}
3454+
</SelectItem>
3455+
<SelectItem value="word">
3456+
{t("setting.word")}
3457+
</SelectItem>
3458+
<SelectItem value="line">
3459+
{t("setting.line")}
3460+
</SelectItem>
3461+
</SelectContent>
3462+
</Select>
3463+
</FormControl>
3464+
</FormItem>
3465+
)}
3466+
/>
34353467
</TabsContent>
34363468
</Tabs>
34373469
</form>

src/constants/prompts.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ Follow these rules to organize your output:
3131
- **Code blocks:** Enclose it in triple backticks (\`\`\` \`\`\`), optionally in a language.
3232
- **Quotes:** Use the \`>\` symbol.
3333
- **Horizontal rule:** Use \`---\`, \`***\` or \`___\`.
34-
- **Table:** Use basic GFM table syntax and do not include any extra spaces or tabs for alignment, use \`|\` and \`-\` symbols to construct. If there is complex table content, it needs to be divided into multiple tables for rendering, nested tables are not allowed.
34+
- **Table**: Use basic GFM table syntax, do not include any extra spaces or tabs for alignment, and use \`|\` and \`-\` symbols to construct. **For complex tables, GFM table syntax is not suitable. You must use HTML syntax to output complex tables.**
3535
- **Emoji:** You can insert Emoji before the title or subtitle, such as \`🔢### 1. Determine the base area of the prism\`.
3636
- **LaTeX:**
3737
- **Inline formula:** Use \`$E=mc^2$\`

src/hooks/useArtifact.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { useState } from "react";
22
import { streamText, smoothStream } from "ai";
33
import { toast } from "sonner";
4+
import { useSettingStore } from "@/store/setting";
45
import useModelProvider from "@/hooks/useAiProvider";
56
import {
67
AIWritePrompt,
@@ -17,8 +18,11 @@ type ArtifactProps = {
1718
onChange: (value: string) => void;
1819
};
1920

20-
function smoothTextStream() {
21-
return smoothStream({ chunking: /./, delayInMs: 0 });
21+
function smoothTextStream(type: "character" | "word" | "line") {
22+
return smoothStream({
23+
chunking: type === "character" ? /./ : type,
24+
delayInMs: 0,
25+
});
2226
}
2327

2428
function handleError(error: unknown) {
@@ -27,6 +31,7 @@ function handleError(error: unknown) {
2731
}
2832

2933
function useArtifact({ value, onChange }: ArtifactProps) {
34+
const { smoothTextStreamType } = useSettingStore();
3035
const { createModelProvider, getModel } = useModelProvider();
3136
const [loadingAction, setLoadingAction] = useState<string>("");
3237

@@ -36,7 +41,7 @@ function useArtifact({ value, onChange }: ArtifactProps) {
3641
const result = streamText({
3742
model: await createModelProvider(thinkingModel),
3843
prompt: AIWritePrompt(value, prompt, systemInstruction),
39-
experimental_transform: smoothTextStream(),
44+
experimental_transform: smoothTextStream(smoothTextStreamType),
4045
onError: handleError,
4146
});
4247
let text = "";
@@ -54,7 +59,7 @@ function useArtifact({ value, onChange }: ArtifactProps) {
5459
const result = streamText({
5560
model: await createModelProvider(thinkingModel),
5661
prompt: changeLanguagePrompt(value, lang, systemInstruction),
57-
experimental_transform: smoothTextStream(),
62+
experimental_transform: smoothTextStream(smoothTextStreamType),
5863
onError: handleError,
5964
});
6065
let text = "";
@@ -72,7 +77,7 @@ function useArtifact({ value, onChange }: ArtifactProps) {
7277
const result = streamText({
7378
model: await createModelProvider(thinkingModel),
7479
prompt: changeReadingLevelPrompt(value, level, systemInstruction),
75-
experimental_transform: smoothTextStream(),
80+
experimental_transform: smoothTextStream(smoothTextStreamType),
7681
onError: handleError,
7782
});
7883
let text = "";
@@ -90,7 +95,7 @@ function useArtifact({ value, onChange }: ArtifactProps) {
9095
const result = streamText({
9196
model: await createModelProvider(thinkingModel),
9297
prompt: adjustLengthPrompt(value, length, systemInstruction),
93-
experimental_transform: smoothTextStream(),
98+
experimental_transform: smoothTextStream(smoothTextStreamType),
9499
onError: handleError,
95100
});
96101
let text = "";
@@ -108,7 +113,7 @@ function useArtifact({ value, onChange }: ArtifactProps) {
108113
const result = streamText({
109114
model: await createModelProvider(thinkingModel),
110115
prompt: continuationPrompt(value, systemInstruction),
111-
experimental_transform: smoothTextStream(),
116+
experimental_transform: smoothTextStream(smoothTextStreamType),
112117
onError: handleError,
113118
});
114119
let text = value + "\n";
@@ -126,7 +131,7 @@ function useArtifact({ value, onChange }: ArtifactProps) {
126131
const result = streamText({
127132
model: await createModelProvider(thinkingModel),
128133
prompt: addEmojisPrompt(value, systemInstruction),
129-
experimental_transform: smoothTextStream(),
134+
experimental_transform: smoothTextStream(smoothTextStreamType),
130135
onError: handleError,
131136
});
132137
let text = "";

0 commit comments

Comments
 (0)