fix(sasquatch): reply in all 24 locales; record translation/Basque state
- Sasquatch UI/guide/FAQ were already 100% in all 24 locales; the AI reply language directive only covered es/th/ja. SASQUATCH_LANGUAGES now maps all 24 app languages (trick names/core vocabulary stay English). - Document the Sasquatch privacy difference: its AI calls the CVM/AI proxy (OpenRouter), unlike the on-device translation. - Record the Basque status: IR 9->8 and target-side tokenizer fixed; model now emits Basque but loops on EOS/generation; remaining gap before 1.7.2.
This commit is contained in:
parent
e85b9aacb6
commit
1fc91d1192
2 changed files with 62 additions and 13 deletions
24
AGENTS.md
24
AGENTS.md
|
|
@ -2455,9 +2455,10 @@ Rules:
|
|||
`handle_path /models/*` → `/srv/models`, CORS `*`; backup
|
||||
`/etc/caddy/Caddyfile.bak-…`).
|
||||
- **Verified from the host:** en↔es, ca↔gl, hi↔en. The Basque packs are
|
||||
converted and hosted (ONNX q8 + generated `tokenizer.json`), but the final
|
||||
in-browser MarianTokenizer/ONNX runtime verification is **still pending**
|
||||
(a Marian/ONNX runtime error in the standalone check).
|
||||
converted and hosted (ONNX q8). Fixed: the ONNX **IR 9→8** mismatch and the
|
||||
Marian tokenizer's **target-side** `tokenizer.json`. The decoder now emits
|
||||
Basque, but it **loops** (EOS/generation config), so Basque is still **not
|
||||
usable**. Next: the `eos_token_id`/generation loop.
|
||||
- Runtime: **`@xenova/transformers` 2.17.2** + ONNX Runtime **1.14** WASM
|
||||
self-hosted in `public/ort/` (37 MB, copied from `onnxruntime-web`), loaded
|
||||
from `../ort/`; worker `src/workers/translate.worker.ts`. M2M100 is used
|
||||
|
|
@ -2480,15 +2481,26 @@ Rules:
|
|||
- **Conversion:** Docker Python 3.11 + torch 2.4.1 + transformers 4.46.3 +
|
||||
optimum 1.24; dynamic q8; `tokenizer.json` generated from the SentencePiece
|
||||
models (needs protobuf + `sentencepiece_model_pb2.py`).
|
||||
- **Still to do:** finish the Basque tokenizer/ONNX runtime fix, verify all 24
|
||||
pairs in the browser/APK, measure speed/memory, and ship **1.7.2** (the phone
|
||||
is on 1.7.1). No SpotChat.
|
||||
- **Still to do:** fix the Basque EOS/generation loop, verify all 24 pairs in
|
||||
the browser/APK, measure speed/memory, and ship **1.7.2** (the phone is on
|
||||
1.7.1). No SpotChat.
|
||||
- **Keyboard caveat:** a malicious OS keyboard or rooted device is outside the
|
||||
app’s control. Warn/recommend a trusted offline keyboard, and avoid the OS
|
||||
keyboard for **secrets** (custom secure input / QR / bunker/Amber,
|
||||
`FLAG_SECURE`, no autofill/suggestions). Translation’s guarantee is
|
||||
app-level: no plaintext egress.
|
||||
|
||||
### Sasquatch translation + privacy (2026-10-27)
|
||||
- The Sasquatch **UI, guide and FAQ** strings (`sasquatchUi`/`sasquatchChat`/
|
||||
`sasquatchGuide`) are translated in all 24 locales (i18n 100%).
|
||||
- The **AI reply language** directive was only `es`/`th`/`ja`;
|
||||
`SasquatchGuide.tsx` now has `SASQUATCH_LANGUAGES` for all 24 (skate trick
|
||||
names and core vocabulary stay in English), so replies follow the app
|
||||
language for every locale.
|
||||
- **Privacy differs:** the Sasquatch AI is **not on-device** — it calls the CVM/
|
||||
AI proxy (OpenRouter). Its questions/replies leave the device. Only the
|
||||
**translation** is local/no-egress; do not conflate the two.
|
||||
|
||||
### Community relay — self-hosted Newlay (2026-10-12)
|
||||
|
||||
The community relay moved off the hosted relay.tools instance
|
||||
|
|
|
|||
|
|
@ -24,12 +24,55 @@ import { PLATFORM_OWNER_PUBKEYS } from '@/hooks/useListingRestrictions';
|
|||
import { SasquatchProDialog } from '@/components/SasquatchProDialog';
|
||||
import { useSasquatchActions, type SasquatchDraft } from '@/hooks/useSasquatchActions';
|
||||
import { useTranslation } from '@/contexts/language';
|
||||
import type { Language } from '@/contexts/language';
|
||||
import { SasquatchActionCard } from '@/components/SasquatchActionCard';
|
||||
import { callSasquatchAI, streamSasquatchAI } from '@/lib/sasquatchBrain';
|
||||
import { buildProAuthHeaders } from '@/lib/proAuth';
|
||||
import { answerFromGlossary } from '@/lib/glossary';
|
||||
import { TripItineraryCard } from '@/components/TripItineraryCard';
|
||||
import { buildItinerary, type Itinerary, type PlannerSpot, type PlannerEvent, type PlannerCoach, type PlannerCrew, type WeatherLite } from '@/lib/tripPlanner';
|
||||
|
||||
/** Native language names for the Sasquatch reply-language directive. */
|
||||
const SASQUATCH_LANGUAGES: Record<Language, string> = {
|
||||
en: 'English',
|
||||
es: 'Spanish (Castellano)',
|
||||
ca: 'Catalan (Català)',
|
||||
eu: 'Basque (Euskara)',
|
||||
gl: 'Galician (Galego)',
|
||||
hi: 'Hindi (हिन्दी)',
|
||||
th: 'Thai (ไทย)',
|
||||
ja: 'Japanese (日本語)',
|
||||
pt: 'Portuguese',
|
||||
'pt-PT': 'European Portuguese',
|
||||
fr: 'French',
|
||||
de: 'German',
|
||||
it: 'Italian',
|
||||
nl: 'Dutch',
|
||||
pl: 'Polish',
|
||||
ru: 'Russian',
|
||||
ko: 'Korean',
|
||||
'ko-KP': 'North Korean',
|
||||
'zh-CN': 'Simplified Chinese',
|
||||
'zh-TW': 'Traditional Chinese',
|
||||
uk: 'Ukrainian',
|
||||
tr: 'Turkish',
|
||||
vi: 'Vietnamese',
|
||||
id: 'Indonesian',
|
||||
sv: 'Swedish',
|
||||
cs: 'Czech',
|
||||
ro: 'Romanian',
|
||||
el: 'Greek',
|
||||
};
|
||||
|
||||
/**
|
||||
* The Sasquatch answers in the app's current language for every locale (not
|
||||
* just es/th/ja). Skate trick names and core vocabulary stay in English.
|
||||
*/
|
||||
function sasquatchLanguageDirective(language: Language): string {
|
||||
if (language === 'en') return '';
|
||||
return `\n\nAlways reply in ${SASQUATCH_LANGUAGES[language]} with a friendly, casual skate tone. Keep skateboarding trick names in English (kickflip, ollie, nollie, heelflip, etc.) and core skate vocabulary (spot, park, bowl, DIY, vert, crew, line) in English — never translate those.`;
|
||||
}
|
||||
|
||||
import { cn } from '@/lib/utils';
|
||||
import { fetchWeather, calculateSkateability } from '@/lib/weather';
|
||||
import { getCurrentPosition } from '@/lib/geolocation';
|
||||
|
|
@ -1117,13 +1160,7 @@ export function SasquatchGuide({ message, onDismiss }: SasquatchGuideProps) {
|
|||
// content. Personal tools are only offered to logged-in Pro supporters.
|
||||
// The reply-language directive is appended so The Sasquatch answers in
|
||||
// the app's current language, keeping skate trick names in English.
|
||||
const languageDirective = language === 'es'
|
||||
? '\n\nAlways reply in Spanish (Castellano). Keep skateboarding trick names in English (kickflip, ollie, nollie, heelflip, etc.) and never translate them.'
|
||||
: language === 'th'
|
||||
? '\n\nAlways reply in Thai (ไทย) with a friendly, casual skate tone. Keep skateboarding trick names in English (kickflip, ollie, nollie, heelflip, etc.) and core skate vocabulary (spot, park, bowl, DIY, vert, crew, line) in English — never translate those.'
|
||||
: language === 'ja'
|
||||
? '\n\nAlways reply in Japanese (日本語) with a friendly, casual skate tone. Keep skateboarding trick names in English (kickflip, ollie, nollie, heelflip, etc.) and core skate vocabulary in English or katakana (spot, park, bowl, DIY, vert, crew, line) — never translate the trick names.'
|
||||
: '';
|
||||
const languageDirective = sasquatchLanguageDirective(language);
|
||||
const systemPrompt = (personal.available && isPro
|
||||
? `${SYSTEM_PROMPT}${PERSONAL_TOOLS_PROMPT}`
|
||||
: SYSTEM_PROMPT) + languageDirective;
|
||||
|
|
|
|||
Loading…
Reference in a new issue