import { dashboardRoutes } from "./routes/dashboard";
import { healthRoutes } from "./routes/health";
import { infoRoutes } from "./routes/info";
-import { proxyRoutes } from "./routes/proxy";
+import { openaiRoutes } from "./routes/openai";
import { getLogger } from "./services/logger";
type Variables = {
app.route("/", healthRoutes);
app.route("/", infoRoutes);
-app.route("/openai/v1", proxyRoutes);
+app.route("/openai/v1", openaiRoutes);
if (config.dashboard.enabled) {
app.route("/dashboard", dashboardRoutes);
import { describe, expect, test } from "bun:test";
import type { MaskingConfig } from "../config";
-import type { ChatMessage } from "../services/llm-client";
+import type { ChatMessage } from "../providers/openai-client";
import { createPIIResult } from "../test-utils/detection-results";
import type { PIIEntity } from "./detect";
import {
import type { MaskingConfig } from "../config";
-import type { ChatCompletionResponse, ChatMessage } from "../services/llm-client";
+import type { ChatCompletionResponse, ChatMessage } from "../providers/openai-client";
import { resolveConflicts } from "../utils/conflict-resolver";
import {
createPlaceholderContext,
import { describe, expect, test } from "bun:test";
import { Hono } from "hono";
-import { proxyRoutes } from "./proxy";
+import { openaiRoutes } from "./openai";
const app = new Hono();
-app.route("/openai/v1", proxyRoutes);
+app.route("/openai/v1", openaiRoutes);
describe("POST /openai/v1/chat/completions", () => {
test("returns 400 for missing messages", async () => {
import { z } from "zod";
import { getConfig, type MaskingConfig } from "../config";
import { unmaskResponse as unmaskPIIResponse } from "../pii/mask";
-import { detectSecretsInMessages, type MessageSecretsResult } from "../secrets/detect";
-import { maskMessages as maskSecretsMessages, unmaskSecretsResponse } from "../secrets/mask";
-import { getRouter, type MaskDecision, type RoutingDecision } from "../services/decision";
import {
type ChatCompletionRequest,
type ChatCompletionResponse,
type ChatMessage,
LLMError,
type LLMResult,
-} from "../services/llm-client";
+} from "../providers/openai-client";
+import { detectSecretsInMessages, type MessageSecretsResult } from "../secrets/detect";
+import { maskMessages as maskSecretsMessages, unmaskSecretsResponse } from "../secrets/mask";
+import { getRouter, type MaskDecision, type RoutingDecision } from "../services/decision";
import { logRequest, type RequestLogData } from "../services/logger";
import { createUnmaskingStream } from "../services/stream-transformer";
import { extractTextContent } from "../utils/content";
})
.passthrough();
-export const proxyRoutes = new Hono();
+export const openaiRoutes = new Hono();
/**
* Type guard for MaskDecision
/**
* POST /v1/chat/completions - OpenAI-compatible chat completion endpoint
*/
-proxyRoutes.post(
+openaiRoutes.post(
"/chat/completions",
zValidator("json", ChatCompletionSchema, (result, c) => {
if (!result.success) {
/**
* Wildcard proxy for /models, /embeddings, /audio/*, /images/*, etc.
*/
-proxyRoutes.all("/*", (c) => {
+openaiRoutes.all("/*", (c) => {
const { openai } = getRouter().getProvidersInfo();
const path = c.req.path.replace(/^\/openai\/v1/, "");
import type { SecretsDetectionConfig } from "../config";
-import type { ChatMessage } from "../services/llm-client";
+import type { ChatMessage } from "../providers/openai-client";
import type { ContentPart } from "../utils/content";
import { patternDetectors } from "./patterns";
import type {
-import type { ChatCompletionResponse, ChatMessage } from "../services/llm-client";
+import type { ChatCompletionResponse, ChatMessage } from "../providers/openai-client";
import { resolveOverlaps } from "../utils/conflict-resolver";
import {
createPlaceholderContext,
import { describe, expect, test } from "bun:test";
import type { PIIDetectionResult, PIIEntity } from "../pii/detect";
import { maskMessages } from "../pii/mask";
-import type { ChatMessage } from "../services/llm-client";
+import type { ChatMessage } from "../providers/openai-client";
import type { ContentPart } from "../utils/content";
/**
import { type Config, getConfig } from "../config";
import { getPIIDetector, type PIIDetectionResult } from "../pii/detect";
import { createMaskingContext, maskMessages } from "../pii/mask";
+import { type ChatMessage, LLMClient } from "../providers/openai-client";
import type { MessageSecretsResult } from "../secrets/detect";
import type { PlaceholderContext } from "../utils/message-transform";
-import { type ChatMessage, LLMClient } from "./llm-client";
/**
* Routing decision result for route mode
import { describe, expect, test } from "bun:test";
-import type { ChatMessage } from "../services/llm-client";
+import type { ChatMessage } from "../providers/openai-client";
import type { Span } from "./conflict-resolver";
import {
createPlaceholderContext,
* This module provides shared infrastructure to avoid duplication.
*/
-import type { ChatMessage } from "../services/llm-client";
+import type { ChatMessage } from "../providers/openai-client";
import type { Span } from "./conflict-resolver";
import type { ContentPart } from "./content";
import { findPartialPlaceholderStart } from "./placeholders";