{{ t('dash_title') }}
{{ t('dash_subtitle') }}
{{ s.label }}
{{ s.value }}
{{ s.sub }}
{{ t('dash_total_token_usage') }}
{{ formatTokens(dashTokenUsage.total_tokens) }}
{{ dashTokenUsage.call_count }} {{ t('dash_api_calls') }}
{{ t('dash_prompt_tokens') }}
{{ formatTokens(dashTokenUsage.prompt_tokens) }}
{{ t('dash_input_cost') }}
{{ t('dash_completion_tokens') }}
{{ formatTokens(dashTokenUsage.completion_tokens) }}
{{ t('dash_output_cost') }}
{{ t('dash_client_usage_ranking') }}
{{ t('dash_no_usage_data') }}
{{ t('dash_quick_actions') }}
{{ t('dash_system_status') }}
{{ t('dash_active_employees') }}
{{ t('dash_no_active_employees') }}
{{ a.name }}
{{ getTenantName(a.tenant_id) }}
Daily Token Usage (30d)
Daily Conversations (30d)
Top Agents by Token Usage
{{ t('tenants_title') }}
{{ t('tenants_subtitle') }}
{{ t('tenants_no_clients') }}
{{ t('tenants_no_clients_desc') }}
{{ filteredTenants.length }} / {{ tenants.length }} clients
{{ tn.name }}
Credits
{{ (tn.credits_balance || 0).toLocaleString() }}
Plan
{{ tn.plan || 'free' }}
Profile
View
No employees yet
{{ t('workflows_title') }}
{{ t('workflows_subtitle') }}
{{ t('workflows_active') }}
{{ wf.name }}
{{ wf.description || t('workflows_no_description') }}
{{ t('workflows_template_library') }}
{{ industryLabel(industry) }}
{{ tpl.name }}
{{ tpl.display_name }}{{ tpl.description }}
{{ t('connectors_title') }}
{{ t('connectors_subtitle') }}
{{ t('connectors_active_bindings') }}
{{ t('connectors_no_bindings') }} {{ t('connectors_channels_tab') }} {{ t('connectors_tab_suffix') }}
{{ a.name }}
{{ t('connectors_available') }}
{{ c.name }}
{{ c.description }}
{{ t('connectors_actions') }}
{{ t('exec_title') }}
{{ t('exec_subtitle') }}
{{ t('exec_no_data') }}
| {{ t('exec_id') }} | {{ t('exec_trigger') }} | {{ t('exec_status') }} |
|---|---|---|
| {{ e.id.substring(0,8) }} | {{ e.triggered_by }} | {{ e.status }} |
{{ t('nav_invocations') }}
全平台AI员工调用记录,按模型和客户分类
总调用次数
{{ (invocationData.summary.total_calls || 0).toLocaleString() }}
总Token消耗
{{ (invocationData.summary.total_tokens || 0).toLocaleString() }}
消耗点数
{{ (invocationData.summary.credits_used || 0).toLocaleString() }}
预估成本 (USD)
${{ (invocationData.summary.total_cost || 0).toFixed(2) }}
按模型分类
{{ m.model }}
{{ m.calls }} 次调用
{{ (m.tokens || 0).toLocaleString() }} tokens
${{ m.cost.toFixed(3) }}
按客户分类
{{ t.tenant_name }}
{{ t.calls }} 次调用 · {{ t.credits }} 点数
{{ (t.tokens || 0).toLocaleString() }} tokens
${{ t.cost.toFixed(3) }}
| 时间 | 客户 | 员工 | 模型 | Prompt | Completion | Total | 点数 | 成本 |
|---|---|---|---|---|---|---|---|---|
| {{ new Date(inv.created_at).toLocaleString('zh-CN', {month:'2-digit',day:'2-digit',hour:'2-digit',minute:'2-digit'}) }} | {{ inv.tenant_name || '-' }} | {{ inv.agent_name || '-' }} | {{ inv.model }} | {{ (inv.prompt_tokens||0).toLocaleString() }} | {{ (inv.completion_tokens||0).toLocaleString() }} | {{ (inv.total_tokens||0).toLocaleString() }} | {{ inv.credits }} | ${{ inv.cost_usd.toFixed(4) }} |
共 {{ invocationData.total }} 条记录
{{ selectedTenant.name }}
{{ industryLabel(selectedTenant.industry) }} · {{ selectedTenant.plan }}
{{ t('client_digital_employees') }}
{{ t('client_no_employees') }}
{{ a.name }}
{{ a.title || roleLabel(a.role) }} · {{ a.tasks_completed }} tasks
{{ t('client_connected_services') }}
{{ t('client_no_connectors') }}
{{ connName(c.connector_type) }}
{{ c.connector_type }}
{{ t('client_documents_data') }}
{{ knowledgeStats.document_count || 0 }}
{{ t('client_documents') }}
{{ knowledgeStats.chunk_count || 0 }}
{{ t('client_text_chunks') }}
{{ knowledgeStats.structured_rows || 0 }}
{{ t('client_data_rows') }}
{{ Math.round((knowledgeStats.total_chars || 0) / 1000) }}k
{{ t('client_characters') }}
{{ t('client_supported_formats') }} {{ t('client_supported_formats_desc') }}
{{ t('client_excel_note') }}
{{ t('client_no_documents') }}
{{ d.filename }}
{{ d.chunk_count }} chunks · {{ d.row_count }} data rows · {{ d.status }}
{{ selectedAgent.name }}
{{ selectedAgent.title || roleLabel(selectedAgent.role) }} · {{ getTenantName(selectedAgent.tenant_id) }}
{{ t('agent_system_prompt') }}
{{ t('agent_system_prompt_desc') }}
{{ t('agent_behavior_rules') }}
{{ t('agent_behavior_rules_desc') }}
{{ t('agent_model_settings') }}
{{ t('agent_builtin_title') || 'Built-in Capabilities' }}
{{ t('agent_default_on') || 'Default ON' }}{{ t('agent_builtin_desc') || 'These capabilities are enabled by default. Toggle off only if you want to restrict this employee.' }}
{{ t('agent_kb_enabled_desc') }}
{{ t('agent_workflow') }}
{{ t('agent_workflow_desc') }}
{{ t('agent_autonomous_desc') }}
{{ t('agent_workflow_desc2') }}
{{ t('chat_channel_title') }}
{{ t('chat_channel_desc') }}
{{ channelLabel(chatChannel.channel_type) }}
{{ t('channels_bot_token_desc') }} @BotFather {{ t('channels_bot_token_desc2') }}
{{ t('channels_bound_success') }}
{{ chatBindResult.error || t('channels_bind_failed') }}
{{ t('agent_pause_external') }}
{{ t('agent_pause_external_desc') }}
{{ t('cap_external_title') }}
{{ t('cap_external_desc') }}
{{ t('cap_channels_title') }}
{{ t('cap_channels_desc') }}
{{ channelLabel(ch.channel_type) }}
{{ t('channels_no_bound') }}
{{ t("channels_bot_token_desc") }} @BotFather {{ t("channels_bot_token_desc2") }}
{{ t('channels_bound_success') }}
{{ bindResult.error || t('channels_bind_failed') }}
{{ t('cap_no_channels') }}
{{ t('cap_cs_settings') }}
{{ t('cap_cs_desc') }}
{{ t('appt_title') }}
{{ t('tpl_appointment_desc') }}
{{ t('sales_title') }}
{{ t('tpl_sales_desc') }}
{{ t('cap_internal_title') }}
{{ t('cap_internal_desc') }}
{{ t('tpl_knowledge_base') }}
{{ t('tpl_knowledge_base_desc') }}
Upload reference materials in the Reference Materials tab. The AI will search them when answering questions.
{{ t('tpl_social_media') }}
{{ t('tpl_social_media_desc') }}
{{ t('tpl_data_entry') }}
{{ t('tpl_data_entry_desc') }}
{{ t('chat_with') }} {{ selectedAgent.name }}
{{ t('chat_test_desc') }}
{{ t('chat_start') }}
{{ t('chat_send_test') }} {{ selectedAgent.name }}{{ t('chat_send_test_suffix') }}
{{ t('appt_title') }}
{{ t('appt_business_hours') }}
Reminders
{{ t('appt_services_title') }}
{{ t('appt_services_desc') }}
{{ svc.description }}
{{ t('appt_appointments_title') }}
| Customer | Service | Time | Status | Actions |
|---|---|---|---|---|
| {{ apt.customer_name }} | {{ apptServiceName(apt.service_id) }} | {{ formatTime(apt.start_time) }} | {{ t('appt_status_'+apt.status) || apt.status }} |
{{ t('appt_tab_overrides') }}
{{ t('sales_title') }}
{{ s.stage }}
{{ s.count }}
{{ s.total_value ? ('HKD ' + s.total_value.toLocaleString()) : '' }}
{{ t('sales_pipeline_title') }}
{{ t('sales_pipeline_desc') }}
{{ t('sales_leads_title') }}
| {{ t('sales_lead_name') }} | {{ t('sales_lead_company') }} | {{ t('sales_lead_status') }} | {{ t('sales_lead_score') }} | {{ t('sales_lead_source') }} | Actions |
|---|---|---|---|---|---|
| {{ lead.name }} | {{ lead.company || '-' }} | {{ lead.status }} | {{ lead.score || '-' }} | {{ lead.source }} |
{{ t('sales_products_title') }}
{{ t('sales_products_desc') }}
{{ prod.description }}
{{ t('sales_activities_title') }}
{{ act.description }}
{{ formatTime(act.created_at) }} Auto
{{ t('usage_total_calls') }}
{{ agentUsage.call_count || 0 }}
{{ t('usage_total_tokens') }}
{{ formatTokens(agentUsage.total_tokens || 0) }}
{{ t('usage_prompt_tokens') }}
{{ formatTokens(agentUsage.prompt_tokens || 0) }}
{{ t('usage_completion_tokens') }}
{{ formatTokens(agentUsage.completion_tokens || 0) }}
{{ t('usage_total_calls') }}
{{ agentUsage.call_count || 0 }}
{{ t('usage_credits_used') || '点数消耗' }}
{{ Math.ceil((agentUsage.total_tokens || 0) / 1000) }}
{{ t('usage_recent') }}
| {{ t('usage_time') }} | {{ t('usage_source') }} | {{ t('usage_model') }} | {{ isAdmin ? t('usage_tokens') : (t('usage_credits') || '点数') }} |
|---|---|---|---|
| {{ formatTime(r.created_at) }} | {{ r.source }} | {{ r.model }} | {{ isAdmin ? r.total_tokens : Math.ceil((r.total_tokens || 0) / 1000) }} |
{{ t('api_title') }}
{{ t('api_subtitle') }}
AI Customer Service Center
Configure AI customer service agents — persona, greetings, escalation, safety rules
Select an agent to configure
Choose an agent above to set up AI customer service
Company Context
Provide company info for customer service context. The agent's identity (name, role, personality) comes from its own profile settings.
Agent Identity: {{ csSelectedAgent.name }} — {{ csSelectedAgent.role || 'AI Agent' }}
Edit the agent's name, role, and personality in the Agent Management page.
Greeting Messages
Customize greeting templates for different scenarios.
Knowledge Domains
Define what topic areas the agent should focus on when searching the knowledge base.
Working Hours
Set business hours for human availability. The AI still responds 24/7 but adjusts messaging.
Escalation Rules
Define when the AI should transfer to a human agent.
Email will receive escalation notifications with conversation summary
Safety & Guardrails
Protect your brand by controlling what the agent can and cannot discuss.
Language Settings
Configure which languages the agent supports and how it detects language.
Connected Channels
Manage messaging channels that this CS agent listens on.
{{ ch.channel_type }}
No channels connected yet. Connect a channel below to start receiving messages.
Connect New Channel
Connect WhatsApp via Twilio
Setup: Go to console.twilio.com → Messaging → Try it out → Send a WhatsApp message
Copy the Account SID and Auth Token from the Twilio Console dashboard.
The Twilio WhatsApp Number is the sandbox number (e.g. +14155238886) or your approved business number.
After connecting, copy the Webhook URL shown below into Twilio Sandbox Settings → "When a message comes in".
WhatsApp connected successfully!
Copy this Webhook URL into Twilio Sandbox Settings → "When a message comes in":
{{ csBindResult.webhook_url }}
Connect Telegram Bot
Create a bot via @BotFather on Telegram, then paste the bot token below. Webhook will be configured automatically.
Connect WeChat Official Account
Web Chat Widget
Web chat widget is already available via the Website Chat feature. Go to your website settings to embed the chat widget.
Channel-Specific Overrides
Customize response behavior per channel.
Response Style
Control how the agent formats and structures responses.
{{ csWizardSteps[csWizardStep]?.label }}
{{ csWizardSteps[csWizardStep]?.desc }}
Agent: {{ csSelectedAgent.name }} — {{ csSelectedAgent.role || 'AI Agent' }}
Agent identity comes from its profile. Only company context needs to be set here.
{{ t('sm_title') }}
{{ t('sm_subtitle') }}
{{ t('sm_select_agent') }}
{{ t('sm_select_agent_desc') }}
{{ t('sm_no_agent') }}
{{ t('sm_workflow_title') }}
{{ t('sm_workflow_desc') }}
{{ t('sm_wf_intelligent_desc') }}
{{ t('sm_wf_intelligent_note') }}
{{ t('sm_wf_no_platforms_hint') }}
{{ t('sm_workflow_empty') }}
{{ t('sm_wf_add_step_hint') }}
{{ t('sm_platforms_title') }}
{{ t('sm_platforms_desc') }}
{{ platform.name || platform.type }}
{{ platform.account_id || 'Connected' }}
{{ t('sm_connect') }} {{ smBindForm.platform_type.replace('_', ' ') }}
{{ t('sm_meta_api_note') }}
{{ t('sm_telegram_note') }}
{{ t('sm_tiktok_note') }}
{{ t('sm_strategy_title') }}
{{ t('sm_strategy_desc') }}
{{ t('sm_media_title') }}
{{ t('sm_media_desc') }}
{{ t('sm_upload_files') }}
{{ t('sm_upload_hint') }}
{{ t('sm_recent_uploads') }}
{{ t('sm_no_media') }}
{{ file.name }}
{{ t('sm_publishing_title') }}
{{ t('sm_publishing_desc') }}
{{ t('sm_queue_empty') }}
{{ t('sm_queue_empty_hint') }}
{{ item.content }}
AI Customer Service
Configure your AI customer service agents
Company Context
Greetings
Same configuration panels as admin view — all tabs functional
{{ t('workspace_title') }}
{{ t('workspace_subtitle') }}
{{ agent.name }}
{{ getWsChatLastTime(agent.id) }}{{ agent.title || agentRoleLabel(agent.role) }}
{{ t('ws_no_selection') }}
{{ t('ws_no_selection_desc') }}
{{ chat.agentName }}
{{ chat.agentTitle || 'AI Employee' }}
{{ t('ws_drop_files') }}
{{ t('ws_drop_files_hint') }}
{{ chat.agentName }}
Start a conversation below
{{ chat.loadingStatus?.text || 'Thinking...' }}
Action Requires Approval
{{ chat.pendingApproval.tool }}
Agent Needs Input
{{ chat.pendingApproval.question }}
{{ t('client_dash_welcome') }} {{ authUser?.name }}
{{ clientDashData.company || t('client_dash_workspace') }}
{{ t('client_dash_not_configured') }}
{{ t('client_dash_not_configured_desc') }}
{{ t('client_dash_credits') }}
{{ clientDashData.credits?.balance || 0 }}
{{ t('client_dash_remaining') }}
{{ t('client_dash_credits_used') }}
{{ clientDashData.usage?.credits_used || 0 }}
{{ clientDashData.usage?.call_count || 0 }} {{ t('client_dash_conversations') }}
{{ t('client_dash_plan') }}
{{ clientDashData.plan || 'Free' }}
{{ clientDashData.agents?.total || 0 }} employee(s)
{{ t('client_dash_your_employees') }}
{{ t('client_dash_setting_up') }}
{{ a.name }}
{{ a.channels.length ? a.channels.map(c => channelLabel(c)).join(', ') : t('client_dash_not_connected') }}
{{ t('client_dash_connect_title') }}
{{ t('client_dash_connect_desc') }}
{{ t("channels_telegram") }}
{{ t('client_dash_telegram_desc') }}
{{ t("channels_whatsapp") }}
{{ t('client_dash_whatsapp_desc') }}
{{ t("channels_wechat") }}
{{ t('client_dash_wechat_desc') }}
{{ t('client_dash_need_help') }}
{{ t('client_agents_title') }}
{{ t('client_agents_subtitle') }}
{{ t('client_agents_not_configured') }}
{{ t('client_agents_not_configured_desc') }}
{{ t('agent_recycle_empty') }}
{{ t('agent_recycle_empty_desc') }}
| {{ t('users_name') }} | {{ t('users_role') }} | {{ t('users_deleted_at') }} | {{ t('users_days_left') }} | {{ t('users_actions') }} |
|---|---|---|---|---|
| {{ a.name }} | {{ a.role }} | {{ a.deleted_at ? new Date(a.deleted_at).toLocaleString() : '-' }} | {{ a.days_remaining }}d |
|
{{ t('client_agents_no_assigned') }}
{{ t('client_agents_no_assigned_desc') }}
{{ a.name }}
{{ a.title || agentRoleLabel(a.role) }}
{{ a.description || t('agent_no_description') }}
{{ t('client_usage_title') }}
{{ t('client_usage_subtitle') }}
{{ t("client_usage_not_configured") }}
{{ t("client_usage_not_configured_desc") }}
{{ t('client_usage_total_conversations') }}
{{ clientDashData.usage?.call_count || 0 }}
{{ t('client_usage_credits_used') }}
{{ clientDashData.usage?.credits_used || 0 }}
{{ t('client_usage_credits_remaining') }}
{{ clientDashData.credits?.balance || 0 }}
{{ t('client_usage_recent') }}
| {{ t('client_usage_time') }} | {{ t('client_usage_employee') }} | {{ t('client_usage_source') }} | {{ t('client_usage_credits') }} |
|---|---|---|---|
| {{ formatTime(r.created_at) }} | {{ getClientAgentName(r.agent_id) }} | {{ r.source }} | {{ Math.ceil(r.total_tokens / 1000) }} |
{{ t('files_title') }}
{{ t('files_subtitle') }}
{{ t('files_empty') }}
{{ f.filename }}
AI indexed {{ (f.size / 1024).toFixed(1) }}KB · {{ formatTime(f.created_at) }}
{{ t('api_keys_title') || 'API Keys' }}
{{ t('api_keys_subtitle') || 'Integrate your AI employees into your own systems' }}
{{ t('api_keys_created') || 'API Key Created — copy it now, it won\'t be shown again:' }}
{{ newApiKey }}
{{ t('api_keys_empty') || 'No API keys yet. Create one to start integrating.' }}
{{ k.name }}
{{ k.key_prefix }}... · {{ k.calls_count || 0 }} calls · {{ k.is_active ? 'Active' : 'Revoked' }}
{{ t('webhooks_title') || 'Webhooks' }}
{{ t('webhooks_subtitle') || 'Receive notifications when events happen with your AI employees' }}
{{ t('webhooks_empty') || 'No webhooks configured. Add one to receive event notifications.' }}
{{ wh.url }}
{{ t('wechat_title') }}
{{ t('wechat_subtitle') }}
{{ t('wechat_select_agent') || 'Select AI Employee' }}
{{ t('wechat_select_agent_desc') || 'Choose which AI employee will handle WeChat messages' }}
{{ t('wechat_not_connected') }}
{{ t('wechat_not_connected_desc') }}
{{ t('wechat_scan_title') }}
{{ t('wechat_scan_desc') }}
{{ t('wechat_connected') }}
{{ t('wechat_account') }}: {{ wechatBinding.wechat_nickname }}
{{ t('wechat_status') }}
{{ t('wechat_status_active') }}
{{ t('wechat_connected_since') }}
{{ wechatBinding.connected_at ? new Date(wechatBinding.connected_at).toLocaleString() : '—' }}
{{ t('wechat_ai_employee') }}
{{ getClientAgentName(wechatBinding.agent_id) }}
{{ t('wechat_how_it_works') }}
{{ t('wechat_how_it_works_desc') }}
{{ t('wechat_error_title') }}
{{ t('wechat_error_desc') }}
{{ t('credits_title') }}
{{ t('credits_subtitle') }}
{{ t('credits_no_requests') }}
| {{ t('credits_time') }} | {{ t('credits_company') }} | {{ t('credits_amount') }} | {{ t('credits_price') }} | {{ t('credits_payment') }} | {{ t('credits_notes') }} | {{ t('credits_status') }} | {{ t('credits_actions') }} |
|---|---|---|---|---|---|---|---|
| {{ formatTime(cr.created_at) }} | {{ cr.tenant_name || getTenantName(cr.tenant_id) }} | {{ cr.credits }} | ¥{{ cr.price }} | {{ cr.payment_method }} | {{ cr.payment_note || '—' }} | {{ cr.status === 'approved' ? t('credits_status_approved') : cr.status === 'rejected' ? t('credits_status_rejected') : t('credits_status_pending') }} |
|
{{ t('llm_title') }}
{{ t('llm_subtitle') }}
{{ t('llm_health_dashboard') }}
{{ t('llm_scenarios') }}
{{ t('llm_scenarios_desc') }}
{{ t('llm_no_providers') }}
{{ t('llm_keys') }} ({{ p.keys?.length || 0 }})
| {{ t('llm_key_label') }} | {{ t('llm_masked_key') }} | {{ t('llm_requests') }} | {{ t('llm_errors') }} | {{ t('llm_enabled') }} | |
|---|---|---|---|---|---|
| {{ k.label || '—' }} | {{ k.masked_key }} | {{ k.requests_count || 0 }} | {{ k.errors_count || 0 }} |
{{ t('llm_add_from_preset') }}
{{ llmEditingId ? t('llm_edit_provider') : t('llm_create_provider') }}
{{ t('users_title') }}
{{ t('users_subtitle') }}
| {{ t('users_name') }} | {{ t('users_email') }} | {{ t('users_role') }} | {{ t('users_tenant') }} | AI員工點數 | {{ t('users_status') }} | {{ t('users_actions') }} |
|---|---|---|---|---|---|---|
|
{{ u.name.charAt(0) }}
{{ u.name }}
|
{{ u.email }} | {{ u.role }} | {{ u.tenant_id ? getTenantName(u.tenant_id) : '—' }} |
{{ getUserTenantCredits(u.tenant_id) }}
—
|
{{ u.is_active ? t('users_active') : t('users_disabled') }} |
|
{{ t('users_recycle_empty') }}
{{ t('users_recycle_empty_desc') }}
{{ t('users_recycle_notice') }}
| {{ t('users_name') }} | {{ t('users_email') }} | {{ t('users_role') }} | {{ t('users_deleted_at') }} | {{ t('users_expires') }} | {{ t('users_actions') }} |
|---|---|---|---|---|---|
|
{{ u.name.charAt(0) }}
{{ u.name }}
|
{{ u.email }} | {{ u.role }} | {{ formatTime(u.deleted_at) }} | {{ u.days_remaining }} {{ t('users_days_left') }} |
|