Files
letta-code-sdk/examples/research-team/tools/file-store.ts
Cameron Pfiffer d5bbce6dec feat: add multi-agent demo examples
Three demo examples showcasing multi-agent orchestration:

- **economics-seminar**: Hostile faculty panel debates AI economist presenter
- **research-team**: Coordinator, Researcher, Analyst, Writer collaboration
- **dungeon-master**: Persistent DM that creates its own game system

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

Co-Authored-By: Letta <noreply@letta.com>
2026-01-27 15:13:19 -08:00

204 lines
4.4 KiB
TypeScript

/**
* File Store Helper
*
* Utilities for reading/writing shared files between agents.
*/
import { readFile, writeFile, mkdir } from 'node:fs/promises';
import { existsSync } from 'node:fs';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// Output directory for research artifacts
const OUTPUT_DIR = join(__dirname, '..', 'output');
/**
* Ensure output directory exists
*/
async function ensureOutputDir(): Promise<void> {
if (!existsSync(OUTPUT_DIR)) {
await mkdir(OUTPUT_DIR, { recursive: true });
}
}
/**
* Write content to a file in the output directory
*/
export async function writeOutput(filename: string, content: string): Promise<string> {
await ensureOutputDir();
const filepath = join(OUTPUT_DIR, filename);
await writeFile(filepath, content, 'utf-8');
return filepath;
}
/**
* Read content from a file in the output directory
*/
export async function readOutput(filename: string): Promise<string> {
const filepath = join(OUTPUT_DIR, filename);
return await readFile(filepath, 'utf-8');
}
/**
* Check if a file exists in the output directory
*/
export function outputExists(filename: string): boolean {
return existsSync(join(OUTPUT_DIR, filename));
}
/**
* Get the full path for an output file
*/
export function getOutputPath(filename: string): string {
return join(OUTPUT_DIR, filename);
}
/**
* Standard filenames for workflow artifacts
*/
export const ARTIFACTS = {
// Research phase
findings: (taskId: string) => `${taskId}-findings.md`,
sourceEvaluations: (taskId: string) => `${taskId}-source-evals.json`,
// Analysis phase
analysis: (taskId: string) => `${taskId}-analysis.md`,
// Writing phase
report: (taskId: string) => `${taskId}-report.md`,
// Meta files
feedback: (taskId: string) => `${taskId}-feedback.json`,
reflections: (taskId: string) => `${taskId}-reflections.json`,
// Team state
teamState: 'team-state.json',
};
/**
* Load team state from disk (or return default)
*/
export async function loadTeamState(): Promise<{
agentIds: Record<string, string | null>;
sharedBlockIds: Record<string, string | null>;
completedTasks: number;
}> {
const filepath = join(OUTPUT_DIR, ARTIFACTS.teamState);
if (existsSync(filepath)) {
const content = await readFile(filepath, 'utf-8');
return JSON.parse(content);
}
return {
agentIds: {
coordinator: null,
researcher: null,
analyst: null,
writer: null,
},
sharedBlockIds: {
sources: null,
terminology: null,
pitfalls: null,
},
completedTasks: 0,
};
}
/**
* Save team state to disk
*/
export async function saveTeamState(state: {
agentIds: Record<string, string | null>;
sharedBlockIds: Record<string, string | null>;
completedTasks: number;
}): Promise<void> {
await ensureOutputDir();
const filepath = join(OUTPUT_DIR, ARTIFACTS.teamState);
await writeFile(filepath, JSON.stringify(state, null, 2), 'utf-8');
}
/**
* Generate a findings template for the researcher
*/
export function generateFindingsTemplate(query: string, sourcesCount: number): string {
return `# Research Findings
## Query
${query}
## Sources Found
Target: ${sourcesCount} sources
---
<!-- Researcher: Fill in the sources below -->
## Source 1
**Title**:
**Authors**:
**Venue**:
**Year**:
**Citations**:
**Relevance Score**: /10
**Quality Score**: /10
**Summary**:
**Key Findings**:
---
<!-- Continue for additional sources -->
`;
}
/**
* Generate an analysis template
*/
export function generateAnalysisTemplate(query: string): string {
return `# Analysis
## Research Question
${query}
## Summary of Findings
<!-- Analyst: Synthesize the key findings here -->
## Key Themes
<!-- Identify 3-5 major themes across the sources -->
1.
2.
3.
## Patterns and Connections
<!-- What patterns emerge? How do findings relate? -->
## Gaps and Limitations
<!-- What questions remain unanswered? -->
## Recommendations
<!-- Based on the analysis, what are the key takeaways? -->
---
*Analysis generated by Research Team*
`;
}
/**
* Clear all outputs for a fresh start
*/
export async function clearOutputs(): Promise<void> {
const { rm } = await import('node:fs/promises');
if (existsSync(OUTPUT_DIR)) {
await rm(OUTPUT_DIR, { recursive: true });
}
await mkdir(OUTPUT_DIR, { recursive: true });
}