Files
openchamber/packages/ui/src/stores/utils/tokenUtils.ts
T
Bohdan Triapitsyn f2507d58cf feat: migrate to OpenCode SDK v2
Update all import statements to use @opencode-ai/sdk/v2
Modify Vite configurations to alias new SDK path
Update API client method signatures for SDK v2 compatibility
2026-01-03 13:39:59 +02:00

52 lines
1.6 KiB
TypeScript

import type { Message, Part } from "@opencode-ai/sdk/v2";
type TokenBreakdown = {
input?: number;
output?: number;
reasoning?: number;
cache?: {
read?: number;
write?: number;
};
};
const sumTokenBreakdown = (breakdown: TokenBreakdown | null | undefined): number => {
if (!breakdown || typeof breakdown !== 'object') {
return 0;
}
const inputTokens = breakdown.input ?? 0;
const outputTokens = breakdown.output ?? 0;
const reasoningTokens = breakdown.reasoning ?? 0;
const cacheReadTokens = breakdown.cache && typeof breakdown.cache === 'object' ? breakdown.cache.read ?? 0 : 0;
const cacheWriteTokens = breakdown.cache && typeof breakdown.cache === 'object' ? breakdown.cache.write ?? 0 : 0;
return inputTokens + outputTokens + reasoningTokens + cacheReadTokens + cacheWriteTokens;
};
export const extractTokensFromMessage = (message: { info: Message; parts: Part[] }): number => {
const tokens = (message.info as { tokens?: number | TokenBreakdown }).tokens;
if (typeof tokens === 'number') {
return tokens;
}
if (tokens && typeof tokens === 'object') {
return sumTokenBreakdown(tokens);
}
const tokenPart = message.parts.find(
(part) => typeof (part as { tokens?: number | TokenBreakdown }).tokens !== 'undefined'
) as { tokens?: number | TokenBreakdown } | undefined;
if (!tokenPart || typeof tokenPart.tokens === 'undefined') {
return 0;
}
if (typeof tokenPart.tokens === 'number') {
return tokenPart.tokens;
}
return sumTokenBreakdown(tokenPart.tokens);
};