Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions fle/env/a2a_namespace.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import logging
from typing import Dict, List, Optional

from a2a.types import AgentCard, Message, Part, TextPart
from a2a.types import AgentCard, Message, Part
from fle.agents.agent_abc import create_default_agent_card

from fle.env.namespace import FactorioNamespace
Expand Down Expand Up @@ -136,7 +136,7 @@ def load_messages(self, messages: List[Dict]) -> None:
a2a_message = Message(
messageId=msg["messageId"],
role="user",
parts=[Part(root=TextPart(text=msg["message"]))],
parts=[Part(text=msg["message"])],
metadata={
"sender": str(msg["sender"]),
"message_type": "text",
Expand Down
6 changes: 3 additions & 3 deletions fle/env/gym_env/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ python env/src/gym_env/example_usage.py --list
### 2. Create an Environment

```python
import gym
import gymnasium as gym

# Create any available environment
env = gym.make("Factorio-iron_ore_throughput_16-v0")
Expand Down Expand Up @@ -192,7 +192,7 @@ To add a new task:
Here's a complete example that demonstrates the full workflow:

```python
import gym
import gymnasium as gym
from gym_env.registry import list_available_environments, get_environment_info
from gym_env.action import Action

Expand Down Expand Up @@ -313,4 +313,4 @@ Run the test suite to verify the registry is working correctly:
python env/tests/gym_env/test_registry.py
```

This registry system provides a clean, standardized interface for working with Factorio gym environments, making it easy to experiment with different tasks and integrate with existing gym-based frameworks.
This registry system provides a clean, standardized interface for working with Factorio gym environments, making it easy to experiment with different tasks and integrate with existing gym-based frameworks.
4 changes: 2 additions & 2 deletions fle/env/gym_env/environment.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import logging

import gym
import gymnasium as gym
import numpy as np
from gym import spaces
from gymnasium import spaces
from typing import Dict, Optional, Tuple, Any
import pickle
import datetime
Expand Down
8 changes: 4 additions & 4 deletions fle/env/gym_env/example_usage.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
python example_usage.py --gym-format # Output in gym.make() format
"""

import gym
import gymnasium as gym
import argparse
import sys
import os
Expand Down Expand Up @@ -104,7 +104,7 @@ def run_interactive_examples():

try:
# Create the environment using gym.make()
env = gym.make(example_env_id)
env = gym.make(example_env_id, disable_env_checker=True)

# Reset the environment with required options parameter
print(" Resetting environment...")
Expand Down Expand Up @@ -144,7 +144,7 @@ def run_interactive_examples():
print(" env_ids = list_available_environments()")
print()
print(" # Create an environment")
print(" import gym")
print(" import gymnasium as gym")
print(" env = gym.make('Factorio-iron_ore_throughput_16-v0')")
print()
print(" # Use the environment")
Expand Down Expand Up @@ -231,7 +231,7 @@ def run_command_line_mode():
example_env = env_ids[0]
print("Example usage:")
print("```python")
print("import gym")
print("import gymnasium as gym")
print(f"env = gym.make('{example_env}')")
print("obs, info = env.reset(options={'game_state': None})")
print(
Expand Down
3 changes: 2 additions & 1 deletion fle/env/gym_env/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from typing import Any, Dict, List, Optional

from fle.env.a2a_instance import A2AFactorioInstance
import gym
import gymnasium as gym

from fle.commons.cluster_ips import get_local_container_ips
from fle.commons.asyncio_utils import run_async_safely
Expand Down Expand Up @@ -78,6 +78,7 @@ def register_environment(
id=task_key,
entry_point="fle.env.gym_env.registry:make_factorio_env",
kwargs={"spec": spec},
order_enforce=False,
)

def list_environments(self) -> List[str]:
Expand Down
14 changes: 9 additions & 5 deletions fle/env/protocols/_mcp/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from fle.env.protocols._mcp.models import FactorioServer, Recipe, ResourcePatch
from fle.env.protocols._mcp.repository import FactorioMCPRepository
import gym
import gymnasium as gym


class FactorioMCPState:
Expand Down Expand Up @@ -48,12 +48,12 @@ def __init__(self):
for id in env_ids:
if "open" in id:
print(f"DEBUG: Using open environment: {id}")
self.gym_env = gym.make(id, run_idx=0)
self.gym_env = gym.make(id, disable_env_checker=True, run_idx=0)
self.gym_env.reset()
return

# print(f"DEBUG: No open environment found, using first available: {env_ids[0]}")
self.gym_env = gym.make(env_ids[0], run_idx=0)
self.gym_env = gym.make(env_ids[0], disable_env_checker=True, run_idx=0)

# program = await self.create_program_from_policy(
# policy=policy,
Expand All @@ -70,12 +70,16 @@ def __init__(self):
f"env_ids length: {len(env_ids) if 'env_ids' in locals() else 'Not available'}"
)
print("Falling back to steel_plate_throughput environment")
self.gym_env = gym.make("steel_plate_throughput", run_idx=0)
self.gym_env = gym.make(
"steel_plate_throughput", disable_env_checker=True, run_idx=0
)
except Exception as e:
print(f"Error in __init__: {e}")
print(f"Error type: {type(e)}")
print("Falling back to steel_plate_throughput environment")
self.gym_env = gym.make("steel_plate_throughput", run_idx=0)
self.gym_env = gym.make(
"steel_plate_throughput", disable_env_checker=True, run_idx=0
)

self.gym_env.reset()

Expand Down
4 changes: 2 additions & 2 deletions fle/env/protocols/a2a/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import asyncio
from pydantic import BaseModel
import requests
from a2a.types import Message, Part, TextPart, AgentCard, Role
from a2a.types import Message, Part, AgentCard, Role


class A2AMessage(BaseModel):
Expand Down Expand Up @@ -190,7 +190,7 @@ def get_messages(self) -> List[Message]:
Message(
messageId=msg.get("messageId", str(uuid.uuid4())),
role=Role.agent, # Default to "agent" if not specified
parts=[Part(root=TextPart(text=msg.get("content", "")))],
parts=[Part(text=msg.get("content", ""))],
metadata=msg.get("metadata", {}),
)
for msg in messages
Expand Down
4 changes: 2 additions & 2 deletions fle/env/tools/agent/send_message/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from fle.env.tools.admin.render_message.client import RenderMessage
import logging
import uuid
from a2a.types import Message, Part, TextPart
from a2a.types import Message, Part


class SendMessage(Tool):
Expand Down Expand Up @@ -46,7 +46,7 @@ def __call__(
a2a_message = Message(
messageId=str(uuid.uuid4()),
role="agent",
parts=[Part(root=TextPart(text=message))],
parts=[Part(text=message)],
metadata={
"sender": self.namespace.agent_id,
"message_type": "text",
Expand Down
8 changes: 5 additions & 3 deletions fle/eval/analysis/run_to_mp4.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
# Add parent directories to path for imports
sys.path.append(str(Path(__file__).parent.parent.parent.parent))

import gym
import gymnasium as gym
from fle.env.gym_env.action import Action
from fle.env.gym_env.environment import FactorioGymEnv
from fle.env.gym_env.registry import list_available_environments
Expand Down Expand Up @@ -133,7 +133,7 @@ def create_gym_environment(version: int) -> FactorioGymEnv:
raise ValueError("No gym environments available!")

try:
gym_env = gym.make(env_id, run_idx=0)
gym_env = gym.make(env_id, disable_env_checker=True, run_idx=0)
print(f"Successfully created gym environment: {env_id}")
return gym_env
except Exception as e:
Expand All @@ -142,7 +142,9 @@ def create_gym_environment(version: int) -> FactorioGymEnv:
if available_envs and env_id != available_envs[0]:
fallback_env_id = available_envs[0]
print(f"Trying final fallback environment: {fallback_env_id}")
gym_env = gym.make(fallback_env_id, run_idx=0)
gym_env = gym.make(
fallback_env_id, disable_env_checker=True, run_idx=0
)
return gym_env
else:
raise e
Expand Down
4 changes: 2 additions & 2 deletions fle/eval/entrypoints/gym_eval.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import multiprocessing
import os

import gym
import gymnasium as gym
import importlib.resources
from dotenv import load_dotenv
from fle.env.gym_env.observation_formatter import BasicObservationFormatter
Expand Down Expand Up @@ -56,7 +56,7 @@ async def run_trajectory(run_idx: int, config: GymEvalConfig):
"""Run a single gym evaluation process"""
db_client = await create_db_client()

gym_env = gym.make(config.env_id, run_idx=run_idx)
gym_env = gym.make(config.env_id, disable_env_checker=True, run_idx=run_idx)

log_dir = os.path.join(".fle", "trajectory_logs", f"v{config.version}")

Expand Down
14 changes: 8 additions & 6 deletions fle/eval/inspect/integration/solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
import importlib.resources
from pathlib import Path
from jinja2 import Template
import gym
import gymnasium as gym


def _load_prompt_template(filename: str) -> Template:
Expand Down Expand Up @@ -237,7 +237,9 @@ async def solve(state: AgentState, *args, **kwargs) -> AgentState:
logger.info(f"📡 Allocated server factorio_{run_idx}")

# Create gym environment
gym_env: FactorioGymEnv = gym.make(env_id, run_idx=run_idx)
gym_env: FactorioGymEnv = gym.make(
env_id, disable_env_checker=True, run_idx=run_idx
)
gym_env.reset()

logger.info("🎮 Connected to Factorio server")
Expand Down Expand Up @@ -385,15 +387,13 @@ async def solve(state: AgentState, *args, **kwargs) -> AgentState:
# Generate response using Inspect's model with reasoning support
generation_config = {
"max_tokens": 4096, # More tokens for complex programs
"transforms": ["middle-out"],
"reasoning_effort": "minimal",
# "temperature": 0.1
}

state.output = await get_model().generate(
state.output = await get_model(transforms=["middle-out"]).generate(
input=state.messages,
config=generation_config,
# transforms = ['middle-out']
)

# Log reasoning usage if available
Expand Down Expand Up @@ -761,7 +761,9 @@ async def solve(state: AgentState, *args, **kwargs) -> AgentState:

# Create gym environment - always use open_play for unbounded tasks
# open_play uses DefaultTask which has no throughput requirements
gym_env: FactorioGymEnv = gym.make(gym_env_id, run_idx=run_idx)
gym_env: FactorioGymEnv = gym.make(
gym_env_id, disable_env_checker=True, run_idx=run_idx
)
gym_env.reset()

logger.info("Connected to Factorio server")
Expand Down
26 changes: 19 additions & 7 deletions fle/eval/inspect/integration/solver_variants.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
from fle.env.tools.agent.sleep.client import Sleep

import importlib.resources
import gym
import gymnasium as gym


logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -181,7 +181,9 @@ async def _base_solver_loop(
logger.warning(f"📡 Allocated server factorio_{run_idx}")

# Create gym environment
gym_env: FactorioGymEnv = gym.make(gym_env_id, run_idx=run_idx)
gym_env: FactorioGymEnv = gym.make(
gym_env_id, disable_env_checker=True, run_idx=run_idx
)
gym_env.reset()

logger.info("Connected to Factorio server")
Expand Down Expand Up @@ -912,7 +914,9 @@ async def solve(state: AgentState, *args, **kwargs) -> AgentState:
logger.warning(f"📡 Allocated server factorio_{run_idx}")

# Create gym environment
gym_env: FactorioGymEnv = gym.make(gym_env_id, run_idx=run_idx)
gym_env: FactorioGymEnv = gym.make(
gym_env_id, disable_env_checker=True, run_idx=run_idx
)
gym_env.reset()

logger.info("Connected to Factorio server")
Expand Down Expand Up @@ -1453,7 +1457,9 @@ async def solve(state: AgentState, *args, **kwargs) -> AgentState:
logger.warning(f"📡 Allocated server factorio_{run_idx}")

# Create gym environment
gym_env: FactorioGymEnv = gym.make(gym_env_id, run_idx=run_idx)
gym_env: FactorioGymEnv = gym.make(
gym_env_id, disable_env_checker=True, run_idx=run_idx
)
gym_env.reset()

logger.info("Connected to Factorio server")
Expand Down Expand Up @@ -2015,7 +2021,9 @@ async def solve(state: AgentState, *args, **kwargs) -> AgentState:
logger.warning(f"📡 Allocated server factorio_{run_idx}")

# Create gym environment
gym_env: FactorioGymEnv = gym.make(gym_env_id, run_idx=run_idx)
gym_env: FactorioGymEnv = gym.make(
gym_env_id, disable_env_checker=True, run_idx=run_idx
)
gym_env.reset()

logger.info("Connected to Factorio server")
Expand Down Expand Up @@ -2528,7 +2536,9 @@ async def solve(state: AgentState, *args, **kwargs) -> AgentState:
logger.warning(f"📡 Allocated server factorio_{run_idx}")

# Create gym environment
gym_env: FactorioGymEnv = gym.make(gym_env_id, run_idx=run_idx)
gym_env: FactorioGymEnv = gym.make(
gym_env_id, disable_env_checker=True, run_idx=run_idx
)
gym_env.reset()

logger.info("Connected to Factorio server")
Expand Down Expand Up @@ -2975,7 +2985,9 @@ async def solve(state: AgentState, *args, **kwargs) -> AgentState:
logger.warning(f"📡 Allocated server factorio_{run_idx}")

# Create gym environment
gym_env: FactorioGymEnv = gym.make(gym_env_id, run_idx=run_idx)
gym_env: FactorioGymEnv = gym.make(
gym_env_id, disable_env_checker=True, run_idx=run_idx
)
gym_env.reset()

logger.info("Connected to Factorio server")
Expand Down
6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,16 @@ dependencies = [
"pillow>=11.1.0",
"tomli",
"numpy>=2.2.3",
"gym",
"a2a-sdk",
"gymnasium>=1.3.0",
"a2a-sdk==1.1",
"tenacity>=9.0.0",
"aiohttp>=3.8.0",
"uvicorn>=0.15.0",
"pytest>=8.4.1",
"mcp[cli]>=1.11.0",
"black>=25.1.0",
"memoization>=0.4.0",
"inspect-ai>=0.3.139",
"inspect-ai>=0.3.239",
"docker>=7.1.0",
"openai>=2.0.0",
"matplotlib>=3.10.7",
Expand Down
2 changes: 1 addition & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

@pytest.fixture(scope="session")
def instance(pytestconfig, worker_id):
# from gym import FactorioInstance
# from gymnasium import FactorioInstance
ips, udp_ports, tcp_ports = get_local_container_ips()
# --- Parallel mapping (pytest-xdist) ---
# Docs-backed approach:
Expand Down
2 changes: 1 addition & 1 deletion tests/gym_env/test_interface.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import pytest
from gym import spaces
from gymnasium import spaces

from fle.env.gym_env.environment import FactorioGymEnv
from fle.env.gym_env.action import Action
Expand Down
Loading