Repository navigation
Conversation
|
I synchronized this branch with the current \main\ and pushed head \ |
|
@jjj-n I don't have a non-production IM bot connected yet, so I haven't run cases 1–5 end to end. Your Feishu run covers that path. What I could do is run Where it holds up
Where it misses: ordinary short Vietnamese questions
These are not the A side finding on Unicode normalisation: whatlanggo scores NFD input differently from NFC. The last two rows come back as reliable Vietnamese when the input is NFD. Separately, the Suggestion. On short text, letters that only Vietnamese uses are a stronger signal than the n-gram score. I tried this variant in a throwaway test, not in the PR: // ơ ư and the tone+circumflex/breve/horn composites occur only in Vietnamese.
// ă (Romanian), đ (Croatian) and plain â ê ô (French, Portuguese) are left out.
const vietnameseOnly = "ơưƠƯấầẩẫậắằẳẵặếềểễệốồổỗộớờởỡợứừửữựẤẦẨẪẬẮẰẲẴẶẾỀỂỄỆỐỒỔỖỘỚỜỞỠỢỨỪỬỮỰ"
text = norm.NFC.String(text)
if strings.ContainsAny(text, vietnameseOnly) {
return whatlanggo.Langs[whatlanggo.Vie]
}I placed it before the letters threshold. With it, all five rows above return The guard sentences kept their current result: French, Portuguese, Romanian, Croatian and English. One behaviour does change. If you would rather keep the detector generic, a Vietnamese-only deployment can work around the first-turn problem on the operator side. I'm happy to run it on live IM traffic once I have a bot connected. |
|
@vinhchuquang Thank you for the concrete Vietnamese samples and the NFC/NFD finding. I reproduced the five first-turn misses and pushed The detector now normalizes to NFC and uses a conservative set of Vietnamese-distinctive letters when a message is below the 20-letter threshold or whatlanggo marks its result unreliable. It still keeps the existing unknown result for One deliberate trade-off matches your observation: |
|
@jjj-n Re-ran the probe at New cases that hold
One small gap: hook-above letters
const vietnameseOnly = "ơưƠƯấầẩẫậắằẳẵặếềểễệốồổỗộớờởỡợứừửữựẤẦẨẪẬẮẰẲẴẶẾỀỂỄỆỐỒỔỖỘỚỜỞỠỢỨỪỬỮỰảẻỉỏủỷẢẺỈỎỦỶ"I tried an equivalent hook-above check in a throwaway test. Both messages then return I'd leave dot-below ( Expected misses. Still no live IM bot on my side, so this covers the detector only. |
|
Thanks @jjj-n. Following the user's language is the natural next step after #3455, and I'm happy with the direction. One thing has to change before this can land, and I have one question.
|
|
1. Locale codes instead of language names — done.
Also folded in @vinhchuquang's hook-above suggestion from the round-2 probe: 2. Why whatlanggo. I picked it for three reasons: (a) it is a small, dependency-free statistical detector with a closed language table, so no message text leaves the process and no network call is added to the IM hot path; (b) its trigram scoring returns a reliability flag, which the Alternatives considered: Maintenance status: upstream has been quiet since March 2023 with open issues unanswered, so I'm treating it as frozen rather than maintained. That is why the detector is isolated in |
|
Review of The locale-code correction in
The migration collision is a cross-PR integration problem; these versions need to remain unique in the final combined tree. |
- resolve frontend/src/api/agent/index.ts conflict keeping zh-TW locale and language_mode - renumber SQLite migration 000034 -> 000035 (collides with merged 000034_mcp_metadata) and versioned 000115 -> 000116 (collides with Tencent#4053) - add the three replyLanguage keys to zh-TW.ts
|
Both items are addressed in 1. zh-TW keys. The branch now merges current
The current locale-key audit passes: 2. Migration numbers. This PR's migrations are renumbered to SQLite Targeted checks on the merged head: |
|
Merged current main in e8ac04c and resolved the conflicts. Renumbered the migrations to SQLite 000042 and PostgreSQL 000125. Added SQLite upgrade/rollback regression coverage and validated the PostgreSQL migration SQL. All seven checks on the updated head pass. Could you take another look when convenient? |
Description
Step 1 (#3455) lets an IM channel use a fixed reply locale. A multilingual channel still cannot make fallback answers, session titles, and other prompts follow the writer's language. This Step 2 adds
language_mode: fixed | follow_user(defaultfixed) to channel configuration and the admin UI.In
follow_usermode, the shared IM message path resolves the reply language before title generation and QA:The last language is stored on
im_channel_sessions, so/clearresets it with the session mapping. Detector output is separate from the five UI locales; Vietnamese is covered. Webhook, WebSocket, and long-poll adapters all reach the sharedHandleMessagepath. The IM platform'sAccept-Languageis not used as the writer's language. API and IM integration docs are updated.Real Feishu IM traffic validation is complete for the follow-user path; this PR is ready for review. The resolver and detector have unit tests, but there is not yet a transport-level assertion that each adapter delivers the resolved
LanguageContextKeyto title generation and QA. The language state follows the existingChannelSessionidentity: user mode keys by platform/user/chat/tenant/agent, and thread mode by platform/chat/thread/tenant/agent. Two channel configurations that resolve to the same existing session key also share its language state; changing that session identity is outside this PR.Type of Change
Related Issue
Refs #3315. Follows merged Step 1 in #3455.
Testing
go test ./internal/im ./internal/database -count=1— passed.go test ./internal/handler -run TestCreateIMChannel -count=1— passed.go vet ./internal/im ./internal/database ./internal/handler— passed.npm run type-checkandnpm run check-i18n— passed.git diff --check origin/main...HEAD— passed.origin/main, Docker Go testsgo test ./internal/im ./internal/database -count=1andgo test ./internal/handler -run TestCreateIMChannel -count=1, plusgo vet ./internal/im ./internal/database ./internal/handler, passed. Frontendnpm run type-checkandnpm run check-i18npassed. Full-repository Go tests were not run locally.Checklist
git diff --check origin/main...HEADpassesgolangci-lint run --new-from-rev=origin/main ./...)website-docs/, Swagger annotations, etc.)Live Feishu IM validation (2026-09-29)
im.message.receive_v1events; a Chinese private-chat message produced a visible Chinese streaming-card reply. The activefollow_userchannel persistedMandarin.Vietnamese. A subsequent?in the same session produced a Vietnamese clarification, validating the short-message session fallback./clearremoved the old channel-session mapping; a new?used the deployment defaulten-USand replied in English.open.feishu.cnin its exact SSRF whitelist because its DNS resolves to a restricted proxy IP. After granting the test appcardkit:card:write, the Chinese turn, Vietnamese turn, short?,/clear, and post-clear?all completed the streaming-card path (Streaming startedandStreaming endedin app logs). These are test-environment settings, not PR source changes.origin/main, renumbered this PR's migrations to SQLite000034and versioned000115to avoid upstream migration-number collisions. GitHub reports the branch mergeable and all seven checks passed. Live IM traffic ran on the pre-merge application image at0034ec8; targeted tests, vet, frontend type-check and i18n ran on merged heade86ea50.Screenshots / Recordings
The local Docker app and Feishu test bot are running. No admin UI screenshot is attached yet. The selector shows the fixed locale only in
fixedmode.Summary
Evidence
okwould have no per-conversation language to reuse.After: a Vietnamese turn stores
Vietnamese;okin the same session uses it; a new session after/clearuses the deployment default until a language is detected.Merge Danger
Door: Two-way. The mode defaults to
fixed; reverting the migration removes the new mode and saved language state.Blast Radius: IM channels. Existing channels retain fixed-language behavior;
follow_useradds one session-row read or write per handled message.