MCPcopy
hub / github.com/opentrace/opentrace / LlmStrategy

Class LlmStrategy

ui/src/runner/browser/enricher/summarizer/strategy.ts:160–234  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

158const LLM_BATCH_CONCURRENCY = 4;
159
160class LlmStrategy implements SummarizationStrategy {
161 readonly type = 'llm' as const;
162 private url: string;
163 private model: string;
164
165 constructor(config: SummarizerConfig) {
166 this.url =
167 config.llmUrl ??
168 `${window.location.protocol}//${window.location.hostname}:11434`;
169 this.model = config.llmModel ?? 'llama3.2';
170 }
171
172 async init(): Promise<void> {}
173
174 private buildPrompt(meta: SymbolMetadata): string {
175 const source = meta.source ?? meta.name;
176 switch (meta.kind) {
177 case 'function':
178 return `Summarize what this function does in one sentence:\n\n${source}`;
179 case 'class':
180 return `Summarize what this class does in one sentence:\n\n${source}`;
181 case 'file':
182 return `Summarize what this source file does in one sentence:\n\n${source}`;
183 case 'directory':
184 return `Describe the purpose of this directory in one sentence:\n\n${source}`;
185 default:
186 return `Summarize this code in one sentence:\n\n${source}`;
187 }
188 }
189
190 async summarize(meta: SymbolMetadata): Promise<string> {
191 const prompt = this.buildPrompt(meta);
192 const json = await withTimeout(
193 fetch(`${this.url}/v1/chat/completions`, {
194 method: 'POST',
195 headers: { 'Content-Type': 'application/json' },
196 body: JSON.stringify({
197 model: this.model,
198 messages: [{ role: 'user', content: prompt }],
199 max_tokens: 100,
200 stream: false,
201 }),
202 }).then(async (r) => {
203 if (!r.ok) throw new Error(`HTTP ${r.status}`);
204 return r.json();
205 }),
206 LLM_CALL_TIMEOUT_MS,
207 `LLM summarize(${meta.name})`,
208 );
209 return (json.choices?.[0]?.message?.content ?? '').trim();
210 }
211
212 async summarizeBatch(items: SymbolMetadata[]): Promise<string[]> {
213 // Bounded concurrency: an unbounded Promise.all fires one request per
214 // symbol at once, flooding the local LLM server and triggering spurious
215 // per-call timeouts under load. A failed summary is best-effort → ''.
216 const results: string[] = new Array(items.length).fill('');
217 let cursor = 0;

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected