3
3
canTalkToDb ,
4
4
} from "../context" ;
5
5
import { buildPrompt , Db2ContextItems } from "../prompt" ;
6
+ import { registerSqlRunTool , RUN_SQL_TOOL_ID } from "./sqlTool" ;
6
7
7
8
const CHAT_ID = `vscode-db2i.chat` ;
8
9
@@ -56,7 +57,7 @@ export function activateChat(context: vscode.ExtensionContext) {
56
57
stream . progress ( `Building response...` ) ;
57
58
58
59
// get history
59
- let history : Db2ContextItems [ ] | undefined ;
60
+ let history : Db2ContextItems [ ] | undefined ;
60
61
if ( context . history . length > 0 ) {
61
62
history = context . history . map ( ( h ) => {
62
63
if ( "prompt" in h ) {
@@ -86,21 +87,49 @@ export function activateChat(context: vscode.ExtensionContext) {
86
87
progress : stream . progress
87
88
} ) ;
88
89
89
- const messages = contextItems . context . map ( c => {
90
+ let messages = contextItems . context . map ( c => {
90
91
if ( c . type === `user` ) {
91
92
return vscode . LanguageModelChatMessage . User ( c . content ) ;
92
93
} else {
93
94
return vscode . LanguageModelChatMessage . Assistant ( c . content ) ;
94
95
}
95
96
} ) ;
96
97
97
- const result = await copilotRequest (
98
- request . model . family ,
99
- messages ,
100
- { } ,
101
- token ,
102
- stream
103
- ) ;
98
+ const tools = vscode . lm . tools . filter ( t => request . toolReferences . some ( r => r . name === t . name ) ) ;
99
+
100
+ const doRequest = ( tools : vscode . LanguageModelToolInformation [ ] = [ ] ) => {
101
+ return copilotRequest (
102
+ request . model . family ,
103
+ messages ,
104
+ {
105
+ tools,
106
+ toolMode : vscode . LanguageModelChatToolMode . Required
107
+ } ,
108
+ token ,
109
+ stream
110
+ ) ;
111
+ }
112
+
113
+ let result = await doRequest ( tools ) ;
114
+
115
+ if ( result . toolCalls . length > 0 ) {
116
+ for ( const toolcall of result . toolCalls ) {
117
+ if ( toolcall . name === RUN_SQL_TOOL_ID ) {
118
+ const result = await vscode . lm . invokeTool ( toolcall . name , { toolInvocationToken : request . toolInvocationToken , input : toolcall . input } ) ;
119
+ const resultOut = result . content . map ( c => {
120
+ if ( c instanceof vscode . LanguageModelTextPart ) {
121
+ return c . value ;
122
+ }
123
+ } ) . filter ( c => c !== undefined ) . join ( "\n\n" ) ;
124
+
125
+ messages = [
126
+ vscode . LanguageModelChatMessage . User ( `Please review and summarize the following result set:\n\n${ resultOut } \n\nThe original user request was: ${ request } ` )
127
+ ] ;
128
+ }
129
+ }
130
+
131
+ result = await doRequest ( ) ;
132
+ }
104
133
105
134
return { metadata : { command : "build" , followUps : contextItems . followUps , statement : result . sqlCodeBlock } } ;
106
135
}
@@ -131,10 +160,12 @@ export function activateChat(context: vscode.ExtensionContext) {
131
160
}
132
161
133
162
context . subscriptions . push ( chat ) ;
163
+ registerSqlRunTool ( context ) ;
134
164
}
135
165
136
166
interface Result {
137
167
output : string ;
168
+ toolCalls : vscode . LanguageModelToolCallPart [ ] ;
138
169
sqlCodeBlock ?: string ;
139
170
}
140
171
@@ -144,18 +175,25 @@ async function copilotRequest(
144
175
options : vscode . LanguageModelChatRequestOptions ,
145
176
token : vscode . CancellationToken ,
146
177
stream : vscode . ChatResponseStream
147
- ) : Promise < Result | undefined > {
178
+ ) : Promise < Result | undefined > {
148
179
const models = await vscode . lm . selectChatModels ( { family : model } ) ;
149
180
if ( models . length > 0 ) {
150
181
const [ first ] = models ;
182
+ options . justification = `Doing cool stuff`
151
183
const response = await first . sendRequest ( messages , options , token ) ;
152
- let result : Result = {
153
- output : "" ,
154
- }
155
184
156
- for await ( const fragment of response . text ) {
157
- stream . markdown ( fragment ) ;
158
- result . output += fragment ;
185
+ const result : Result = {
186
+ output : "" ,
187
+ toolCalls : [ ]
188
+ } ;
189
+
190
+ for await ( const fragment of response . stream ) {
191
+ if ( fragment instanceof vscode . LanguageModelTextPart ) {
192
+ stream . markdown ( fragment . value ) ;
193
+ result . output += fragment . value ;
194
+ } else if ( fragment instanceof vscode . LanguageModelToolCallPart ) {
195
+ result . toolCalls . push ( fragment ) ;
196
+ }
159
197
}
160
198
161
199
const codeBlockStart = result . output . indexOf ( "```sql" ) ;
0 commit comments