Files
letta-code-sdk/examples/research-team/agents/analyst.ts
Cameron Pfiffer de682b0e26 fix: update all examples to use stream() instead of receive()
- dungeon-master, economics-seminar, research-team all updated
- Also improved tool output display in dungeon-master

🤖 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>
2026-01-27 16:37:00 -08:00

240 lines
6.6 KiB
TypeScript

/**
* Analyst Agent
*
* Synthesizes research findings, identifies patterns, and produces analysis.
* Learns effective analytical frameworks and quality standards.
*/
import { createSession, resumeSession, type Session } from '../../../src/index.js';
import type { Depth } from '../types.js';
import { DEPTH_CONFIGS } from '../types.js';
import { ARTIFACTS, getOutputPath } from '../tools/file-store.js';
const ANALYST_SYSTEM_PROMPT = `You are a Research Analyst on an academic research team.
## Your Role
You synthesize findings from the Researcher, identify patterns and themes, and produce analytical insights. Your analysis feeds into the final research report produced by the Writer.
## Your Process
1. Receive findings from the Researcher via a shared file
2. Read and understand all sources and their evaluations
3. Identify key themes, patterns, and connections
4. Note gaps, contradictions, and limitations
5. Produce a structured analysis document
6. Report completion to the Coordinator
## Analysis Framework
For each analysis, address:
1. **Synthesis**: What are the main findings across sources?
2. **Themes**: What 3-5 major themes emerge?
3. **Patterns**: How do findings relate? What patterns exist?
4. **Gaps**: What questions remain unanswered?
5. **Implications**: What are the key takeaways?
## Quality Standards
- Cite specific sources for claims
- Distinguish between consensus views and contested claims
- Note the strength of evidence for each finding
- Be intellectually honest about limitations
## Memory Usage
You have memory blocks that persist:
- **analysis-patterns**: Effective frameworks and synthesis techniques
- **quality-standards**: What makes good analysis, common pitfalls
- **citation-practices**: How to properly cite and attribute
Update these when you discover effective approaches or learn from mistakes.`;
/**
* Create or resume the analyst agent
*/
export async function createAnalyst(
existingAgentId?: string | null,
depth: Depth = 'standard'
): Promise<Session> {
if (existingAgentId) {
return resumeSession(existingAgentId, {
model: 'haiku',
allowedTools: ['Glob', 'Read', 'Write'],
permissionMode: 'bypassPermissions',
});
}
return createSession({
model: 'haiku',
systemPrompt: ANALYST_SYSTEM_PROMPT,
memory: [
{
label: 'analysis-patterns',
value: `# Analysis Patterns
## Effective Frameworks
- Thematic analysis: Group findings by topic
- Compare/contrast: Find agreements and disagreements
- Temporal analysis: Track evolution of ideas over time
- Gap analysis: What's missing from the literature?
## Synthesis Techniques
- Start with highest-quality sources
- Look for convergent findings across multiple sources
- Note where sources disagree and why
## Patterns to Watch For
[Add effective patterns as you discover them]
`,
description: 'Effective analytical frameworks and synthesis techniques',
},
{
label: 'quality-standards',
value: `# Quality Standards
## Good Analysis Includes
- Clear thesis or main finding
- Evidence from multiple sources
- Acknowledgment of limitations
- Logical flow of arguments
## Common Pitfalls
- Over-generalizing from single sources
- Ignoring contradictory evidence
- Failing to distinguish correlation from causation
- Not citing specific sources
## Lessons Learned
[Add lessons from past analyses]
`,
description: 'Quality standards and common pitfalls to avoid',
},
{
label: 'citation-practices',
value: `# Citation Practices
## When to Cite
- Specific claims or statistics
- Direct quotes
- Novel ideas or frameworks
- Contested claims
## Citation Format
Use inline citations: (Author, Year)
List full references at end
## Attribution Notes
[Track any attribution issues or patterns]
`,
description: 'Proper citation and attribution practices',
},
],
allowedTools: ['Glob', 'Read', 'Write'],
permissionMode: 'bypassPermissions',
});
}
/**
* Run analysis on research findings
*/
export async function runAnalysis(
session: Session,
taskId: string,
query: string,
depth: Depth
): Promise<{ success: boolean; analysisPath: string }> {
const config = DEPTH_CONFIGS[depth];
const findingsPath = getOutputPath(ARTIFACTS.findings(taskId));
const analysisPath = ARTIFACTS.analysis(taskId);
const depthGuidance = {
quick: 'Provide a brief analysis focusing on the top 2-3 key findings.',
standard: 'Provide a thorough analysis covering all major themes and their connections.',
comprehensive: 'Provide an extensive analysis with detailed examination of all themes, patterns, sub-themes, and implications.',
};
const prompt = `## Analysis Task
**Original Query**: ${query}
**Analysis Depth**: ${depth}
**Findings File**: \`${findingsPath}\`
Please:
1. Read the findings file from the Researcher
2. Identify key themes and patterns across sources
3. Synthesize the main findings
4. Note any gaps or limitations
5. Write your analysis to: \`examples/research-team/output/${analysisPath}\`
**Depth Guidance**: ${depthGuidance[depth]}
Your analysis should include:
- Summary of key findings
- ${depth === 'quick' ? '2-3' : depth === 'standard' ? '3-5' : '5-7'} major themes with supporting evidence
- Patterns and connections between findings
- Gaps and limitations
- Key implications/takeaways
Cite specific sources using (Author, Year) format.
Confirm when complete.`;
await session.send(prompt);
let success = false;
let response = '';
for await (const msg of session.stream()) {
if (msg.type === 'assistant') {
response += msg.content;
process.stdout.write('.'); // Progress indicator
}
if (msg.type === 'result') {
success = msg.success;
console.log(''); // Newline after progress dots
}
}
return {
success,
analysisPath,
};
}
/**
* Ask analyst to reflect on task performance
*/
export async function reflectOnTask(
session: Session,
taskId: string,
feedback?: { rating: number; comment?: string }
): Promise<string> {
let prompt = `## Post-Task Reflection
The analysis task "${taskId}" is complete.`;
if (feedback) {
prompt += `
User feedback:
- Rating: ${feedback.rating}/5 stars
- Comment: ${feedback.comment || 'None provided'}`;
}
prompt += `
Please reflect:
1. What analytical approaches worked well?
2. What could improve your synthesis?
3. Any frameworks or patterns worth remembering?
Update your memory with insights, then summarize your reflection.`;
await session.send(prompt);
let reflection = '';
for await (const msg of session.stream()) {
if (msg.type === 'assistant') {
reflection += msg.content;
}
}
return reflection;
}