Claude Code Plugins

Community-maintained marketplace

Feedback

enforcing-user-language-consistency

@margeruite/germanexampro
0
0

Ensures userLanguage/preferredLanguage is passed through ALL AI-related code paths. Use when modifying UI/UX, agents, RAG, tool factories, or any AI core code. Prevents translation inconsistencies.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name enforcing-user-language-consistency
description Ensures userLanguage/preferredLanguage is passed through ALL AI-related code paths. Use when modifying UI/UX, agents, RAG, tool factories, or any AI core code. Prevents translation inconsistencies.

Enforcing User Language Consistency

MANDATORY when modifying any code that touches:

  • UI/UX components that display AI feedback
  • Agent prompts or CoT instructions
  • RAG context generation
  • Tool factories
  • Evaluation output
  • Any AI-generated text shown to users

The Problem

User language (preferredLanguage) must flow through the ENTIRE call chain:

API Route → Tool Factory → Tool Implementation → Agent → RAG → Response

If ANY step loses the language context, users get mixed-language responses (e.g., German explanation for a Greek user).

Language Flow Architecture

Source of Truth

// apps/web-app/app/api/chat-agentkit/route.ts
const preferredLanguage = getUserNativeLanguage({
  dbNativeLanguage,      // 1st priority: DB stored preference
  browserLanguage,       // 2nd priority: Accept-Language header
  defaultLanguage: "English"
});

Required Flow

┌─────────────────────────────────────────────────────────────────┐
│ API Route (route.ts)                                            │
│ - Calculates preferredLanguage from DB/browser                  │
│ - Passes to ALL tool factories                                  │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│ Tool Factory (tool-factories.ts)                                │
│ - Captures userNativeLanguage in closure                        │
│ - Uses as fallback when agent doesn't pass it                   │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│ Tool Implementation (evaluate-text.ts, etc.)                    │
│ - Receives userLanguage in params                               │
│ - Passes to Agent context                                       │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│ Agents (*-agent-cot.ts)                                         │
│ - Receives userLanguage in analyze() method                     │
│ - Uses in prompt: "Feedback in ${feedbackLang}"                 │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│ RAG Context (hybrid-context.ts)                                 │
│ - Receives userNativeLanguage in options                        │
│ - May affect content retrieval/filtering                        │
└─────────────────────────────────────────────────────────────────┘

Checklist When Modifying AI Code

1. API Route Changes

// ALWAYS pass preferredLanguage to tool factories
const toolInstance = createSomeTool(
  userId,
  supabase,
  preferredLanguage  // ← REQUIRED
);

2. New Tool Factory

export function createNewTool(
  userId: string,
  supabase: SupabaseClient,
  userNativeLanguage?: string  // ← REQUIRED PARAMETER
) {
  // Capture in closure for fallback
  const capturedLanguage = userNativeLanguage || "English";

  return tool({
    parameters: z.object({
      userLanguage: z.string().optional()  // ← Agent can override
    }),
    execute: async (params) => {
      // Use captured language as fallback
      const effectiveLanguage = params.userLanguage || capturedLanguage;
      // ... pass effectiveLanguage to implementation
    }
  });
}

3. New Agent Method

async analyze(
  text: string,
  userLanguage?: string,  // ← REQUIRED PARAMETER
  context?: AgentEvaluationContext
): Promise<any> {
  const feedbackLang = userLanguage || "German";

  const prompt = `
    ...
    "feedback": "... in ${feedbackLang}",
    "explanation": "... in ${feedbackLang}"
  `;
}

4. RAG Context Generation

const ragContext = await hybridRAGContextManager.generateContext(
  queryText,
  {
    examType: params.examType,
    userNativeLanguage: effectiveLanguage  // ← REQUIRED
  }
);

5. UI Components Displaying AI Text

// If component shows AI feedback, ensure language context is available
interface Props {
  feedback: string;
  userLanguage?: string;  // For potential re-rendering
}

Anti-Patterns (NEVER DO)

Missing Language in Tool Factory

// WRONG - Language will default to English for everyone
export function createBadTool(userId: string, supabase: SupabaseClient) {
  return tool({
    execute: async (params) => {
      // No language context available!
    }
  });
}

Hardcoded Language in Agent

// WRONG - Ignores user preference
const prompt = `Feedback auf Deutsch...`;  // Should be ${feedbackLang}

Not Passing Language to Nested Calls

// WRONG - Language lost in nested call
const result = await evaluateText({
  text: params.text,
  examType: params.examType
  // Missing: userLanguage: effectiveLanguage
});

Validation Checklist

Before committing any AI-related code changes:

Language Flow:
- [ ] API route passes preferredLanguage to ALL tool factories?
- [ ] Tool factory captures userNativeLanguage in closure?
- [ ] Tool factory uses captured language as fallback?
- [ ] Tool implementation passes language to agent?
- [ ] Agent prompt uses ${feedbackLang} variable?
- [ ] RAG context receives userNativeLanguage?

No Hardcoding:
- [ ] No hardcoded "German", "English", etc. in prompts?
- [ ] Language variable used for all user-facing text?
- [ ] Default fallback is "English" not "German"?

Key Files to Check

File Language Variable Purpose
route.ts preferredLanguage Source of truth, passes to tools
tool-factories.ts userNativeLanguage Captures in closure for tools
*-agent-cot.ts userLanguage Uses in prompts as feedbackLang
hybrid-context.ts userNativeLanguage RAG context options
evaluate-text.ts userLanguage Tool implementation

Quick Reference

// Pattern: Always capture + fallback + pass through
const capturedLanguage = userNativeLanguage || "English";
const effectiveLanguage = params.userLanguage || capturedLanguage;

// In prompts: Variable, not hardcoded
const feedbackLang = userLanguage || "German";
prompt = `"explanation": "... in ${feedbackLang}"`;

Summary

Before every AI-related change, ask:

  1. Does preferredLanguage flow from API route to this code?
  2. Is there a fallback if language is missing?
  3. Are prompts using variables, not hardcoded languages?
  4. Is language passed to ALL nested calls (agents, RAG, etc.)?

If any answer is NO → fix before committing.