Structured Output

This example demonstrates a realistic workflow that combines the Research Agent with the Structured Data Extractor to gather information and convert it into structured JSON data using custom schemas.

Key features:

  • Two-step workflow: Research Agent → Structured Data Extractor
  • Custom schema definition for precise data extraction
  • Full TypeScript support with type safety
  • Proper error handling for production use
1

Install Package

$pnpm add athena-intelligence
2

Set Up Client

1import {
2 type AthenaIntelligence,
3 AthenaIntelligenceClient,
4 AthenaIntelligenceError,
5} from 'athena-intelligence';
6
7// Basic client setup (uses default production API)
8const client = new AthenaIntelligenceClient({
9 apiKey: process.env.ATHENA_API_KEY,
10});
11
12// Override baseUrl for custom API endpoints
13const customClient = new AthenaIntelligenceClient({
14 apiKey: process.env.ATHENA_API_KEY,
15 baseUrl: 'https://your-custom-api.example.com', // Custom API endpoint
16});
3

Step 1: Gather Information with Research Agent

First, use the Research Agent to gather comprehensive information on your topic:

1const researchRequest: AthenaIntelligence.ResearchAgentRequest = {
2 config: {
3 enabled_tools: ['search'],
4 model: 'gpt-4-turbo-preview',
5 },
6 messages: [
7 {
8 content: 'Research recent AI investment trends and find specific funding rounds from 2024',
9 role: 'user',
10 type: 'user',
11 },
12 ],
13};
14
15console.log('🔎 Running Research Agent…');
16const researchResponse: AthenaIntelligence.ResearchAgentResponse =
17 await client.agents.research.invoke(researchRequest);
18
19// Extract research content from the response
20const researchContent = researchResponse?.findings ?? '';
21
22console.log('📝 Research summary obtained:');
23console.log(researchContent);
4

Step 2: Define Your Schema

Define the exact structure you want for your extracted data:

1// Define the schema we expect from the extractor
2const schema = {
3 investments: {
4 item_1: {
5 company: 'string',
6 amount_usd_millions: 'number',
7 country: 'string',
8 investors: 'string',
9 },
10 item_2: {
11 company: 'string',
12 amount_usd_millions: 'number',
13 country: 'string',
14 investors: 'string',
15 },
16 },
17 total_announced_usd_millions: 'number',
18} as const;
5

Step 3: Extract Structured Data

Use the Structured Data Extractor to convert the research findings into your desired format:

1const extractorRequest: AthenaIntelligence.StructuredDataExtractorRequest = {
2 text_input: researchContent,
3 custom_type_dict: schema,
4 parsing_model: 'gpt-4-turbo-preview',
5 chunk_messages: [],
6};
7
8console.log('🏗️ Extracting structured data…');
9const extractionResponse: AthenaIntelligence.StructuredDataExtractorResponse =
10 await client.tools.structuredDataExtractor.invoke(extractorRequest);
11
12console.log('✅ Structured output:');
13const structuredData = extractionResponse?.reduced_data;
14console.log(JSON.stringify(structuredData, null, 2));
6

Advanced Schema Examples

Create more complex schemas for different use cases:

1// Company analysis schema
2const companySchema = {
3 companies: {
4 company_1: {
5 name: 'string',
6 description: 'string',
7 market_cap_billions: 'number',
8 industry: 'string',
9 headquarters: 'string',
10 key_products: 'string',
11 },
12 company_2: {
13 name: 'string',
14 description: 'string',
15 market_cap_billions: 'number',
16 industry: 'string',
17 headquarters: 'string',
18 key_products: 'string',
19 },
20 },
21 market_trends: {
22 trend_1: 'string',
23 trend_2: 'string',
24 trend_3: 'string',
25 },
26 summary_metrics: {
27 total_market_cap: 'number',
28 average_growth_rate: 'number',
29 number_of_companies: 'number',
30 },
31} as const;
32
33// News analysis schema
34const newsSchema = {
35 articles: {
36 article_1: {
37 headline: 'string',
38 summary: 'string',
39 publication_date: 'string',
40 source: 'string',
41 sentiment: 'string',
42 },
43 article_2: {
44 headline: 'string',
45 summary: 'string',
46 publication_date: 'string',
47 source: 'string',
48 sentiment: 'string',
49 },
50 },
51 overall_sentiment: 'string',
52 key_themes: {
53 theme_1: 'string',
54 theme_2: 'string',
55 },
56} as const;
7

TypeScript Type Safety

Define interfaces for better type safety when working with extracted data:

1// Define TypeScript interfaces based on your schema
2interface InvestmentItem {
3 company: string;
4 amount_usd_millions: number;
5 country: string;
6 investors: string;
7}
8
9interface InvestmentData {
10 investments: {
11 item_1: InvestmentItem;
12 item_2: InvestmentItem;
13 };
14 total_announced_usd_millions: number;
15}
16
17// Type the extracted data
18const typedData = structuredData as InvestmentData;
19
20// Now you have full TypeScript support
21console.log(`Total funding: $${typedData.total_announced_usd_millions}M`);
22typedData.investments.item_1.company; // TypeScript knows this is a string
8

Error Handling

Always include comprehensive error handling for production applications:

1try {
2 // Research step
3 const researchResponse = await client.agents.research.invoke(researchRequest);
4 const researchContent = researchResponse?.findings ?? '';
5
6 if (!researchContent) {
7 throw new Error('No research content received');
8 }
9
10 // Extraction step
11 const extractionResponse = await client.tools.structuredDataExtractor.invoke({
12 text_input: researchContent,
13 custom_type_dict: schema,
14 parsing_model: 'gpt-4-turbo-preview',
15 chunk_messages: [],
16 });
17
18 const structuredData = extractionResponse?.reduced_data;
19 console.log('Extraction successful:', structuredData);
20} catch (error) {
21 if (error instanceof AthenaIntelligenceError) {
22 console.error(`Athena API error (${error.statusCode}): ${error.message}`);
23 } else {
24 console.error('Unexpected error:', error);
25 }
26}
9

Complete Working Example

Here’s a complete example that demonstrates the full workflow:

1import {
2 type AthenaIntelligence,
3 AthenaIntelligenceClient,
4 AthenaIntelligenceError,
5} from 'athena-intelligence';
6
7async function runStructuredOutputExample() {
8 try {
9 const client = new AthenaIntelligenceClient({
10 apiKey: process.env.ATHENA_API_KEY,
11 // Optional: override baseUrl for custom environments
12 // baseUrl: 'https://your-custom-api.example.com',
13 });
14
15 // Step 1: Research
16 const researchRequest: AthenaIntelligence.ResearchAgentRequest = {
17 config: {
18 enabled_tools: ['search'],
19 model: 'gpt-4-turbo-preview',
20 },
21 messages: [
22 {
23 content: 'Research recent AI investment trends and find specific funding rounds from 2024',
24 role: 'user',
25 type: 'user',
26 },
27 ],
28 };
29
30 console.log('🔎 Running Research Agent…');
31 const researchResponse = await client.agents.research.invoke(researchRequest);
32 const researchContent = researchResponse?.findings ?? '';
33
34 console.log('📝 Research summary obtained');
35
36 // Step 2: Define schema
37 const schema = {
38 investments: {
39 item_1: {
40 company: 'string',
41 amount_usd_millions: 'number',
42 country: 'string',
43 investors: 'string',
44 },
45 item_2: {
46 company: 'string',
47 amount_usd_millions: 'number',
48 country: 'string',
49 investors: 'string',
50 },
51 },
52 total_announced_usd_millions: 'number',
53 } as const;
54
55 // Step 3: Extract structured data
56 const extractorRequest: AthenaIntelligence.StructuredDataExtractorRequest = {
57 text_input: researchContent,
58 custom_type_dict: schema,
59 parsing_model: 'gpt-4-turbo-preview',
60 chunk_messages: [],
61 };
62
63 console.log('🏗️ Extracting structured data…');
64 const extractionResponse = await client.tools.structuredDataExtractor.invoke(extractorRequest);
65
66 console.log('✅ Structured output:');
67 const structuredData = extractionResponse?.reduced_data;
68 console.log(JSON.stringify(structuredData, null, 2));
69 } catch (error) {
70 if (error instanceof AthenaIntelligenceError) {
71 console.error(`Athena API error (${error.statusCode}): ${error.message}`);
72 } else {
73 console.error('Unexpected error:', error);
74 }
75 }
76}
77
78runStructuredOutputExample();