MCPcopy Create free account
hub / github.com/Noumena-Network/code / approximateMessageTokens

Function approximateMessageTokens

src/utils/analyzeContext.ts:854–917  ·  view source on GitHub ↗
(
  messages: Message[],
)

Source from the content-addressed store, hash-verified

852}
853
854async function approximateMessageTokens(
855 messages: Message[],
856): Promise<MessageBreakdown> {
857 const microcompactResult = await microcompactMessages(messages)
858
859 // Initialize tracking
860 const breakdown: MessageBreakdown = {
861 totalTokens: 0,
862 toolCallTokens: 0,
863 toolResultTokens: 0,
864 attachmentTokens: 0,
865 assistantMessageTokens: 0,
866 userMessageTokens: 0,
867 toolCallsByType: new Map<string, number>(),
868 toolResultsByType: new Map<string, number>(),
869 attachmentsByType: new Map<string, number>(),
870 }
871
872 // Build a map of tool_use_id to tool_name for easier lookup
873 const toolUseIdToName = new Map<string, string>()
874 for (const msg of microcompactResult.messages) {
875 if (msg.type === 'assistant') {
876 for (const block of msg.message.content) {
877 if ('type' in block && block.type === 'tool_use') {
878 const toolUseId = 'id' in block ? block.id : undefined
879 const toolName =
880 ('name' in block ? block.name : undefined) || 'unknown'
881 if (toolUseId) {
882 toolUseIdToName.set(toolUseId, toolName)
883 }
884 }
885 }
886 }
887 }
888
889 // Process each message for detailed breakdown
890 for (const msg of microcompactResult.messages) {
891 if (msg.type === 'assistant') {
892 processAssistantMessage(msg, breakdown)
893 } else if (msg.type === 'user') {
894 processUserMessage(msg, breakdown, toolUseIdToName)
895 } else if (msg.type === 'attachment') {
896 processAttachment(msg, breakdown)
897 }
898 }
899
900 // Calculate total tokens using the API for accuracy
901 const approximateMessageTokens = await countTokensWithFallback(
902 normalizeMessagesForAPI(microcompactResult.messages).map(_ => {
903 if (_.type === 'assistant') {
904 return {
905 // Important: strip out fields like id, etc. -- the counting API errors if they're present
906 role: 'assistant',
907 content: _.message.content,
908 }
909 }
910 return _.message
911 }),

Callers 1

analyzeContextUsageFunction · 0.85

Calls 7

microcompactMessagesFunction · 0.85
processAssistantMessageFunction · 0.85
processUserMessageFunction · 0.85
processAttachmentFunction · 0.85
countTokensWithFallbackFunction · 0.85
normalizeMessagesForAPIFunction · 0.85
setMethod · 0.80

Tested by

no test coverage detected