TinyShip
TinyShip
 TinyShip
TinyShip
TinyShip Documentation
TinyShip User GuideGetting StartedBasic Configuration
Credits System ConfigurationAffiliate System Configuration
AI Features ConfigurationAI Chat ConfigurationAI Image Generation ConfigurationAI Video Generation Configuration
Storage Service ConfigurationDatabase ConfigurationCaptcha Configuration
Development Best PracticesLocal E2E Workflow
User GuideAI Features

AI Chat Configuration

Configure OpenAI, Qwen, and DeepSeek chat

TinyShip's chat sample is built on the Vercel AI SDK (ai 6.x), AI Elements, and Streamdown. The provider list is OpenAI, Qwen, and DeepSeek. Keys and model ids live in config/ai.ts and .env.

For an English-language product, start with OpenAI. Qwen and DeepSeek stay available when you want stronger Chinese or a lower token price. The file in the repo still defaults to Qwen; change defaultProvider when you want OpenAI selected on first load.

AI quick setup: If you have Agent Skills installed, ask your AI to "help me configure AI features". The tinyship-ai skill walks through this setup.

Related pages

PagePathDescription
AI chat/aiChat UI

Providers

ProviderModels in config/ai.tsFit
OpenAIgpt-5, gpt-5-codex, gpt-5-proEnglish products and harder reasoning
Qwenqwen-max, qwen-plus, qwen-turboChinese chat, lower cost
DeepSeekdeepseek-chat, deepseek-coderCode help, low cost

config/ai.ts

defaultProvider is 'qwen' | 'deepseek' | 'openai'. defaultModels maps each provider to one model id. availableModels maps each provider to a string array. Those arrays fill the model menu on /ai.

// config/ai.ts
export const aiConfig = {
  defaultProvider: 'qwen' as const, // 'qwen' | 'deepseek' | 'openai'

  defaultModels: {
    qwen: 'qwen-turbo',
    deepseek: 'deepseek-chat',
    openai: 'gpt-5',
  },

  availableModels: {
    qwen: ['qwen-max', 'qwen-plus', 'qwen-turbo'],
    deepseek: ['deepseek-chat', 'deepseek-coder'],
    openai: ['gpt-5', 'gpt-5-codex', 'gpt-5-pro'],
  },
}

Set defaultProvider to 'openai' if the first screen should open on GPT-5. Keep the same object shape when you add or remove model ids. API keys are not stored in this file. libs/ai/config.ts reads them from the environment (OPENAI_API_KEY, OPENAI_BASE_URL, QWEN_API_KEY, QWEN_BASE_URL, DEEPSEEK_API_KEY).

Environment variables

Configure at least one provider. You can set all three and let people switch in the UI.

# Optional. Read by getConfig() in libs/ai. The /ai page uses config/ai.ts instead.
AI_PROVIDER="qwen" # qwen | deepseek | openai

# OpenAI — start here for an English product
OPENAI_API_KEY="your-openai-api-key"
OPENAI_BASE_URL="https://api.openai.com/v1" # optional custom endpoint

# Qwen — Chinese chat and lower cost
QWEN_API_KEY="your-qwen-api-key"
QWEN_BASE_URL="https://dashscope.aliyuncs.com/compatible-mode/v1"

# DeepSeek — code and low cost
DEEPSEEK_API_KEY="your-deepseek-api-key"

The /ai page initializes provider and model from config.ai.defaultProvider and config.ai.defaultModels. Changing AI_PROVIDER does not change that page. AI_PROVIDER is only the fallback inside getConfig() in libs/ai/config.ts (it defaults to 'openai' when the variable is unset). If a chat request omits provider, streamResponseWithUsage also falls back to 'openai'.

API keys

OpenAI

  1. Open the OpenAI platform.
  2. Create an API key.
  3. Put it in OPENAI_API_KEY.

Use this when the product is aimed at English users. It costs more than Qwen or DeepSeek.

Qwen

  1. Open Alibaba Cloud Model Studio.
  2. Create an API key.
  3. Put it in QWEN_API_KEY. The compatible-mode base URL above is the one in env.example.

Qwen is the better default for Chinese conversations, and new accounts often include a free quota.

DeepSeek

  1. Open the DeepSeek platform.
  2. Create an API key.
  3. Put it in DEEPSEEK_API_KEY.

DeepSeek is inexpensive and strong at code. New accounts often include a free quota.

The /ai page

The page is a small, streaming chat you can extend. It uses AI SDK 6, AI Elements, and Streamdown.

  • Streaming replies from the AI SDK
  • Markdown, including code blocks with copy
  • Provider and model switching from availableModels
  • New chat and regenerate
  • A credit check: /api/chat returns 402 when the balance is empty, then creditService.consumeCredits after the stream reports token usage
  • Layout that works on mobile and desktop

Treat it as a starting point. The same route can grow into longer memory, tool calls, file upload, per-user history, or a custom system prompt. Chat spend is configured in Credits. Model ids you want in the menu belong in config/ai.ts. The provider clients live in libs/ai.


Related docs:

  • AI image generation
  • Credits

AI Features Configuration

Configure AI chat and image generation features

AI Image Generation Configuration

Configure Fal, OpenAI, and Qwen image generation

On this page

Related pagesProvidersconfig/ai.tsEnvironment variablesAPI keysOpenAIQwenDeepSeekThe /ai page