Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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
1 change: 1 addition & 0 deletions examples/ts-group-chat/chat-server/claude-service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Claude AI service for handling queued AI responses
import { anthropicText } from '@tanstack/ai-anthropic'
import { zaiText } from '@tanstack/ai-zai'
import { chat, toolDefinition } from '@tanstack/ai'
import type { JSONSchema, ModelMessage, StreamChunk } from '@tanstack/ai'

Expand Down
1 change: 1 addition & 0 deletions examples/ts-group-chat/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"@tanstack/ai-anthropic": "workspace:*",
"@tanstack/ai-client": "workspace:*",
"@tanstack/ai-react": "workspace:*",
"@tanstack/ai-zai": "workspace:*",
"@tanstack/react-devtools": "^0.8.2",
"@tanstack/react-router": "^1.141.1",
"@tanstack/react-router-devtools": "^1.139.7",
Expand Down
1 change: 1 addition & 0 deletions examples/ts-react-chat/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@tanstack/ai-openai": "workspace:*",
"@tanstack/ai-react": "workspace:*",
"@tanstack/ai-react-ui": "workspace:*",
"@tanstack/ai-zai": "workspace:*",
"@tanstack/nitro-v2-vite-plugin": "^1.141.0",
"@tanstack/react-devtools": "^0.8.2",
"@tanstack/react-router": "^1.141.1",
Expand Down
19 changes: 18 additions & 1 deletion examples/ts-react-chat/src/lib/model-selection.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export type Provider = 'openai' | 'anthropic' | 'gemini' | 'ollama' | 'grok'
export type Provider = 'openai' | 'anthropic' | 'gemini' | 'ollama' | 'grok' | 'zai'

export interface ModelOption {
provider: Provider
Expand Down Expand Up @@ -84,6 +84,23 @@ export const MODEL_OPTIONS: Array<ModelOption> = [
model: 'grok-2-vision-1212',
label: 'Grok - Grok 2 Vision',
},

// Z.AI (GLM)
{
provider: 'zai',
model: 'glm-4.7',
label: 'Z.AI - GLM-4.7',
},
{
provider: 'zai',
model: 'glm-4.6',
label: 'Z.AI - GLM-4.6',
},
{
provider: 'zai',
model: 'glm-4.6v',
label: 'Z.AI - GLM-4.6V',
},
]

const STORAGE_KEY = 'tanstack-ai-model-preference'
Expand Down
8 changes: 7 additions & 1 deletion examples/ts-react-chat/src/routes/api.tanchat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { ollamaText } from '@tanstack/ai-ollama'
import { anthropicText } from '@tanstack/ai-anthropic'
import { geminiText } from '@tanstack/ai-gemini'
import { grokText } from '@tanstack/ai-grok'
import { zaiText } from '@tanstack/ai-zai'
import type { AnyTextAdapter } from '@tanstack/ai'
import {
addToCartToolDef,
Expand All @@ -19,7 +20,7 @@ import {
recommendGuitarToolDef,
} from '@/lib/guitar-tools'

type Provider = 'openai' | 'anthropic' | 'gemini' | 'ollama' | 'grok'
type Provider = 'openai' | 'anthropic' | 'gemini' | 'ollama' | 'grok' | 'zai'

const SYSTEM_PROMPT = `You are a helpful assistant for a guitar store.

Expand Down Expand Up @@ -114,6 +115,11 @@ export const Route = createFileRoute('/api/tanchat')({
temperature: 2,
modelOptions: {},
}),
zai: () =>
createChatOptions({
adapter: zaiText((model || 'glm-4.7') as 'glm-4.7'),
modelOptions: {},
}),
}

try {
Expand Down
1 change: 1 addition & 0 deletions examples/ts-solid-chat/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@tanstack/ai-openai": "workspace:*",
"@tanstack/ai-solid": "workspace:*",
"@tanstack/ai-solid-ui": "workspace:*",
"@tanstack/ai-zai": "workspace:*",
"@tanstack/nitro-v2-vite-plugin": "^1.141.0",
"@tanstack/router-plugin": "^1.139.7",
"@tanstack/solid-ai-devtools": "workspace:*",
Expand Down
55 changes: 34 additions & 21 deletions examples/ts-solid-chat/src/routes/api.chat.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { createFileRoute } from '@tanstack/solid-router'
import { chat, maxIterations, toServerSentEventsResponse } from '@tanstack/ai'
import { anthropicText } from '@tanstack/ai-anthropic'
import { zaiText } from '@tanstack/ai-zai'
import { serverTools } from '@/lib/guitar-tools'

const SYSTEM_PROMPT = `You are a helpful assistant for a guitar store.
Expand Down Expand Up @@ -30,19 +31,6 @@ export const Route = createFileRoute('/api/chat')({
server: {
handlers: {
POST: async ({ request }) => {
if (!process.env.ANTHROPIC_API_KEY) {
return new Response(
JSON.stringify({
error:
'ANTHROPIC_API_KEY not configured. Please add it to .env or .env.local',
}),
{
status: 500,
headers: { 'Content-Type': 'application/json' },
},
)
}

// Capture request signal before reading body (it may be aborted after body is consumed)
const requestSignal = request.signal

Expand All @@ -53,21 +41,46 @@ export const Route = createFileRoute('/api/chat')({

const abortController = new AbortController()

const { messages } = await request.json()
const { messages, data } = await request.json()
const provider = data?.provider || 'anthropic'
const model = data?.model || 'claude-sonnet-4-5'

try {
let adapter
let modelOptions = {}

if (provider === 'zai') {
adapter = zaiText(model)
} else {
if (!process.env.ANTHROPIC_API_KEY) {
return new Response(
JSON.stringify({
error:
'ANTHROPIC_API_KEY not configured. Please add it to .env or .env.local',
}),
{
status: 500,
headers: { 'Content-Type': 'application/json' },
},
)
}
adapter = anthropicText(model)
modelOptions = {
thinking: {
type: 'enabled',
budget_tokens: 10000,
},
}
}

// Use the stream abort signal for proper cancellation handling
const stream = chat({
adapter: anthropicText('claude-sonnet-4-5'),
adapter,
tools: serverTools,
systemPrompts: [SYSTEM_PROMPT],
agentLoopStrategy: maxIterations(20),
messages,
modelOptions: {
thinking: {
type: 'enabled',
budget_tokens: 10000,
},
},
modelOptions,
abortController,
})

Expand Down
1 change: 1 addition & 0 deletions examples/ts-svelte-chat/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@tanstack/ai-ollama": "workspace:*",
"@tanstack/ai-openai": "workspace:*",
"@tanstack/ai-svelte": "workspace:*",
"@tanstack/ai-zai": "workspace:*",
"highlight.js": "^11.11.1",
"lucide-svelte": "^0.468.0",
"marked": "^15.0.6",
Expand Down
2 changes: 1 addition & 1 deletion examples/ts-svelte-chat/src/lib/model-selection.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export type Provider = 'openai' | 'anthropic' | 'gemini' | 'ollama'
export type Provider = 'openai' | 'anthropic' | 'gemini' | 'ollama' | 'zai'

export interface ModelOption {
provider: Provider
Expand Down
12 changes: 8 additions & 4 deletions examples/ts-svelte-chat/src/routes/api/chat/+server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import { openaiText } from '@tanstack/ai-openai'
import { ollamaText } from '@tanstack/ai-ollama'
import { anthropicText } from '@tanstack/ai-anthropic'
import { geminiText } from '@tanstack/ai-gemini'
import { zaiText } from '@tanstack/ai-zai'

import type { RequestHandler } from './$types'
import { env } from '$env/dynamic/private'

import {
addToCartToolDef,
addToWishListToolDef,
Expand All @@ -20,7 +20,7 @@ import {
recommendGuitarToolDef,
} from '$lib/guitar-tools'

type Provider = 'openai' | 'anthropic' | 'gemini' | 'ollama'
type Provider = 'openai' | 'anthropic' | 'gemini' | 'ollama' | 'zai'

// Populate process.env with the SvelteKit environment variables
// This is needed because the TanStack AI adapters read from process.env
Expand All @@ -37,7 +37,7 @@ const adapterConfig = {
}),
gemini: () =>
createChatOptions({
adapter: geminiText('gemini-2.0-flash-exp'),
adapter: geminiText('gemini-2.0-flash'),
}),
ollama: () =>
createChatOptions({
Expand All @@ -47,6 +47,10 @@ const adapterConfig = {
createChatOptions({
adapter: openaiText('gpt-4o'),
}),
zai: () =>
createChatOptions({
adapter: zaiText('glm-4.7'),
}),
}

const SYSTEM_PROMPT = `You are a helpful assistant for a guitar store.
Expand Down Expand Up @@ -99,7 +103,7 @@ export const POST: RequestHandler = async ({ request }) => {
const provider: Provider = data?.provider || 'openai'

// Get typed adapter options using createOptions pattern
const options = adapterConfig[provider]()
const options = adapterConfig[provider]() as any

const stream = chat({
...options,
Expand Down
1 change: 1 addition & 0 deletions examples/ts-vue-chat/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"@tanstack/ai-openai": "workspace:*",
"@tanstack/ai-vue": "workspace:*",
"@tanstack/ai-vue-ui": "workspace:*",
"@tanstack/ai-zai": "workspace:*",
"marked": "^15.0.6",
"vue": "^3.5.25",
"vue-router": "^4.5.0",
Expand Down
19 changes: 18 additions & 1 deletion examples/ts-vue-chat/src/lib/model-selection.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export type Provider = 'openai' | 'anthropic' | 'gemini' | 'ollama'
export type Provider = 'openai' | 'anthropic' | 'gemini' | 'ollama' | 'zai'

export interface ModelOption {
provider: Provider
Expand Down Expand Up @@ -67,6 +67,23 @@ export const MODEL_OPTIONS: Array<ModelOption> = [
model: 'smollm',
label: 'Ollama - SmolLM',
},

// Z.AI (GLM)
{
provider: 'zai',
model: 'glm-4.7',
label: 'Z.AI - GLM-4.7',
},
{
provider: 'zai',
model: 'glm-4.6',
label: 'Z.AI - GLM-4.6',
},
{
provider: 'zai',
model: 'glm-4.6v',
label: 'Z.AI - GLM-4.6V',
},
]

const STORAGE_KEY = 'tanstack-ai-model-preference'
Expand Down
7 changes: 6 additions & 1 deletion examples/ts-vue-chat/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { openaiText } from '@tanstack/ai-openai'
import { anthropicText } from '@tanstack/ai-anthropic'
import { geminiText } from '@tanstack/ai-gemini'
import { ollamaText } from '@tanstack/ai-ollama'
import { zaiText } from '@tanstack/ai-zai'
import { toolDefinition } from '@tanstack/ai'
import { z } from 'zod'
import dotenv from 'dotenv'
Expand Down Expand Up @@ -175,7 +176,7 @@ IMPORTANT:
- Do NOT describe the guitar yourself - let the recommendGuitar tool do it
`

type Provider = 'openai' | 'anthropic' | 'gemini' | 'ollama'
type Provider = 'openai' | 'anthropic' | 'gemini' | 'ollama' | 'zai'

export default defineConfig({
plugins: [
Expand Down Expand Up @@ -218,6 +219,10 @@ export default defineConfig({
selectedModel = model || 'mistral:7b'
adapter = ollamaText(selectedModel)
break
case 'zai':
selectedModel = model || 'glm-4.7'
adapter = zaiText(selectedModel)
break
case 'openai':
default:
selectedModel = model || 'gpt-4o'
Expand Down
22 changes: 22 additions & 0 deletions packages/typescript/ai-zai/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# @tanstack/ai-zai

## 0.1.0

### Minor Changes

- Initial release of Z.AI adapter for TanStack AI
- Added Web Search tool support for Z.AI models
- Added Thinking Mode support for deep reasoning (GLM-4.7/4.6/4.5)
- Added Tool Streaming support for real-time argument streaming (GLM-4.7)
- Added subpath export for `@tanstack/ai-zai/tools` to expose `webSearchTool`
- Implemented tree-shakeable adapters:
- Text adapter for chat/completion functionality
- Summarization adapter for text summarization
- Features:
- Streaming chat responses
- Function/tool calling with automatic execution
- Structured output with Zod schema validation through system prompts
- OpenAI-compatible API integration
- Full TypeScript support with per-model type inference


Loading