@@ -3,6 +3,7 @@ import { isMessageCompacted } from "../shared-utils"
33import { Logger } from "../logger"
44import type { SessionState , WithParts } from "../state"
55import type { UserMessage } from "@opencode-ai/sdk/v2"
6+ import { countToolTokens } from "../strategies/utils"
67
78export const COMPRESS_SUMMARY_PREFIX = "[Compressed conversation block]\n\n"
89
@@ -267,3 +268,26 @@ export const isIgnoredUserMessage = (message: WithParts): boolean => {
267268export const findMessageIndex = ( messages : WithParts [ ] , messageId : string ) : number => {
268269 return messages . findIndex ( ( msg ) => msg . info . id === messageId )
269270}
271+
272+ function formatTokenCount ( n : number ) : string {
273+ if ( n >= 1000 ) return `${ ( n / 1000 ) . toFixed ( 1 ) } k tokens`
274+ return `${ n } tokens`
275+ }
276+
277+ export function annotateContext ( messages : WithParts [ ] ) : void {
278+ for ( const msg of messages ) {
279+ const parts = Array . isArray ( msg . parts ) ? msg . parts : [ ]
280+ for ( const part of parts ) {
281+ if ( part . type !== "tool" ) continue
282+ const tokens = countToolTokens ( part )
283+ if ( tokens <= 0 ) continue
284+ const tag = `[${ formatTokenCount ( tokens ) } ]`
285+ if ( part . state ?. status === "completed" && typeof part . state . output === "string" ) {
286+ part . state . output = `${ tag } \n${ part . state . output } `
287+ }
288+ if ( part . state ?. status === "error" && typeof part . state . error === "string" ) {
289+ part . state . error = `${ tag } \n${ part . state . error } `
290+ }
291+ }
292+ }
293+ }
0 commit comments