# Internationalization (i18n)

## Locale Files

Create `locales/` directory in the assistant:

```
assistants/my-assistant/
└── locales/
    ├── en-us.yml
    ├── zh-cn.yml
    └── ja.yml
```

## Locale File Format

```yaml
# locales/en-us.yml
name: My Assistant
description: A helpful AI assistant

chat:
  title: New Chat
  description: How can I help you today?
  prompts:
    - What can you do?
    - Help me with a task
    - Tell me about yourself

messages:
  welcome: Welcome back!
  error: Something went wrong
  processing: Processing your request...
```

```yaml
# locales/zh-cn.yml
name: 我的助手
description: 一个有帮助的AI助手

chat:
  title: 新对话
  description: 今天我能帮您什么？
  prompts:
    - 你能做什么？
    - 帮我完成一个任务
    - 介绍一下你自己

messages:
  welcome: 欢迎回来！
  error: 出了点问题
  processing: 正在处理您的请求...
```

## Using Translations

### In package.yao

Use `{{ key }}` syntax:

```json
{
  "name": "{{ name }}",
  "description": "{{ description }}",
  "placeholder": {
    "title": "{{ chat.title }}",
    "description": "{{ chat.description }}",
    "prompts": [
      "{{ chat.prompts.0 }}",
      "{{ chat.prompts.1 }}",
      "{{ chat.prompts.2 }}"
    ]
  }
}
```

### In Prompts

```yaml
- role: system
  content: |
    You are {{ name }}.
    {{ description }}

    Respond in the user's language.
```

## Locale Detection

The system detects locale from:

1. Request header `Accept-Language`
2. User preference (stored in memory)
3. Default: `en-us`

### Override in Hook

```typescript
function Create(ctx: agent.Context, messages: agent.Message[]): agent.Create {
  // Get user preference
  const userLocale = ctx.memory.user.Get("preferred_locale");

  return {
    messages,
    locale: userLocale || "en-us"
  };
}
```

## Global Translations

Define global translations in `agent/locales/`:

```
agent/
└── locales/
    ├── en-us.yml
    └── zh-cn.yml
```

These are available to all assistants via the `__global__` namespace.

## Accessing Translations in Hooks

```typescript
function Create(ctx: agent.Context, messages: agent.Message[]): agent.Create {
  const locale = ctx.locale;  // e.g., "en-us"

  // Use locale for custom logic
  if (locale.startsWith("zh")) {
    return {
      messages,
      prompt_preset: "chinese"
    };
  }

  return { messages };
}
```

## Nested Keys

Access nested values with dot notation:

```yaml
# locales/en-us.yml
errors:
  validation:
    required: This field is required
    invalid: Invalid value
  network:
    timeout: Connection timed out
```

```json
{
  "placeholder": {
    "title": "{{ errors.validation.required }}"
  }
}
```

## Fallback Behavior

If a translation key is not found:

1. Try the requested locale
2. Fall back to `en-us`
3. Return the key itself if not found

## Dynamic Locale Content

```typescript
function Create(ctx: agent.Context, messages: agent.Message[]): agent.Create {
  // Add locale-specific system message
  const localeGreeting = {
    "en-us": "Hello! How can I help you?",
    "zh-cn": "你好！有什么可以帮您的？",
    "ja": "こんにちは！何かお手伝いできますか？"
  };

  const greeting = localeGreeting[ctx.locale] || localeGreeting["en-us"];

  return {
    messages: [
      { role: "system", content: `Greeting: ${greeting}` },
      ...messages
    ]
  };
}
```

## Best Practices

1. **Keep keys consistent** - Use the same keys across all locale files
2. **Use nested structure** - Organize related translations together
3. **Provide fallbacks** - Always have `en-us` as the base locale
4. **Test all locales** - Verify translations render correctly
5. **Use context variables** - Combine with `$CTX.locale` in prompts
