Make the Instruction agent reply in the user's language, at a human pace
The agent answers in the language each message is written in (Indonesian or English), whatever the UI language; short replies such as "LLM" keep the conversation's language. inLang() runs t() in that language. Each turn now reads like a person: a thinking step with what the agent is doing, the reply typed out with "Thought for Ns" above it, a short typing pause, then one question, with its options shown once it is typed. Reduced motion skips the animation. "dari file LLM" / "from the document X" is read as the topic, and topics keep the user's capitals. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
21
src/i18n.ts
21
src/i18n.ts
@@ -269,6 +269,11 @@ const en = {
|
||||
'ins.budgetVideo': '{n} per video',
|
||||
'agent.name': 'Express Agent',
|
||||
'agent.status': 'Asks when something is unclear',
|
||||
'agent.statusThinking': 'Thinking…',
|
||||
'agent.think1': 'Reading your message',
|
||||
'agent.think2': 'Checking the plan',
|
||||
'agent.think3': 'Working out what is still unclear',
|
||||
'agent.thought': 'Thought for {s}s',
|
||||
'agent.greeting': 'Hi! Tell me what to create from the Brain and how often, or what to research on the internet. If anything is unclear, I will ask you here.',
|
||||
'agent.understood': 'Got it. Here is the plan so far:\n{list}',
|
||||
'agent.added': 'Added to the plan:\n{list}',
|
||||
@@ -638,6 +643,11 @@ const id: Record<Key, string> = {
|
||||
'ins.budgetVideo': '{n} per video',
|
||||
'agent.name': 'Agen Express',
|
||||
'agent.status': 'Bertanya bila ada yang belum jelas',
|
||||
'agent.statusThinking': 'Sedang berpikir…',
|
||||
'agent.think1': 'Membaca pesan Anda',
|
||||
'agent.think2': 'Memeriksa rencana',
|
||||
'agent.think3': 'Mencari yang masih belum jelas',
|
||||
'agent.thought': 'Berpikir {s} detik',
|
||||
'agent.greeting': 'Halo! Ceritakan konten apa yang perlu dibuat dari Otak dan seberapa sering, atau apa yang perlu diriset di internet. Kalau ada yang belum jelas, saya tanyakan di sini.',
|
||||
'agent.understood': 'Siap. Ini rencananya sejauh ini:\n{list}',
|
||||
'agent.added': 'Ditambahkan ke rencana:\n{list}',
|
||||
@@ -760,6 +770,8 @@ function initial(): Lang {
|
||||
}
|
||||
|
||||
let lang: Lang = initial()
|
||||
// The language of the text being built right now, when it differs from the UI (see inLang).
|
||||
let override: Lang | null = null
|
||||
const listeners = new Set<() => void>()
|
||||
if (typeof document !== 'undefined') document.documentElement.lang = lang
|
||||
|
||||
@@ -774,10 +786,17 @@ export function setLang(next: Lang) {
|
||||
}
|
||||
|
||||
export function t(key: Key, vars?: Record<string, string | number>): string {
|
||||
const text = dictionaries[lang][key] ?? en[key]
|
||||
const text = dictionaries[override ?? lang][key] ?? en[key]
|
||||
return vars ? text.replace(/\{(\w+)\}/g, (m, k) => (k in vars ? String(vars[k]) : m)) : text
|
||||
}
|
||||
|
||||
/** Runs fn with t() in another language, e.g. the agent answering in the language the user writes in. */
|
||||
export function inLang<T>(l: Lang, fn: () => T): T {
|
||||
const previous = override
|
||||
override = l
|
||||
try { return fn() } finally { override = previous }
|
||||
}
|
||||
|
||||
/** Re-renders the component when the language changes; returns the active language. */
|
||||
export function useLang(): Lang {
|
||||
return useSyncExternalStore(cb => { listeners.add(cb); return () => listeners.delete(cb) }, getLang)
|
||||
|
||||
Reference in New Issue
Block a user