docs-ai-helper
v0.2.0
Published
A floating AI documentation assistant component for VuePress and VitePress.
Downloads
256
Maintainers
Readme
docs-ai-helper
A lightweight floating AI assistant for VuePress and VitePress documentation sites.
docs-ai-helper gives your docs a chat panel that can stream answers, render Markdown, highlight code with Shiki, carry page context to your backend, show reasoning blocks, follow internal documentation links, and fit into existing themes with CSS variables.
Features
- Vue 2.7+ and Vue 3 support through
vue-demi - VitePress and VuePress navigation helpers
- Streaming responses from plain text, JSON lines, or SSE-style
data:events - Markdown rendering with a Shiki-powered fallback
- Optional reasoning display with a user-facing toggle
- Suggested questions and configurable welcome state
- Custom request payloads, stream parsers, identities, avatars, sizes, and CSS variables
- Fixed or inline launcher modes, including compact toolbar and plain variants
- Resizable chat panel with light and dark theme variables
Install
npm install docs-ai-helper vue-demiIf you do not pass your own renderMarkdown function, the fallback renderer dynamically imports shiki:
npm install shikiFor Vue 2 projects below Vue 2.7, also install and register @vue/composition-api.
Quick Start
VitePress
// .vitepress/theme/index.ts
import DefaultTheme from 'vitepress/theme';
import { h } from 'vue';
import { useRouter } from 'vitepress';
import { DocsAiHelper, createVitePressNavigator } from 'docs-ai-helper';
import 'docs-ai-helper/style.css';
export default {
extends: DefaultTheme,
enhanceApp({ app }) {
app.component('DocsAiHelper', DocsAiHelper);
},
Layout() {
const router = useRouter();
return h(DefaultTheme.Layout, null, {
'layout-bottom': () => h(DocsAiHelper, {
endpoint: '/api/docs-chat',
navigate: createVitePressNavigator(router),
context: () => ({
path: window.location.pathname,
title: document.title
}),
suggestedQuestions: [
{ label: 'How do I get started?' },
{ label: 'Explain this page' },
{ label: 'Show me a TypeScript example' }
]
})
});
}
};VuePress
// client.ts / enhanceApp.ts
import { h } from 'vue';
import { DocsAiHelper, createVuePressNavigator } from 'docs-ai-helper';
import 'docs-ai-helper/style.css';
export default ({ app, router }) => {
app.component('DocsAiHelperHost', {
render() {
return h(DocsAiHelper, {
endpoint: '/api/docs-chat',
navigate: createVuePressNavigator(router),
context: () => ({
path: window.location.pathname,
title: document.title
})
});
}
});
};Backend Contract
By default, the component sends POST requests to endpoint with this JSON body:
{
"question": "User question",
"context": {},
"messages": [{ "role": "user", "content": "..." }]
}The default stream parser accepts plain text chunks and SSE-style events:
data: {"content":"Answer chunk","reasoning":"Reasoning chunk"}
data: [DONE]It also understands common OpenAI-compatible choices[0].delta.content payloads. Use requestBody or parseStream when your backend has a different protocol.
For the best visual match, pass the same Markdown renderer your docs site already uses:
h(DocsAiHelper, {
endpoint: '/api/docs-chat',
renderMarkdown: (markdown, message) => docsMarkdownRenderer.render(markdown)
});Without renderMarkdown, the built-in fallback uses markdown-it and dynamically imports shiki for fenced code blocks:
import { createShikiMarkdownRenderer } from 'docs-ai-helper';
h(DocsAiHelper, {
endpoint: '/api/docs-chat',
renderMarkdown: createShikiMarkdownRenderer({
theme: { light: 'github-light', dark: 'github-dark' },
fallbackLang: 'text'
})
});h(DocsAiHelper, {
endpoint: '/api/docs-chat',
headers: { Authorization: 'Bearer ...' },
assistant: { name: 'Docs Assistant', avatar: '/bot.png' },
user: { name: 'You', avatar: '/me.png' },
defaultOpen: false,
showReasoningDefault: true,
allowReasoningToggle: true,
launcherText: 'AI',
launcherMode: 'fixed',
launcherVariant: 'primary',
size: { width: 460, height: 660 },
maxWidth: 960,
maxHeight: 900,
closeOnClear: false,
cssVars: {
'--dah-accent': '#0f766e',
'--dah-radius': '6px'
},
panelClass: 'my-docs-ai-panel',
launcherClass: 'my-docs-ai-launcher',
suggestedQuestions: [
{ label: 'What is this page about?' },
{
label: 'Give me a TypeScript example',
question: 'Give me a TypeScript example based on the current page.'
}
],
welcome: {
title: 'Hi, I am your docs assistant',
description: 'Choose a suggestion or ask your own question.'
},
context: () => ({
path: location.pathname,
title: document.title
})
});import DocsAiHelperPlugin, {
DocsAiHelper,
createShikiMarkdownRenderer,
createVitePressNavigator,
createVuePressNavigator,
defaultMarkdownRenderer,
defaultNavigate,
defaultStreamParser
} from 'docs-ai-helper';
import type {
ChatMessage,
ChatRequestContext,
MarkdownRenderer,
NavigateHandler,
RequestBodyBuilder,
StreamParser
} from 'docs-ai-helper';:root {
--dah-font-family: Inter, ui-sans-serif, system-ui, sans-serif;
--dah-z-index: 2147481000;
--dah-accent: #2563eb;
--dah-accent-strong: #1d4ed8;
--dah-bg: #ffffff;
--dah-surface: #f8fafc;
--dah-border: #d9e2ec;
--dah-text: #172033;
--dah-muted: #64748b;
--dah-shadow: 0 18px 50px rgba(15, 23, 42, 0.18);
--dah-radius: 8px;
}You can also override .dah-* classes directly for deeper styling.
npm Publishing Checklist
- Update
versioninpackage.json. - Run
npm run typecheck. - Run
npm run build. - Preview the package with
npm pack --dry-run. - Publish with
npm publish --access public.
The package includes dist, README.md, README_ZH.md, and LICENSE. The prepublishOnly script runs type checking and a production build before publishing.
License
MIT License. Copyright (c) ZhaiSoul.
