Localization messaging agent
This page explains how a localization messaging agent reads the source campaign and live regional pages under an interactive grant, checks messaging consistency market by market against a versioned glossary and forbidden-translation list, and streams sweep progress and the diff list back as typed events. After reading it, you will understand which modules this scenario needs, how per-market sweep progress streams back in real time, and why data like the glossary belongs in a localization config store rather than Memory.
Use case
International marketing teams need to adapt campaigns, landing pages, or ad copy for a target region and verify that live multilingual pages stay consistent with the source messaging. Regional pages are maintained by local teams, so translation drift, misused forbidden translations, and lag after source-copy updates are hard to catch market by market with manual review.
Typical triggers:
- Source campaign copy changes, and every language market's pages must be checked for sync.
- Before entering a new market, messaging must be calibrated against local competitors and market conventions.
- The glossary or forbidden-translation list changes, and existing regional translations must be swept.
Engineering challenges
- Check volume grows linearly with markets: every market means capturing live copy and comparing it against the glossary entry by entry. Serial manual checks cannot finish within the window after a source-copy update — and the team needs to see in real time which market the sweep is on and where it is stuck.
- Diff decisions depend on versioned rules: the glossary and forbidden-translation list change frequently, so whether a diff is "real drift" or "based on a stale glossary" must be traceable to a rule version — otherwise local reviewers cannot re-verify it.
- Borrowed employee access to regional workspaces is too broad: a borrowed session can read campaign materials for every market, while a single check only needs read-only access to the specified source copy and target region.
Module composition
| Module | Role | Notes |
|---|---|---|
| GenAuth | Core | Read-only delegation, revocation, and the audit chain for regional workspaces and campaign materials; publishing translations and editing pages stay outside the grant. |
| Web Agent | Core | Controlled sessions capture live copy from each market's pages, keeping source URLs and screenshots, and research local competitor pages for phrasing conventions. |
| GUMem | Not used | The glossary and forbidden translations are versioned policy — keep them in your localization config store and inject them per version; diff lists and reviewer decisions are business state and belong in your localization records. Neither is Memory. |
Permission and delegation boundaries
The Agent holds no inherent permissions. The effective authority for each verification task is the intersection of three sets: what the user actually holds ∩ what was explicitly delegated for this task ∩ what the enterprise has approved. Applied here:
- The delegated scope covers only "read the specified campaign materials, regional workspaces, and local public pages" — no publishing translations, editing regional pages, or changing the glossary.
- Delegation credentials are short-lived; minute-level validity is recommended for a single verification run, with re-delegation after expiry.
- The user or an administrator can revoke the grant at any time; new material-read requests fail immediately after revocation.
- Out-of-scope attempts (for example, a market workspace outside the delegation) are rejected and recorded — the audit chain covers all attempts, not just successful actions.
Note: the SDK example requests product-level scopes (such as webagent.do_anything:read). Fine-grained boundaries — domain lists, page ranges, action whitelists — are enforced by the GenAuth Agent Profile or your policy layer, not by the task prompt; that configuration is not shown on this page. See Delegate token and attenuation for the full semantics.
Workflow
The user selects the source copy, target region, and the local page list to verify.
GenAuth starts an interactive delegation; after the user confirms in Qoni Console, your server-side callback exchanges it for a least-privilege, read-only credential.
Your app loads the current version of the glossary, forbidden translations, and regional phrasing rules from the localization config store and injects them into the task.
Web Agent captures live copy from the local pages market by market, keeping source URLs and screenshots; sweep progress streams back as events.
Checkpoint: When a regional workspace or local page hits a login wall, CAPTCHA, or risk-control page, the Web Agent should escalate to a human instead of silently bypassing it.
Web Agent researches local competitors and public market context for phrasing conventions.
The Agent compares each local page against the source messaging, glossary, and forbidden translations, flagging translation drift, misused terms, and unsynced lag, each with a page source and the rule version it was checked against.
The Agent returns a localization diff list, fix suggestion drafts, rationale, and sources with an audit id; after app-side validation they go to the local reviewer.
Checkpoint: Every diff and suggestion should trace back to a concrete page source or glossary entry; conclusions without evidence should not enter the deliverable.
Example code
The example below wires this scenario into your backend with the official Qoni SDK (@qoniai/qoni): interactive delegation (with a full callback) → load the glossary from your localization config store → one doAnything.run() for the market verification, streaming per-market sweep progress through run.events() → parse and validate the diff list.
import { Qoni, QoniScopes } from '@qoniai/qoni'
const qoni = new Qoni({
accessKey: process.env.QONI_ACCESS_KEY!,
secretKey: process.env.QONI_SECRET_KEY!,
})
export async function startLocaleCheck(userId: string, taskId: string) {
// 1. Interactive delegation: regional workspace sign-in is involved,
// so the user confirms in Qoni Console
const { data: authorization } = await qoni.delegateToken({
mode: 'interactive',
agent: 'localization-messaging',
scopes: [QoniScopes.DO_ANYTHING_READ, QoniScopes.DO_ANYTHING_MANAGE],
redirectUri: 'https://app.example.com/qoni/callback',
state: taskId,
user: { id: userId },
expiresIn: 900, // minute-level validity for a single verification run
})
redirectUserTo(authorization.authorizationUrl)
}
// GET /qoni/callback — after the user approves, exchange for the grant
// server-side and continue the task
export async function handleQoniCallback(request: Request) {
const query = new URL(request.url).searchParams
const { data: grant } = await qoni.completeDelegateToken({
grantId: query.get('grantId')!,
code: query.get('code')!,
state: query.get('state')!,
})
const task = await loadLocaleCheckTask(query.get('state')!) // your task store
return runLocaleCheck(grant, task)
}
async function runLocaleCheck(
grant: { token: string; auditId: string; grantedScopes: string[] },
task: { region: string; localPages: string[]; sourceMessaging: string },
) {
// 2. Before the run: load the current glossary and forbidden translations
// from YOUR localization config store (versioned policy, not Memory)
const policy = await loadLocalizationPolicy(task.region) // e.g. { version: '2026-08', glossary: [...], forbiddenTranslations: [...] }
// 3. One call runs the verification: capture live copy, compare, drafts only
const run = await qoni.doAnything.run({
token: grant.token,
prompt: `
Verify the live pages for market ${task.region}:
${task.localPages.join(', ')}.
Capture the live copy, compare it against the source messaging,
glossary and forbidden translations, then flag drift, misused
terms and unsynced copy. Return diffs as a JSON array of
{ page, diff, suggestion, sourceUrl, glossaryRef } objects.
Never publish, edit pages or change the glossary.
Source messaging: ${task.sourceMessaging}
Localization policy (version ${policy.version}):
${JSON.stringify(policy)}
`,
capture: { screenshots: true },
})
// 4. Event stream: forward per-market progress, screenshots, and
// human-in-the-loop steps to your frontend in real time
let output: unknown
for await (const event of run.events()) {
if (event.type === 'progress') appendTrace(event.data) // which page the sweep is on
if (event.type === 'screenshot') renderScreenshot(event.image) // evidence per page
if (event.type === 'interaction') handleInteraction(event.data) // login walls / CAPTCHAs → human
if (event.type === 'done') output = event.data.output
}
// 5. Parse and validate the output contract on the app side:
// diffs without a source or glossary reference never reach the deliverable
const diffs = parseLocaleDiffs(output).filter(
(d) => d.sourceUrl && d.glossaryRef,
)
return {
diffs,
policyVersion: policy.version,
audit: { auditId: grant.auditId, permissionBoundary: grant.grantedScopes },
}
}The output structure is a contract set by the task prompt: here it is an array of { page, diff, suggestion, sourceUrl, glossaryRef }, parsed and validated by parseLocaleDiffs on the app side, and any entry missing sourceUrl or glossaryRef is dropped. When the event stream disconnects, the SDK reconnects and resumes with Last-Event-ID; event type constants live in QoniEventTypes.
Data and memory boundaries
This scenario touches four kinds of data; GUMem is not used here:
- Versioned rules: the glossary, forbidden translations, regional phrasing rules — managed by version in your localization config store, with every diff referencing a rule version.
- Business state: diff lists, fix suggestions, page screenshots, reviewer decisions — archived to your localization records for review and traceability.
- Audit records: the delegation and behavior chain formed by
grantIdandauditId— maintained by GenAuth. - User Memory (optional): only long-term personal preferences a user has explicitly confirmed belong in GUMem; the glossary and regional rules are team-level policy, not personal memory, so this scenario neither recalls nor writes back by default.
Failure handling
| Situation | Recommended handling |
|---|---|
| Regional workspace login state expires | Suspend the task, notify the user to sign in again, and resume from the checkpoint. |
| Local page structure changes break extraction | Treat it as a failure and replay the session recording; never emit diffs without evidence. |
| Request for a market workspace outside the delegated scope | Reject and record it; the attempted access remains visible in the audit chain. |
| A diff lacks a page source or glossary reference | App-side validation drops the diff and records how many were dropped and the policy version applied. |
Production notes
Do not treat localization suggestions as final legal, cultural, or compliance review. A local reviewer should confirm before release. The Agent only produces diff lists and fix suggestion drafts; it never publishes translations or edits regional pages, and extraction frequency against local competitor pages should be capped. When the glossary changes, publish a new version in the config store so stale rules never judge new diffs.
Next steps
- Read the Quickstart to run the shortest path for Agent identity and delegation.
- Read Authorization and browser sandbox for the security boundaries of controlled sessions.
- Continue with the Brand consistency agent for an adjacent scenario.