Skip to content

Commit a46516c

Browse files
authored
Merge pull request #20 from ssdeanx/develop
feat: Refactor tool imports and improve progress logging
2 parents 06e6d40 + 30272c4 commit a46516c

41 files changed

Lines changed: 370 additions & 408 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

lib/client-stream-to-ai-sdk.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ async function* asyncIterableFromReadableStream<T>(
3939
try {
4040
while (true) {
4141
const { done, value } = await reader.read();
42-
if (done) break;
42+
if (done) {break;}
4343
yield value;
4444
}
4545
} finally {
@@ -49,16 +49,16 @@ async function* asyncIterableFromReadableStream<T>(
4949

5050
/**
5151
* Creates a streaming Response for Next.js API routes using server-side Mastra agent.
52-
*
52+
*
5353
* IMPORTANT: This should be used in API 5stra instance,
5454
* not the client SDK. The client SDK (MastraClient) is for frontend use only.
55-
*
55+
*
5656
* @example
5757
* ```ts
5858
* // app/api/chat/route.ts
5959
* import { mastra } from "@/src/mastra";
6060
* import { createAgentStreamResponse } from "@/lib/server/agent-stream";
61-
*
61+
*
6262
* export async function POST(req: Request) {
6363
* const { messages, agentId, threadId, resourceId, memory } = await req.json();
6464
* return createAgentStreamResponse(mastra, agentId, messages, {
@@ -68,7 +68,7 @@ async function* asyncIterableFromReadableStream<T>(
6868
* });
6969
* }
7070
* ```
71-
*
71+
*
7272
* @see https://mastra.ai/docs/frameworks/agentic-uis/ai-sdk
7373
*/
7474
export async function createAgentStreamResponse(
@@ -78,7 +78,7 @@ export async function createAgentStreamResponse(
7878
options?: AgentStreamOptions
7979
): Promise<Response> {
8080
const agent = mastra.getAgent(agentId);
81-
81+
8282
const streamOptions = {
8383
format: options?.format ?? "aisdk",
8484
threadId: options?.threadId,
@@ -100,12 +100,12 @@ export async function createAgentStreamResponse(
100100
const uiMessageStream = createUIMessageStream({
101101
execute: async ({ writer }) => {
102102
const aiSdkResult = toAISdkFormat(stream, { from: "agent" });
103-
103+
104104
// Handle both ReadableStream and AsyncIterable
105105
const iterable: AsyncIterable<unknown> = isReadableStream(aiSdkResult)
106106
? asyncIterableFromReadableStream(aiSdkResult)
107107
: aiSdkResult;
108-
108+
109109
for await (const value of iterable) {
110110
writer.write(value as Parameters<typeof writer.write>[0]);
111111
}
@@ -120,11 +120,11 @@ export async function createAgentStreamResponse(
120120
* This export exists for backward compatibility only.
121121
*/
122122
export async function createMastraStreamResponse(
123-
_client: unknown,
124-
_options: StreamToAISdkOptions
123+
client: unknown,
124+
options: StreamToAISdkOptions
125125
): Promise<Response> {
126126
throw new Error(
127127
"createMastraStreamResponse is deprecated. Use createAgentStreamResponse with " +
128128
"the server-side mastra instance instead. See: https://mastra.ai/docs/frameworks/agentic-uis/ai-sdk"
129129
);
130-
}
130+
}

src/mastra/index.ts

Lines changed: 32 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ import { telephoneGameWorkflow } from './workflows/telephone-game';
8686
import { weatherWorkflow } from './workflows/weather-workflow';
8787
import { repoIngestionWorkflow } from './workflows/repo-ingestion-workflow';
8888
import { specGenerationWorkflow } from './workflows/spec-generation-workflow';
89-
89+
import { ResearchRuntimeContext } from './agents/index';
90+
import { metadata } from '../../app/docs/layout';
9091

9192
export const mastra = new Mastra({
9293
workflows: {
@@ -223,6 +224,36 @@ export const mastra = new Mastra({
223224
},
224225
server: {
225226
apiRoutes: [
227+
workflowRoute({
228+
path: "/workflow/:workflowId",
229+
includeTextStreamParts: true,
230+
}),
231+
networkRoute({
232+
path: "/network/:agentId",
233+
defaultOptions: {
234+
memory: {
235+
thread: {
236+
id: 'network',
237+
resourceId: 'network',
238+
metadata: { agentId: ':agentId' }
239+
},
240+
resource: "network",
241+
options: {
242+
lastMessages: 500,
243+
semanticRecall: true,
244+
workingMemory: { enabled: true },
245+
threads: { generateTitle: true }
246+
}
247+
},
248+
maxSteps: 200,
249+
telemetry: {
250+
isEnabled: true,
251+
recordInputs: true,
252+
recordOutputs: true,
253+
},
254+
includeRawChunks: true,
255+
}
256+
}),
226257
chatRoute({
227258
path: "/chat/:agentId",
228259
defaultOptions: {
@@ -500,97 +531,6 @@ export const mastra = new Mastra({
500531
sendReasoning: true,
501532
sendSources: true,
502533
}),
503-
workflowRoute({
504-
path: "/workflow/:agentId",
505-
workflow: "specGenerationWorkflow",
506-
includeTextStreamParts: true,
507-
}),
508-
workflowRoute({
509-
path: "/workflow/weatherWorkflow",
510-
workflow: "weatherWorkflow",
511-
includeTextStreamParts: true,
512-
}),
513-
workflowRoute({
514-
path: "/workflow/contentStudioWorkflow",
515-
workflow: "contentStudioWorkflow",
516-
includeTextStreamParts: true,
517-
}),
518-
workflowRoute({
519-
path: "/workflow/contentlogWorkflow",
520-
workflow: "changelogWorkflow",
521-
includeTextStreamParts: true,
522-
}),
523-
workflowRoute({
524-
path: "/workflow/contentReviewWorkflow",
525-
workflow: "contentReviewWorkflow",
526-
includeTextStreamParts: true,
527-
}),
528-
workflowRoute({
529-
path: "/workflow/documentProcessingWorkflow",
530-
workflow: "documentProcessingWorkflow",
531-
includeTextStreamParts: true,
532-
}),
533-
workflowRoute({
534-
path: "/workflow/financialReportWorkflow",
535-
workflow: "financialReportWorkflow",
536-
includeTextStreamParts: true,
537-
}),
538-
workflowRoute({
539-
path: "/workflow/learningExtractionWorkflow",
540-
workflow: "learningExtractionWorkflow",
541-
includeTextStreamParts: true,
542-
}),
543-
workflowRoute({
544-
path: "/workflow/researchSynthesisWorkflow",
545-
workflow: "researchSynthesisWorkflow",
546-
includeTextStreamParts: true,
547-
}),
548-
workflowRoute({
549-
path: "/workflow/stockAnalysisWorkflow",
550-
workflow: "stockAnalysisWorkflow",
551-
includeTextStreamParts: true,
552-
}),
553-
workflowRoute({
554-
path: "/workflow/telephoneGameWorkflow",
555-
workflow: "telephoneGameWorkflow",
556-
includeTextStreamParts: true,
557-
}),
558-
workflowRoute({
559-
path: "/workflow/repoIngestionWorkflow",
560-
workflow: "repoIngestionWorkflow",
561-
562-
}),
563-
workflowRoute({
564-
path: "/workflow/specGenerationWorkflow",
565-
workflow: "specGenerationWorkflow",
566-
567-
}),
568-
networkRoute({
569-
path: "/network/:agentId",
570-
defaultOptions: {
571-
memory: {
572-
thread: {
573-
id: 'network',
574-
resourceId: 'network',
575-
},
576-
resource: "network",
577-
options: {
578-
lastMessages: 500,
579-
semanticRecall: true,
580-
workingMemory: { enabled: true },
581-
threads: { generateTitle: true }
582-
}
583-
},
584-
maxSteps: 200,
585-
telemetry: {
586-
isEnabled: true,
587-
recordInputs: true,
588-
recordOutputs: true,
589-
},
590-
includeRawChunks: true,
591-
savePerStep: true,
592-
}
593-
}),
594534
],
595535
// cors: {
596536
// origin: ["*"], // Allow specific origins or '*' for all

src/mastra/tools/alpha-vantage.tool.ts

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { AISpanType, InternalSpans } from "@mastra/core/ai-tracing";
2-
import { InferUITool, createTool } from "@mastra/core/tools";
2+
import type { InferUITool} from "@mastra/core/tools";
3+
import { createTool } from "@mastra/core/tools";
34
import { z } from "zod";
45

56
/**
@@ -63,11 +64,11 @@ export const alphaVantageCryptoTool = createTool({
6364
tracingPolicy: { internal: InternalSpans.TOOL }
6465
});
6566

66-
await writer?.write({ type: 'progress', data: { message: `📈 Fetching Alpha Vantage crypto data for ${context.symbol}/${context.market}` } });
67+
await writer?.custom({ type: 'data-tool-progress', data: { message: `📈 Fetching Alpha Vantage crypto data for ${context.symbol}/${context.market}` } });
6768
const apiKey = process.env.ALPHA_VANTAGE_API_KEY;
6869

6970
if (typeof apiKey !== "string" || apiKey.trim() === '') {
70-
await writer?.write({ type: 'progress', data: { message: '❌ Missing ALPHA_VANTAGE_API_KEY' } });
71+
await writer?.custom({ type: 'data-tool-progress', data: { message: '❌ Missing ALPHA_VANTAGE_API_KEY' } });
7172
return {
7273
data: null,
7374
error: "ALPHA_VANTAGE_API_KEY environment variable is required"
@@ -95,7 +96,7 @@ export const alphaVantageCryptoTool = createTool({
9596

9697
const url = `https://www.alphavantage.co/query?${params.toString()}`;
9798

98-
await writer?.write({ type: 'progress', data: { message: '📡 Querying Alpha Vantage API...' } });
99+
await writer?.custom({ type: 'data-tool-progress', data: { message: '📡 Querying Alpha Vantage API...' } });
99100
const response = await fetch(url);
100101

101102
if (!response.ok) {
@@ -152,7 +153,7 @@ export const alphaVantageCryptoTool = createTool({
152153
return null;
153154
};
154155

155-
await writer?.write({ type: 'progress', data: { message: `✅ Crypto data ready for ${context.symbol}` } });
156+
await writer?.custom({ type: 'data-tool-progress', data: { message: `✅ Crypto data ready for ${context.symbol}` } });
156157
const result = {
157158
data,
158159
metadata: {
@@ -170,7 +171,7 @@ export const alphaVantageCryptoTool = createTool({
170171

171172
} catch (error) {
172173
const errMsg = error instanceof Error ? error.message : "Unknown error occurred";
173-
await writer?.write({ type: 'progress', data: { message: `❌ Crypto fetch error: ${errMsg}` } });
174+
await writer?.custom({ type: 'data-tool-progress', data: { message: `❌ Crypto fetch error: ${errMsg}` } });
174175
span?.error({ error: error instanceof Error ? error : new Error(errMsg), endSpan: true });
175176
return {
176177
data: null,
@@ -243,11 +244,11 @@ export const alphaVantageStockTool = createTool({
243244
tracingPolicy: { internal: InternalSpans.TOOL }
244245
});
245246

246-
await writer?.write({ type: 'progress', data: { message: `📈 Fetching Alpha Vantage stock data for ${context.symbol || 'symbol'}` } });
247+
await writer?.custom({ type: 'data-tool-progress', data: { message: `📈 Fetching Alpha Vantage stock data for ${context.symbol || 'symbol'}` } });
247248
const apiKey = process.env.ALPHA_VANTAGE_API_KEY;
248249

249250
if (typeof apiKey !== "string" || apiKey.trim() === '') {
250-
await writer?.write({ type: 'progress', data: { message: '❌ Missing ALPHA_VANTAGE_API_KEY' } });
251+
await writer?.custom({ type: 'data-tool-progress', data: { message: '❌ Missing ALPHA_VANTAGE_API_KEY' } });
251252
return {
252253
data: null,
253254
error: "ALPHA_VANTAGE_API_KEY environment variable is required"
@@ -438,11 +439,11 @@ export const alphaVantageTool = createTool({
438439
tracingPolicy: { internal: InternalSpans.TOOL }
439440
});
440441

441-
await writer?.write({ type: 'data-tool-progress', data: { message: `💰 Fetching general Alpha Vantage data for ${context.function}` } });
442+
await writer?.custom({ type: 'data-tool-progress', data: { message: `💰 Fetching general Alpha Vantage data for ${context.function}` } });
442443
const apiKey = process.env.ALPHA_VANTAGE_API_KEY;
443444

444445
if (typeof apiKey !== "string" || apiKey.trim() === "") {
445-
await writer?.write({ type: 'data-tool-progress', data: { message: '❌ Missing ALPHA_VANTAGE_API_KEY' } });
446+
await writer?.custom({ type: 'data-tool-progress', data: { message: '❌ Missing ALPHA_VANTAGE_API_KEY' } });
446447
return {
447448
data: null,
448449
error: "ALPHA_VANTAGE_API_KEY environment variable is required"
@@ -488,7 +489,7 @@ export const alphaVantageTool = createTool({
488489
params.append("function", context.economic_indicator);
489490
}
490491

491-
await writer?.write({ type: 'progress', data: { message: '📡 Querying Alpha Vantage API...' } });
492+
await writer?.custom({ type: 'data-tool-progress', data: { message: '📡 Querying Alpha Vantage API...' } });
492493

493494
const url = `https://www.alphavantage.co/query?${params.toString()}`;
494495

@@ -524,7 +525,7 @@ export const alphaVantageTool = createTool({
524525

525526
const metadataObj = metadata as unknown;
526527

527-
await writer?.write({ type: 'progress', data: { message: `✅ General data ready for ${context.function}` } });
528+
await writer?.custom({ type: 'data-tool-progress', data: { message: `✅ General data ready for ${context.function}` } });
528529

529530
const result = {
530531
data,

src/mastra/tools/arxiv.tool.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { AISpanType, InternalSpans } from "@mastra/core/ai-tracing";
2-
import { InferUITool, createTool } from "@mastra/core/tools";
2+
import type { InferUITool} from "@mastra/core/tools";
3+
import { createTool } from "@mastra/core/tools";
34
import { z } from "zod";
45

56
// In-memory counter to track tool calls per request

src/mastra/tools/browser-tool.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,19 @@
22
* Not working
33
*/
44
import { AISpanType, InternalSpans } from '@mastra/core/ai-tracing';
5-
import { InferUITool, createTool } from "@mastra/core/tools";
5+
import type { InferUITool} from "@mastra/core/tools";
6+
import { createTool } from "@mastra/core/tools";
67
import { MDocument } from '@mastra/rag';
7-
import { Browser, chromium } from 'playwright-core';
8+
import type { Browser} from 'playwright-core';
9+
import { chromium } from 'playwright-core';
810
import { z } from 'zod';
911
import { log } from '../config/logger';
1012

1113
// Browser instance cache for reuse
1214
let browserInstance: Browser | null = null;
1315

1416
async function getBrowser(): Promise<Browser> {
15-
if (!browserInstance || !browserInstance.isConnected()) {
17+
if (!browserInstance?.isConnected()) {
1618
browserInstance = await chromium.launch({
1719
headless: true,
1820
chromiumSandbox: false,
@@ -423,7 +425,7 @@ export const extractTablesTool = createTool({
423425
bodyRows.forEach(row => {
424426
const rowData: string[] = [];
425427
row.querySelectorAll('td').forEach(cell => rowData.push(cell.textContent?.trim() ?? ''));
426-
if (rowData.length > 0) rows.push(rowData);
428+
if (rowData.length > 0) {rows.push(rowData);}
427429
});
428430

429431
result.push({ headers, rows });
@@ -480,7 +482,7 @@ export const monitorPageTool = createTool({
480482
const selector = context.selector ?? 'body';
481483

482484
await page.goto(context.url, { waitUntil: 'domcontentloaded' });
483-
let previousContent = await page.$eval(selector, el => el.textContent ?? '');
485+
const previousContent = await page.$eval(selector, el => el.textContent ?? '');
484486

485487
let checkCount = 0;
486488
let changed = false;

0 commit comments

Comments
 (0)