chore: migrate AI LLM router from 9router to omniroute

Switch GMW's AI LLM base URL from 9router (https://9router.asepharyana.my.id/v1)
to omniroute on imrnes (http://100.121.180.82:20128/api/v1).

- Update default AI_LLM_BASE_URL in discord-gateway + backend config schemas
- Update .env.example documentation
- Update all 9router references in comments/docs/tests to omniroute
- Production BWS secret gmw_ai_llm_base_url already updated

Omniroute uses /api/v1 prefix (not /v1 like 9router), so the base URL
now correctly points at the right API path for the OpenAI SDK.
This commit is contained in:
asepharyana
2026-08-28 20:18:48 +07:00
parent 14bd20f072
commit ffbe9959ab
9 changed files with 16 additions and 16 deletions
@@ -1,7 +1,7 @@
// ═══════════════════════════════════════════════════════════════════════════
// llmClient chunk extraction — reasoning_content fallback (pure, no network)
// ═══════════════════════════════════════════════════════════════════════════
// Regression: 9router "multimodal" combo routed to cloudflare gemma-4-26b
// Regression: omniroute "multimodal" combo routed to cloudflare gemma-4-26b
// which streams ALL output in delta.reasoning_content with content:"" — the
// old extractor returned empty text → llmVision reported "Vision API null
// response" → every image moderation batch fell back to text-only analysis
@@ -19,7 +19,7 @@ describe("extractChunkText — streaming chunk text extraction", () => {
});
it("falls back to delta.reasoning_content when content is empty — reasoning-only models (cloudflare gemma)", () => {
// Exact shape seen from 9router → cloudflare-ai/@cf/google/gemma-4-26b:
// Exact shape seen from omniroute → cloudflare-ai/@cf/google/gemma-4-26b:
// {"choices":[{"delta":{"content":"","reasoning_content":"Task","role":"assistant"},"finish_reason":null,...}]}
expect(
extractChunkText({
@@ -33,8 +33,8 @@ describe("extractChunkText — streaming chunk text extraction", () => {
).toBe("Task");
});
it('falls back to delta.reasoning — mimo via 9router streams reasoning there with content:""', () => {
// Exact shape seen from 9router → mimo-v2.5-free (2026-08-11):
it('falls back to delta.reasoning — mimo via omniroute streams reasoning there with content:""', () => {
// Exact shape seen from omniroute → mimo-v2.5-free (2026-08-11):
// {"choices":[{"delta":{"content":"","reasoning":"The user wants a","role":"assistant"},"finish_reason":null,...}]}
expect(
extractChunkText({
@@ -6,7 +6,7 @@
// a VALID vision_llm result. Every later analysis of the same image (same
// hash / phash) then hit the poisoned cache and the moderation LLM wrote
// "lampiran yang gagal terbaca" — image analysis seemed permanently broken
// even though 9router was responding fine.
// even though omniroute was responding fine.
import { describe, expect, it } from "vitest";
import { isNoImageSeenText } from "../src/modules/ai-moderation/visionAnalyzer.js";