mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
Python: Lab: Updates to GAIA module (#1763)
* Lab: Updates to GAIA module * update * emoj! * fix lint * update lab test workflow to only trigger for python changes * lint * lint * Fix broken OpenAI agents JS documentation link
This commit is contained in:
committed by
GitHub
Unverified
parent
7431b46bf0
commit
1543370027
@@ -43,21 +43,6 @@ async def main() -> None:
|
||||
|
||||
See the [gaia_sample.py](./samples/gaia_sample.py) for more detail.
|
||||
|
||||
### Run the evaluation
|
||||
|
||||
Run the evaluation script using `uv`:
|
||||
|
||||
```bash
|
||||
uv run python run_gaia.py
|
||||
```
|
||||
|
||||
By default, the script will first look for cached GAIA data in the `data_gaia_hub` directory,
|
||||
and download it if not found.
|
||||
The result will be saved to `gaia_results_<timestamp>.jsonl`.
|
||||
|
||||
**Don't run the script inside this directory because it will confuse the local `agent_framework` namespace
|
||||
package with the real one.**
|
||||
|
||||
## View results
|
||||
|
||||
We provide a console viewer for reading GAIA results:
|
||||
|
||||
@@ -54,17 +54,29 @@ class GAIATelemetryConfig:
|
||||
if not self.enable_tracing:
|
||||
return
|
||||
|
||||
from agent_framework.observability import setup_observability
|
||||
# If only file tracing is requested (no OTLP or Application Insights),
|
||||
# skip the default setup_observability which adds console exporter
|
||||
if self.trace_to_file and not self.otlp_endpoint and not self.applicationinsights_connection_string:
|
||||
# Set up minimal tracing with only file export
|
||||
from opentelemetry.sdk.trace import TracerProvider
|
||||
from opentelemetry.trace import set_tracer_provider
|
||||
|
||||
setup_observability(
|
||||
enable_sensitive_data=True, # Enable for detailed task traces
|
||||
otlp_endpoint=self.otlp_endpoint,
|
||||
applicationinsights_connection_string=self.applicationinsights_connection_string,
|
||||
)
|
||||
|
||||
# Set up local file export if requested
|
||||
if self.trace_to_file:
|
||||
tracer_provider = TracerProvider()
|
||||
set_tracer_provider(tracer_provider)
|
||||
self._setup_file_export()
|
||||
else:
|
||||
# Use full observability setup for OTLP/AppInsights
|
||||
from agent_framework.observability import setup_observability
|
||||
|
||||
setup_observability(
|
||||
enable_sensitive_data=True, # Enable for detailed task traces
|
||||
otlp_endpoint=self.otlp_endpoint,
|
||||
applicationinsights_connection_string=self.applicationinsights_connection_string,
|
||||
)
|
||||
|
||||
# Set up local file export if requested
|
||||
if self.trace_to_file:
|
||||
self._setup_file_export()
|
||||
|
||||
def _setup_file_export(self) -> None:
|
||||
"""Set up local file export for traces."""
|
||||
@@ -204,29 +216,87 @@ def _load_gaia_local(repo_dir: Path, wanted_levels: list[int] | None = None, max
|
||||
"""Load GAIA tasks from local repository directory."""
|
||||
tasks: list[Task] = []
|
||||
|
||||
for p in repo_dir.rglob("metadata.jsonl"):
|
||||
for rec in _read_jsonl(p):
|
||||
# Robustly extract fields used across variants
|
||||
q = rec.get("Question") or rec.get("question") or rec.get("query") or rec.get("prompt")
|
||||
ans = rec.get("Final answer") or rec.get("answer") or rec.get("final_answer")
|
||||
qid = str(
|
||||
rec.get("task_id")
|
||||
or rec.get("question_id")
|
||||
or rec.get("id")
|
||||
or rec.get("uuid")
|
||||
or f"{p.stem}:{len(tasks)}"
|
||||
)
|
||||
lvl = rec.get("Level") or rec.get("level")
|
||||
fname = rec.get("file_name") or rec.get("filename") or None
|
||||
# First try to load from parquet files (new format)
|
||||
# Prioritize validation split over test split (validation has answers)
|
||||
parquet_files = sorted(
|
||||
repo_dir.rglob("metadata*.parquet"), key=lambda p: (0 if "validation" in str(p) else 1, str(p))
|
||||
)
|
||||
|
||||
# Only evaluate examples with public answers (dev/validation split)
|
||||
if not q or ans is None:
|
||||
continue
|
||||
for p in parquet_files:
|
||||
try:
|
||||
import pyarrow.parquet as pq
|
||||
|
||||
if wanted_levels and (lvl not in wanted_levels):
|
||||
continue
|
||||
table = pq.read_table(p)
|
||||
for row in table.to_pylist():
|
||||
# Robustly extract fields used across variants
|
||||
q = row.get("Question") or row.get("question") or row.get("query") or row.get("prompt")
|
||||
ans = row.get("Final answer") or row.get("answer") or row.get("final_answer")
|
||||
qid = str(
|
||||
row.get("task_id")
|
||||
or row.get("question_id")
|
||||
or row.get("id")
|
||||
or row.get("uuid")
|
||||
or f"{p.stem}:{len(tasks)}"
|
||||
)
|
||||
lvl = row.get("Level") or row.get("level")
|
||||
|
||||
tasks.append(Task(task_id=qid, question=q, answer=str(ans), level=lvl, file_name=fname, metadata=rec))
|
||||
# Convert level to int if it's a string
|
||||
def _parse_level(lvl: Any) -> int | None:
|
||||
"""Parse level value to integer if possible."""
|
||||
if isinstance(lvl, int):
|
||||
return lvl
|
||||
if isinstance(lvl, str) and lvl.isdigit():
|
||||
return int(lvl)
|
||||
return None
|
||||
|
||||
lvl = _parse_level(lvl)
|
||||
fname = row.get("file_name") or row.get("filename") or None
|
||||
|
||||
# Only evaluate examples with public answers (dev/validation split)
|
||||
# Skip if no question, no answer, or answer is placeholder like "?"
|
||||
if not q or ans is None or str(ans).strip() in ["?", ""]:
|
||||
continue
|
||||
|
||||
if wanted_levels and (lvl not in wanted_levels):
|
||||
continue
|
||||
|
||||
tasks.append(Task(task_id=qid, question=q, answer=str(ans), level=lvl, file_name=fname, metadata=row))
|
||||
except ImportError:
|
||||
print("Warning: pyarrow not installed. Install with: pip install pyarrow")
|
||||
continue
|
||||
except Exception as e:
|
||||
print(f"Warning: Could not load parquet file {p}: {e}")
|
||||
continue
|
||||
|
||||
# Fall back to jsonl files (old format) if no parquet files found
|
||||
if not tasks:
|
||||
for p in repo_dir.rglob("metadata.jsonl"):
|
||||
for rec in _read_jsonl(p):
|
||||
# Robustly extract fields used across variants
|
||||
q = rec.get("Question") or rec.get("question") or rec.get("query") or rec.get("prompt")
|
||||
ans = rec.get("Final answer") or rec.get("answer") or rec.get("final_answer")
|
||||
qid = str(
|
||||
rec.get("task_id")
|
||||
or rec.get("question_id")
|
||||
or rec.get("id")
|
||||
or rec.get("uuid")
|
||||
or f"{p.stem}:{len(tasks)}"
|
||||
)
|
||||
lvl = rec.get("Level") or rec.get("level")
|
||||
# Convert level to int if it's a string
|
||||
if isinstance(lvl, str) and lvl.isdigit():
|
||||
lvl = int(lvl)
|
||||
fname = rec.get("file_name") or rec.get("filename") or None
|
||||
|
||||
# Only evaluate examples with public answers (dev/validation split)
|
||||
# Skip if no question, no answer, or answer is placeholder like "?"
|
||||
if not q or ans is None or str(ans).strip() in ["?", ""]:
|
||||
continue
|
||||
|
||||
if wanted_levels and (lvl not in wanted_levels):
|
||||
continue
|
||||
|
||||
tasks.append(Task(task_id=qid, question=q, answer=str(ans), level=lvl, file_name=fname, metadata=rec))
|
||||
|
||||
# Shuffle to help with rate-limits and fairness if max_n is provided
|
||||
random.shuffle(tasks)
|
||||
@@ -290,7 +360,6 @@ class GAIA:
|
||||
"with access to gaia-benchmark/GAIA."
|
||||
)
|
||||
|
||||
print(f"Downloading GAIA dataset to {self.data_dir}...")
|
||||
from huggingface_hub import snapshot_download
|
||||
|
||||
local_dir = snapshot_download( # type: ignore
|
||||
@@ -438,8 +507,6 @@ class GAIA:
|
||||
"Make sure you have dataset access and selected valid levels."
|
||||
)
|
||||
|
||||
print(f"Running {len(tasks)} GAIA tasks (levels={levels}) with {parallel} parallel workers...")
|
||||
|
||||
# Update benchmark span with task info
|
||||
if benchmark_span:
|
||||
benchmark_span.set_attributes({
|
||||
@@ -473,17 +540,12 @@ class GAIA:
|
||||
"gaia.benchmark.avg_runtime_seconds": avg_runtime,
|
||||
})
|
||||
|
||||
print("\nGAIA Benchmark Results:")
|
||||
print(f"Accuracy: {accuracy:.3f} ({correct}/{len(results)})")
|
||||
print(f"Average runtime: {avg_runtime:.2f}s")
|
||||
|
||||
# Save results if requested
|
||||
if out:
|
||||
with self.tracer.start_as_current_span(
|
||||
"gaia.results.save", kind=SpanKind.INTERNAL, attributes={"gaia.results.output_file": out}
|
||||
):
|
||||
self._save_results(results, out)
|
||||
print(f"Results saved to {out}")
|
||||
|
||||
return results
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
"""Azure AI Agent factory for GAIA benchmark.
|
||||
|
||||
This module provides a factory function to create an Azure AI agent
|
||||
configured for GAIA benchmark tasks.
|
||||
|
||||
Required Environment Variables:
|
||||
AZURE_AI_PROJECT_ENDPOINT: Azure AI project endpoint URL
|
||||
AZURE_AI_MODEL_DEPLOYMENT_NAME: Name of the model deployment to use
|
||||
|
||||
Optional Environment Variables:
|
||||
BING_CONNECTION_NAME: Name of the Bing connection for web search
|
||||
OR
|
||||
BING_CONNECTION_ID: ID of the Bing connection for web search
|
||||
|
||||
Authentication:
|
||||
Uses Azure CLI credentials via AzureCliCredential.
|
||||
Run `az login` before executing to authenticate.
|
||||
|
||||
Example:
|
||||
export AZURE_AI_PROJECT_ENDPOINT="https://your-project.azure.com"
|
||||
export AZURE_AI_MODEL_DEPLOYMENT_NAME="gpt-4o"
|
||||
export BING_CONNECTION_NAME="bing-grounding-connection"
|
||||
az login
|
||||
"""
|
||||
|
||||
from collections.abc import AsyncIterator
|
||||
from contextlib import asynccontextmanager
|
||||
|
||||
from agent_framework import ChatAgent, HostedCodeInterpreterTool, HostedWebSearchTool
|
||||
from agent_framework.azure import AzureAIAgentClient
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def create_gaia_agent() -> AsyncIterator[ChatAgent]:
|
||||
"""Create an Azure AI agent configured for GAIA benchmark tasks.
|
||||
|
||||
The agent is configured with:
|
||||
- Bing Search tool for web information retrieval
|
||||
- Code Interpreter tool for calculations and data analysis
|
||||
|
||||
Yields:
|
||||
ChatAgent: A configured agent ready to run GAIA tasks.
|
||||
|
||||
Example:
|
||||
async with create_gaia_agent() as agent:
|
||||
result = await agent.run("What is the capital of France?")
|
||||
print(result.text)
|
||||
"""
|
||||
async with (
|
||||
AzureCliCredential() as credential,
|
||||
AzureAIAgentClient(async_credential=credential).create_agent(
|
||||
name="GaiaAgent",
|
||||
instructions="Solve tasks to your best ability. Use Bing Search to find "
|
||||
"information and Code Interpreter to perform calculations and data analysis.",
|
||||
tools=[
|
||||
HostedWebSearchTool(
|
||||
name="Bing Grounding Search",
|
||||
description="Search the web for current information using Bing",
|
||||
),
|
||||
HostedCodeInterpreterTool(),
|
||||
],
|
||||
) as agent,
|
||||
):
|
||||
yield agent
|
||||
@@ -2,43 +2,148 @@
|
||||
|
||||
"""GAIA Benchmark Sample.
|
||||
|
||||
To run this sample, execute it from the root directory of the agent-framework repository:
|
||||
cd /path/to/agent-framework
|
||||
uv run python python/packages/lab/gaia/gaia_sample.py
|
||||
Run the GAIA (General AI Assistant) benchmark with configurable agent providers,
|
||||
telemetry options, and benchmark parameters.
|
||||
|
||||
This avoids namespace package conflicts that occur when running from within the gaia package directory.
|
||||
Agent Providers:
|
||||
- Azure AI (default): See azure_ai_agent.py for required environment variables
|
||||
- OpenAI: See openai_agent.py for required environment variables
|
||||
|
||||
Prerequisites:
|
||||
1. Set HF_TOKEN environment variable with your Hugging Face token:
|
||||
- Get token: https://huggingface.co/settings/tokens
|
||||
- Request dataset access: https://huggingface.co/datasets/gaia-benchmark/GAIA
|
||||
- Set: export HF_TOKEN="your-huggingface-token"
|
||||
|
||||
2. Configure your chosen agent provider (see agent module files for details)
|
||||
|
||||
Telemetry:
|
||||
When using --otlp-endpoint or --trace-file, OpenTelemetry will export trace data
|
||||
in JSON format to the console in addition to the configured endpoints. This is
|
||||
expected behavior from the OpenTelemetry SDK and provides visibility into the
|
||||
telemetry being captured. The traces are also exported to:
|
||||
- OTLP endpoint (e.g., Aspire Dashboard) if --otlp-endpoint is specified
|
||||
- Local file if --trace-file is specified
|
||||
|
||||
To suppress console output, redirect stderr: `python gaia_sample.py 2>/dev/null`
|
||||
|
||||
Usage:
|
||||
# Run with default settings (Azure AI agent)
|
||||
uv run python gaia_sample.py
|
||||
|
||||
# Run with OpenAI agent
|
||||
uv run python gaia_sample.py --agent-provider openai
|
||||
|
||||
# Run with telemetry export to Aspire Dashboard
|
||||
uv run python gaia_sample.py --otlp-endpoint http://localhost:4318
|
||||
|
||||
# See all options
|
||||
uv run python gaia_sample.py --help
|
||||
"""
|
||||
|
||||
from agent_framework.azure import AzureAIAgentClient
|
||||
import argparse
|
||||
|
||||
from agent_framework.lab.gaia import GAIA, Evaluation, GAIATelemetryConfig, Prediction, Task
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
|
||||
|
||||
def evaluate_task(task: Task, prediction: Prediction) -> Evaluation:
|
||||
async def evaluate_task(task: Task, prediction: Prediction) -> Evaluation:
|
||||
"""Evaluate the prediction for a given task."""
|
||||
# Simple evaluation: check if the prediction contains the answer
|
||||
is_correct = (task.answer or "").lower() in prediction.prediction.lower()
|
||||
return Evaluation(is_correct=is_correct, score=1 if is_correct else 0)
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
"""Run GAIA benchmark with telemetry configuration."""
|
||||
async def main(
|
||||
otlp_endpoint: str | None = None,
|
||||
trace_file: str | None = None,
|
||||
result_file: str | None = None,
|
||||
data_dir: str | None = None,
|
||||
agent_provider: str = "azure-ai",
|
||||
level: int | list[int] = 1,
|
||||
max_n: int = 2,
|
||||
parallel: int = 1,
|
||||
timeout: int = 120,
|
||||
) -> None:
|
||||
"""Run GAIA benchmark with telemetry configuration.
|
||||
|
||||
Args:
|
||||
otlp_endpoint: Optional OTLP endpoint URL for exporting traces (e.g., http://localhost:4318)
|
||||
trace_file: Optional file path to export traces to. If None, traces won't be saved to file.
|
||||
result_file: Optional file path to save benchmark results. If None, results won't be saved to file.
|
||||
data_dir: Directory to cache GAIA dataset. If None, uses temp directory.
|
||||
agent_provider: Agent provider to use: 'azure-ai' or 'openai' (default: 'azure-ai')
|
||||
level: GAIA level(s) to run (1, 2, or 3)
|
||||
max_n: Maximum number of tasks to run per level
|
||||
parallel: Number of parallel tasks to run
|
||||
timeout: Timeout per task in seconds
|
||||
"""
|
||||
# Check for required Hugging Face token
|
||||
import logging
|
||||
import os
|
||||
|
||||
# Suppress console logging for traces and verbose SDK output
|
||||
logging.getLogger("opentelemetry").setLevel(logging.ERROR)
|
||||
logging.getLogger("azure").setLevel(logging.WARNING)
|
||||
logging.getLogger("agent_framework").setLevel(logging.WARNING)
|
||||
logging.getLogger("httpx").setLevel(logging.WARNING)
|
||||
logging.getLogger("httpcore").setLevel(logging.WARNING)
|
||||
|
||||
# Suppress OpenTelemetry exporters console output
|
||||
import os as _os
|
||||
|
||||
_os.environ.setdefault("OTEL_PYTHON_LOG_LEVEL", "error")
|
||||
|
||||
# Print trace export configuration
|
||||
print("\n=== Telemetry Configuration ===")
|
||||
if trace_file:
|
||||
print(f"📁 Trace file: {os.path.abspath(trace_file)}")
|
||||
else:
|
||||
print("📁 Trace file: disabled")
|
||||
|
||||
if otlp_endpoint:
|
||||
print(f"🌐 OTLP endpoint: {otlp_endpoint}")
|
||||
else:
|
||||
print("🌐 OTLP endpoint: disabled")
|
||||
|
||||
if result_file:
|
||||
print(f"📊 Results file: {os.path.abspath(result_file)}")
|
||||
else:
|
||||
print("📊 Results file: disabled")
|
||||
|
||||
print("\n=== Run Configuration ===")
|
||||
print(f"🤖 Agent provider: {agent_provider}")
|
||||
if data_dir:
|
||||
print(f"📂 Data directory: {os.path.abspath(data_dir)}")
|
||||
else:
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
default_data_dir = Path(tempfile.gettempdir()) / "data_gaia_hub"
|
||||
print(f"📂 Data directory: {default_data_dir} (default)")
|
||||
print(f"🎯 Level: {level}")
|
||||
print(f"🔢 Max tasks: {max_n}")
|
||||
print(f"⚡ Parallel: {parallel}")
|
||||
print(f"⏱️ Timeout: {timeout}s")
|
||||
print()
|
||||
|
||||
# Import the appropriate agent factory based on provider
|
||||
if agent_provider == "azure-ai":
|
||||
from azure_ai_agent import create_gaia_agent
|
||||
elif agent_provider == "openai":
|
||||
from openai_agent import create_gaia_agent
|
||||
else:
|
||||
raise ValueError(f"Unknown agent provider: {agent_provider}. Use 'azure-ai' or 'openai'.")
|
||||
|
||||
# Configure telemetry for tracing
|
||||
telemetry_config = GAIATelemetryConfig(
|
||||
enable_tracing=True, # Enable OpenTelemetry tracing
|
||||
# Configure local file tracing
|
||||
trace_to_file=True, # Export traces to local file
|
||||
file_path="gaia_benchmark_traces.jsonl", # Custom file path for traces
|
||||
trace_to_file=trace_file is not None, # Export traces to local file only if path provided
|
||||
file_path=trace_file, # Custom file path for traces (can be None)
|
||||
otlp_endpoint=otlp_endpoint, # Optional OTLP endpoint for Aspire Dashboard or other collectors
|
||||
)
|
||||
|
||||
# Create a single agent once and reuse it for all tasks
|
||||
async with (
|
||||
AzureCliCredential() as credential,
|
||||
AzureAIAgentClient(async_credential=credential).create_agent(
|
||||
name="GaiaAgent",
|
||||
instructions="Solve tasks to your best ability.",
|
||||
) as agent,
|
||||
):
|
||||
async with create_gaia_agent() as agent:
|
||||
|
||||
async def run_task(task: Task) -> Prediction:
|
||||
"""Run a single GAIA task and return the prediction using the shared agent."""
|
||||
@@ -49,30 +154,142 @@ async def main() -> None:
|
||||
return Prediction(prediction=result.text, messages=result.messages)
|
||||
|
||||
# Create the GAIA benchmark runner with telemetry configuration
|
||||
runner = GAIA(evaluator=evaluate_task, telemetry_config=telemetry_config)
|
||||
runner = GAIA(
|
||||
evaluator=evaluate_task,
|
||||
telemetry_config=telemetry_config,
|
||||
data_dir=data_dir,
|
||||
)
|
||||
|
||||
# Run the benchmark with the task runner.
|
||||
# By default, this will check for locally cached benchmark data and checkout
|
||||
# the latest version from HuggingFace if not found.
|
||||
# Note: The GAIA dataset has been updated to use Parquet format.
|
||||
# If you encounter issues, try using validation split which has labeled data.
|
||||
results = await runner.run(
|
||||
run_task,
|
||||
level=1, # Level 1, 2, or 3 or multiple levels like [1, 2]
|
||||
max_n=5, # Maximum number of tasks to run per level
|
||||
parallel=2, # Number of parallel tasks to run
|
||||
timeout=60, # Timeout per task in seconds
|
||||
out="gaia_results_level1.jsonl", # Output file to save results including detailed traces (optional)
|
||||
level=level,
|
||||
max_n=max_n,
|
||||
parallel=parallel,
|
||||
timeout=timeout,
|
||||
out=result_file, # Output file to save results including detailed traces (optional, None = no file output)
|
||||
)
|
||||
|
||||
# Print the results.
|
||||
print("\n=== GAIA Benchmark Results ===")
|
||||
for result in results:
|
||||
print(f"\n--- Task ID: {result.task_id} ---")
|
||||
print(f"Task: {result.task.question[:100]}...")
|
||||
print(f"Prediction: {result.prediction.prediction}")
|
||||
print(f"Evaluation: Correct={result.evaluation.is_correct}, Score={result.evaluation.score}")
|
||||
# Print summary similar to the viewer in gaia.py
|
||||
total = len(results)
|
||||
correct = sum(1 for r in results if r.evaluation.is_correct)
|
||||
accuracy = correct / total if total > 0 else 0.0
|
||||
avg_runtime = sum(r.runtime_seconds or 0 for r in results) / total if total > 0 else 0.0
|
||||
|
||||
print("\n=== GAIA Benchmark Summary ===")
|
||||
print(f"📝 Total: {total}, ✅ Correct: {correct}, 🎯 Accuracy: {accuracy:.3f}")
|
||||
print(f"⏱️ Average runtime: {avg_runtime:.2f}s")
|
||||
if result_file:
|
||||
print(f"💾 Detailed results saved to: {result_file}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import asyncio
|
||||
|
||||
asyncio.run(main())
|
||||
# Parse command line arguments
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Run GAIA benchmark with optional telemetry export to OTLP endpoint and/or file",
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
epilog="""
|
||||
Examples:
|
||||
# Run with default settings
|
||||
python gaia_sample.py
|
||||
|
||||
# Run with custom data directory
|
||||
python gaia_sample.py --data-dir ./gaia_data
|
||||
|
||||
# Run with OpenAI agent provider
|
||||
python gaia_sample.py --agent-provider openai
|
||||
|
||||
# Run with trace file export
|
||||
python gaia_sample.py --trace-file gaia_benchmark_traces.jsonl
|
||||
|
||||
# Run level 2 tasks with 5 maximum tasks
|
||||
python gaia_sample.py --level 2 --max-n 5
|
||||
|
||||
# Run with OTLP export to Aspire Dashboard and custom settings
|
||||
python gaia_sample.py --otlp-endpoint http://localhost:4318 --level 1 --max-n 10 --parallel 2
|
||||
|
||||
# Run with all options configured
|
||||
python gaia_sample.py --agent-provider openai \
|
||||
--trace-file traces.jsonl \
|
||||
--result-file results.jsonl \
|
||||
--otlp-endpoint http://localhost:4318 --level 1 --max-n 5 --parallel 2 --timeout 180
|
||||
""",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--otlp-endpoint",
|
||||
type=str,
|
||||
default=None,
|
||||
help="OTLP endpoint URL for exporting traces (e.g., http://localhost:4318 for Aspire Dashboard)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--trace-file",
|
||||
type=str,
|
||||
default=None,
|
||||
help="File path to export traces to (e.g., gaia_benchmark_traces.jsonl). "
|
||||
"If not set, traces won't be saved to file.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--result-file",
|
||||
type=str,
|
||||
default="gaia_results_level1.jsonl",
|
||||
help="File path to save benchmark results (default: gaia_results_level1.jsonl)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--data-dir",
|
||||
type=str,
|
||||
default=None,
|
||||
help="Directory to cache GAIA dataset. If not set, uses system temp directory.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--agent-provider",
|
||||
type=str,
|
||||
default="azure-ai",
|
||||
choices=["azure-ai", "openai"],
|
||||
help="Agent provider to use: 'azure-ai' or 'openai' (default: 'azure-ai')",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--level",
|
||||
type=int,
|
||||
default=1,
|
||||
choices=[1, 2, 3],
|
||||
help="GAIA benchmark level to run: 1, 2, or 3 (default: 1)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--max-n",
|
||||
type=int,
|
||||
default=2,
|
||||
help="Maximum number of tasks to run per level (default: 2)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--parallel",
|
||||
type=int,
|
||||
default=1,
|
||||
help="Number of parallel tasks to run (default: 1)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--timeout",
|
||||
type=int,
|
||||
default=120,
|
||||
help="Timeout per task in seconds (default: 120)",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
asyncio.run(
|
||||
main(
|
||||
otlp_endpoint=args.otlp_endpoint,
|
||||
trace_file=args.trace_file,
|
||||
result_file=args.result_file,
|
||||
data_dir=args.data_dir,
|
||||
agent_provider=args.agent_provider,
|
||||
level=args.level,
|
||||
max_n=args.max_n,
|
||||
parallel=args.parallel,
|
||||
timeout=args.timeout,
|
||||
)
|
||||
)
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
"""OpenAI Agent factory for GAIA benchmark.
|
||||
|
||||
This module provides a factory function to create an OpenAI agent
|
||||
configured for GAIA benchmark tasks using the OpenAI Responses API.
|
||||
|
||||
Required Environment Variables:
|
||||
OPENAI_API_KEY: Your OpenAI API key
|
||||
OPENAI_RESPONSES_MODEL_ID: Model to use with Responses API (e.g., gpt-4o, gpt-4o-mini)
|
||||
|
||||
Optional Environment Variables:
|
||||
OPENAI_BASE_URL: Custom API base URL if using a proxy or compatible service
|
||||
OPENAI_ORG_ID: Organization ID for OpenAI API (if applicable)
|
||||
|
||||
Authentication:
|
||||
Uses OPENAI_API_KEY environment variable.
|
||||
Get your API key from: https://platform.openai.com/api-keys
|
||||
|
||||
Example:
|
||||
export OPENAI_API_KEY="sk-..."
|
||||
export OPENAI_RESPONSES_MODEL_ID="gpt-4o"
|
||||
"""
|
||||
|
||||
from collections.abc import AsyncIterator
|
||||
from contextlib import asynccontextmanager
|
||||
|
||||
from agent_framework import ChatAgent, HostedCodeInterpreterTool, HostedWebSearchTool
|
||||
from agent_framework.openai import OpenAIResponsesClient
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def create_gaia_agent() -> AsyncIterator[ChatAgent]:
|
||||
"""Create an OpenAI agent configured for GAIA benchmark tasks.
|
||||
|
||||
Uses OpenAI Responses API for enhanced capabilities.
|
||||
|
||||
The agent is configured with:
|
||||
- Web Search tool for information retrieval
|
||||
- Code Interpreter tool for calculations and data analysis
|
||||
|
||||
Yields:
|
||||
ChatAgent: A configured agent ready to run GAIA tasks.
|
||||
|
||||
Example:
|
||||
async with create_gaia_agent() as agent:
|
||||
result = await agent.run("What is the capital of France?")
|
||||
print(result.text)
|
||||
"""
|
||||
chat_client = OpenAIResponsesClient()
|
||||
|
||||
async with chat_client.create_agent(
|
||||
name="GaiaAgent",
|
||||
instructions="Solve tasks to your best ability. Use Web Search to find "
|
||||
"information and Code Interpreter to perform calculations and data analysis.",
|
||||
tools=[
|
||||
HostedWebSearchTool(
|
||||
name="Web Search",
|
||||
description="Search the web for current information",
|
||||
),
|
||||
HostedCodeInterpreterTool(),
|
||||
],
|
||||
) as agent:
|
||||
yield agent
|
||||
@@ -32,6 +32,7 @@ gaia = [
|
||||
"tqdm>=4.60.0",
|
||||
"huggingface-hub>=0.20.0",
|
||||
"orjson>=3.8.0",
|
||||
"pyarrow>=10.0.0", # For reading parquet files
|
||||
]
|
||||
|
||||
# Lightning RL training module dependencies
|
||||
@@ -111,7 +112,13 @@ extend = "../../pyproject.toml"
|
||||
extend-exclude = ["**/data/**"]
|
||||
|
||||
[tool.ruff.lint]
|
||||
ignore = ["T201", "ASYNC230", "INP001"] # Allow print statements, blocking file operations, and implicit namespace packages in lab modules
|
||||
ignore = [
|
||||
"T201", # Allow print statements in experimental/lab code for debugging purposes.
|
||||
"ASYNC230", # Allow 'await' outside of async functions in test and experimental code.
|
||||
"INP001", # Ignore missing __init__.py in namespace packages.
|
||||
"RUF029", # Allow use of 'assert' statements; assertions are used for internal checks in experimental code.
|
||||
"ASYNC240", # Allow 'async for' outside of async functions in test and experimental code.
|
||||
]
|
||||
|
||||
[tool.coverage.run]
|
||||
omit = [
|
||||
|
||||
Generated
+61
-2
@@ -297,6 +297,7 @@ gaia = [
|
||||
{ name = "huggingface-hub", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
|
||||
{ name = "opentelemetry-api", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
|
||||
{ name = "orjson", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
|
||||
{ name = "pyarrow", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
|
||||
{ name = "pydantic", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
|
||||
{ name = "tqdm", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" },
|
||||
]
|
||||
@@ -344,6 +345,7 @@ requires-dist = [
|
||||
{ name = "numpy", marker = "extra == 'tau2'" },
|
||||
{ name = "opentelemetry-api", marker = "extra == 'gaia'", specifier = ">=1.24.0" },
|
||||
{ name = "orjson", marker = "extra == 'gaia'", specifier = ">=3.8.0" },
|
||||
{ name = "pyarrow", marker = "extra == 'gaia'", specifier = ">=10.0.0" },
|
||||
{ name = "pydantic", marker = "extra == 'gaia'", specifier = ">=2.0.0" },
|
||||
{ name = "pydantic", marker = "extra == 'tau2'", specifier = ">=2.0.0" },
|
||||
{ name = "sympy", marker = "extra == 'math'", specifier = ">=1.13.0" },
|
||||
@@ -909,7 +911,7 @@ name = "cffi"
|
||||
version = "2.0.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "pycparser", marker = "(implementation_name != 'PyPy' and sys_platform == 'darwin') or (implementation_name != 'PyPy' and sys_platform == 'linux') or (implementation_name != 'PyPy' and sys_platform == 'win32')" },
|
||||
{ name = "pycparser", marker = "(python_full_version < '3.13' and implementation_name != 'PyPy' and sys_platform == 'darwin') or (python_full_version < '3.13' and implementation_name != 'PyPy' and sys_platform == 'linux') or (python_full_version < '3.13' and implementation_name != 'PyPy' and sys_platform == 'win32') or (implementation_name != 'PyPy' and platform_python_implementation != 'PyPy' and sys_platform == 'darwin') or (implementation_name != 'PyPy' and platform_python_implementation != 'PyPy' and sys_platform == 'linux') or (implementation_name != 'PyPy' and platform_python_implementation != 'PyPy' and sys_platform == 'win32')" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload-time = "2025-09-08T23:24:04.541Z" }
|
||||
wheels = [
|
||||
@@ -1571,7 +1573,7 @@ name = "exceptiongroup"
|
||||
version = "1.3.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "typing-extensions", marker = "(python_full_version < '3.13' and sys_platform == 'darwin') or (python_full_version < '3.13' and sys_platform == 'linux') or (python_full_version < '3.13' and sys_platform == 'win32')" },
|
||||
{ name = "typing-extensions", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" }
|
||||
wheels = [
|
||||
@@ -4169,6 +4171,63 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/c2/94/6475c7faa94a1d90303f624936471cd0f4c20430bd2c92deab607cd0ff31/py2docfx-0.1.22-py3-none-any.whl", hash = "sha256:ccee611af2aefe9f39f446f72b5e07d3369bbdb77c13ebafb69ed1a116116467", size = 11420273, upload-time = "2025-10-10T07:16:25.294Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyarrow"
|
||||
version = "22.0.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/30/53/04a7fdc63e6056116c9ddc8b43bc28c12cdd181b85cbeadb79278475f3ae/pyarrow-22.0.0.tar.gz", hash = "sha256:3d600dc583260d845c7d8a6db540339dd883081925da2bd1c5cb808f720b3cd9", size = 1151151, upload-time = "2025-10-24T12:30:00.762Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d9/9b/cb3f7e0a345353def531ca879053e9ef6b9f38ed91aebcf68b09ba54dec0/pyarrow-22.0.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:77718810bd3066158db1e95a63c160ad7ce08c6b0710bc656055033e39cdad88", size = 34223968, upload-time = "2025-10-24T10:03:31.21Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6c/41/3184b8192a120306270c5307f105b70320fdaa592c99843c5ef78aaefdcf/pyarrow-22.0.0-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:44d2d26cda26d18f7af7db71453b7b783788322d756e81730acb98f24eb90ace", size = 35942085, upload-time = "2025-10-24T10:03:38.146Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d9/3d/a1eab2f6f08001f9fb714b8ed5cfb045e2fe3e3e3c0c221f2c9ed1e6d67d/pyarrow-22.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:b9d71701ce97c95480fecb0039ec5bb889e75f110da72005743451339262f4ce", size = 44964613, upload-time = "2025-10-24T10:03:46.516Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/46/46/a1d9c24baf21cfd9ce994ac820a24608decf2710521b29223d4334985127/pyarrow-22.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:710624ab925dc2b05a6229d47f6f0dac1c1155e6ed559be7109f684eba048a48", size = 47627059, upload-time = "2025-10-24T10:03:55.353Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3a/4c/f711acb13075c1391fd54bc17e078587672c575f8de2a6e62509af026dcf/pyarrow-22.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f963ba8c3b0199f9d6b794c90ec77545e05eadc83973897a4523c9e8d84e9340", size = 47947043, upload-time = "2025-10-24T10:04:05.408Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4e/70/1f3180dd7c2eab35c2aca2b29ace6c519f827dcd4cfeb8e0dca41612cf7a/pyarrow-22.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:bd0d42297ace400d8febe55f13fdf46e86754842b860c978dfec16f081e5c653", size = 50206505, upload-time = "2025-10-24T10:04:15.786Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/80/07/fea6578112c8c60ffde55883a571e4c4c6bc7049f119d6b09333b5cc6f73/pyarrow-22.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:00626d9dc0f5ef3a75fe63fd68b9c7c8302d2b5bbc7f74ecaedba83447a24f84", size = 28101641, upload-time = "2025-10-24T10:04:22.57Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2e/b7/18f611a8cdc43417f9394a3ccd3eace2f32183c08b9eddc3d17681819f37/pyarrow-22.0.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:3e294c5eadfb93d78b0763e859a0c16d4051fc1c5231ae8956d61cb0b5666f5a", size = 34272022, upload-time = "2025-10-24T10:04:28.973Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/26/5c/f259e2526c67eb4b9e511741b19870a02363a47a35edbebc55c3178db22d/pyarrow-22.0.0-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:69763ab2445f632d90b504a815a2a033f74332997052b721002298ed6de40f2e", size = 35995834, upload-time = "2025-10-24T10:04:35.467Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/50/8d/281f0f9b9376d4b7f146913b26fac0aa2829cd1ee7e997f53a27411bbb92/pyarrow-22.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:b41f37cabfe2463232684de44bad753d6be08a7a072f6a83447eeaf0e4d2a215", size = 45030348, upload-time = "2025-10-24T10:04:43.366Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f5/e5/53c0a1c428f0976bf22f513d79c73000926cb00b9c138d8e02daf2102e18/pyarrow-22.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:35ad0f0378c9359b3f297299c3309778bb03b8612f987399a0333a560b43862d", size = 47699480, upload-time = "2025-10-24T10:04:51.486Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/95/e1/9dbe4c465c3365959d183e6345d0a8d1dc5b02ca3f8db4760b3bc834cf25/pyarrow-22.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8382ad21458075c2e66a82a29d650f963ce51c7708c7c0ff313a8c206c4fd5e8", size = 48011148, upload-time = "2025-10-24T10:04:59.585Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c5/b4/7caf5d21930061444c3cf4fa7535c82faf5263e22ce43af7c2759ceb5b8b/pyarrow-22.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1a812a5b727bc09c3d7ea072c4eebf657c2f7066155506ba31ebf4792f88f016", size = 50276964, upload-time = "2025-10-24T10:05:08.175Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ae/f3/cec89bd99fa3abf826f14d4e53d3d11340ce6f6af4d14bdcd54cd83b6576/pyarrow-22.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:ec5d40dd494882704fb876c16fa7261a69791e784ae34e6b5992e977bd2e238c", size = 28106517, upload-time = "2025-10-24T10:05:14.314Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/af/63/ba23862d69652f85b615ca14ad14f3bcfc5bf1b99ef3f0cd04ff93fdad5a/pyarrow-22.0.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:bea79263d55c24a32b0d79c00a1c58bb2ee5f0757ed95656b01c0fb310c5af3d", size = 34211578, upload-time = "2025-10-24T10:05:21.583Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b1/d0/f9ad86fe809efd2bcc8be32032fa72e8b0d112b01ae56a053006376c5930/pyarrow-22.0.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:12fe549c9b10ac98c91cf791d2945e878875d95508e1a5d14091a7aaa66d9cf8", size = 35989906, upload-time = "2025-10-24T10:05:29.485Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b4/a8/f910afcb14630e64d673f15904ec27dd31f1e009b77033c365c84e8c1e1d/pyarrow-22.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:334f900ff08ce0423407af97e6c26ad5d4e3b0763645559ece6fbf3747d6a8f5", size = 45021677, upload-time = "2025-10-24T10:05:38.274Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/13/95/aec81f781c75cd10554dc17a25849c720d54feafb6f7847690478dcf5ef8/pyarrow-22.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:c6c791b09c57ed76a18b03f2631753a4960eefbbca80f846da8baefc6491fcfe", size = 47726315, upload-time = "2025-10-24T10:05:47.314Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bb/d4/74ac9f7a54cfde12ee42734ea25d5a3c9a45db78f9def949307a92720d37/pyarrow-22.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c3200cb41cdbc65156e5f8c908d739b0dfed57e890329413da2748d1a2cd1a4e", size = 47990906, upload-time = "2025-10-24T10:05:58.254Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2e/71/fedf2499bf7a95062eafc989ace56572f3343432570e1c54e6599d5b88da/pyarrow-22.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ac93252226cf288753d8b46280f4edf3433bf9508b6977f8dd8526b521a1bbb9", size = 50306783, upload-time = "2025-10-24T10:06:08.08Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/68/ed/b202abd5a5b78f519722f3d29063dda03c114711093c1995a33b8e2e0f4b/pyarrow-22.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:44729980b6c50a5f2bfcc2668d36c569ce17f8b17bccaf470c4313dcbbf13c9d", size = 27972883, upload-time = "2025-10-24T10:06:14.204Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a6/d6/d0fac16a2963002fc22c8fa75180a838737203d558f0ed3b564c4a54eef5/pyarrow-22.0.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:e6e95176209257803a8b3d0394f21604e796dadb643d2f7ca21b66c9c0b30c9a", size = 34204629, upload-time = "2025-10-24T10:06:20.274Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c6/9c/1d6357347fbae062ad3f17082f9ebc29cc733321e892c0d2085f42a2212b/pyarrow-22.0.0-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:001ea83a58024818826a9e3f89bf9310a114f7e26dfe404a4c32686f97bd7901", size = 35985783, upload-time = "2025-10-24T10:06:27.301Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ff/c0/782344c2ce58afbea010150df07e3a2f5fdad299cd631697ae7bd3bac6e3/pyarrow-22.0.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:ce20fe000754f477c8a9125543f1936ea5b8867c5406757c224d745ed033e691", size = 45020999, upload-time = "2025-10-24T10:06:35.387Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1b/8b/5362443737a5307a7b67c1017c42cd104213189b4970bf607e05faf9c525/pyarrow-22.0.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e0a15757fccb38c410947df156f9749ae4a3c89b2393741a50521f39a8cf202a", size = 47724601, upload-time = "2025-10-24T10:06:43.551Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/69/4d/76e567a4fc2e190ee6072967cb4672b7d9249ac59ae65af2d7e3047afa3b/pyarrow-22.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cedb9dd9358e4ea1d9bce3665ce0797f6adf97ff142c8e25b46ba9cdd508e9b6", size = 48001050, upload-time = "2025-10-24T10:06:52.284Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/01/5e/5653f0535d2a1aef8223cee9d92944cb6bccfee5cf1cd3f462d7cb022790/pyarrow-22.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:252be4a05f9d9185bb8c18e83764ebcfea7185076c07a7a662253af3a8c07941", size = 50307877, upload-time = "2025-10-24T10:07:02.405Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2d/f8/1d0bd75bf9328a3b826e24a16e5517cd7f9fbf8d34a3184a4566ef5a7f29/pyarrow-22.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:a4893d31e5ef780b6edcaf63122df0f8d321088bb0dee4c8c06eccb1ca28d145", size = 27977099, upload-time = "2025-10-24T10:08:07.259Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/90/81/db56870c997805bf2b0f6eeeb2d68458bf4654652dccdcf1bf7a42d80903/pyarrow-22.0.0-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:f7fe3dbe871294ba70d789be16b6e7e52b418311e166e0e3cba9522f0f437fb1", size = 34336685, upload-time = "2025-10-24T10:07:11.47Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1c/98/0727947f199aba8a120f47dfc229eeb05df15bcd7a6f1b669e9f882afc58/pyarrow-22.0.0-cp313-cp313t-macosx_12_0_x86_64.whl", hash = "sha256:ba95112d15fd4f1105fb2402c4eab9068f0554435e9b7085924bcfaac2cc306f", size = 36032158, upload-time = "2025-10-24T10:07:18.626Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/96/b4/9babdef9c01720a0785945c7cf550e4acd0ebcd7bdd2e6f0aa7981fa85e2/pyarrow-22.0.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:c064e28361c05d72eed8e744c9605cbd6d2bb7481a511c74071fd9b24bc65d7d", size = 44892060, upload-time = "2025-10-24T10:07:26.002Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f8/ca/2f8804edd6279f78a37062d813de3f16f29183874447ef6d1aadbb4efa0f/pyarrow-22.0.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:6f9762274496c244d951c819348afbcf212714902742225f649cf02823a6a10f", size = 47504395, upload-time = "2025-10-24T10:07:34.09Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b9/f0/77aa5198fd3943682b2e4faaf179a674f0edea0d55d326d83cb2277d9363/pyarrow-22.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a9d9ffdc2ab696f6b15b4d1f7cec6658e1d788124418cb30030afbae31c64746", size = 48066216, upload-time = "2025-10-24T10:07:43.528Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/79/87/a1937b6e78b2aff18b706d738c9e46ade5bfcf11b294e39c87706a0089ac/pyarrow-22.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ec1a15968a9d80da01e1d30349b2b0d7cc91e96588ee324ce1b5228175043e95", size = 50288552, upload-time = "2025-10-24T10:07:53.519Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/60/ae/b5a5811e11f25788ccfdaa8f26b6791c9807119dffcf80514505527c384c/pyarrow-22.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:bba208d9c7decf9961998edf5c65e3ea4355d5818dd6cd0f6809bec1afb951cc", size = 28262504, upload-time = "2025-10-24T10:08:00.932Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bd/b0/0fa4d28a8edb42b0a7144edd20befd04173ac79819547216f8a9f36f9e50/pyarrow-22.0.0-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:9bddc2cade6561f6820d4cd73f99a0243532ad506bc510a75a5a65a522b2d74d", size = 34224062, upload-time = "2025-10-24T10:08:14.101Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0f/a8/7a719076b3c1be0acef56a07220c586f25cd24de0e3f3102b438d18ae5df/pyarrow-22.0.0-cp314-cp314-macosx_12_0_x86_64.whl", hash = "sha256:e70ff90c64419709d38c8932ea9fe1cc98415c4f87ea8da81719e43f02534bc9", size = 35990057, upload-time = "2025-10-24T10:08:21.842Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/89/3c/359ed54c93b47fb6fe30ed16cdf50e3f0e8b9ccfb11b86218c3619ae50a8/pyarrow-22.0.0-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:92843c305330aa94a36e706c16209cd4df274693e777ca47112617db7d0ef3d7", size = 45068002, upload-time = "2025-10-24T10:08:29.034Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/55/fc/4945896cc8638536ee787a3bd6ce7cec8ec9acf452d78ec39ab328efa0a1/pyarrow-22.0.0-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:6dda1ddac033d27421c20d7a7943eec60be44e0db4e079f33cc5af3b8280ccde", size = 47737765, upload-time = "2025-10-24T10:08:38.559Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cd/5e/7cb7edeb2abfaa1f79b5d5eb89432356155c8426f75d3753cbcb9592c0fd/pyarrow-22.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:84378110dd9a6c06323b41b56e129c504d157d1a983ce8f5443761eb5256bafc", size = 48048139, upload-time = "2025-10-24T10:08:46.784Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/88/c6/546baa7c48185f5e9d6e59277c4b19f30f48c94d9dd938c2a80d4d6b067c/pyarrow-22.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:854794239111d2b88b40b6ef92aa478024d1e5074f364033e73e21e3f76b25e0", size = 50314244, upload-time = "2025-10-24T10:08:55.771Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3c/79/755ff2d145aafec8d347bf18f95e4e81c00127f06d080135dfc86aea417c/pyarrow-22.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:b883fe6fd85adad7932b3271c38ac289c65b7337c2c132e9569f9d3940620730", size = 28757501, upload-time = "2025-10-24T10:09:59.891Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0e/d2/237d75ac28ced3147912954e3c1a174df43a95f4f88e467809118a8165e0/pyarrow-22.0.0-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:7a820d8ae11facf32585507c11f04e3f38343c1e784c9b5a8b1da5c930547fe2", size = 34355506, upload-time = "2025-10-24T10:09:02.953Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1e/2c/733dfffe6d3069740f98e57ff81007809067d68626c5faef293434d11bd6/pyarrow-22.0.0-cp314-cp314t-macosx_12_0_x86_64.whl", hash = "sha256:c6ec3675d98915bf1ec8b3c7986422682f7232ea76cad276f4c8abd5b7319b70", size = 36047312, upload-time = "2025-10-24T10:09:10.334Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7c/2b/29d6e3782dc1f299727462c1543af357a0f2c1d3c160ce199950d9ca51eb/pyarrow-22.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:3e739edd001b04f654b166204fc7a9de896cf6007eaff33409ee9e50ceaff754", size = 45081609, upload-time = "2025-10-24T10:09:18.61Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8d/42/aa9355ecc05997915af1b7b947a7f66c02dcaa927f3203b87871c114ba10/pyarrow-22.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:7388ac685cab5b279a41dfe0a6ccd99e4dbf322edfb63e02fc0443bf24134e91", size = 47703663, upload-time = "2025-10-24T10:09:27.369Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ee/62/45abedde480168e83a1de005b7b7043fd553321c1e8c5a9a114425f64842/pyarrow-22.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:f633074f36dbc33d5c05b5dc75371e5660f1dbf9c8b1d95669def05e5425989c", size = 48066543, upload-time = "2025-10-24T10:09:34.908Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/84/e9/7878940a5b072e4f3bf998770acafeae13b267f9893af5f6d4ab3904b67e/pyarrow-22.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:4c19236ae2402a8663a2c8f21f1870a03cc57f0bef7e4b6eb3238cc82944de80", size = 50288838, upload-time = "2025-10-24T10:09:44.394Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7b/03/f335d6c52b4a4761bcc83499789a1e2e16d9d201a58c327a9b5cc9a41bd9/pyarrow-22.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:0c34fe18094686194f204a3b1787a27456897d8a2d62caf84b61e8dfbc0252ae", size = 29185594, upload-time = "2025-10-24T10:09:53.111Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyasn1"
|
||||
version = "0.6.1"
|
||||
|
||||
Reference in New Issue
Block a user