@@ -11,6 +11,7 @@ export const marked = (() => {
11
11
}
12
12
} )
13
13
)
14
+ ret . use ( { extensions :[ thinkTag ( ) ] } )
14
15
//ret.use({ extensions: [divExtension()] })
15
16
return ret
16
17
} ) ( ) ;
@@ -105,4 +106,75 @@ function escape(html, encode) {
105
106
}
106
107
107
108
return html
108
- }
109
+ }
110
+
111
+ /**
112
+ * Marked.js extension for rendering <think> tags as expandable, scrollable components
113
+ * using Tailwind CSS
114
+ */
115
+
116
+ // Extension for Marked.js to handle <think> tags
117
+ function thinkTag ( ) {
118
+ globalThis . toggleThink = toggleThink
119
+ return ( {
120
+ name : 'thinkTag' ,
121
+ level : 'block' ,
122
+ start ( src ) {
123
+ return src . match ( / ^ < t h i n k > / ) ?. index ;
124
+ } ,
125
+ tokenizer ( src ) {
126
+ const rule = / ^ < t h i n k > ( [ \s \S ] * ?) < \/ t h i n k > /
127
+ const match = rule . exec ( src )
128
+ if ( match ) {
129
+ return {
130
+ type : 'thinkTag' ,
131
+ raw : match [ 0 ] ,
132
+ content : match [ 1 ] . trim ( ) ,
133
+ }
134
+ }
135
+ return undefined
136
+ } ,
137
+ renderer ( token ) {
138
+ // Parse the markdown content inside the think tag
139
+ const parsedContent = marked . parse ( token . content )
140
+
141
+ // Generate a unique ID for this think component
142
+ const uniqueId = 'think-' + Math . random ( ) . toString ( 36 ) . substring ( 2 , 10 )
143
+
144
+ // Create the expandable, scrollable component with Tailwind CSS
145
+ return `
146
+ <div class="my-4 border border-gray-200 rounded-lg shadow-sm">
147
+ <button
148
+ id="${ uniqueId } -toggle"
149
+ class="flex justify-between items-center w-full py-2 px-4 text-left text-gray-700 font-medium hover:bg-gray-50 focus:outline-none"
150
+ onclick="toggleThink('${ uniqueId } ')">
151
+ <span>Thinking</span>
152
+ <svg id="${ uniqueId } -icon" class="h-5 w-5 text-gray-500 transform transition-transform" fill="none" viewBox="0 0 24 24" stroke="currentColor">
153
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
154
+ </svg>
155
+ </button>
156
+ <div
157
+ id="${ uniqueId } -content"
158
+ class="hidden overflow-auto max-h-64 px-4 border-t border-gray-200 bg-gray-50"
159
+ style="max-height:16rem;">
160
+ ${ parsedContent }
161
+ </div>
162
+ </div>
163
+ `
164
+ }
165
+ } )
166
+ }
167
+
168
+ // JavaScript function to toggle the visibility of the think content
169
+ function toggleThink ( id ) {
170
+ const content = document . getElementById ( `${ id } -content` )
171
+ const icon = document . getElementById ( `${ id } -icon` )
172
+
173
+ if ( content . classList . contains ( 'hidden' ) ) {
174
+ content . classList . remove ( 'hidden' )
175
+ icon . classList . add ( 'rotate-180' )
176
+ } else {
177
+ content . classList . add ( 'hidden' )
178
+ icon . classList . remove ( 'rotate-180' )
179
+ }
180
+ }
0 commit comments