11import type { SessionState , WithParts } from "../../state"
22import type { Logger } from "../../logger"
33import type { PluginConfig } from "../../config"
4- import { formatMessageIdMarker } from "../../message-ids"
4+ import { formatMessageIdMarker , formatMessageIdTag } from "../../message-ids"
55import { createSyntheticTextPart , createSyntheticToolPart , isIgnoredUserMessage } from "../utils"
66import {
77 addAnchor ,
@@ -16,6 +16,35 @@ import {
1616import { renderNudge } from "../../prompts"
1717
1818const CONTEXT_LIMIT_HINT_TEXT = renderNudge ( "context-limit" )
19+ type MessagePart = WithParts [ "parts" ] [ number ]
20+ type ToolPart = Extract < MessagePart , { type : "tool" } >
21+
22+ const appendMessageIdTagToToolOutput = ( part : ToolPart , tag : string ) : boolean => {
23+ if ( part . type !== "tool" ) {
24+ return false
25+ }
26+ if ( part . state ?. status !== "completed" || typeof part . state . output !== "string" ) {
27+ return false
28+ }
29+ if ( part . state . output . includes ( tag ) ) {
30+ return true
31+ }
32+
33+ const separator = part . state . output . length > 0 && ! part . state . output . endsWith ( "\n" ) ? "\n" : ""
34+ part . state . output = `${ part . state . output } ${ separator } ${ tag } `
35+ return true
36+ }
37+
38+ const findLastToolPart = ( message : WithParts ) : ToolPart | null => {
39+ for ( let i = message . parts . length - 1 ; i >= 0 ; i -- ) {
40+ const part = message . parts [ i ]
41+ if ( part . type === "tool" ) {
42+ return part
43+ }
44+ }
45+
46+ return null
47+ }
1948
2049export const insertCompressToolContext = (
2150 state : SessionState ,
@@ -74,6 +103,7 @@ export const insertMessageIdContext = (state: SessionState, messages: WithParts[
74103 }
75104
76105 const marker = formatMessageIdMarker ( messageRef )
106+ const tag = formatMessageIdTag ( messageRef )
77107
78108 if ( message . info . role === "user" ) {
79109 const hasMarker = message . parts . some (
@@ -89,21 +119,11 @@ export const insertMessageIdContext = (state: SessionState, messages: WithParts[
89119 continue
90120 }
91121
92- const hasMarker = message . parts . some ( ( part ) => {
93- if ( part . type !== "tool" ) {
94- return false
95- }
96- if ( part . tool !== "context_info" ) {
97- return false
98- }
99- return (
100- part . state ?. status === "completed" &&
101- typeof part . state . output === "string" &&
102- part . state . output . trim ( ) === marker
103- )
104- } )
105- if ( ! hasMarker ) {
106- message . parts . push ( createSyntheticToolPart ( message , marker , toolModelId ) )
122+ const lastToolPart = findLastToolPart ( message )
123+ if ( lastToolPart && appendMessageIdTagToToolOutput ( lastToolPart , tag ) ) {
124+ continue
107125 }
126+
127+ message . parts . push ( createSyntheticToolPart ( message , marker , toolModelId ) )
108128 }
109129}
0 commit comments