Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,10 @@ function createSynthesisStep(id: string, config: ResearchWorkflowPrompts) {
execute: async ({ abortSignal, inputData, mastra, requestContext }) => {
const agent = mastra.getAgent("general");
const sources = mergeResearchSources(inputData);
const response = await agent.generate(config.synthesisPrompt(inputData), {
const response = await agent.generate(researchSynthesisPrompt(config, inputData), {
activeTools: [],
abortSignal,
modelSettings: { maxOutputTokens: 8_192 },
providerOptions: RESEARCH_PROVIDER_OPTIONS,
requestContext,
structuredOutput: { schema: ResearchSynthesisDraftSchema },
Expand Down Expand Up @@ -289,12 +290,24 @@ function researchPassPrompt(
config.queryPrompt(query),
"Use only the provider evidence below. For Exa citations, copy providerResultId and URL exactly. For Firecrawl citations, copy the URL exactly.",
"Set providerResultId to an empty string for every Firecrawl citation.",
"Return 4-6 distinct, synthesis-ready claims, no more than 3 sources per claim, and a concise summary. Prioritize the strongest guidance instead of exhaustively restating the evidence.",
"Do not cite sourceId directly and do not add sources that are absent from this evidence pack.",
"",
JSON.stringify(evidence, null, 2),
].join("\n");
}

function researchSynthesisPrompt(
config: ResearchWorkflowPrompts,
findings: z.output<typeof ResearchFindingSchema>[],
): string {
return [
config.synthesisPrompt(findings),
"Consolidate overlapping evidence into at most 16 distinct claims with no more than 4 source IDs per claim.",
"Keep the report focused and complete within 2,000 words while retaining actionable findings and citations.",
].join("\n");
}

function parseResearchPassDraft(value: unknown) {
const parsed = ResearchPassDraftSchema.safeParse(value);
if (parsed.success) {
Expand Down
34 changes: 20 additions & 14 deletions packages/agent-core/src/mastra/workflows/research-provenance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,23 +31,29 @@ const SourceReferenceDraftSchema = z.strictObject({
});

export const ResearchPassDraftSchema = z.strictObject({
claims: z.array(
z.strictObject({
claim: z.string().trim().min(1),
sources: z.array(SourceReferenceDraftSchema).min(1),
}),
),
summary: z.string().trim().min(1),
claims: z
.array(
z.strictObject({
claim: z.string().trim().min(1).max(800),
sources: z.array(SourceReferenceDraftSchema).min(1).max(3),
}),
)
.min(1)
.max(6),
summary: z.string().trim().min(1).max(2_000),
});

export const ResearchSynthesisDraftSchema = z.strictObject({
claims: z.array(
z.strictObject({
claim: z.string().trim().min(1),
sourceIds: z.array(z.string().trim().min(1).max(4_096)).min(1),
}),
),
report: z.string().trim().min(1),
claims: z
.array(
z.strictObject({
claim: z.string().trim().min(1).max(800),
sourceIds: z.array(z.string().trim().min(1).max(4_096)).min(1).max(4),
}),
)
.min(1)
.max(16),
report: z.string().trim().min(1).max(12_000),
});

type SourceReference = z.infer<typeof SourceReferenceSchema>;
Expand Down