MCPcopy Create free account
hub / github.com/microsoft/data-formulator / streamIdeas

Function streamIdeas

src/app/useFormulateData.ts:224–329  ·  view source on GitHub ↗

* Stream ideas/recommendations from the exploration agent via SSE.

(options: StreamIdeasOptions)

Source from the content-addressed store, hash-verified

222 * Stream ideas/recommendations from the exploration agent via SSE.
223 */
224 async function streamIdeas(options: StreamIdeasOptions): Promise<void> {
225 const {
226 actionTableIds, currentTable,
227 onIdeas, onThinkingBuffer, onLoadingChange, onProgress,
228 currentChartImage, currentDataSample,
229 startQuestion,
230 } = options;
231
232 onLoadingChange(true);
233 onThinkingBuffer("");
234 onIdeas([]);
235
236 let timeoutId: ReturnType<typeof setTimeout> | undefined;
237 let timedOut = false;
238 try {
239 const focusedThread = buildFocusedThread(currentTable);
240 const otherThreads = buildOtherThreads(currentTable);
241 const actionTables = actionTableIds.map(id => tables.find(t => t.id === id) as DictTable);
242
243 const messageBody = JSON.stringify({
244 model: activeModel,
245 input_tables: actionTables.map(t => ({
246 name: t.virtual?.tableId || t.id.replace(/\.[^/.]+$/, ""),
247 })),
248 primary_tables: (() => {
249 if (currentTable.derive && !currentTable.anchored) {
250 return (currentTable.derive.source as string[]).map(id => {
251 const t = tables.find(tbl => tbl.id === id);
252 return t?.virtual?.tableId || id.replace(/\.[^/.]+$/, "");
253 });
254 }
255 return [currentTable.virtual?.tableId || currentTable.id.replace(/\.[^/.]+$/, "")];
256 })(),
257 ...(focusedThread.length > 0 ? { focused_thread: focusedThread } : {}),
258 ...(otherThreads.length > 0 ? { other_threads: otherThreads } : {}),
259 ...(currentChartImage ? { current_chart: currentChartImage } : {}),
260 ...(startQuestion ? { start_question: startQuestion } : {}),
261 });
262
263 const engine = getUrls().GET_RECOMMENDATION_QUESTIONS;
264 const controller = new AbortController();
265 timeoutId = setTimeout(() => { timedOut = true; controller.abort(); }, config.formulateTimeoutSeconds * 1000);
266
267 const questions: IdeaItem[] = [];
268 for await (const event of streamRequest(engine, {
269 method: 'POST',
270 headers: { 'Content-Type': 'application/json' },
271 body: messageBody,
272 }, controller.signal)) {
273 if (event.type === 'error') {
274 throw new Error(event.error ? getErrorMessage(event.error) : t('messages.error'));
275 }
276 if (event.type === 'warning') {
277 dispatch(dfActions.addMessages({
278 timestamp: Date.now(), type: 'warning',
279 component: 'exploration',
280 value: (event as any).warning?.message ?? 'Warning from server',
281 }));

Callers 1

getIdeasForVisualizationFunction · 0.85

Calls 5

getUrlsFunction · 0.90
streamRequestFunction · 0.90
getErrorMessageFunction · 0.90
buildFocusedThreadFunction · 0.85
buildOtherThreadsFunction · 0.85

Tested by

no test coverage detected