Files
wehub-resource-sync 0d3cb498a3
Deploy local.promptfoo.app / Deploy to Cloudflare Pages (push) Waiting to run
Test and Publish Multi-arch Docker Image / test (push) Waiting to run
Test and Publish Multi-arch Docker Image / build-docker-and-push-digests (map[digest-suffix:linux-amd64 platform:linux/amd64 runner:ubuntu-latest]) (push) Blocked by required conditions
Test and Publish Multi-arch Docker Image / build-docker-and-push-digests (map[digest-suffix:linux-arm64 platform:linux/arm64 runner:ubuntu-24.04-arm]) (push) Blocked by required conditions
Test and Publish Multi-arch Docker Image / merge-docker-digests (push) Blocked by required conditions
Test and Publish Multi-arch Docker Image / Attest Multi-arch Image (push) Blocked by required conditions
Validate Renovate Config / Validate Renovate Configuration (push) Waiting to run
CI / Shell Format Check (push) Has been cancelled
CI / Check Ruby (3.4) (push) Has been cancelled
CI / CI Config (push) Has been cancelled
CI / Test on Node ${{ matrix.node }} and ${{ matrix.os }}${{ matrix.shard && format(' (shard {0}/3)', matrix.shard) || '' }} (push) Has been cancelled
CI / Build on Node ${{ matrix.node }} (push) Has been cancelled
CI / Style Check (push) Has been cancelled
CI / Generate Assets (push) Has been cancelled
CI / Check Python (3.14) (push) Has been cancelled
CI / Check Python (3.9) (push) Has been cancelled
CI / Build Docs (push) Has been cancelled
CI / Code Scan Action (push) Has been cancelled
CI / Site tests (push) Has been cancelled
CI / webui tests (push) Has been cancelled
CI / Run Integration Tests (push) Has been cancelled
CI / Run Smoke Tests (push) Has been cancelled
CI / Go Tests (push) Has been cancelled
CI / Share Test (push) Has been cancelled
CI / Redteam (Production API) (push) Has been cancelled
CI / Redteam (Staging API) (push) Has been cancelled
CI / GitHub Actions Lint (push) Has been cancelled
CI / Check Ruby (3.0) (push) Has been cancelled
release-please / release-please (push) Has been cancelled
release-please / build (push) Has been cancelled
release-please / publish-npm (push) Has been cancelled
release-please / publish-npm-backfill (push) Has been cancelled
release-please / docker (push) Has been cancelled
release-please / publish-code-scan-action (push) Has been cancelled
release-please / attest-code-scan-action (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:24:08 +08:00

72 lines
2.7 KiB
Python

import asyncio
import os
from langchain_openai import ChatOpenAI
from langgraph.graph import StateGraph
from pydantic import BaseModel
# Load the OpenAI API key from environment variable
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
# Define the data structure (state) passed between nodes in the graph
class ResearchState(BaseModel):
query: str # The original research query
raw_info: str = "" # Raw fetched or mocked information
summary: str = "" # Final summarized result
# Function to create and return the research agent graph
def get_research_agent(model="gpt-4o"):
# Initialize the OpenAI LLM with the specified model and API key
llm = ChatOpenAI(model=model, api_key=OPENAI_API_KEY)
# Create a stateful graph with ResearchState as the shared state type
graph = StateGraph(ResearchState)
# Node 1: Simulate a search function that populates raw_info
def search_info(state: ResearchState) -> ResearchState:
# TODO: Replace with real search API integration
mock_info = f"(Mock) According to recent sources, the latest trends in {state.query} include X, Y, Z."
return ResearchState(query=state.query, raw_info=mock_info)
# Node 2: Use the LLM to summarize the raw_info content
def summarize_info(state: ResearchState) -> ResearchState:
prompt = f"Summarize the following:\n{state.raw_info}"
response = llm.invoke(prompt) # Call the LLM to get the summary
return ResearchState(
query=state.query, raw_info=state.raw_info, summary=response.content
)
# Node 3: Format the final summary for output
def output_summary(state: ResearchState) -> ResearchState:
final_summary = f"Research summary for '{state.query}': {state.summary}"
return ResearchState(
query=state.query, raw_info=state.raw_info, summary=final_summary
)
# Add nodes to the graph
graph.add_node("search_info", search_info)
graph.add_node("summarize_info", summarize_info)
graph.add_node("output_summary", output_summary)
# Define the flow between nodes (edges)
graph.add_edge("search_info", "summarize_info")
graph.add_edge("summarize_info", "output_summary")
# Set the starting and ending points of the graph
graph.set_entry_point("search_info")
graph.set_finish_point("output_summary")
# Compile the graph into an executable app
return graph.compile()
# Function to run the research agent with a given query prompt
def run_research_agent(prompt):
# Get the compiled graph application
app = get_research_agent()
# Run the asynchronous invocation and get the result
result = asyncio.run(app.ainvoke(ResearchState(query=prompt)))
return result