(signal: AbortSignal)
| 77 | } |
| 78 | |
| 79 | async execute(signal: AbortSignal): Promise<WebSearchToolResult> { |
| 80 | const anusClient = this.config.getAnusClient(); |
| 81 | |
| 82 | try { |
| 83 | const response = await anusClient.generateContent( |
| 84 | [{ role: 'user', parts: [{ text: this.params.query }] }], |
| 85 | { tools: [{ googleSearch: {} }] }, |
| 86 | signal, |
| 87 | ); |
| 88 | |
| 89 | const responseText = getResponseText(response); |
| 90 | const groundingMetadata = response.candidates?.[0]?.groundingMetadata; |
| 91 | const sources = groundingMetadata?.groundingChunks as |
| 92 | | GroundingChunkItem[] |
| 93 | | undefined; |
| 94 | const groundingSupports = groundingMetadata?.groundingSupports as |
| 95 | | GroundingSupportItem[] |
| 96 | | undefined; |
| 97 | |
| 98 | if (!responseText || !responseText.trim()) { |
| 99 | return { |
| 100 | llmContent: `No search results or information found for query: "${this.params.query}"`, |
| 101 | returnDisplay: 'No information found.', |
| 102 | }; |
| 103 | } |
| 104 | |
| 105 | let modifiedResponseText = responseText; |
| 106 | const sourceListFormatted: string[] = []; |
| 107 | |
| 108 | if (sources && sources.length > 0) { |
| 109 | sources.forEach((source: GroundingChunkItem, index: number) => { |
| 110 | const title = source.web?.title || 'Untitled'; |
| 111 | const uri = source.web?.uri || 'No URI'; |
| 112 | sourceListFormatted.push(`[${index + 1}] ${title} (${uri})`); |
| 113 | }); |
| 114 | |
| 115 | if (groundingSupports && groundingSupports.length > 0) { |
| 116 | const insertions: Array<{ index: number; marker: string }> = []; |
| 117 | groundingSupports.forEach((support: GroundingSupportItem) => { |
| 118 | if (support.segment && support.groundingChunkIndices) { |
| 119 | const citationMarker = support.groundingChunkIndices |
| 120 | .map((chunkIndex: number) => `[${chunkIndex + 1}]`) |
| 121 | .join(''); |
| 122 | insertions.push({ |
| 123 | index: support.segment.endIndex, |
| 124 | marker: citationMarker, |
| 125 | }); |
| 126 | } |
| 127 | }); |
| 128 | |
| 129 | // Sort insertions by index in descending order to avoid shifting subsequent indices |
| 130 | insertions.sort((a, b) => b.index - a.index); |
| 131 | |
| 132 | const responseChars = modifiedResponseText.split(''); // Use new variable |
| 133 | insertions.forEach((insertion) => { |
| 134 | responseChars.splice(insertion.index, 0, insertion.marker); |
| 135 | }); |
| 136 | modifiedResponseText = responseChars.join(''); // Assign back to modifiedResponseText |
nothing calls this directly
no test coverage detected