Skip to content

Research Workflow Example

This page provides a complete example of how to use Octagon's specialized agents with the OpenAI Agents SDK to conduct a comprehensive investment research workflow.

Complete Public Market Research Workflow Example

The following example demonstrates how to set up a research workflow that:

  1. Gathers basic company information
  2. Analyzes SEC filings
  3. Analyzes earnings call transcripts
  4. Evaluates financial metrics
  5. Analyzes stock performance
  6. Generates a comprehensive investment report
Python
#!/usr/bin/env python3
"""
Simple Octagon Agents Demo

This example demonstrates how easy it is to use Octagon's specialized 
financial research agents with the OpenAI Agents SDK.
"""

import asyncio
import os
import json
from openai import AsyncOpenAI

from agents import Agent, ModelSettings, OpenAIResponsesModel


# Set OpenAI API key for the coordinator agent
os.environ["OPENAI_API_KEY"] = "<your-openai-api-key>"
os.environ['OCTAGON_API_KEY'] = "<your-octagon-api-key>"
# Configure Octagon client
octagon_client = AsyncOpenAI(
    api_key=os.environ['OCTAGON_API_KEY'],
    base_url="https://api.octagonagents.com/v1",
)


# Create Octagon specialized agents
companies_agent = Agent(
    name="Companies Database",
    instructions="You retrieve basic company information from Octagon's companies database.",
    model=OpenAIResponsesModel(
        model="octagon-companies-agent",
        openai_client=octagon_client,
    ),
)

sec_filings_agent = Agent(
    name="SEC Filings Analysis",
    instructions="You analyze SEC filings to extract financial data, management commentary, risk factors, and other key information from 10-K, 10-Q, and 8-K filings.",
    model=OpenAIResponsesModel(
        model="octagon-sec-agent",
        openai_client=octagon_client,
    ),
)

transcripts_agent = Agent(
    name="Earnings Call Analysis",
    instructions="You analyze earnings call transcripts to extract executive statements, financial guidance, analyst questions, and forward-looking statements.",
    model=OpenAIResponsesModel(
        model="octagon-transcripts-agent",
        openai_client=octagon_client,
    ),
)

financials_agent = Agent(
    name="Financial Metrics Analysis",
    instructions="You analyze financial statements, calculate financial metrics, compare ratios, and evaluate performance indicators.",
    model=OpenAIResponsesModel(
        model="octagon-financials-agent",
        openai_client=octagon_client,
    ),
)

stock_data_agent = Agent(
    name="Stock Performance Analysis",
    instructions="You analyze stock price movements, trading volumes, market trends, valuation metrics, and technical indicators.",
    model=OpenAIResponsesModel(
        model="octagon-stock-data-agent",
        openai_client=octagon_client,
    ),
)

report_agent = Agent(
    name="Investment Report Generation",
    instructions="You create professional investor-ready company reports based on research data. You can analyze the findings and organize them into a structured report with relevant insights.",
    model=OpenAIResponsesModel(
        model="octagon-report-agent",
        openai_client=octagon_client,
    ),
)


# Create a research workflow coordinator with OpenAI
openai_client = AsyncOpenAI(api_key=os.environ["OPENAI_API_KEY"])
coordinator = Agent(
    name="Research Coordinator",
    instructions="""
    You coordinate company research by delegating to specialized Octagon agents:
    1. First, ask the Companies Database agent for basic company information
    2. Then, ask the SEC Filings Analysis agent for insights from regulatory filings
    3. Next, ask the Earnings Call Analysis agent for insights from recent earnings calls
    4. Then, ask the Financial Metrics Analysis agent for key financial ratios and metrics
    5. Next, ask the Stock Performance Analysis agent for stock price trends and market data
    6. Finally, ask the Investment Report Generation agent to create a comprehensive investor report
    
    Always explain what you're doing before each handoff.
    """,
    model=OpenAIResponsesModel(
        model="gpt-4o",
        openai_client=openai_client,
    ),
    handoffs=[
        companies_agent,
        sec_filings_agent,
        transcripts_agent,
        financials_agent,
        stock_data_agent,
        report_agent
    ],
)


# Simple function to handle the research workflow without relying on the SDK's streaming internals
async def run_research_workflow(company_name):
    """Run the research workflow directly without using Runner's streaming functionality."""
    print(f"\n🔍 Researching {company_name}...\n")
    print("=" * 60)
    
    # Create a simple input for our coordinator agent
    user_input = f"Create a comprehensive investment research report for {company_name}."
    
    # Initialize clients for Octagon and OpenAI
    octagon_api_key = os.environ.get('OCTAGON_API_KEY', 'not-set')
    openai_api_key = os.environ.get('OPENAI_API_KEY', 'not-set')
    
    # Call each agent in sequence to build the report
    try:
        # Step 1: Basic company information
        print("🔍 Step 1: Gathering basic company information...")
        companies_response = await octagon_client.responses.create(
            model="octagon-companies-agent",
            instructions="You retrieve basic company information.",
            input=f"Provide basic information about {company_name}",
            stream=True
        )
        companies_info = await process_stream(companies_response, "Companies Database")
        
        # Step 2: SEC Filings Analysis
        print("\n🔍 Step 2: Analyzing SEC filings...")
        sec_response = await octagon_client.responses.create(
            model="octagon-sec-agent",
            instructions="You analyze SEC filings to extract financial data.",
            input=f"Analyze recent SEC filings for {company_name}. {companies_info}",
            stream=True
        )
        sec_info = await process_stream(sec_response, "SEC Filings Analysis")
        
        # Step 3: Earnings Call Analysis
        print("\n🔍 Step 3: Analyzing earnings call transcripts...")
        transcripts_response = await octagon_client.responses.create(
            model="octagon-transcripts-agent",
            instructions="You analyze earnings call transcripts.",
            input=f"Analyze recent earnings call transcripts for {company_name}. {companies_info}",
            stream=True
        )
        transcripts_info = await process_stream(transcripts_response, "Earnings Call Analysis")
        
        # Step 4: Financial Metrics Analysis
        print("\n🔍 Step 4: Analyzing financial metrics...")
        financials_response = await octagon_client.responses.create(
            model="octagon-financials-agent",
            instructions="You analyze financial statements and metrics.",
            input=f"Analyze key financial metrics for {company_name}. {companies_info}",
            stream=True
        )
        financials_info = await process_stream(financials_response, "Financial Metrics Analysis")
        
        # Step 5: Stock Performance Analysis
        print("\n🔍 Step 5: Analyzing stock performance...")
        stock_response = await octagon_client.responses.create(
            model="octagon-stock-data-agent",
            instructions="You analyze stock price movements and market trends.",
            input=f"Analyze stock performance for {company_name}. {companies_info}",
            stream=True
        )
        stock_info = await process_stream(stock_response, "Stock Performance Analysis")
        
        # Step 6: Generate final report
        print("\n🔍 Step 6: Generating comprehensive report...")
        report_response = await openai_client.responses.create(
            model="gpt-4o",
            instructions="You create professional investor-ready company reports.",
            input=f"Create a comprehensive investment report for {company_name} based on this research:\n\nCompany Info: {companies_info}\n\nSEC Filings: {sec_info}\n\nEarnings Calls: {transcripts_info}\n\nFinancials: {financials_info}\n\nStock Performance: {stock_info}",
            stream=True
        )
        final_report = await process_stream(report_response, "Investment Report Generation")
        
        print("\n" + "=" * 60)
        print("\n✅ Research complete!")
        
        return final_report
        
    except Exception as e:
        print(f"\n❌ Error during research: {str(e)}")
        return f"Error: {str(e)}"

async def process_stream(stream, source_name):
    """Process a streaming response and return the full text."""
    full_response = ""
    print(f"\n--- {source_name} ---\n")
    
    async for event in stream:
        if event.type == "response.output_text.delta":
            content = event.delta
            full_response += content
            print(content, end="", flush=True)
    
    print("\n")
    return full_response

async def main():
    """Run a simple demo of Octagon agents with direct API calls."""
    # The company to research - use a public company for best results with these agents
    company_name = "Apple"
    
    print("\n🤖 Octagon Agents Demo")
    print("This demo shows how easily Octagon's specialized agents can be used for financial research")
    print(f"OpenAI API Key: {os.environ['OPENAI_API_KEY'][:6]}...")
    print(f"Octagon API Key: {os.environ.get('OCTAGON_API_KEY', 'not-set')[:6]}...")
    
    # Run the research workflow
    await run_research_workflow(company_name)


if __name__ == "__main__":
    asyncio.run(main())
JavaScript
/**
 * Simple Octagon Agents Demo
 * 
 * This example demonstrates how easy it is to use Octagon's specialized 
 * financial research agents with the OpenAI Agents SDK.
 */

import OpenAI from 'openai';
import { Agent, OpenAIResponsesModel } from 'openai-agents';
import dotenv from 'dotenv';

// Load environment variables
dotenv.config();

// Set API keys
const OPENAI_API_KEY = process.env.OPENAI_API_KEY || '<your-openai-api-key>';
const OCTAGON_API_KEY = process.env.OCTAGON_API_KEY || '<your-octagon-api-key>';

// Configure Octagon client
const octagonClient = new OpenAI({
  apiKey: OCTAGON_API_KEY,
  baseURL: 'https://api.octagonagents.com/v1',
});

// Create Octagon specialized agents
const companiesAgent = new Agent({
  name: "Companies Database",
  instructions: "You retrieve basic company information from Octagon's companies database.",
  model: new OpenAIResponsesModel({
    model: "octagon-companies-agent",
    openaiClient: octagonClient,
  }),
});

const secFilingsAgent = new Agent({
  name: "SEC Filings Analysis",
  instructions: "You analyze SEC filings to extract financial data, management commentary, risk factors, and other key information from 10-K, 10-Q, and 8-K filings.",
  model: new OpenAIResponsesModel({
    model: "octagon-sec-agent",
    openaiClient: octagonClient,
  }),
});

const transcriptsAgent = new Agent({
  name: "Earnings Call Analysis",
  instructions: "You analyze earnings call transcripts to extract executive statements, financial guidance, analyst questions, and forward-looking statements.",
  model: new OpenAIResponsesModel({
    model: "octagon-transcripts-agent",
    openaiClient: octagonClient,
  }),
});

const financialsAgent = new Agent({
  name: "Financial Metrics Analysis",
  instructions: "You analyze financial statements, calculate financial metrics, compare ratios, and evaluate performance indicators.",
  model: new OpenAIResponsesModel({
    model: "octagon-financials-agent",
    openaiClient: octagonClient,
  }),
});

const stockDataAgent = new Agent({
  name: "Stock Performance Analysis",
  instructions: "You analyze stock price movements, trading volumes, market trends, valuation metrics, and technical indicators.",
  model: new OpenAIResponsesModel({
    model: "octagon-stock-data-agent",
    openaiClient: octagonClient,
  }),
});

const reportAgent = new Agent({
  name: "Investment Report Generation",
  instructions: "You create professional investor-ready company reports based on research data. You can analyze the findings and organize them into a structured report with relevant insights.",
  model: new OpenAIResponsesModel({
    model: "octagon-report-agent",
    openaiClient: octagonClient,
  }),
});

// Create a research workflow coordinator with OpenAI
const openaiClient = new OpenAI({
  apiKey: OPENAI_API_KEY,
});

const coordinator = new Agent({
  name: "Research Coordinator",
  instructions: `
    You coordinate company research by delegating to specialized Octagon agents:
    1. First, ask the Companies Database agent for basic company information
    2. Then, ask the SEC Filings Analysis agent for insights from regulatory filings
    3. Next, ask the Earnings Call Analysis agent for insights from recent earnings calls
    4. Then, ask the Financial Metrics Analysis agent for key financial ratios and metrics
    5. Next, ask the Stock Performance Analysis agent for stock price trends and market data
    6. Finally, ask the Investment Report Generation agent to create a comprehensive investor report
    
    Always explain what you're doing before each handoff.
  `,
  model: new OpenAIResponsesModel({
    model: "gpt-4o",
    openaiClient: openaiClient,
  }),
  handoffs: [
    companiesAgent,
    secFilingsAgent,
    transcriptsAgent,
    financialsAgent,
    stockDataAgent,
    reportAgent
  ],
});

/**
 * Process a streaming response and return the full text
 * @param {Stream} stream - The streaming response
 * @param {string} sourceName - Name of the source agent
 * @returns {Promise<string>} The full response text
 */
async function processStream(stream, sourceName) {
  let fullResponse = "";
  console.log(`\n--- ${sourceName} ---\n`);
  
  for await (const event of stream) {
    if (event.type === "response.output_text.delta") {
      const content = event.delta;
      fullResponse += content;
      process.stdout.write(content);
    }
  }
  
  console.log("\n");
  return fullResponse;
}

/**
 * Run the research workflow directly without using Runner's streaming functionality
 * @param {string} companyName - Name of the company to research
 * @returns {Promise<string>} The final research report
 */
async function runResearchWorkflow(companyName) {
  console.log(`\n🔍 Researching ${companyName}...\n`);
  console.log("=".repeat(60));
  
  // Create a simple input for our coordinator agent
  const userInput = `Create a comprehensive investment research report for ${companyName}.`;
  
  try {
    // Step 1: Basic company information
    console.log("🔍 Step 1: Gathering basic company information...");
    const companiesResponse = await octagonClient.responses.create({
      model: "octagon-companies-agent",
      instructions: "You retrieve basic company information.",
      input: `Provide basic information about ${companyName}`,
      stream: true
    });
    const companiesInfo = await processStream(companiesResponse, "Companies Database");
    
    // Step 2: SEC Filings Analysis
    console.log("\n🔍 Step 2: Analyzing SEC filings...");
    const secResponse = await octagonClient.responses.create({
      model: "octagon-sec-agent",
      instructions: "You analyze SEC filings to extract financial data.",
      input: `Analyze recent SEC filings for ${companyName}. ${companiesInfo}`,
      stream: true
    });
    const secInfo = await processStream(secResponse, "SEC Filings Analysis");
    
    // Step 3: Earnings Call Analysis
    console.log("\n🔍 Step 3: Analyzing earnings call transcripts...");
    const transcriptsResponse = await octagonClient.responses.create({
      model: "octagon-transcripts-agent",
      instructions: "You analyze earnings call transcripts.",
      input: `Analyze recent earnings call transcripts for ${companyName}. ${companiesInfo}`,
      stream: true
    });
    const transcriptsInfo = await processStream(transcriptsResponse, "Earnings Call Analysis");
    
    // Step 4: Financial Metrics Analysis
    console.log("\n🔍 Step 4: Analyzing financial metrics...");
    const financialsResponse = await octagonClient.responses.create({
      model: "octagon-financials-agent",
      instructions: "You analyze financial statements and metrics.",
      input: `Analyze key financial metrics for ${companyName}. ${companiesInfo}`,
      stream: true
    });
    const financialsInfo = await processStream(financialsResponse, "Financial Metrics Analysis");
    
    // Step 5: Stock Performance Analysis
    console.log("\n🔍 Step 5: Analyzing stock performance...");
    const stockResponse = await octagonClient.responses.create({
      model: "octagon-stock-data-agent",
      instructions: "You analyze stock price movements and market trends.",
      input: `Analyze stock performance for ${companyName}. ${companiesInfo}`,
      stream: true
    });
    const stockInfo = await processStream(stockResponse, "Stock Performance Analysis");
    
    // Step 6: Generate final report
    console.log("\n🔍 Step 6: Generating comprehensive report...");
    const reportResponse = await openaiClient.responses.create({
      model: "gpt-4o",
      instructions: "You create professional investor-ready company reports.",
      input: `Create a comprehensive investment report for ${companyName} based on this research:

Company Info: ${companiesInfo}

SEC Filings: ${secInfo}

Earnings Calls: ${transcriptsInfo}

Financials: ${financialsInfo}

Stock Performance: ${stockInfo}`,
      stream: true
    });
    const finalReport = await processStream(reportResponse, "Investment Report Generation");
    
    console.log("\n" + "=".repeat(60));
    console.log("\n✅ Research complete!");
    
    return finalReport;
  } catch (error) {
    console.error(`\n❌ Error during research: ${error.message}`);
    return `Error: ${error.message}`;
  }
}

/**
 * Main function to run the demo
 */
async function main() {
  // The company to research - use a public company for best results with these agents
  const companyName = "Apple";
  
  console.log("\n🤖 Octagon Agents Demo");
  console.log("This demo shows how easily Octagon's specialized agents can be used for financial research");
  console.log(`OpenAI API Key: ${OPENAI_API_KEY.substring(0, 6)}...`);
  console.log(`Octagon API Key: ${OCTAGON_API_KEY.substring(0, 6)}...`);
  
  // Run the research workflow
  await runResearchWorkflow(companyName);
}

// Run the main function
main().catch(console.error);

How the Research Workflow Works

The example code demonstrates two approaches to creating a research workflow:

  1. Using the Agents SDK Handoff Mechanism: The first part of the code sets up a coordinator agent with handoffs to specialized Octagon agents. This uses the official Agents SDK pattern for agent delegation.

  2. Manual Implementation: The second part (the run_research_workflow function) shows a manual implementation of the research workflow, which provides more control over the process and demonstrates how each agent is called in sequence.

Key Components

  1. Specialized Agents: Each Octagon agent is specialized for a specific type of financial analysis:

    • Companies Database agent for basic company information
    • SEC Filings agent for regulatory filing analysis
    • Earnings Call agent for transcript analysis
    • Financial Metrics agent for financial statement analysis
    • Stock Performance agent for market data analysis
    • Report Generation agent for creating comprehensive reports
  2. Coordinator Agent: The OpenAI GPT-4o model serves as a coordinator that orchestrates the workflow and delegates to specialized agents.

  3. Context Passing: Each agent's findings are passed as context to subsequent agents, ensuring a cohesive analysis flow.

Running the Example

To run this example:

  1. Save the code to a file (e.g., octagon_research_workflow.py or octagon_research_workflow.js)
  2. Install the required dependencies:
cURL
pip install openai openai-agents
cURL
npm install openai openai-agents dotenv
  1. Replace the API key placeholders with your actual keys
  2. Run the script:
cURL
python octagon_research_workflow.py
cURL
node octagon_research_workflow.js

Customizing the Workflow

You can customize this workflow for your specific research needs:

  • Different Company: Change the company_name variable to research a different company
  • Additional Agents: Add more specialized Octagon agents to the workflow
  • Custom Instructions: Modify the instructions for each agent to focus on specific aspects of financial analysis
  • Alternative Coordinator: Use a different OpenAI model for coordination, such as GPT-4 Turbo or GPT-3.5 Turbo
  • Different Output Format: Customize the report generation step to output in different formats (PDF, JSON, etc.)

Next Steps