Giter Site home page Giter Site logo

Comments (11)

jt6677 avatar jt6677 commented on May 18, 2024 4

I will try to tackle this problem on Thursday. My hacky way to preserve line breaks and format previously was to put text in blackquote onFinish

    onFinish: (_prompt, completion) => {
      if (!editor) return
      const from = editor.state.selection.from - completion.length
      const to = editor.state.selection.from
      const text = editor.state.doc.textBetween(from, to)
      editor
        ?.chain()
        .deleteRange({ from, to })
        .insertContent({ type: 'paragraph', content: [{ type: 'text', text: text }] })
        .setBlockquote()
        .run()
    },

from novel.

jt6677 avatar jt6677 commented on May 18, 2024 1

That would have issue too. Previously, the gtp response would have a nice format but any editing of the response would cause the text to lose all the line break. I could not find a solution to that problem at the moment.

from novel.

steven-tey avatar steven-tey commented on May 18, 2024 1

Removed markdown formatting from the prompt for now until we figure out a solution for this: 97b0c49

from novel.

jt6677 avatar jt6677 commented on May 18, 2024 1

@steven-tey I came close with a solution.

//temporarily escape markdown syntax as stream coming in  
useEffect(() => {
  const diff = completion.slice(prev.current.length);
  prev.current = completion;

  // Escape markdown syntax
  const escapedDiff = diff.replace(/([#*_{}[\]()`~>#+-.!|])/g, '\\$1');

  // Replace the content in the editor with the escaped markdown
  editor?.commands.setContent(escapedDiff, false);

}, [isLoading, editor, completion]);
\\ parse it again onFinish 

onFinish: (_prompt, completion) => {
  if (!editor) return
  console.log('πŸš€ ~ file: Editor.tsx:116 ~ Editor ~ completion:', completion)
  const from = editor.state.selection.from - completion.length
  const to = editor.state.selection.from

  // Replace the current content in the editor with the completion, parsed as Markdown
  editor.commands.setContent(completion, false);
},

The problem is setContent would work but not insertContent. setContent replaces everything. Maybe someone with better knowledge with tiptap would know what to do here.

from novel.

jt6677 avatar jt6677 commented on May 18, 2024 1

yeah, tiptap markdown does not play nice with streamed response. You either need to escape all the markdown syntax while streaming then set it again or just no using markdown at all. I delete the markdown plugin because the markdown was just too unpredictable.

from novel.

steven-tey avatar steven-tey commented on May 18, 2024

Yeahhh I noticed that too – might need to coerce that to plaintext for now :meow_disappointed:

from novel.

steven-tey avatar steven-tey commented on May 18, 2024

@jt6677 yeah that's smart! The root of the issue is streaming response doesn't play well with the way they're converted into markdown by tiptap-markdown – the maintainer of the lib, @aguingand confirmed that as well!

Setting everything with setContent when the response finishes streaming would work, but it becomes a blocking response and defeats the purpose of streaming: #7 (reply in thread)

from novel.

peterokwara avatar peterokwara commented on May 18, 2024

@jt6677 ended up doing the same thing.
I stream the content. Then when the streaming finishes, I set it. Will work for now.

from novel.

mixasite avatar mixasite commented on May 18, 2024

@steven-tey, really appreciate your work. From Vercel's Platforms Starter Kit to this awesome UI editor!

Format gets broken as the generated markdown text streams into the editor. Solution is replacing the whole content iteratively instead of just inserting the diff

so instead of

  const prev = useRef("");

  // Insert chunks of the generated text
  useEffect(() => {
    const diff = completion.slice(prev.current.length);
    prev.current = completion;
    editor?.commands.insertContent(diff);
  }, [isLoading, editor, completion]);

remove the last appended completion + append the whole new completion again to let the editor fix the formatting:

const prev = useRef("");
useEffect(() => {
  // reset prev when `complete` is called again
  if (prev?.current.length > completion.length) {
    prev.current = ""
  }
  editor?.chain()
    .deleteRange({
      from: editor.state.selection.from - prev.length,
      to: editor.state.selection.from,
    })
    .insertContent(completion)
    .run()
}, [editor, completion])

from novel.

haydenbleasel avatar haydenbleasel commented on May 18, 2024

@andrewdoro This issue is likely resolved by the new AI implementation since it's not streamed into the editor directly.

from novel.

andrewdoro avatar andrewdoro commented on May 18, 2024

@haydenbleasel Yep thanks for the tag here. So the new AI implementation works with Markdown. We no longer have a working example for the old ++ implementation where we stream directly in the editor. (if someone wants to work with that, the current AI code might help).

I also recommend the new approach. This is what Notion also uses.

from novel.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.