fix: apply code review fixes (fire-and-forget usage, theme-aware chart colors)
This commit is contained in:
1 parent
fd1b2b8bc0
commit
bf4bcf4f96
4 files changed
+30
-29
No files matched your search
@@ -1,15 +1,15 @@
|
|||||||
export const COLOR_PROMPT = '#5b9bd5';
|
export const COLOR_PROMPT = 'var(--chart-2)';
|
||||||
export const COLOR_COMPLETION = '#70ad47';
|
export const COLOR_COMPLETION = 'var(--chart-1)';
|
||||||
export const COLOR_TOTAL = '#a5a5a5';
|
export const COLOR_TOTAL = 'var(--chart-3)';
|
||||||
export const PIE_COLORS = [
|
export const PIE_COLORS = [
|
||||||
'#5b9bd5',
|
'var(--chart-1)',
|
||||||
'#ed7d31',
|
'var(--chart-2)',
|
||||||
'#70ad47',
|
'var(--chart-3)',
|
||||||
'#a5a5a5',
|
'var(--chart-4)',
|
||||||
'#ffc000',
|
'var(--chart-5)',
|
||||||
'#4472c4',
|
'var(--chart-1)',
|
||||||
'#91d1c2',
|
'var(--chart-2)',
|
||||||
'#c55a5a',
|
'var(--chart-3)',
|
||||||
];
|
];
|
||||||
|
|
||||||
const colorMap: Record<string, string> = {
|
const colorMap: Record<string, string> = {
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ function barColor(bar: any): string {
|
|||||||
if (bar.id === 'Prompt') return COLOR_PROMPT;
|
if (bar.id === 'Prompt') return COLOR_PROMPT;
|
||||||
if (bar.id === 'Completion') return COLOR_COMPLETION;
|
if (bar.id === 'Completion') return COLOR_COMPLETION;
|
||||||
if (bar.id === 'Total') return COLOR_TOTAL;
|
if (bar.id === 'Total') return COLOR_TOTAL;
|
||||||
return '#a5a5a5';
|
return 'var(--chart-3)';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ export class ProxyService {
|
|||||||
@Inject(TokenUsageService) private readonly tokenUsageService: TokenUsageService,
|
@Inject(TokenUsageService) private readonly tokenUsageService: TokenUsageService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
private async recordUsage(
|
private recordUsage(
|
||||||
accountId: string,
|
accountId: string,
|
||||||
model: string,
|
model: string,
|
||||||
usage:
|
usage:
|
||||||
@@ -73,11 +73,11 @@ export class ProxyService {
|
|||||||
| null,
|
| null,
|
||||||
requestType: string,
|
requestType: string,
|
||||||
isEstimated?: boolean,
|
isEstimated?: boolean,
|
||||||
): Promise<void> {
|
): void {
|
||||||
if (!usage) {
|
if (!usage) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await this.tokenUsageService.recordUsage({
|
this.tokenUsageService.recordUsage({
|
||||||
accountId,
|
accountId,
|
||||||
model,
|
model,
|
||||||
promptTokens: usage.promptTokenCount ?? 0,
|
promptTokens: usage.promptTokenCount ?? 0,
|
||||||
@@ -358,9 +358,7 @@ export class ProxyService {
|
|||||||
finishChunks.forEach((c) => subscriber.next(c));
|
finishChunks.forEach((c) => subscriber.next(c));
|
||||||
const usage = this.extractUsageFromMetadata(lastUsageMetadata);
|
const usage = this.extractUsageFromMetadata(lastUsageMetadata);
|
||||||
if (usage) {
|
if (usage) {
|
||||||
this.recordUsage(accountId, _model, usage, 'anthropic').catch((err) =>
|
this.recordUsage(accountId, _model, usage, 'anthropic');
|
||||||
this.logger.error('Usage recording failed', err),
|
|
||||||
);
|
|
||||||
} else if (accumulatedText) {
|
} else if (accumulatedText) {
|
||||||
const estimated = this.estimateTokens(accumulatedText);
|
const estimated = this.estimateTokens(accumulatedText);
|
||||||
this.recordUsage(
|
this.recordUsage(
|
||||||
@@ -373,7 +371,7 @@ export class ProxyService {
|
|||||||
},
|
},
|
||||||
'anthropic',
|
'anthropic',
|
||||||
true,
|
true,
|
||||||
).catch((err) => this.logger.error('Usage recording failed', err));
|
);
|
||||||
}
|
}
|
||||||
subscriber.complete();
|
subscriber.complete();
|
||||||
});
|
});
|
||||||
@@ -629,9 +627,7 @@ export class ProxyService {
|
|||||||
}
|
}
|
||||||
const usage = this.extractUsageFromMetadata(lastUsageMetadata);
|
const usage = this.extractUsageFromMetadata(lastUsageMetadata);
|
||||||
if (usage) {
|
if (usage) {
|
||||||
this.recordUsage(accountId, model, usage, 'gemini').catch((err) =>
|
this.recordUsage(accountId, model, usage, 'gemini');
|
||||||
this.logger.error('Usage recording failed', err),
|
|
||||||
);
|
|
||||||
} else if (accumulatedText) {
|
} else if (accumulatedText) {
|
||||||
const estimated = this.estimateTokens(accumulatedText);
|
const estimated = this.estimateTokens(accumulatedText);
|
||||||
this.recordUsage(
|
this.recordUsage(
|
||||||
@@ -644,7 +640,7 @@ export class ProxyService {
|
|||||||
},
|
},
|
||||||
'gemini',
|
'gemini',
|
||||||
true,
|
true,
|
||||||
).catch((err) => this.logger.error('Usage recording failed', err));
|
);
|
||||||
}
|
}
|
||||||
subscriber.complete();
|
subscriber.complete();
|
||||||
});
|
});
|
||||||
@@ -1421,9 +1417,7 @@ export class ProxyService {
|
|||||||
}
|
}
|
||||||
const usage = this.extractUsageFromMetadata(lastUsageMetadata);
|
const usage = this.extractUsageFromMetadata(lastUsageMetadata);
|
||||||
if (usage) {
|
if (usage) {
|
||||||
this.recordUsage(accountId, effectiveTargetModel, usage, 'openai').catch((err) =>
|
this.recordUsage(accountId, effectiveTargetModel, usage, 'openai');
|
||||||
this.logger.error('Usage recording failed', err),
|
|
||||||
);
|
|
||||||
} else if (accumulatedText) {
|
} else if (accumulatedText) {
|
||||||
const estimated = this.estimateTokens(accumulatedText);
|
const estimated = this.estimateTokens(accumulatedText);
|
||||||
this.recordUsage(
|
this.recordUsage(
|
||||||
@@ -1436,7 +1430,7 @@ export class ProxyService {
|
|||||||
},
|
},
|
||||||
'openai',
|
'openai',
|
||||||
true,
|
true,
|
||||||
).catch((err) => this.logger.error('Usage recording failed', err));
|
);
|
||||||
}
|
}
|
||||||
subscriber.complete();
|
subscriber.complete();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -15,9 +15,16 @@ const RecordUsageInputSchema = z.object({
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class TokenUsageService {
|
export class TokenUsageService {
|
||||||
recordUsage(params: RecordUsageParams): boolean {
|
recordUsage(params: RecordUsageParams): void {
|
||||||
RecordUsageInputSchema.parse(params);
|
RecordUsageInputSchema.parse(params);
|
||||||
return TokenUsageRepo.recordUsage(params);
|
// Fire-and-forget: don't block the proxy request cycle
|
||||||
|
setImmediate(() => {
|
||||||
|
try {
|
||||||
|
TokenUsageRepo.recordUsage(params);
|
||||||
|
} catch {
|
||||||
|
// Silently ignore: usage recording should not break proxy requests
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getUsageByHour(accountId?: string, start?: number, end?: number) {
|
getUsageByHour(accountId?: string, start?: number, end?: number) {
|
||||||
|
|||||||
Reference in new issue
Block a user