@@ -2,50 +2,28 @@ import { OperationType, TelemetryToolMetadata, ToolArgs, ToolBase, ToolCategory
2
2
import { z } from "zod" ;
3
3
import { CallToolResult } from "@modelcontextprotocol/sdk/types.js" ;
4
4
import { EJSON } from "bson" ;
5
-
6
- const PLAYGROUND_SEARCH_URL = "https://search-playground.mongodb.com/api/tools/code-playground/search" ;
7
-
8
- const DEFAULT_DOCUMENTS = [
9
- {
10
- name : "First document" ,
11
- } ,
12
- {
13
- name : "Second document" ,
14
- } ,
15
- ] ;
5
+ import {
6
+ PlaygroundRunError ,
7
+ PlaygroundRunRequest ,
8
+ PlaygroundRunResponse ,
9
+ } from "../../common/playground/playgroundClient.js" ;
16
10
17
11
const DEFAULT_SEARCH_INDEX_DEFINITION = {
18
12
mappings : {
19
13
dynamic : true ,
20
14
} ,
21
15
} ;
22
16
23
- const DEFAULT_PIPELINE = [
24
- {
25
- $search : {
26
- index : "default" ,
27
- text : {
28
- query : "first" ,
29
- path : {
30
- wildcard : "*" ,
31
- } ,
32
- } ,
33
- } ,
34
- } ,
35
- ] ;
36
-
37
17
const DEFAULT_SYNONYMS : Array < Record < string , unknown > > = [ ] ;
38
18
39
19
export const RunPipelineOperationArgs = {
40
20
documents : z
41
21
. array ( z . record ( z . string ( ) , z . unknown ( ) ) )
42
22
. max ( 500 )
43
- . describe ( "Documents to run the pipeline against. 500 is maxim
10000
um." )
44
- . default ( DEFAULT_DOCUMENTS ) ,
23
+ . describe ( "Documents to run the pipeline against. 500 is maximum." ) ,
45
24
aggregationPipeline : z
46
25
. array ( z . record ( z . string ( ) , z . unknown ( ) ) )
47
- . describe ( "MongoDB aggregation pipeline to run on the provided documents." )
48
- . default ( DEFAULT_PIPELINE ) ,
26
+ . describe ( "MongoDB aggregation pipeline to run on the provided documents." ) ,
49
27
searchIndexDefinition : z
50
28
. record ( z . string ( ) , z . unknown ( ) )
51
29
. describe ( "MongoDB search index definition to create before running the pipeline." )
@@ -58,22 +36,6 @@ export const RunPipelineOperationArgs = {
58
36
. default ( DEFAULT_SYNONYMS ) ,
59
37
} ;
60
38
61
- interface RunRequest {
62
- documents : string ;
63
- aggregationPipeline : string ;
64
- indexDefinition : string ;
65
- synonyms : string ;
66
- }
67
-
68
- interface RunResponse {
69
- documents : Array < Record < string , unknown > > ;
70
- }
71
-
72
- interface RunErrorResponse {
73
- code : string ;
74
- message : string ;
75
- }
76
-
77
39
export class RunPipeline extends ToolBase {
78
40
protected name = "run-pipeline" ;
79
41
protected description =
@@ -93,47 +55,24 @@ export class RunPipeline extends ToolBase {
93
55
return { } ;
94
56
}
95
57
96
- private async runPipeline ( runRequest : RunRequest ) : Promise < RunResponse > {
97
- const options : RequestInit = {
98
- method : "POST" ,
99
- headers : {
100
- "Content-Type" : "application/json" ,
101
- } ,
102
- body : JSON . stringify ( runRequest ) ,
103
- } ;
104
-
105
- let response : Response ;
58
+ private async runPipeline ( runRequest : PlaygroundRunRequest ) : Promise < PlaygroundRunResponse > {
59
+ // import PlaygroundClient dynamically so we can mock it properly in the tests
60
+ const { PlaygroundClient } = await import ( "../../common/playground/playgroundClient.js" ) ;
61
+ const client = new PlaygroundClient ( ) ;
106
62
try {
107
- response = await fetch ( PLAYGROUND_SEARCH_URL , options ) ;
108
- } catch {
109
- throw new Error ( "Cannot run pipeline: network error." ) ;
110
- }
63
+ return await client . run ( runRequest ) ;
64
+ } catch ( error : unknown ) {
65
+ let message : string | undefined ;
111
66
112
- if ( ! response . ok ) {
113
- const errorMessage = await this . getPlaygroundResponseError ( response ) ;
114
- throw new Error ( `Pipeline run failed: ${ errorMessage } ` ) ;
115
- }
67
+ if ( error instanceof PlaygroundRunError ) {
68
+ message = `Error code: ${ error . code } . Error message: ${ error . message } .` ;
69
+ }
116
70
117
- try {
118
- return ( await response . json ( ) ) as RunResponse ;
119
- } catch {
120
- throw new Error ( "Pipeline run failed: response is not valid JSON." ) ;
71
+ throw new Error ( message || "Cannot run pipeline." ) ;
121
72
}
122
73
}
123
74
124
- private async getPlaygroundResponseError ( response : Response ) : Promise < string > {
125
- let errorMessage = `HTTP ${ response . status } ${ response . statusText } .` ;
126
- try {
127
- const errorResponse = ( await response . json ( ) ) as RunErrorResponse ;
128
- errorMessage += ` Error code: ${ errorResponse . code } . Error message: ${ errorResponse . message } ` ;
129
- } catch {
130
- // Ignore JSON parse errors
131
- }
132
-
133
- return errorMessage ;
134
- }
135
-
136
- private convertToRunRequest ( toolArgs : ToolArgs < typeof this . argsShape > ) : RunRequest {
75
+ private convertToRunRequest ( toolArgs : ToolArgs < typeof this . argsShape > ) : PlaygroundRunRequest {
137
76
try {
138
77
return {
139
78
documents : JSON . stringify ( toolArgs . documents ) ,
@@ -146,7 +85,7 @@ export class RunPipeline extends ToolBase {
146
85
}
147
86
}
148
87
149
- private convertToToolResult ( runResponse : RunResponse ) : CallToolResult {
88
+ private convertToToolResult ( runResponse : PlaygroundRunResponse ) : CallToolResult {
150
89
const content : Array < { text : string ; type : "text" } > = [
151
90
{
152
91
text : `Found ${ runResponse . documents . length } documents":` ,
0 commit comments