Skip to content
Open
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
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