Skip to content
Latestv1.0.63

useAIStream

useAIStream is built on top of useSSE, designed for AI application scenarios, providing a complete set of streaming capabilities including typewriter effect, thinking chain, tool calling, etc.

AI Streaming Chat Demo

💡 Note: useAIStream requires a real AI API (e.g. OpenAI, Claude). The demo below simulates streaming output including the thinking phase and typewriter content. In real usage, replace the URL in start() with your AI endpoint.

AI Streaming Chat Demo (Thinking Chain + Typewriter)

Basic Usage

typescript
import { useAIStream } from '@yh-ui/request'

const {
  loading,
  content, // Raw text
  text, // Parsed current text
  thinking, // Thinking content
  toolCalls, // Tool call list
  done,
  error,
  start,
  stop,
  reset
} = useAIStream({
  onText: (full, delta) => {
    console.log('New content:', delta)
  },
  onThinking: (t) => {
    console.log('Thinking:', t)
  },
  onToolCall: (tools) => {
    console.log('Tool calls:', tools)
  }
})

// Start AI request
start({
  url: '/api/ai/chat',
  method: 'POST',
  data: {
    model: 'gpt-4',
    messages: [{ role: 'user', content: 'Write a welcome message' }],
    stream: true
  }
})

Return Values

FieldTypeDescription
loadingRef<boolean>Whether receiving
contentRef<string>Raw streaming text
textRef<string>Parsed plain text (append or override)
thinkingRef<string>Thinking chain content
toolCallsRef<AIStreamMessage['toolCalls']>Tool call list
doneRef<boolean>Whether done
messagesRef<SSEMessage[]>Underlying SSE messages
errorRef<Error | undefined>Error object
start(options?)Start AI streaming request
stop()Stop streaming request
reset()Reset all state

Options

typescript
interface UseAIStreamOptions extends UseSSEOptions {
  parseAIMessage?: boolean // Parse AI JSON structure, default true
  appendMode?: boolean // Text append mode, default true
  onText?: (text: string, delta: string) => void
  onToolCall?: (toolCalls?: AIStreamMessage['toolCalls']) => void
  onThinking?: (thinking: string) => void
}

Typewriter Effect

typescript
const display = ref('')

const { start, stop } = useAIStream({
  appendMode: true,
  onText: (full, delta) => {
    display.value += delta
  }
})

const ask = (message: string) => {
  display.value = ''
  start({
    url: '/api/ai/chat',
    method: 'POST',
    data: { messages: [{ role: 'user', content: message }], stream: true }
  })
}

Display Thinking Chain

typescript
const thinking = ref('')
const showThinking = ref(false)

const { start } = useAIStream({
  onThinking: (t) => {
    thinking.value = t
    showThinking.value = !!t
  }
})

// Use with thinking chain component in template:
// <yh-ai-thought-chain v-if="showThinking" :thinking="true" title="AI is thinking...">
//   <div>{{ thinking }}</div>
// </yh-ai-thought-chain>

Tool Calling

typescript
const toolCalls = ref<AIStreamMessage['toolCalls']>([])

const { start } = useAIStream({
  onToolCall: (calls) => {
    toolCalls.value = calls || []
  }
})

watch(toolCalls, async (calls) => {
  for (const call of calls || []) {
    if (call.name === 'search') {
      const result = await searchApi(call.arguments)
      console.log('Search result:', result)
    }
  }
})

Relationship with useSSE

  • useSSE: Responsible for streaming transport protocol itself (SSE / fetch streaming);
  • useAIStream: Parses AI model return format on top of it, providing more friendly state fields.

When you only need to handle generic log/progress streaming, use useSSE; when integrating AI models (OpenAI, Claude, etc.), use useAIStream.

Released under the MIT License.