@pythoughts/vue-skills-mcp 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/skills/vue-ai-apps/SKILL.md +3 -3
- package/skills/vue-ai-apps/references/error-handling-and-abort.md +2 -2
- package/skills/vue-ai-apps/references/streaming-chat-ui.md +2 -2
- package/skills/vue-ai-apps/references/structured-output.md +6 -8
- package/skills/vue-ai-apps/references/tool-calling.md +3 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pythoughts/vue-skills-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "MCP server exposing the Vue 3 best-practice skills so any MCP coding agent can fetch them automatically on Vue work.",
|
|
6
6
|
"author": "Mohamed Elkholy (elkaix)",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: vue-ai-apps
|
|
3
3
|
description: "Building AI/LLM and agent apps with Vue 3 and Nuxt: streaming chat UIs, the Vercel AI SDK (`ai` + `@ai-sdk/vue`), `useChat`, tool calling, structured output, and abort/error handling. Load for AI chatbots, assistant UIs, LLM streaming, or agent frontends in Vue or Nuxt."
|
|
4
|
-
version: "1.
|
|
4
|
+
version: "1.1.0"
|
|
5
5
|
license: MIT
|
|
6
6
|
author: github.com/Pythoughts-labs
|
|
7
7
|
---
|
|
@@ -16,14 +16,14 @@ Assumes the foundations in `vue-best-practices` (Composition API, `<script setup
|
|
|
16
16
|
|
|
17
17
|
- **Keys never reach the client.** The provider API key lives on the server. The browser talks to *your* endpoint, never to the model provider directly.
|
|
18
18
|
- **Server streams, client consumes.** A server route runs `streamText`/`streamObject` and returns a stream; the Vue component renders it incrementally. Never block on the full response.
|
|
19
|
-
- **Render message *parts*, not a content string.** AI SDK
|
|
19
|
+
- **Render message *parts*, not a content string.** AI SDK messages are `UIMessage[]` made of typed `parts` (text, tool calls, reasoning). Iterate `message.parts`.
|
|
20
20
|
- **Drive UI from `status`, not a boolean.** Disabled inputs, spinners, and the stop button key off the `status` state machine.
|
|
21
21
|
|
|
22
22
|
## 1) Confirm the stack (required)
|
|
23
23
|
|
|
24
24
|
- Packages: `ai` (core), `@ai-sdk/vue` (composables), a provider (`@ai-sdk/openai`, `@ai-sdk/anthropic`, …), `zod` for tool/object schemas.
|
|
25
25
|
- `useChat` from `@ai-sdk/vue` works against **any** streaming backend. The server snippets here use **Nuxt/Nitro** (`defineEventHandler`, `readBody`); for a non-Nuxt backend, keep the same AI SDK calls in your own route handler.
|
|
26
|
-
-
|
|
26
|
+
- This skill targets the **v5+ API**, verified against `ai@7` / `@ai-sdk/vue@4`: messages have `parts`; the hook does not manage input; `status` is `'submitted' | 'streaming' | 'ready' | 'error'`; tool schemas use `inputSchema`; `useObject` is exported as `experimental_useObject`. The pre-v5 API (`ai@4`: `message.content`, hook-managed `input`, `isLoading`, `parameters`) differs — check the installed version first.
|
|
27
27
|
|
|
28
28
|
## 2) Build the streaming chat UI (required for chat features)
|
|
29
29
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: Abort and Error Handling for AI Streams (AI SDK v5)
|
|
2
|
+
title: Abort and Error Handling for AI Streams (AI SDK v5+)
|
|
3
3
|
impact: HIGH
|
|
4
4
|
impactDescription: A streaming UI with no stop button and no error surface leaves users stuck on hung or failed requests
|
|
5
5
|
type: best-practice
|
|
6
6
|
tags: [vue3, nuxt, ai-sdk, useChat, abort, error-handling, streaming]
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
# Abort and Error Handling for AI Streams (AI SDK v5)
|
|
9
|
+
# Abort and Error Handling for AI Streams (AI SDK v5+)
|
|
10
10
|
|
|
11
11
|
**Impact: HIGH** - LLM streams are long-running and can fail mid-response. `useChat` exposes everything needed — `status`, `stop()`, `error`, `clearError()`, `regenerate()`, and an `onError` option — but none of it is wired up by default. A chat UI is not shippable until the user can stop a runaway generation and recover from an error.
|
|
12
12
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: Streaming Chat UI with useChat (AI SDK v5)
|
|
2
|
+
title: Streaming Chat UI with useChat (AI SDK v5+)
|
|
3
3
|
impact: HIGH
|
|
4
4
|
impactDescription: Rendering message.content or managing input inside the hook is the v4 API and silently breaks in v5
|
|
5
5
|
type: capability
|
|
6
6
|
tags: [vue3, nuxt, ai-sdk, useChat, streaming, llm, chat]
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
# Streaming Chat UI with useChat (AI SDK v5)
|
|
9
|
+
# Streaming Chat UI with useChat (AI SDK v5+)
|
|
10
10
|
|
|
11
11
|
**Impact: HIGH** - In AI SDK v5 the Vue `useChat` composable no longer manages the input field, exposes `status` instead of `isLoading`, and returns messages as `UIMessage[]` built from typed `parts`. Code written for v4 (`input`, `handleSubmit`, `message.content`, `isLoading`) compiles but renders nothing useful.
|
|
12
12
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: Streaming Structured Output in Vue (AI SDK v5)
|
|
2
|
+
title: Streaming Structured Output in Vue (AI SDK v5+)
|
|
3
3
|
impact: MEDIUM
|
|
4
4
|
impactDescription: Use streamObject + useObject for typed data; the object streams in partial, so the UI must tolerate undefined fields
|
|
5
5
|
type: capability
|
|
6
6
|
tags: [vue3, nuxt, ai-sdk, streamObject, useObject, structured-output, zod]
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
# Streaming Structured Output in Vue (AI SDK v5)
|
|
9
|
+
# Streaming Structured Output in Vue (AI SDK v5+)
|
|
10
10
|
|
|
11
11
|
**Impact: MEDIUM** - When the model should return a typed object (a recipe, a form, an extraction) rather than chat, use `streamObject` on the server and the `useObject` composable on the client. The object arrives **incrementally as a deep-partial**, so every field can be `undefined` mid-stream. Templates must guard with optional chaining and `v-if`, or they throw while streaming.
|
|
12
12
|
|
|
@@ -18,7 +18,7 @@ tags: [vue3, nuxt, ai-sdk, streamObject, useObject, structured-output, zod]
|
|
|
18
18
|
- [ ] Return `result.toTextStreamResponse()`
|
|
19
19
|
- [ ] Drive the UI from `useObject`'s `object`, `submit`, `isLoading`
|
|
20
20
|
- [ ] Treat every field of `object` as possibly `undefined` while streaming
|
|
21
|
-
- [ ]
|
|
21
|
+
- [ ] Import it as `experimental_useObject` (aliased to `useObject`) from `@ai-sdk/vue`
|
|
22
22
|
|
|
23
23
|
**Incorrect - assuming the object is complete:**
|
|
24
24
|
```vue
|
|
@@ -55,10 +55,8 @@ export default defineEventHandler(async (event) => {
|
|
|
55
55
|
**Correct - component:**
|
|
56
56
|
```vue
|
|
57
57
|
<script setup lang="ts">
|
|
58
|
-
//
|
|
59
|
-
|
|
60
|
-
// it as `experimental_useObject`).
|
|
61
|
-
import { useObject } from '@ai-sdk/vue'
|
|
58
|
+
// @ai-sdk/vue exports this only as `experimental_useObject` — alias it on import.
|
|
59
|
+
import { experimental_useObject as useObject } from '@ai-sdk/vue'
|
|
62
60
|
import { z } from 'zod'
|
|
63
61
|
|
|
64
62
|
const schema = z.object({
|
|
@@ -81,7 +79,7 @@ const { object, submit, isLoading } = useObject({ api: '/api/recipe', schema })
|
|
|
81
79
|
|
|
82
80
|
## Notes
|
|
83
81
|
|
|
84
|
-
-
|
|
82
|
+
- The composable is experimental; `@ai-sdk/vue` exports it as `experimental_useObject` (no plain `useObject`). Verified against `@ai-sdk/vue@4` (with `ai@7`).
|
|
85
83
|
- `object` is typed as `DeepPartial<Schema>` — TypeScript already forces the optional-chaining discipline above.
|
|
86
84
|
- For free-form text streaming use `useChat` (or `useCompletion`); reach for `useObject` only when you need a validated shape.
|
|
87
85
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: Tool Calling in Vue Chat UIs (AI SDK v5)
|
|
2
|
+
title: Tool Calling in Vue Chat UIs (AI SDK v5+)
|
|
3
3
|
impact: HIGH
|
|
4
4
|
impactDescription: Tool calls arrive as typed message parts with a state machine; ignoring the state renders blank or stale UI
|
|
5
5
|
type: capability
|
|
6
6
|
tags: [vue3, nuxt, ai-sdk, tools, function-calling, agents, useChat]
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
# Tool Calling in Vue Chat UIs (AI SDK v5)
|
|
9
|
+
# Tool Calling in Vue Chat UIs (AI SDK v5+)
|
|
10
10
|
|
|
11
11
|
**Impact: HIGH** - When the model calls a tool, the result surfaces in the chat as a `parts` entry of type `tool-<name>` with a `state` field. The Vue UI must branch on `part.state` (`input-streaming` → `input-available` → `output-available` / `output-error`) to show progress and results. Rendering the part without checking `state` shows nothing while the tool runs, then throws when accessing `part.output` too early.
|
|
12
12
|
|
|
@@ -80,7 +80,7 @@ export default defineEventHandler(async (event) => {
|
|
|
80
80
|
|
|
81
81
|
- Part type follows the pattern `tool-${toolName}`; dynamically registered tools use type `dynamic-tool` with `part.toolName`.
|
|
82
82
|
- Useful accessors: `part.input`, `part.output`, `part.toolCallId`, `part.errorText`.
|
|
83
|
-
- **Client-side tools** (a `tool()` with no `execute`) are fulfilled from the UI by calling `
|
|
83
|
+
- **Client-side tools** (a `tool()` with no `execute`) are fulfilled from the UI by calling `addToolOutput({ tool, toolCallId, output })` returned by `useChat` (`addToolResult` is the deprecated alias).
|
|
84
84
|
- `stepCountIs` / `stopWhen` and the `tool()` signature are core AI SDK API — confirm against the installed version.
|
|
85
85
|
|
|
86
86
|
## Reference
|