Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 22 additions & 14 deletions docs/content/en/4.ai/1.assistant.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,19 +247,21 @@ On Vercel with OIDC, remove the auto-injected system environment variable from y

## Advanced Configuration

Configure advanced options in `nuxt.config.ts`:
Configure advanced options in `nuxt.config.ts` under `docus.assistant`.

```ts [nuxt.config.ts]
export default defineNuxtConfig({
assistant: {
// AI model (uses AI SDK Gateway format)
model: 'google/gemini-3-flash',
docus: {
assistant: {
// AI model (uses AI SDK Gateway format)
model: 'google/gemini-3-flash',

// MCP server (path or URL)
mcpServer: '/mcp',
// MCP server (path or URL)
mcpServer: '/mcp',

// API endpoint path
apiPath: '/__docus__/assistant'
// API endpoint path
apiPath: '/__docus__/assistant'
}
}
})
```
Expand All @@ -274,8 +276,10 @@ By default, the assistant uses Docus's built-in MCP server at `/mcp`:

```ts [nuxt.config.ts]
export default defineNuxtConfig({
assistant: {
mcpServer: '/mcp'
docus: {
assistant: {
mcpServer: '/mcp'
}
}
})
```
Expand All @@ -290,8 +294,10 @@ Connect to any external MCP server by providing a full URL:

```ts [nuxt.config.ts]
export default defineNuxtConfig({
assistant: {
mcpServer: 'https://other-docs.example.com/mcp'
docus: {
assistant: {
mcpServer: 'https://other-docs.example.com/mcp'
}
}
})
```
Expand All @@ -304,8 +310,10 @@ The assistant uses `google/gemini-3-flash` by default. You can change this to an

```ts [nuxt.config.ts]
export default defineNuxtConfig({
assistant: {
model: 'anthropic/claude-opus-4.5'
docus: {
assistant: {
model: 'anthropic/claude-opus-4.5'
}
}
})
```
Expand Down
8 changes: 5 additions & 3 deletions docs/content/en/4.ai/3.skills.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,14 @@ Keep your main `SKILL.md` under 500 lines. Move detailed reference material to s

## Configuration

By default, Docus looks for skills in the `skills/` directory at the root of your project. You can change this with the `skills.dir` option in your `nuxt.config.ts`:
By default, Docus looks for skills in the `skills/` directory at the root of your project. You can change this with `docus.skills.dir` in your `nuxt.config.ts`:

```ts [nuxt.config.ts]
export default defineNuxtConfig({
skills: {
dir: 'agent-skills'
docus: {
skills: {
dir: 'agent-skills'
}
}
})
```
Expand Down
36 changes: 22 additions & 14 deletions docs/content/fr/4.ai/1.assistant.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,19 +247,21 @@ Sur Vercel avec OIDC, supprimez la variable d'environnement système auto-inject

## Configuration avancée

Configurez les options avancées dans `nuxt.config.ts` :
Configurez les options avancées dans `nuxt.config.ts` sous `docus.assistant`.

```ts [nuxt.config.ts]
export default defineNuxtConfig({
assistant: {
// Modèle IA (utilise le format AI SDK Gateway)
model: 'google/gemini-3-flash',
docus: {
assistant: {
// Modèle IA (utilise le format AI SDK Gateway)
model: 'google/gemini-3-flash',

// Serveur MCP (chemin ou URL)
mcpServer: '/mcp',
// Serveur MCP (chemin ou URL)
mcpServer: '/mcp',

// Chemin de l'endpoint API
apiPath: '/__docus__/assistant'
// Chemin de l'endpoint API
apiPath: '/__docus__/assistant'
}
}
})
```
Expand All @@ -274,8 +276,10 @@ Par défaut, l'assistant utilise le serveur MCP intégré de Docus à `/mcp` :

```ts [nuxt.config.ts]
export default defineNuxtConfig({
assistant: {
mcpServer: '/mcp'
docus: {
assistant: {
mcpServer: '/mcp'
}
}
})
```
Expand All @@ -290,8 +294,10 @@ Connectez-vous à n'importe quel serveur MCP externe en fournissant une URL comp

```ts [nuxt.config.ts]
export default defineNuxtConfig({
assistant: {
mcpServer: 'https://autre-docs.exemple.com/mcp'
docus: {
assistant: {
mcpServer: 'https://autre-docs.exemple.com/mcp'
}
}
})
```
Expand All @@ -304,8 +310,10 @@ L'assistant utilise `google/gemini-3-flash` par défaut. Vous pouvez le changer

```ts [nuxt.config.ts]
export default defineNuxtConfig({
assistant: {
model: 'anthropic/claude-opus-4.5'
docus: {
assistant: {
model: 'anthropic/claude-opus-4.5'
}
}
})
```
Expand Down
8 changes: 5 additions & 3 deletions docs/content/fr/4.ai/3.skills.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,14 @@ Gardez votre `SKILL.md` principal sous 500 lignes. Déplacez le matériel de ré

## Configuration

Par défaut, Docus cherche les skills dans le dossier `skills/` à la racine de votre projet. Vous pouvez modifier cela avec l'option `skills.dir` dans votre `nuxt.config.ts` :
Par défaut, Docus cherche les skills dans le dossier `skills/` à la racine de votre projet. Vous pouvez modifier cela avec `docus.skills.dir` dans votre `nuxt.config.ts` :

```ts [nuxt.config.ts]
export default defineNuxtConfig({
skills: {
dir: 'agent-skills'
docus: {
skills: {
dir: 'agent-skills'
}
}
})
```
Expand Down
33 changes: 33 additions & 0 deletions layer/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import type { AssistantModuleOptions } from './modules/assistant'
import type { SkillsModuleOptions } from './modules/skills'

export interface DocusNuxtConfig {
assistant?: AssistantModuleOptions
skills?: SkillsModuleOptions
}

declare module '@nuxt/schema' {
interface NuxtConfig {
docus?: DocusNuxtConfig
/** @deprecated Use `docus.assistant` instead */
assistant?: AssistantModuleOptions
}
interface NuxtOptions {
docus?: DocusNuxtConfig
/** @deprecated Use `docus.assistant` instead */
assistant?: AssistantModuleOptions
}
}

declare module 'nuxt/schema' {
interface NuxtConfig {
docus?: DocusNuxtConfig
/** @deprecated Use `docus.assistant` instead */
assistant?: AssistantModuleOptions
}
interface NuxtOptions {
docus?: DocusNuxtConfig
/** @deprecated Use `docus.assistant` instead */
assistant?: AssistantModuleOptions
}
}
12 changes: 7 additions & 5 deletions layer/modules/assistant/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@ pnpm add @ai-sdk/mcp @ai-sdk/vue @ai-sdk/gateway ai motion-v shiki shiki-stream
export default defineNuxtConfig({
modules: ['./modules/assistant'],

assistant: {
apiPath: '/__docus__/assistant',
mcpServer: '/mcp',
model: 'google/gemini-3-flash',
}
docus: {
assistant: {
apiPath: '/__docus__/assistant',
mcpServer: '/mcp',
model: 'google/gemini-3-flash',
},
},
})
```

Expand Down
30 changes: 19 additions & 11 deletions layer/modules/assistant/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { addComponent, addImports, addServerHandler, createResolver, defineNuxtModule, logger } from '@nuxt/kit'
import { defu } from 'defu'

export interface AssistantModuleOptions {
/**
Expand All @@ -22,17 +23,24 @@ export interface AssistantModuleOptions {

const log = logger.withTag('Docus')

const defaults: Required<AssistantModuleOptions> = {
apiPath: '/__docus__/assistant',
mcpServer: '/mcp',
model: 'google/gemini-3-flash',
}

export default defineNuxtModule<AssistantModuleOptions>({
meta: {
name: 'assistant',
configKey: 'assistant',
},
defaults: {
apiPath: '/__docus__/assistant',
mcpServer: '/mcp',
model: 'google/gemini-3-flash',
},
setup(options, nuxt) {
setup(_options, nuxt) {
const legacyOptions = nuxt.options.assistant
if (legacyOptions && Object.keys(legacyOptions).length > 0) {
log.warn('`assistant` top-level config is deprecated. Move it under `docus.assistant` in nuxt.config.ts')
}

const options = defu(nuxt.options.docus?.assistant, legacyOptions, defaults) as Required<AssistantModuleOptions>

const hasAiGatewayAuth = !!(
process.env.AI_GATEWAY_API_KEY || process.env.VERCEL_OIDC_TOKEN
)
Expand All @@ -41,7 +49,7 @@ export default defineNuxtModule<AssistantModuleOptions>({

nuxt.options.runtimeConfig.public.assistant = {
enabled: hasAiGatewayAuth,
apiPath: options.apiPath!,
apiPath: options.apiPath,
}

addImports([
Expand Down Expand Up @@ -74,11 +82,11 @@ export default defineNuxtModule<AssistantModuleOptions>({
}

nuxt.options.runtimeConfig.assistant = {
mcpServer: options.mcpServer!,
model: options.model!,
mcpServer: options.mcpServer,
model: options.model,
}

const routePath = options.apiPath!.replace(/^\//, '')
const routePath = options.apiPath.replace(/^\//, '')
addServerHandler({
route: `/${routePath}`,
handler: resolve('./runtime/server/api/search'),
Expand Down
39 changes: 22 additions & 17 deletions layer/modules/skills/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { addServerHandler, createResolver, defineNuxtModule, logger } from '@nuxt/kit'
import { addPrerenderRoutes, addServerHandler, createResolver, defineNuxtModule, logger } from '@nuxt/kit'
import { defu } from 'defu'
import { existsSync } from 'node:fs'
import { readdir, readFile } from 'node:fs/promises'
import { join } from 'node:path'
import type { NitroConfig } from 'nitropack'
import { parse as parseYaml } from 'yaml'

interface SkillEntry {
Expand All @@ -10,7 +12,7 @@ interface SkillEntry {
files: string[]
}

interface ModuleOptions {
export interface SkillsModuleOptions {
dir?: string
}

Expand All @@ -19,15 +21,18 @@ const MAX_NAME_LENGTH = 64

const log = logger.withTag('Docus')

export default defineNuxtModule<ModuleOptions>({
const defaults: Required<SkillsModuleOptions> = {
dir: 'skills',
}

export default defineNuxtModule<SkillsModuleOptions>({
meta: {
name: 'skills',
},
defaults: {
dir: 'skills',
},
async setup(options, nuxt) {
const skillsDir = join(nuxt.options.rootDir, options.dir!)
async setup(_inlineOptions, nuxt) {
const options = defu(nuxt.options.docus?.skills, defaults) as Required<SkillsModuleOptions>

const skillsDir = join(nuxt.options.rootDir, options.dir)
if (!existsSync(skillsDir)) return

const catalog = await scanSkills(skillsDir)
Expand All @@ -39,19 +44,19 @@ export default defineNuxtModule<ModuleOptions>({

const { resolve } = createResolver(import.meta.url)

nuxt.hook('nitro:config', (nitroConfig) => {
const onNitroConfig = nuxt.hook as (name: 'nitro:config', cb: (nitroConfig: NitroConfig) => void) => void
onNitroConfig('nitro:config', (nitroConfig) => {
nitroConfig.serverAssets ||= []
nitroConfig.serverAssets.push({ baseName: 'skills', dir: skillsDir })
})

nitroConfig.prerender ||= {}
nitroConfig.prerender.routes ||= []
nitroConfig.prerender.routes.push('/.well-known/skills/index.json')
for (const skill of catalog) {
for (const file of skill.files) {
nitroConfig.prerender.routes.push(`/.well-known/skills/${skill.name}/${file}`)
}
const prerenderRoutes = ['/.well-known/skills/index.json']
for (const skill of catalog) {
for (const file of skill.files) {
prerenderRoutes.push(`/.well-known/skills/${skill.name}/${file}`)
}
})
}
addPrerenderRoutes(prerenderRoutes)

addServerHandler({
route: '/.well-known/skills/index.json',
Expand Down
1 change: 1 addition & 0 deletions layer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"app",
"i18n",
"content.config.ts",
"index.d.ts",
"modules",
"nuxt.config.ts",
"nuxt.schema.ts",
Expand Down
3 changes: 0 additions & 3 deletions playground/nuxt.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
export default defineNuxtConfig({
// Explicitly disable i18n for playground testing (enabled by .nuxtrc)
i18n: false,
skills: {
dir: 'skills',
},
})
Loading