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:
@@ -117,6 +117,50 @@ export class SessionBridge {
|
||||
return this.clients.size;
|
||||
}
|
||||
|
||||
/** Get usage stats for a specific connection's agent. */
|
||||
getUsage(connectionId: string): { inputTokens: number; outputTokens: number; calls: number } | undefined {
|
||||
const agent = this.clients.get(connectionId)?.agent;
|
||||
return agent?.getUsage();
|
||||
}
|
||||
|
||||
/** Get usage stats for all active sessions. Returns an array of per-session usage entries. */
|
||||
getAllUsage(): Array<{
|
||||
sessionId: string;
|
||||
primary: { inputTokens: number; outputTokens: number; calls: number };
|
||||
delegation: Record<string, { inputTokens: number; outputTokens: number; calls: number }>;
|
||||
total: { inputTokens: number; outputTokens: number; calls: number; estimatedCost: number };
|
||||
}> {
|
||||
const results: Array<{
|
||||
sessionId: string;
|
||||
primary: { inputTokens: number; outputTokens: number; calls: number };
|
||||
delegation: Record<string, { inputTokens: number; outputTokens: number; calls: number }>;
|
||||
total: { inputTokens: number; outputTokens: number; calls: number; estimatedCost: number };
|
||||
}> = [];
|
||||
|
||||
// De-duplicate by sessionId (multiple connections may share a session)
|
||||
const seen = new Set<string>();
|
||||
|
||||
for (const client of this.clients.values()) {
|
||||
if (seen.has(client.sessionId)) continue;
|
||||
seen.add(client.sessionId);
|
||||
|
||||
const usage = client.agent.getUsage();
|
||||
results.push({
|
||||
sessionId: client.sessionId,
|
||||
primary: { inputTokens: usage.inputTokens, outputTokens: usage.outputTokens, calls: usage.calls },
|
||||
delegation: {} as Record<string, { inputTokens: number; outputTokens: number; calls: number }>,
|
||||
total: {
|
||||
inputTokens: usage.inputTokens,
|
||||
outputTokens: usage.outputTokens,
|
||||
calls: usage.calls,
|
||||
estimatedCost: 0, // NativeAgent doesn't track cost; only AgentOrchestrator does
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private getOrCreateAgent(sessionId: string): NativeAgent {
|
||||
let agent = this.agents.get(sessionId);
|
||||
if (!agent) {
|
||||
|
||||
Reference in New Issue
Block a user