feat: implement Tier 3 features — lane queue, credential redaction, token dashboard, xAI, Voyage AI

- Lane Queue: per-session FIFO queue in gateway replacing reject-when-busy (9 tests)
- Credential Redaction: redactConfig() expanded to cover 18+ secret fields (16 tests)
- Web UI Token Dashboard: system.tokenUsage endpoint + Usage page with summary cards
- xAI (Grok) Provider: OpenAI-compatible client with model pricing
- Voyage AI Embeddings: new embedding provider with configurable dimensions (5 tests)
- Update gap analysis: 90→95 match (70%→74%), Tier 3 section marked DONE
- Update state.json: test count 1001→1034, add tier3_completion entry

Total: 1034 tests passing across 85 files, typecheck clean
This commit is contained in:
William Valentin
2026-02-09 10:32:57 -08:00
parent 1d126cddfb
commit 9be8f76bc7
26 changed files with 1395 additions and 105 deletions
+8
View File
@@ -5,6 +5,7 @@ import { Router } from './router.js';
import { serveStatic } from './static.js';
import { SessionBridge } from './session-bridge.js';
import type { SessionBridgeConfig } from './session-bridge.js';
import { LaneQueue } from './lane-queue.js';
import { authenticateRequest } from './auth.js';
import type { AuthConfig } from './auth.js';
import {
@@ -20,6 +21,7 @@ import {
createAgentHandlers,
createConfigHandlers,
} from './handlers/index.js';
import type { TokenUsageEntry } from './handlers/system.js';
import type { SessionManager } from '../session/manager.js';
import type { Config } from '../config/index.js';
import type { ToolRegistry } from '../tools/registry.js';
@@ -48,6 +50,8 @@ export interface GatewayServerConfig {
webhookHandler?: WebhookHandler;
/** Optional Gmail handler for Pub/Sub push notifications. */
gmailHandler?: GmailWatcher;
/** Optional callback to retrieve per-session token usage data for the dashboard. */
getTokenUsage?: () => TokenUsageEntry[];
}
export class GatewayServer {
@@ -55,6 +59,7 @@ export class GatewayServer {
private httpServer: HttpServer | null = null;
private router: Router;
private sessionBridge: SessionBridge;
private laneQueue: LaneQueue;
private connectionMap: Map<WebSocket, string> = new Map();
private config: GatewayServerConfig;
private startTime: number = Date.now();
@@ -70,6 +75,7 @@ export class GatewayServer {
toolExecutor: config.toolExecutor,
});
this.laneQueue = new LaneQueue();
this.router = new Router();
this.registerHandlers();
}
@@ -89,6 +95,7 @@ export class GatewayServer {
totalSessions: this.config.sessionManager.listSessions().length,
activeConnections: this.sessionBridge.connectionCount,
}),
getTokenUsage: this.config.getTokenUsage,
});
const sessionHandlers = createSessionHandlers({
@@ -103,6 +110,7 @@ export class GatewayServer {
const agentHandlers = createAgentHandlers({
sessionBridge: this.sessionBridge,
laneQueue: this.laneQueue,
});
// Config handlers (only if config object is provided)