mirror of
https://github.com/FoundationAgents/MetaGPT.git
synced 2026-06-11 15:15:18 +02:00
Merge branch 'code_intepreter' of https://gitlab.deepwisdomai.com/agents/data_agents_opt into code_intepreter
resolve conflict
This commit is contained in:
commit
7d38181f56
313 changed files with 8523 additions and 4255 deletions
|
|
@ -12,14 +12,19 @@ import logging
|
|||
import os
|
||||
import re
|
||||
import uuid
|
||||
from typing import Callable
|
||||
|
||||
import pytest
|
||||
|
||||
from metagpt.config import CONFIG, Config
|
||||
from metagpt.const import DEFAULT_WORKSPACE_ROOT, TEST_DATA_PATH
|
||||
from metagpt.context import Context as MetagptContext
|
||||
from metagpt.llm import LLM
|
||||
from metagpt.logs import logger
|
||||
from metagpt.utils.git_repository import GitRepository
|
||||
from metagpt.utils.project_repo import ProjectRepo
|
||||
from tests.mock.mock_aiohttp import MockAioResponse
|
||||
from tests.mock.mock_curl_cffi import MockCurlCffiResponse
|
||||
from tests.mock.mock_httplib2 import MockHttplib2Response
|
||||
from tests.mock.mock_llm import MockLLM
|
||||
|
||||
RSP_CACHE_NEW = {} # used globally for producing new and useful only response cache
|
||||
|
|
@ -30,7 +35,6 @@ ALLOW_OPENAI_API_CALL = int(
|
|||
|
||||
@pytest.fixture(scope="session")
|
||||
def rsp_cache():
|
||||
# model_version = CONFIG.openai_api_model
|
||||
rsp_cache_file_path = TEST_DATA_PATH / "rsp_cache.json" # read repo-provided
|
||||
new_rsp_cache_file_path = TEST_DATA_PATH / "rsp_cache_new.json" # exporting a new copy
|
||||
if os.path.exists(rsp_cache_file_path):
|
||||
|
|
@ -76,7 +80,7 @@ def llm_mock(rsp_cache, mocker, request):
|
|||
class Context:
|
||||
def __init__(self):
|
||||
self._llm_ui = None
|
||||
self._llm_api = LLM(provider=CONFIG.get_default_llm_provider_enum())
|
||||
self._llm_api = LLM()
|
||||
|
||||
@property
|
||||
def llm_api(self):
|
||||
|
|
@ -90,9 +94,9 @@ class Context:
|
|||
@pytest.fixture(scope="package")
|
||||
def llm_api():
|
||||
logger.info("Setting up the test")
|
||||
_context = Context()
|
||||
g_context = Context()
|
||||
|
||||
yield _context.llm_api
|
||||
yield g_context.llm_api
|
||||
|
||||
logger.info("Tearing down the test")
|
||||
|
||||
|
|
@ -125,7 +129,7 @@ def proxy():
|
|||
server = await asyncio.start_server(handle_client, "127.0.0.1", 0)
|
||||
return server, "http://{}:{}".format(*server.sockets[0].getsockname())
|
||||
|
||||
return proxy_func()
|
||||
return proxy_func
|
||||
|
||||
|
||||
# see https://github.com/Delgan/loguru/issues/59#issuecomment-466591978
|
||||
|
|
@ -139,23 +143,25 @@ def loguru_caplog(caplog):
|
|||
yield caplog
|
||||
|
||||
|
||||
# init & dispose git repo
|
||||
@pytest.fixture(scope="function", autouse=True)
|
||||
def setup_and_teardown_git_repo(request):
|
||||
CONFIG.git_repo = GitRepository(local_path=DEFAULT_WORKSPACE_ROOT / f"unittest/{uuid.uuid4().hex}")
|
||||
CONFIG.git_reinit = True
|
||||
@pytest.fixture(scope="function")
|
||||
def context(request):
|
||||
ctx = MetagptContext()
|
||||
ctx.git_repo = GitRepository(local_path=DEFAULT_WORKSPACE_ROOT / f"unittest/{uuid.uuid4().hex}")
|
||||
ctx.repo = ProjectRepo(ctx.git_repo)
|
||||
|
||||
# Destroy git repo at the end of the test session.
|
||||
def fin():
|
||||
CONFIG.git_repo.delete_repository()
|
||||
if ctx.git_repo:
|
||||
ctx.git_repo.delete_repository()
|
||||
|
||||
# Register the function for destroying the environment.
|
||||
request.addfinalizer(fin)
|
||||
return ctx
|
||||
|
||||
|
||||
@pytest.fixture(scope="session", autouse=True)
|
||||
def init_config():
|
||||
Config()
|
||||
pass
|
||||
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
|
|
@ -165,39 +171,63 @@ def new_filename(mocker):
|
|||
yield mocker
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def search_rsp_cache():
|
||||
rsp_cache_file_path = TEST_DATA_PATH / "search_rsp_cache.json" # read repo-provided
|
||||
if os.path.exists(rsp_cache_file_path):
|
||||
with open(rsp_cache_file_path, "r") as f1:
|
||||
rsp_cache_json = json.load(f1)
|
||||
else:
|
||||
rsp_cache_json = {}
|
||||
yield rsp_cache_json
|
||||
with open(rsp_cache_file_path, "w") as f2:
|
||||
json.dump(rsp_cache_json, f2, indent=4, ensure_ascii=False)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def aiohttp_mocker(mocker):
|
||||
class MockAioResponse:
|
||||
async def json(self, *args, **kwargs):
|
||||
return self._json
|
||||
|
||||
def set_json(self, json):
|
||||
self._json = json
|
||||
|
||||
response = MockAioResponse()
|
||||
|
||||
class MockCTXMng:
|
||||
async def __aenter__(self):
|
||||
return response
|
||||
|
||||
async def __aexit__(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def __await__(self):
|
||||
yield
|
||||
return response
|
||||
|
||||
def mock_request(self, method, url, **kwargs):
|
||||
return MockCTXMng()
|
||||
MockResponse = type("MockResponse", (MockAioResponse,), {})
|
||||
|
||||
def wrap(method):
|
||||
def run(self, url, **kwargs):
|
||||
return mock_request(self, method, url, **kwargs)
|
||||
return MockResponse(self, method, url, **kwargs)
|
||||
|
||||
return run
|
||||
|
||||
mocker.patch("aiohttp.ClientSession.request", mock_request)
|
||||
mocker.patch("aiohttp.ClientSession.request", MockResponse)
|
||||
for i in ["get", "post", "delete", "patch"]:
|
||||
mocker.patch(f"aiohttp.ClientSession.{i}", wrap(i))
|
||||
yield MockResponse
|
||||
|
||||
yield response
|
||||
|
||||
@pytest.fixture
|
||||
def curl_cffi_mocker(mocker):
|
||||
MockResponse = type("MockResponse", (MockCurlCffiResponse,), {})
|
||||
|
||||
def request(self, *args, **kwargs):
|
||||
return MockResponse(self, *args, **kwargs)
|
||||
|
||||
mocker.patch("curl_cffi.requests.Session.request", request)
|
||||
yield MockResponse
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def httplib2_mocker(mocker):
|
||||
MockResponse = type("MockResponse", (MockHttplib2Response,), {})
|
||||
|
||||
def request(self, *args, **kwargs):
|
||||
return MockResponse(self, *args, **kwargs)
|
||||
|
||||
mocker.patch("httplib2.Http.request", request)
|
||||
yield MockResponse
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def search_engine_mocker(aiohttp_mocker, curl_cffi_mocker, httplib2_mocker, search_rsp_cache):
|
||||
# aiohttp_mocker: serpapi/serper
|
||||
# httplib2_mocker: google
|
||||
# curl_cffi_mocker: ddg
|
||||
check_funcs: dict[tuple[str, str], Callable[[dict], str]] = {}
|
||||
aiohttp_mocker.rsp_cache = httplib2_mocker.rsp_cache = curl_cffi_mocker.rsp_cache = search_rsp_cache
|
||||
aiohttp_mocker.check_funcs = httplib2_mocker.check_funcs = curl_cffi_mocker.check_funcs = check_funcs
|
||||
yield check_funcs
|
||||
|
|
|
|||
BIN
tests/data/audio/hello.mp3
Normal file
BIN
tests/data/audio/hello.mp3
Normal file
Binary file not shown.
|
|
@ -1 +1 @@
|
|||
{"docs/system_design/20231221155954.json": ["docs/prds/20231221155954.json"], "docs/tasks/20231221155954.json": ["docs/system_design/20231221155954.json"], "game_2048/game.py": ["docs/tasks/20231221155954.json", "docs/system_design/20231221155954.json"], "game_2048/main.py": ["docs/tasks/20231221155954.json", "docs/system_design/20231221155954.json"], "resources/code_summaries/20231221155954.md": ["docs/tasks/20231221155954.json", "game_2048/game.py", "docs/system_design/20231221155954.json", "game_2048/main.py"], "docs/code_summaries/20231221155954.json": ["docs/tasks/20231221155954.json", "game_2048/game.py", "docs/system_design/20231221155954.json", "game_2048/main.py"], "tests/test_main.py": ["game_2048/main.py"], "tests/test_game.py": ["game_2048/game.py"], "test_outputs/test_main.py.json": ["game_2048/main.py", "tests/test_main.py"], "test_outputs/test_game.py.json": ["game_2048/game.py", "tests/test_game.py"]}
|
||||
{"docs/system_design/20231221155954.json": ["docs/prd/20231221155954.json"], "docs/task/20231221155954.json": ["docs/system_design/20231221155954.json"], "game_2048/game.py": ["docs/task/20231221155954.json", "docs/system_design/20231221155954.json"], "game_2048/main.py": ["docs/task/20231221155954.json", "docs/system_design/20231221155954.json"], "resources/code_summary/20231221155954.md": ["docs/task/20231221155954.json", "game_2048/game.py", "docs/system_design/20231221155954.json", "game_2048/main.py"], "docs/code_summary/20231221155954.json": ["docs/task/20231221155954.json", "game_2048/game.py", "docs/system_design/20231221155954.json", "game_2048/main.py"], "tests/test_main.py": ["game_2048/main.py"], "tests/test_game.py": ["game_2048/game.py"], "test_outputs/test_main.py.json": ["game_2048/main.py", "tests/test_main.py"], "test_outputs/test_game.py.json": ["game_2048/game.py", "tests/test_game.py"]}
|
||||
BIN
tests/data/incremental_dev_project/Gomoku.zip
Normal file
BIN
tests/data/incremental_dev_project/Gomoku.zip
Normal file
Binary file not shown.
BIN
tests/data/incremental_dev_project/dice_simulator_new.zip
Normal file
BIN
tests/data/incremental_dev_project/dice_simulator_new.zip
Normal file
Binary file not shown.
466
tests/data/incremental_dev_project/mock.py
Normal file
466
tests/data/incremental_dev_project/mock.py
Normal file
|
|
@ -0,0 +1,466 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
@Time : 2024/01/17
|
||||
@Author : mannaandpoem
|
||||
@File : mock.py
|
||||
"""
|
||||
NEW_REQUIREMENT_SAMPLE = """
|
||||
Adding graphical interface functionality to enhance the user experience in the number-guessing game. The existing number-guessing game currently relies on command-line input for numbers. The goal is to introduce a graphical interface to improve the game's usability and visual appeal
|
||||
"""
|
||||
|
||||
PRD_SAMPLE = """
|
||||
## Language
|
||||
|
||||
en_us
|
||||
|
||||
## Programming Language
|
||||
|
||||
Python
|
||||
|
||||
## Original Requirements
|
||||
|
||||
Make a simple number guessing game
|
||||
|
||||
## Product Goals
|
||||
|
||||
- Ensure a user-friendly interface for the game
|
||||
- Provide a challenging yet enjoyable game experience
|
||||
- Design the game to be easily extendable for future features
|
||||
|
||||
## User Stories
|
||||
|
||||
- As a player, I want to guess numbers and receive feedback on whether my guess is too high or too low
|
||||
- As a player, I want to be able to set the difficulty level by choosing the range of possible numbers
|
||||
- As a player, I want to see my previous guesses to strategize my next guess
|
||||
- As a player, I want to know how many attempts it took me to guess the number once I get it right
|
||||
|
||||
## Competitive Analysis
|
||||
|
||||
- Guess The Number Game A: Basic text interface, no difficulty levels
|
||||
- Number Master B: Has difficulty levels, but cluttered interface
|
||||
- Quick Guess C: Sleek design, but lacks performance tracking
|
||||
- NumGuess D: Good performance tracking, but not mobile-friendly
|
||||
- GuessIt E: Mobile-friendly, but too many ads
|
||||
- Perfect Guess F: Offers hints, but the hints are not very helpful
|
||||
- SmartGuesser G: Has a learning mode, but lacks a competitive edge
|
||||
|
||||
## Competitive Quadrant Chart
|
||||
|
||||
quadrantChart
|
||||
title "User Engagement and Game Complexity"
|
||||
x-axis "Low Complexity" --> "High Complexity"
|
||||
y-axis "Low Engagement" --> "High Engagement"
|
||||
quadrant-1 "Too Simple"
|
||||
quadrant-2 "Niche Appeal"
|
||||
quadrant-3 "Complex & Unengaging"
|
||||
quadrant-4 "Sweet Spot"
|
||||
"Guess The Number Game A": [0.2, 0.4]
|
||||
"Number Master B": [0.5, 0.3]
|
||||
"Quick Guess C": [0.6, 0.7]
|
||||
"NumGuess D": [0.4, 0.6]
|
||||
"GuessIt E": [0.7, 0.5]
|
||||
"Perfect Guess F": [0.6, 0.4]
|
||||
"SmartGuesser G": [0.8, 0.6]
|
||||
"Our Target Product": [0.5, 0.8]
|
||||
|
||||
## Requirement Analysis
|
||||
|
||||
The game should be simple yet engaging, allowing players of different skill levels to enjoy it. It should provide immediate feedback and track the player's performance. The game should also be designed with a clean and intuitive interface, and it should be easy to add new features in the future.
|
||||
|
||||
## Requirement Pool
|
||||
|
||||
- ['P0', 'Implement the core game logic to randomly select a number and allow the user to guess it']
|
||||
- ['P0', 'Design a user interface that displays the game status and results clearly']
|
||||
- ['P1', 'Add difficulty levels by varying the range of possible numbers']
|
||||
- ['P1', 'Keep track of and display the number of attempts for each game session']
|
||||
- ['P2', "Store and show the history of the player's guesses during a game session"]
|
||||
|
||||
## UI Design draft
|
||||
|
||||
The UI will feature a clean and minimalist design with a number input field, submit button, and messages area to provide feedback. There will be options to select the difficulty level and a display showing the number of attempts and history of past guesses.
|
||||
|
||||
## Anything UNCLEAR"""
|
||||
|
||||
DESIGN_SAMPLE = """
|
||||
## Implementation approach
|
||||
|
||||
We will create a Python-based number guessing game with a simple command-line interface. For the user interface, we will use the built-in 'input' and 'print' functions for interaction. The random library will be used for generating random numbers. We will structure the code to be modular and easily extendable, separating the game logic from the user interface.
|
||||
|
||||
## File list
|
||||
|
||||
- main.py
|
||||
- game.py
|
||||
- ui.py
|
||||
|
||||
## Data structures and interfaces
|
||||
|
||||
|
||||
classDiagram
|
||||
class Game {
|
||||
-int secret_number
|
||||
-int min_range
|
||||
-int max_range
|
||||
-list attempts
|
||||
+__init__(difficulty: str)
|
||||
+start_game()
|
||||
+check_guess(guess: int) str
|
||||
+get_attempts() int
|
||||
+get_history() list
|
||||
}
|
||||
class UI {
|
||||
+start()
|
||||
+display_message(message: str)
|
||||
+get_user_input(prompt: str) str
|
||||
+show_attempts(attempts: int)
|
||||
+show_history(history: list)
|
||||
+select_difficulty() str
|
||||
}
|
||||
class Main {
|
||||
+main()
|
||||
}
|
||||
Main --> UI
|
||||
UI --> Game
|
||||
|
||||
|
||||
## Program call flow
|
||||
|
||||
|
||||
sequenceDiagram
|
||||
participant M as Main
|
||||
participant UI as UI
|
||||
participant G as Game
|
||||
M->>UI: start()
|
||||
UI->>UI: select_difficulty()
|
||||
UI-->>G: __init__(difficulty)
|
||||
G->>G: start_game()
|
||||
loop Game Loop
|
||||
UI->>UI: get_user_input("Enter your guess:")
|
||||
UI-->>G: check_guess(guess)
|
||||
G->>UI: display_message(feedback)
|
||||
G->>UI: show_attempts(attempts)
|
||||
G->>UI: show_history(history)
|
||||
end
|
||||
G->>UI: display_message("Correct! Game over.")
|
||||
UI->>M: main() # Game session ends
|
||||
|
||||
|
||||
## Anything UNCLEAR
|
||||
|
||||
The requirement analysis suggests the need for a clean and intuitive interface. Since we are using a command-line interface, we need to ensure that the text-based UI is as user-friendly as possible. Further clarification on whether a graphical user interface (GUI) is expected in the future would be helpful for planning the extendability of the game."""
|
||||
|
||||
TASKS_SAMPLE = """
|
||||
## Required Python packages
|
||||
|
||||
- random==2.2.1
|
||||
|
||||
## Required Other language third-party packages
|
||||
|
||||
- No third-party dependencies required
|
||||
|
||||
## Logic Analysis
|
||||
|
||||
- ['game.py', 'Contains Game class with methods __init__, start_game, check_guess, get_attempts, get_history and uses random library for generating secret_number']
|
||||
- ['ui.py', 'Contains UI class with methods start, display_message, get_user_input, show_attempts, show_history, select_difficulty and interacts with Game class']
|
||||
- ['main.py', 'Contains Main class with method main that initializes UI class and starts the game loop']
|
||||
|
||||
## Task list
|
||||
|
||||
- game.py
|
||||
- ui.py
|
||||
- main.py
|
||||
|
||||
## Full API spec
|
||||
|
||||
|
||||
|
||||
## Shared Knowledge
|
||||
|
||||
`game.py` contains the core game logic and is used by `ui.py` to interact with the user. `main.py` serves as the entry point to start the game.
|
||||
|
||||
## Anything UNCLEAR
|
||||
|
||||
The requirement analysis suggests the need for a clean and intuitive interface. Since we are using a command-line interface, we need to ensure that the text-based UI is as user-friendly as possible. Further clarification on whether a graphical user interface (GUI) is expected in the future would be helpful for planning the extendability of the game."""
|
||||
|
||||
OLD_CODE_SAMPLE = """
|
||||
--- game.py
|
||||
```## game.py
|
||||
|
||||
import random
|
||||
|
||||
class Game:
|
||||
def __init__(self, difficulty: str = 'medium'):
|
||||
self.min_range, self.max_range = self._set_difficulty(difficulty)
|
||||
self.secret_number = random.randint(self.min_range, self.max_range)
|
||||
self.attempts = []
|
||||
|
||||
def _set_difficulty(self, difficulty: str):
|
||||
difficulties = {
|
||||
'easy': (1, 10),
|
||||
'medium': (1, 100),
|
||||
'hard': (1, 1000)
|
||||
}
|
||||
return difficulties.get(difficulty, (1, 100))
|
||||
|
||||
def start_game(self):
|
||||
self.secret_number = random.randint(self.min_range, self.max_range)
|
||||
self.attempts = []
|
||||
|
||||
def check_guess(self, guess: int) -> str:
|
||||
self.attempts.append(guess)
|
||||
if guess < self.secret_number:
|
||||
return "It's higher."
|
||||
elif guess > self.secret_number:
|
||||
return "It's lower."
|
||||
else:
|
||||
return "Correct! Game over."
|
||||
|
||||
def get_attempts(self) -> int:
|
||||
return len(self.attempts)
|
||||
|
||||
def get_history(self) -> list:
|
||||
return self.attempts```
|
||||
|
||||
--- ui.py
|
||||
```## ui.py
|
||||
|
||||
from game import Game
|
||||
|
||||
class UI:
|
||||
def start(self):
|
||||
difficulty = self.select_difficulty()
|
||||
game = Game(difficulty)
|
||||
game.start_game()
|
||||
self.display_welcome_message(game)
|
||||
|
||||
feedback = ""
|
||||
while feedback != "Correct! Game over.":
|
||||
guess = self.get_user_input("Enter your guess: ")
|
||||
if self.is_valid_guess(guess):
|
||||
feedback = game.check_guess(int(guess))
|
||||
self.display_message(feedback)
|
||||
self.show_attempts(game.get_attempts())
|
||||
self.show_history(game.get_history())
|
||||
else:
|
||||
self.display_message("Please enter a valid number.")
|
||||
|
||||
def display_welcome_message(self, game):
|
||||
print("Welcome to the Number Guessing Game!")
|
||||
print(f"Guess the number between {game.min_range} and {game.max_range}.")
|
||||
|
||||
def is_valid_guess(self, guess):
|
||||
return guess.isdigit()
|
||||
|
||||
def display_message(self, message: str):
|
||||
print(message)
|
||||
|
||||
def get_user_input(self, prompt: str) -> str:
|
||||
return input(prompt)
|
||||
|
||||
def show_attempts(self, attempts: int):
|
||||
print(f"Number of attempts: {attempts}")
|
||||
|
||||
def show_history(self, history: list):
|
||||
print("Guess history:")
|
||||
for guess in history:
|
||||
print(guess)
|
||||
|
||||
def select_difficulty(self) -> str:
|
||||
while True:
|
||||
difficulty = input("Select difficulty (easy, medium, hard): ").lower()
|
||||
if difficulty in ['easy', 'medium', 'hard']:
|
||||
return difficulty
|
||||
else:
|
||||
self.display_message("Invalid difficulty. Please choose 'easy', 'medium', or 'hard'.")```
|
||||
|
||||
--- main.py
|
||||
```## main.py
|
||||
|
||||
from ui import UI
|
||||
|
||||
class Main:
|
||||
def main(self):
|
||||
user_interface = UI()
|
||||
user_interface.start()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main_instance = Main()
|
||||
main_instance.main()```
|
||||
"""
|
||||
|
||||
REFINED_PRD_JSON = {
|
||||
"Language": "en_us",
|
||||
"Programming Language": "Python",
|
||||
"Refined Requirements": "Adding graphical interface functionality to enhance the user experience in the number-guessing game.",
|
||||
"Project Name": "number_guessing_game",
|
||||
"Refined Product Goals": [
|
||||
"Ensure a user-friendly interface for the game with the new graphical interface",
|
||||
"Provide a challenging yet enjoyable game experience with visual enhancements",
|
||||
"Design the game to be easily extendable for future features, including graphical elements",
|
||||
],
|
||||
"Refined User Stories": [
|
||||
"As a player, I want to interact with a graphical interface to guess numbers and receive visual feedback on my guesses",
|
||||
"As a player, I want to easily select the difficulty level through the graphical interface",
|
||||
"As a player, I want to visually track my previous guesses and the number of attempts in the graphical interface",
|
||||
"As a player, I want to be congratulated with a visually appealing message when I guess the number correctly",
|
||||
],
|
||||
"Competitive Analysis": [
|
||||
"Guess The Number Game A: Basic text interface, no difficulty levels",
|
||||
"Number Master B: Has difficulty levels, but cluttered interface",
|
||||
"Quick Guess C: Sleek design, but lacks performance tracking",
|
||||
"NumGuess D: Good performance tracking, but not mobile-friendly",
|
||||
"GuessIt E: Mobile-friendly, but too many ads",
|
||||
"Perfect Guess F: Offers hints, but the hints are not very helpful",
|
||||
"SmartGuesser G: Has a learning mode, but lacks a competitive edge",
|
||||
"Graphical Guess H: Graphical interface, but poor user experience due to complex design",
|
||||
],
|
||||
"Competitive Quadrant Chart": 'quadrantChart\n title "User Engagement and Game Complexity with Graphical Interface"\n x-axis "Low Complexity" --> "High Complexity"\n y-axis "Low Engagement" --> "High Engagement"\n quadrant-1 "Too Simple"\n quadrant-2 "Niche Appeal"\n quadrant-3 "Complex & Unengaging"\n quadrant-4 "Sweet Spot"\n "Guess The Number Game A": [0.2, 0.4]\n "Number Master B": [0.5, 0.3]\n "Quick Guess C": [0.6, 0.7]\n "NumGuess D": [0.4, 0.6]\n "GuessIt E": [0.7, 0.5]\n "Perfect Guess F": [0.6, 0.4]\n "SmartGuesser G": [0.8, 0.6]\n "Graphical Guess H": [0.7, 0.3]\n "Our Target Product": [0.5, 0.9]',
|
||||
"Refined Requirement Analysis": [
|
||||
"The game should maintain its simplicity while integrating a graphical interface for enhanced engagement.",
|
||||
"Immediate visual feedback is crucial for user satisfaction in the graphical interface.",
|
||||
"The interface must be intuitive, allowing for easy navigation and selection of game options.",
|
||||
"The graphical design should be clean and not detract from the game's core guessing mechanic.",
|
||||
],
|
||||
"Refined Requirement Pool": [
|
||||
["P0", "Implement a graphical user interface (GUI) to replace the command-line interaction"],
|
||||
[
|
||||
"P0",
|
||||
"Design a user interface that displays the game status, results, and feedback clearly with graphical elements",
|
||||
],
|
||||
["P1", "Incorporate interactive elements for selecting difficulty levels"],
|
||||
["P1", "Visualize the history of the player's guesses and the number of attempts within the game session"],
|
||||
["P2", "Create animations for correct or incorrect guesses to enhance user feedback"],
|
||||
["P2", "Ensure the GUI is responsive and compatible with various screen sizes"],
|
||||
["P2", "Store and show the history of the player's guesses during a game session"],
|
||||
],
|
||||
"UI Design draft": "The UI will feature a modern and minimalist design with a graphical number input field, a submit button with animations, and a dedicated area for visual feedback. It will include interactive elements to select the difficulty level and a visual display for the number of attempts and history of past guesses.",
|
||||
"Anything UNCLEAR": "",
|
||||
}
|
||||
|
||||
REFINED_DESIGN_JSON = {
|
||||
"Refined Implementation Approach": "To accommodate the new graphical user interface (GUI) requirements, we will leverage the Tkinter library, which is included with Python and supports the creation of a user-friendly GUI. The game logic will remain in Python, with Tkinter handling the rendering of the interface. We will ensure that the GUI is responsive and provides immediate visual feedback. The main game loop will be event-driven, responding to user inputs such as button clicks and difficulty selection.",
|
||||
"Refined File list": ["main.py", "game.py", "ui.py", "gui.py"],
|
||||
"Refined Data structures and interfaces": "\nclassDiagram\n class Game {\n -int secret_number\n -int min_range\n -int max_range\n -list attempts\n +__init__(difficulty: str)\n +start_game()\n +check_guess(guess: int) str\n +get_attempts() int\n +get_history() list\n }\n class UI {\n +start()\n +display_message(message: str)\n +get_user_input(prompt: str) str\n +show_attempts(attempts: int)\n +show_history(history: list)\n +select_difficulty() str\n }\n class GUI {\n +__init__()\n +setup_window()\n +bind_events()\n +update_feedback(message: str)\n +update_attempts(attempts: int)\n +update_history(history: list)\n +show_difficulty_selector()\n +animate_guess_result(correct: bool)\n }\n class Main {\n +main()\n }\n Main --> UI\n UI --> Game\n UI --> GUI\n GUI --> Game\n",
|
||||
"Refined Program call flow": '\nsequenceDiagram\n participant M as Main\n participant UI as UI\n participant G as Game\n participant GU as GUI\n M->>UI: start()\n UI->>GU: setup_window()\n GU->>GU: bind_events()\n GU->>UI: select_difficulty()\n UI-->>G: __init__(difficulty)\n G->>G: start_game()\n loop Game Loop\n GU->>GU: show_difficulty_selector()\n GU->>UI: get_user_input("Enter your guess:")\n UI-->>G: check_guess(guess)\n G->>GU: update_feedback(feedback)\n G->>GU: update_attempts(attempts)\n G->>GU: update_history(history)\n GU->>GU: animate_guess_result(correct)\n end\n G->>GU: update_feedback("Correct! Game over.")\n GU->>M: main() # Game session ends\n',
|
||||
"Anything UNCLEAR": "",
|
||||
}
|
||||
|
||||
REFINED_TASKS_JSON = {
|
||||
"Required Python packages": ["random==2.2.1", "Tkinter==8.6"],
|
||||
"Required Other language third-party packages": ["No third-party dependencies required"],
|
||||
"Refined Logic Analysis": [
|
||||
[
|
||||
"game.py",
|
||||
"Contains Game class with methods __init__, start_game, check_guess, get_attempts, get_history and uses random library for generating secret_number",
|
||||
],
|
||||
[
|
||||
"ui.py",
|
||||
"Contains UI class with methods start, display_message, get_user_input, show_attempts, show_history, select_difficulty and interacts with Game class",
|
||||
],
|
||||
[
|
||||
"gui.py",
|
||||
"Contains GUI class with methods __init__, setup_window, bind_events, update_feedback, update_attempts, update_history, show_difficulty_selector, animate_guess_result and interacts with Game class for GUI rendering",
|
||||
],
|
||||
[
|
||||
"main.py",
|
||||
"Contains Main class with method main that initializes UI class and starts the event-driven game loop",
|
||||
],
|
||||
],
|
||||
"Refined Task list": ["game.py", "ui.py", "gui.py", "main.py"],
|
||||
"Full API spec": "",
|
||||
"Refined Shared Knowledge": "`game.py` contains the core game logic and is used by `ui.py` to interact with the user. `main.py` serves as the entry point to start the game. `gui.py` is introduced to handle the graphical user interface using Tkinter, which will interact with both `game.py` and `ui.py` for a responsive and user-friendly experience.",
|
||||
"Anything UNCLEAR": "",
|
||||
}
|
||||
|
||||
CODE_PLAN_AND_CHANGE_SAMPLE = {
|
||||
"Code Plan And Change": '\n1. Plan for gui.py: Develop the GUI using Tkinter to replace the command-line interface. Start by setting up the main window and event handling. Then, add widgets for displaying the game status, results, and feedback. Implement interactive elements for difficulty selection and visualize the guess history. Finally, create animations for guess feedback and ensure responsiveness across different screen sizes.\n```python\nclass GUI:\n- pass\n+ def __init__(self):\n+ self.setup_window()\n+\n+ def setup_window(self):\n+ # Initialize the main window using Tkinter\n+ pass\n+\n+ def bind_events(self):\n+ # Bind button clicks and other events\n+ pass\n+\n+ def update_feedback(self, message: str):\n+ # Update the feedback label with the given message\n+ pass\n+\n+ def update_attempts(self, attempts: int):\n+ # Update the attempts label with the number of attempts\n+ pass\n+\n+ def update_history(self, history: list):\n+ # Update the history view with the list of past guesses\n+ pass\n+\n+ def show_difficulty_selector(self):\n+ # Show buttons or a dropdown for difficulty selection\n+ pass\n+\n+ def animate_guess_result(self, correct: bool):\n+ # Trigger an animation for correct or incorrect guesses\n+ pass\n```\n\n2. Plan for main.py: Modify the main.py to initialize the GUI and start the event-driven game loop. Ensure that the GUI is the primary interface for user interaction.\n```python\nclass Main:\n def main(self):\n- user_interface = UI()\n- user_interface.start()\n+ graphical_user_interface = GUI()\n+ graphical_user_interface.setup_window()\n+ graphical_user_interface.bind_events()\n+ # Start the Tkinter main loop\n+ pass\n\n if __name__ == "__main__":\n main_instance = Main()\n main_instance.main()\n```\n\n3. Plan for ui.py: Refactor ui.py to work with the new GUI class. Remove command-line interactions and delegate display and input tasks to the GUI.\n```python\nclass UI:\n- def display_message(self, message: str):\n- print(message)\n+\n+ def display_message(self, message: str):\n+ # This method will now pass the message to the GUI to display\n+ pass\n\n- def get_user_input(self, prompt: str) -> str:\n- return input(prompt)\n+\n+ def get_user_input(self, prompt: str) -> str:\n+ # This method will now trigger the GUI to get user input\n+ pass\n\n- def show_attempts(self, attempts: int):\n- print(f"Number of attempts: {attempts}")\n+\n+ def show_attempts(self, attempts: int):\n+ # This method will now update the GUI with the number of attempts\n+ pass\n\n- def show_history(self, history: list):\n- print("Guess history:")\n- for guess in history:\n- print(guess)\n+\n+ def show_history(self, history: list):\n+ # This method will now update the GUI with the guess history\n+ pass\n```\n\n4. Plan for game.py: Ensure game.py remains mostly unchanged as it contains the core game logic. However, make minor adjustments if necessary to integrate with the new GUI.\n```python\nclass Game:\n # No changes required for now\n```\n'
|
||||
}
|
||||
|
||||
REFINED_CODE_INPUT_SAMPLE = """
|
||||
-----Now, game.py to be rewritten
|
||||
```## game.py
|
||||
|
||||
import random
|
||||
|
||||
class Game:
|
||||
def __init__(self, difficulty: str = 'medium'):
|
||||
self.min_range, self.max_range = self._set_difficulty(difficulty)
|
||||
self.secret_number = random.randint(self.min_range, self.max_range)
|
||||
self.attempts = []
|
||||
|
||||
def _set_difficulty(self, difficulty: str):
|
||||
difficulties = {
|
||||
'easy': (1, 10),
|
||||
'medium': (1, 100),
|
||||
'hard': (1, 1000)
|
||||
}
|
||||
return difficulties.get(difficulty, (1, 100))
|
||||
|
||||
def start_game(self):
|
||||
self.secret_number = random.randint(self.min_range, self.max_range)
|
||||
self.attempts = []
|
||||
|
||||
def check_guess(self, guess: int) -> str:
|
||||
self.attempts.append(guess)
|
||||
if guess < self.secret_number:
|
||||
return "It's higher."
|
||||
elif guess > self.secret_number:
|
||||
return "It's lower."
|
||||
else:
|
||||
return "Correct! Game over."
|
||||
|
||||
def get_attempts(self) -> int:
|
||||
return len(self.attempts)
|
||||
|
||||
def get_history(self) -> list:
|
||||
return self.attempts```
|
||||
"""
|
||||
|
||||
REFINED_CODE_SAMPLE = """
|
||||
## game.py
|
||||
|
||||
import random
|
||||
|
||||
class Game:
|
||||
def __init__(self, difficulty: str = 'medium'):
|
||||
# Set the difficulty level with default value 'medium'
|
||||
self.min_range, self.max_range = self._set_difficulty(difficulty)
|
||||
# Initialize the secret number based on the difficulty
|
||||
self.secret_number = random.randint(self.min_range, self.max_range)
|
||||
# Initialize the list to keep track of attempts
|
||||
self.attempts = []
|
||||
|
||||
def _set_difficulty(self, difficulty: str):
|
||||
# Define the range of numbers for each difficulty level
|
||||
difficulties = {
|
||||
'easy': (1, 10),
|
||||
'medium': (1, 100),
|
||||
'hard': (1, 1000)
|
||||
}
|
||||
# Return the corresponding range for the selected difficulty, default to 'medium' if not found
|
||||
return difficulties.get(difficulty, (1, 100))
|
||||
|
||||
def start_game(self):
|
||||
# Reset the secret number and attempts list for a new game
|
||||
self.secret_number = random.randint(self.min_range, self.max_range)
|
||||
self.attempts.clear()
|
||||
|
||||
def check_guess(self, guess: int) -> str:
|
||||
# Add the guess to the attempts list
|
||||
self.attempts.append(guess)
|
||||
# Provide feedback based on the guess
|
||||
if guess < self.secret_number:
|
||||
return "It's higher."
|
||||
elif guess > self.secret_number:
|
||||
return "It's lower."
|
||||
else:
|
||||
return "Correct! Game over."
|
||||
|
||||
def get_attempts(self) -> int:
|
||||
# Return the number of attempts made
|
||||
return len(self.attempts)
|
||||
|
||||
def get_history(self) -> list:
|
||||
# Return the list of attempts made
|
||||
return self.attempts
|
||||
"""
|
||||
BIN
tests/data/incremental_dev_project/number_guessing_game.zip
Normal file
BIN
tests/data/incremental_dev_project/number_guessing_game.zip
Normal file
Binary file not shown.
BIN
tests/data/incremental_dev_project/pygame_2048.zip
Normal file
BIN
tests/data/incremental_dev_project/pygame_2048.zip
Normal file
Binary file not shown.
3
tests/data/incremental_dev_project/readme.md
Normal file
3
tests/data/incremental_dev_project/readme.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# Code archive
|
||||
|
||||
This folder contains a compressed package for the test_incremental_dev.py file, which is used to demonstrate the process of incremental development.
|
||||
BIN
tests/data/incremental_dev_project/simple_add_calculator.zip
Normal file
BIN
tests/data/incremental_dev_project/simple_add_calculator.zip
Normal file
Binary file not shown.
BIN
tests/data/incremental_dev_project/snake_game.zip
Normal file
BIN
tests/data/incremental_dev_project/snake_game.zip
Normal file
Binary file not shown.
BIN
tests/data/incremental_dev_project/word_cloud.zip
Normal file
BIN
tests/data/incremental_dev_project/word_cloud.zip
Normal file
Binary file not shown.
180
tests/data/ml_datasets/titanic/split_eval.csv
Normal file
180
tests/data/ml_datasets/titanic/split_eval.csv
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
PassengerId,Survived,Pclass,Name,Sex,Age,SibSp,Parch,Ticket,Fare,Cabin,Embarked
|
||||
206,0,3,"Strom, Miss. Telma Matilda",female,2.0,0,1,347054,10.4625,G6,S
|
||||
45,1,3,"Devaney, Miss. Margaret Delia",female,19.0,0,0,330958,7.8792,,Q
|
||||
822,1,3,"Lulic, Mr. Nikola",male,27.0,0,0,315098,8.6625,,S
|
||||
459,1,2,"Toomey, Miss. Ellen",female,50.0,0,0,F.C.C. 13531,10.5,,S
|
||||
796,0,2,"Otter, Mr. Richard",male,39.0,0,0,28213,13.0,,S
|
||||
119,0,1,"Baxter, Mr. Quigg Edmond",male,24.0,0,1,PC 17558,247.5208,B58 B60,C
|
||||
425,0,3,"Rosblom, Mr. Viktor Richard",male,18.0,1,1,370129,20.2125,,S
|
||||
679,0,3,"Goodwin, Mrs. Frederick (Augusta Tyler)",female,43.0,1,6,CA 2144,46.9,,S
|
||||
270,1,1,"Bissette, Miss. Amelia",female,35.0,0,0,PC 17760,135.6333,C99,S
|
||||
230,0,3,"Lefebre, Miss. Mathilde",female,,3,1,4133,25.4667,,S
|
||||
690,1,1,"Madill, Miss. Georgette Alexandra",female,15.0,0,1,24160,211.3375,B5,S
|
||||
321,0,3,"Dennis, Mr. Samuel",male,22.0,0,0,A/5 21172,7.25,,S
|
||||
406,0,2,"Gale, Mr. Shadrach",male,34.0,1,0,28664,21.0,,S
|
||||
41,0,3,"Ahlin, Mrs. Johan (Johanna Persdotter Larsson)",female,40.0,1,0,7546,9.475,,S
|
||||
25,0,3,"Palsson, Miss. Torborg Danira",female,8.0,3,1,349909,21.075,,S
|
||||
554,1,3,"Leeni, Mr. Fahim (""Philip Zenni"")",male,22.0,0,0,2620,7.225,,C
|
||||
413,1,1,"Minahan, Miss. Daisy E",female,33.0,1,0,19928,90.0,C78,Q
|
||||
513,1,1,"McGough, Mr. James Robert",male,36.0,0,0,PC 17473,26.2875,E25,S
|
||||
756,1,2,"Hamalainen, Master. Viljo",male,0.67,1,1,250649,14.5,,S
|
||||
392,1,3,"Jansson, Mr. Carl Olof",male,21.0,0,0,350034,7.7958,,S
|
||||
602,0,3,"Slabenoff, Mr. Petco",male,,0,0,349214,7.8958,,S
|
||||
326,1,1,"Young, Miss. Marie Grice",female,36.0,0,0,PC 17760,135.6333,C32,C
|
||||
373,0,3,"Beavan, Mr. William Thomas",male,19.0,0,0,323951,8.05,,S
|
||||
377,1,3,"Landergren, Miss. Aurora Adelia",female,22.0,0,0,C 7077,7.25,,S
|
||||
201,0,3,"Vande Walle, Mr. Nestor Cyriel",male,28.0,0,0,345770,9.5,,S
|
||||
512,0,3,"Webber, Mr. James",male,,0,0,SOTON/OQ 3101316,8.05,,S
|
||||
601,1,2,"Jacobsohn, Mrs. Sidney Samuel (Amy Frances Christy)",female,24.0,2,1,243847,27.0,,S
|
||||
631,1,1,"Barkworth, Mr. Algernon Henry Wilson",male,80.0,0,0,27042,30.0,A23,S
|
||||
364,0,3,"Asim, Mr. Adola",male,35.0,0,0,SOTON/O.Q. 3101310,7.05,,S
|
||||
144,0,3,"Burke, Mr. Jeremiah",male,19.0,0,0,365222,6.75,,Q
|
||||
202,0,3,"Sage, Mr. Frederick",male,,8,2,CA. 2343,69.55,,S
|
||||
134,1,2,"Weisz, Mrs. Leopold (Mathilde Francoise Pede)",female,29.0,1,0,228414,26.0,,S
|
||||
431,1,1,"Bjornstrom-Steffansson, Mr. Mauritz Hakan",male,28.0,0,0,110564,26.55,C52,S
|
||||
419,0,2,"Matthews, Mr. William John",male,30.0,0,0,28228,13.0,,S
|
||||
782,1,1,"Dick, Mrs. Albert Adrian (Vera Gillespie)",female,17.0,1,0,17474,57.0,B20,S
|
||||
705,0,3,"Hansen, Mr. Henrik Juul",male,26.0,1,0,350025,7.8542,,S
|
||||
536,1,2,"Hart, Miss. Eva Miriam",female,7.0,0,2,F.C.C. 13529,26.25,,S
|
||||
335,1,1,"Frauenthal, Mrs. Henry William (Clara Heinsheimer)",female,,1,0,PC 17611,133.65,,S
|
||||
273,1,2,"Mellinger, Mrs. (Elizabeth Anne Maidment)",female,41.0,0,1,250644,19.5,,S
|
||||
108,1,3,"Moss, Mr. Albert Johan",male,,0,0,312991,7.775,,S
|
||||
403,0,3,"Jussila, Miss. Mari Aina",female,21.0,1,0,4137,9.825,,S
|
||||
307,1,1,"Fleming, Miss. Margaret",female,,0,0,17421,110.8833,,C
|
||||
218,0,2,"Jacobsohn, Mr. Sidney Samuel",male,42.0,1,0,243847,27.0,,S
|
||||
789,1,3,"Dean, Master. Bertram Vere",male,1.0,1,2,C.A. 2315,20.575,,S
|
||||
160,0,3,"Sage, Master. Thomas Henry",male,,8,2,CA. 2343,69.55,,S
|
||||
20,1,3,"Masselmani, Mrs. Fatima",female,,0,0,2649,7.225,,C
|
||||
174,0,3,"Sivola, Mr. Antti Wilhelm",male,21.0,0,0,STON/O 2. 3101280,7.925,,S
|
||||
311,1,1,"Hays, Miss. Margaret Bechstein",female,24.0,0,0,11767,83.1583,C54,C
|
||||
595,0,2,"Chapman, Mr. John Henry",male,37.0,1,0,SC/AH 29037,26.0,,S
|
||||
592,1,1,"Stephenson, Mrs. Walter Bertram (Martha Eustis)",female,52.0,1,0,36947,78.2667,D20,C
|
||||
164,0,3,"Calic, Mr. Jovo",male,17.0,0,0,315093,8.6625,,S
|
||||
563,0,2,"Norman, Mr. Robert Douglas",male,28.0,0,0,218629,13.5,,S
|
||||
172,0,3,"Rice, Master. Arthur",male,4.0,4,1,382652,29.125,,Q
|
||||
871,0,3,"Balkic, Mr. Cerin",male,26.0,0,0,349248,7.8958,,S
|
||||
176,0,3,"Klasen, Mr. Klas Albin",male,18.0,1,1,350404,7.8542,,S
|
||||
434,0,3,"Kallio, Mr. Nikolai Erland",male,17.0,0,0,STON/O 2. 3101274,7.125,,S
|
||||
462,0,3,"Morley, Mr. William",male,34.0,0,0,364506,8.05,,S
|
||||
49,0,3,"Samaan, Mr. Youssef",male,,2,0,2662,21.6792,,C
|
||||
126,1,3,"Nicola-Yarred, Master. Elias",male,12.0,1,0,2651,11.2417,,C
|
||||
125,0,1,"White, Mr. Percival Wayland",male,54.0,0,1,35281,77.2875,D26,S
|
||||
266,0,2,"Reeves, Mr. David",male,36.0,0,0,C.A. 17248,10.5,,S
|
||||
550,1,2,"Davies, Master. John Morgan Jr",male,8.0,1,1,C.A. 33112,36.75,,S
|
||||
589,0,3,"Gilinski, Mr. Eliezer",male,22.0,0,0,14973,8.05,,S
|
||||
779,0,3,"Kilgannon, Mr. Thomas J",male,,0,0,36865,7.7375,,Q
|
||||
179,0,2,"Hale, Mr. Reginald",male,30.0,0,0,250653,13.0,,S
|
||||
107,1,3,"Salkjelsvik, Miss. Anna Kristine",female,21.0,0,0,343120,7.65,,S
|
||||
624,0,3,"Hansen, Mr. Henry Damsgaard",male,21.0,0,0,350029,7.8542,,S
|
||||
115,0,3,"Attalah, Miss. Malake",female,17.0,0,0,2627,14.4583,,C
|
||||
42,0,2,"Turpin, Mrs. William John Robert (Dorothy Ann Wonnacott)",female,27.0,1,0,11668,21.0,,S
|
||||
664,0,3,"Coleff, Mr. Peju",male,36.0,0,0,349210,7.4958,,S
|
||||
661,1,1,"Frauenthal, Dr. Henry William",male,50.0,2,0,PC 17611,133.65,,S
|
||||
762,0,3,"Nirva, Mr. Iisakki Antino Aijo",male,41.0,0,0,SOTON/O2 3101272,7.125,,S
|
||||
580,1,3,"Jussila, Mr. Eiriik",male,32.0,0,0,STON/O 2. 3101286,7.925,,S
|
||||
265,0,3,"Henry, Miss. Delia",female,,0,0,382649,7.75,,Q
|
||||
757,0,3,"Carlsson, Mr. August Sigfrid",male,28.0,0,0,350042,7.7958,,S
|
||||
666,0,2,"Hickman, Mr. Lewis",male,32.0,2,0,S.O.C. 14879,73.5,,S
|
||||
634,0,1,"Parr, Mr. William Henry Marsh",male,,0,0,112052,0.0,,S
|
||||
532,0,3,"Toufik, Mr. Nakli",male,,0,0,2641,7.2292,,C
|
||||
640,0,3,"Thorneycroft, Mr. Percival",male,,1,0,376564,16.1,,S
|
||||
599,0,3,"Boulos, Mr. Hanna",male,,0,0,2664,7.225,,C
|
||||
220,0,2,"Harris, Mr. Walter",male,30.0,0,0,W/C 14208,10.5,,S
|
||||
150,0,2,"Byles, Rev. Thomas Roussel Davids",male,42.0,0,0,244310,13.0,,S
|
||||
269,1,1,"Graham, Mrs. William Thompson (Edith Junkins)",female,58.0,0,1,PC 17582,153.4625,C125,S
|
||||
670,1,1,"Taylor, Mrs. Elmer Zebley (Juliet Cummins Wright)",female,,1,0,19996,52.0,C126,S
|
||||
578,1,1,"Silvey, Mrs. William Baird (Alice Munger)",female,39.0,1,0,13507,55.9,E44,S
|
||||
786,0,3,"Harmer, Mr. Abraham (David Lishin)",male,25.0,0,0,374887,7.25,,S
|
||||
82,1,3,"Sheerlinck, Mr. Jan Baptist",male,29.0,0,0,345779,9.5,,S
|
||||
400,1,2,"Trout, Mrs. William H (Jessie L)",female,28.0,0,0,240929,12.65,,S
|
||||
135,0,2,"Sobey, Mr. Samuel James Hayden",male,25.0,0,0,C.A. 29178,13.0,,S
|
||||
223,0,3,"Green, Mr. George Henry",male,51.0,0,0,21440,8.05,,S
|
||||
693,1,3,"Lam, Mr. Ali",male,,0,0,1601,56.4958,,S
|
||||
280,1,3,"Abbott, Mrs. Stanton (Rosa Hunt)",female,35.0,1,1,C.A. 2673,20.25,,S
|
||||
102,0,3,"Petroff, Mr. Pastcho (""Pentcho"")",male,,0,0,349215,7.8958,,S
|
||||
288,0,3,"Naidenoff, Mr. Penko",male,22.0,0,0,349206,7.8958,,S
|
||||
711,1,1,"Mayne, Mlle. Berthe Antonine (""Mrs de Villiers"")",female,24.0,0,0,PC 17482,49.5042,C90,C
|
||||
256,1,3,"Touma, Mrs. Darwis (Hanne Youssef Razi)",female,29.0,0,2,2650,15.2458,,C
|
||||
23,1,3,"McGowan, Miss. Anna ""Annie""",female,15.0,0,0,330923,8.0292,,Q
|
||||
582,1,1,"Thayer, Mrs. John Borland (Marian Longstreth Morris)",female,39.0,1,1,17421,110.8833,C68,C
|
||||
564,0,3,"Simmons, Mr. John",male,,0,0,SOTON/OQ 392082,8.05,,S
|
||||
405,0,3,"Oreskovic, Miss. Marija",female,20.0,0,0,315096,8.6625,,S
|
||||
429,0,3,"Flynn, Mr. James",male,,0,0,364851,7.75,,Q
|
||||
848,0,3,"Markoff, Mr. Marin",male,35.0,0,0,349213,7.8958,,C
|
||||
726,0,3,"Oreskovic, Mr. Luka",male,20.0,0,0,315094,8.6625,,S
|
||||
721,1,2,"Harper, Miss. Annie Jessie ""Nina""",female,6.0,0,1,248727,33.0,,S
|
||||
637,0,3,"Leinonen, Mr. Antti Gustaf",male,32.0,0,0,STON/O 2. 3101292,7.925,,S
|
||||
863,1,1,"Swift, Mrs. Frederick Joel (Margaret Welles Barron)",female,48.0,0,0,17466,25.9292,D17,S
|
||||
615,0,3,"Brocklebank, Mr. William Alfred",male,35.0,0,0,364512,8.05,,S
|
||||
199,1,3,"Madigan, Miss. Margaret ""Maggie""",female,,0,0,370370,7.75,,Q
|
||||
787,1,3,"Sjoblom, Miss. Anna Sofia",female,18.0,0,0,3101265,7.4958,,S
|
||||
156,0,1,"Williams, Mr. Charles Duane",male,51.0,0,1,PC 17597,61.3792,,C
|
||||
190,0,3,"Turcin, Mr. Stjepan",male,36.0,0,0,349247,7.8958,,S
|
||||
556,0,1,"Wright, Mr. George",male,62.0,0,0,113807,26.55,,S
|
||||
890,1,1,"Behr, Mr. Karl Howell",male,26.0,0,0,111369,30.0,C148,C
|
||||
827,0,3,"Lam, Mr. Len",male,,0,0,1601,56.4958,,S
|
||||
534,1,3,"Peter, Mrs. Catherine (Catherine Rizk)",female,,0,2,2668,22.3583,,C
|
||||
834,0,3,"Augustsson, Mr. Albert",male,23.0,0,0,347468,7.8542,,S
|
||||
279,0,3,"Rice, Master. Eric",male,7.0,4,1,382652,29.125,,Q
|
||||
189,0,3,"Bourke, Mr. John",male,40.0,1,1,364849,15.5,,Q
|
||||
561,0,3,"Morrow, Mr. Thomas Rowan",male,,0,0,372622,7.75,,Q
|
||||
375,0,3,"Palsson, Miss. Stina Viola",female,3.0,3,1,349909,21.075,,S
|
||||
322,0,3,"Danoff, Mr. Yoto",male,27.0,0,0,349219,7.8958,,S
|
||||
158,0,3,"Corn, Mr. Harry",male,30.0,0,0,SOTON/OQ 392090,8.05,,S
|
||||
524,1,1,"Hippach, Mrs. Louis Albert (Ida Sophia Fischer)",female,44.0,0,1,111361,57.9792,B18,C
|
||||
175,0,1,"Smith, Mr. James Clinch",male,56.0,0,0,17764,30.6958,A7,C
|
||||
117,0,3,"Connors, Mr. Patrick",male,70.5,0,0,370369,7.75,,Q
|
||||
810,1,1,"Chambers, Mrs. Norman Campbell (Bertha Griggs)",female,33.0,1,0,113806,53.1,E8,S
|
||||
472,0,3,"Cacic, Mr. Luka",male,38.0,0,0,315089,8.6625,,S
|
||||
228,0,3,"Lovell, Mr. John Hall (""Henry"")",male,20.5,0,0,A/5 21173,7.25,,S
|
||||
330,1,1,"Hippach, Miss. Jean Gertrude",female,16.0,0,1,111361,57.9792,B18,C
|
||||
147,1,3,"Andersson, Mr. August Edvard (""Wennerstrom"")",male,27.0,0,0,350043,7.7958,,S
|
||||
98,1,1,"Greenfield, Mr. William Bertram",male,23.0,0,1,PC 17759,63.3583,D10 D12,C
|
||||
493,0,1,"Molson, Mr. Harry Markland",male,55.0,0,0,113787,30.5,C30,S
|
||||
73,0,2,"Hood, Mr. Ambrose Jr",male,21.0,0,0,S.O.C. 14879,73.5,,S
|
||||
645,1,3,"Baclini, Miss. Eugenie",female,0.75,2,1,2666,19.2583,,C
|
||||
303,0,3,"Johnson, Mr. William Cahoone Jr",male,19.0,0,0,LINE,0.0,,S
|
||||
699,0,1,"Thayer, Mr. John Borland",male,49.0,1,1,17421,110.8833,C68,C
|
||||
704,0,3,"Gallagher, Mr. Martin",male,25.0,0,0,36864,7.7417,,Q
|
||||
639,0,3,"Panula, Mrs. Juha (Maria Emilia Ojala)",female,41.0,0,5,3101295,39.6875,,S
|
||||
99,1,2,"Doling, Mrs. John T (Ada Julia Bone)",female,34.0,0,1,231919,23.0,,S
|
||||
74,0,3,"Chronopoulos, Mr. Apostolos",male,26.0,1,0,2680,14.4542,,C
|
||||
157,1,3,"Gilnagh, Miss. Katherine ""Katie""",female,16.0,0,0,35851,7.7333,,Q
|
||||
475,0,3,"Strandberg, Miss. Ida Sofia",female,22.0,0,0,7553,9.8375,,S
|
||||
240,0,2,"Hunt, Mr. George Henry",male,33.0,0,0,SCO/W 1585,12.275,,S
|
||||
801,0,2,"Ponesell, Mr. Martin",male,34.0,0,0,250647,13.0,,S
|
||||
829,1,3,"McCormack, Mr. Thomas Joseph",male,,0,0,367228,7.75,,Q
|
||||
208,1,3,"Albimona, Mr. Nassef Cassem",male,26.0,0,0,2699,18.7875,,C
|
||||
29,1,3,"O'Dwyer, Miss. Ellen ""Nellie""",female,,0,0,330959,7.8792,,Q
|
||||
616,1,2,"Herman, Miss. Alice",female,24.0,1,2,220845,65.0,,S
|
||||
309,0,2,"Abelson, Mr. Samuel",male,30.0,1,0,P/PP 3381,24.0,,C
|
||||
382,1,3,"Nakid, Miss. Maria (""Mary"")",female,1.0,0,2,2653,15.7417,,C
|
||||
703,0,3,"Barbara, Miss. Saiide",female,18.0,0,1,2691,14.4542,,C
|
||||
623,1,3,"Nakid, Mr. Sahid",male,20.0,1,1,2653,15.7417,,C
|
||||
26,1,3,"Asplund, Mrs. Carl Oscar (Selma Augusta Emilia Johansson)",female,38.0,1,5,347077,31.3875,,S
|
||||
519,1,2,"Angle, Mrs. William A (Florence ""Mary"" Agnes Hughes)",female,36.0,1,0,226875,26.0,,S
|
||||
638,0,2,"Collyer, Mr. Harvey",male,31.0,1,1,C.A. 31921,26.25,,S
|
||||
360,1,3,"Mockler, Miss. Helen Mary ""Ellie""",female,,0,0,330980,7.8792,,Q
|
||||
736,0,3,"Williams, Mr. Leslie",male,28.5,0,0,54636,16.1,,S
|
||||
101,0,3,"Petranec, Miss. Matilda",female,28.0,0,0,349245,7.8958,,S
|
||||
165,0,3,"Panula, Master. Eino Viljami",male,1.0,4,1,3101295,39.6875,,S
|
||||
591,0,3,"Rintamaki, Mr. Matti",male,35.0,0,0,STON/O 2. 3101273,7.125,,S
|
||||
11,1,3,"Sandstrom, Miss. Marguerite Rut",female,4.0,1,1,PP 9549,16.7,G6,S
|
||||
217,1,3,"Honkanen, Miss. Eliina",female,27.0,0,0,STON/O2. 3101283,7.925,,S
|
||||
734,0,2,"Berriman, Mr. William John",male,23.0,0,0,28425,13.0,,S
|
||||
385,0,3,"Plotcharsky, Mr. Vasil",male,,0,0,349227,7.8958,,S
|
||||
854,1,1,"Lines, Miss. Mary Conover",female,16.0,0,1,PC 17592,39.4,D28,S
|
||||
860,0,3,"Razi, Mr. Raihed",male,,0,0,2629,7.2292,,C
|
||||
359,1,3,"McGovern, Miss. Mary",female,,0,0,330931,7.8792,,Q
|
||||
448,1,1,"Seward, Mr. Frederic Kimber",male,34.0,0,0,113794,26.55,,S
|
||||
214,0,2,"Givard, Mr. Hans Kristensen",male,30.0,0,0,250646,13.0,,S
|
||||
652,1,2,"Doling, Miss. Elsie",female,18.0,0,1,231919,23.0,,S
|
||||
192,0,2,"Carbines, Mr. William",male,19.0,0,0,28424,13.0,,S
|
||||
57,1,2,"Rugg, Miss. Emily",female,21.0,0,0,C.A. 31026,10.5,,S
|
||||
868,0,1,"Roebling, Mr. Washington Augustus II",male,31.0,0,0,PC 17590,50.4958,A24,S
|
||||
531,1,2,"Quick, Miss. Phyllis May",female,2.0,1,1,26360,26.0,,S
|
||||
248,1,2,"Hamalainen, Mrs. William (Anna)",female,24.0,0,2,250649,14.5,,S
|
||||
260,1,2,"Parrish, Mrs. (Lutie Davis)",female,50.0,0,1,230433,26.0,,S
|
||||
354,0,3,"Arnold-Franchi, Mr. Josef",male,25.0,1,0,349237,17.8,,S
|
||||
784,0,3,"Johnston, Mr. Andrew G",male,,1,2,W./C. 6607,23.45,,S
|
||||
853,0,3,"Boulos, Miss. Nourelain",female,9.0,1,1,2678,15.2458,,C
|
||||
|
713
tests/data/ml_datasets/titanic/split_train.csv
Normal file
713
tests/data/ml_datasets/titanic/split_train.csv
Normal file
|
|
@ -0,0 +1,713 @@
|
|||
PassengerId,Survived,Pclass,Name,Sex,Age,SibSp,Parch,Ticket,Fare,Cabin,Embarked
|
||||
409,0,3,"Birkeland, Mr. Hans Martin Monsen",male,21.0,0,0,312992,7.775,,S
|
||||
481,0,3,"Goodwin, Master. Harold Victor",male,9.0,5,2,CA 2144,46.9,,S
|
||||
511,1,3,"Daly, Mr. Eugene Patrick",male,29.0,0,0,382651,7.75,,Q
|
||||
610,1,1,"Shutes, Miss. Elizabeth W",female,40.0,0,0,PC 17582,153.4625,C125,S
|
||||
548,1,2,"Padro y Manent, Mr. Julian",male,,0,0,SC/PARIS 2146,13.8625,,C
|
||||
710,1,3,"Moubarek, Master. Halim Gonios (""William George"")",male,,1,1,2661,15.2458,,C
|
||||
153,0,3,"Meo, Mr. Alfonzo",male,55.5,0,0,A.5. 11206,8.05,,S
|
||||
494,0,1,"Artagaveytia, Mr. Ramon",male,71.0,0,0,PC 17609,49.5042,,C
|
||||
393,0,3,"Gustafsson, Mr. Johan Birger",male,28.0,2,0,3101277,7.925,,S
|
||||
824,1,3,"Moor, Mrs. (Beila)",female,27.0,0,1,392096,12.475,E121,S
|
||||
577,1,2,"Garside, Miss. Ethel",female,34.0,0,0,243880,13.0,,S
|
||||
773,0,2,"Mack, Mrs. (Mary)",female,57.0,0,0,S.O./P.P. 3,10.5,E77,S
|
||||
745,1,3,"Stranden, Mr. Juho",male,31.0,0,0,STON/O 2. 3101288,7.925,,S
|
||||
328,1,2,"Ball, Mrs. (Ada E Hall)",female,36.0,0,0,28551,13.0,D,S
|
||||
460,0,3,"O'Connor, Mr. Maurice",male,,0,0,371060,7.75,,Q
|
||||
222,0,2,"Bracken, Mr. James H",male,27.0,0,0,220367,13.0,,S
|
||||
851,0,3,"Andersson, Master. Sigvard Harald Elias",male,4.0,4,2,347082,31.275,,S
|
||||
558,0,1,"Robbins, Mr. Victor",male,,0,0,PC 17757,227.525,,C
|
||||
47,0,3,"Lennon, Mr. Denis",male,,1,0,370371,15.5,,Q
|
||||
449,1,3,"Baclini, Miss. Marie Catherine",female,5.0,2,1,2666,19.2583,,C
|
||||
371,1,1,"Harder, Mr. George Achilles",male,25.0,1,0,11765,55.4417,E50,C
|
||||
196,1,1,"Lurette, Miss. Elise",female,58.0,0,0,PC 17569,146.5208,B80,C
|
||||
761,0,3,"Garfirth, Mr. John",male,,0,0,358585,14.5,,S
|
||||
55,0,1,"Ostby, Mr. Engelhart Cornelius",male,65.0,0,1,113509,61.9792,B30,C
|
||||
573,1,1,"Flynn, Mr. John Irwin (""Irving"")",male,36.0,0,0,PC 17474,26.3875,E25,S
|
||||
379,0,3,"Betros, Mr. Tannous",male,20.0,0,0,2648,4.0125,,C
|
||||
198,0,3,"Olsen, Mr. Karl Siegwart Andreas",male,42.0,0,1,4579,8.4042,,S
|
||||
396,0,3,"Johansson, Mr. Erik",male,22.0,0,0,350052,7.7958,,S
|
||||
111,0,1,"Porter, Mr. Walter Chamberlain",male,47.0,0,0,110465,52.0,C110,S
|
||||
138,0,1,"Futrelle, Mr. Jacques Heath",male,37.0,1,0,113803,53.1,C123,S
|
||||
312,1,1,"Ryerson, Miss. Emily Borie",female,18.0,2,2,PC 17608,262.375,B57 B59 B63 B66,C
|
||||
391,1,1,"Carter, Mr. William Ernest",male,36.0,1,2,113760,120.0,B96 B98,S
|
||||
24,1,1,"Sloper, Mr. William Thompson",male,28.0,0,0,113788,35.5,A6,S
|
||||
818,0,2,"Mallet, Mr. Albert",male,31.0,1,1,S.C./PARIS 2079,37.0042,,C
|
||||
110,1,3,"Moran, Miss. Bertha",female,,1,0,371110,24.15,,Q
|
||||
302,1,3,"McCoy, Mr. Bernard",male,,2,0,367226,23.25,,Q
|
||||
104,0,3,"Johansson, Mr. Gustaf Joel",male,33.0,0,0,7540,8.6542,,S
|
||||
875,1,2,"Abelson, Mrs. Samuel (Hannah Wizosky)",female,28.0,1,0,P/PP 3381,24.0,,C
|
||||
62,1,1,"Icard, Miss. Amelie",female,38.0,0,0,113572,80.0,B28,
|
||||
154,0,3,"van Billiard, Mr. Austin Blyler",male,40.5,0,2,A/5. 851,14.5,,S
|
||||
289,1,2,"Hosono, Mr. Masabumi",male,42.0,0,0,237798,13.0,,S
|
||||
245,0,3,"Attalah, Mr. Sleiman",male,30.0,0,0,2694,7.225,,C
|
||||
681,0,3,"Peters, Miss. Katie",female,,0,0,330935,8.1375,,Q
|
||||
797,1,1,"Leader, Dr. Alice (Farnham)",female,49.0,0,0,17465,25.9292,D17,S
|
||||
226,0,3,"Berglund, Mr. Karl Ivar Sven",male,22.0,0,0,PP 4348,9.35,,S
|
||||
857,1,1,"Wick, Mrs. George Dennick (Mary Hitchcock)",female,45.0,1,1,36928,164.8667,,S
|
||||
621,0,3,"Yasbeck, Mr. Antoni",male,27.0,1,0,2659,14.4542,,C
|
||||
451,0,2,"West, Mr. Edwy Arthur",male,36.0,1,2,C.A. 34651,27.75,,S
|
||||
424,0,3,"Danbom, Mrs. Ernst Gilbert (Anna Sigrid Maria Brogren)",female,28.0,1,1,347080,14.4,,S
|
||||
450,1,1,"Peuchen, Major. Arthur Godfrey",male,52.0,0,0,113786,30.5,C104,S
|
||||
161,0,3,"Cribb, Mr. John Hatfield",male,44.0,0,1,371362,16.1,,S
|
||||
743,1,1,"Ryerson, Miss. Susan Parker ""Suzette""",female,21.0,2,2,PC 17608,262.375,B57 B59 B63 B66,C
|
||||
651,0,3,"Mitkoff, Mr. Mito",male,,0,0,349221,7.8958,,S
|
||||
250,0,2,"Carter, Rev. Ernest Courtenay",male,54.0,1,0,244252,26.0,,S
|
||||
540,1,1,"Frolicher, Miss. Hedwig Margaritha",female,22.0,0,2,13568,49.5,B39,C
|
||||
414,0,2,"Cunningham, Mr. Alfred Fleming",male,,0,0,239853,0.0,,S
|
||||
207,0,3,"Backstrom, Mr. Karl Alfred",male,32.0,1,0,3101278,15.85,,S
|
||||
828,1,2,"Mallet, Master. Andre",male,1.0,0,2,S.C./PARIS 2079,37.0042,,C
|
||||
484,1,3,"Turkula, Mrs. (Hedwig)",female,63.0,0,0,4134,9.5875,,S
|
||||
607,0,3,"Karaic, Mr. Milan",male,30.0,0,0,349246,7.8958,,S
|
||||
185,1,3,"Kink-Heilmann, Miss. Luise Gretchen",female,4.0,0,2,315153,22.025,,S
|
||||
683,0,3,"Olsvigen, Mr. Thor Anderson",male,20.0,0,0,6563,9.225,,S
|
||||
794,0,1,"Hoyt, Mr. William Fisher",male,,0,0,PC 17600,30.6958,,C
|
||||
13,0,3,"Saundercock, Mr. William Henry",male,20.0,0,0,A/5. 2151,8.05,,S
|
||||
118,0,2,"Turpin, Mr. William John Robert",male,29.0,1,0,11668,21.0,,S
|
||||
483,0,3,"Rouse, Mr. Richard Henry",male,50.0,0,0,A/5 3594,8.05,,S
|
||||
421,0,3,"Gheorgheff, Mr. Stanio",male,,0,0,349254,7.8958,,C
|
||||
543,0,3,"Andersson, Miss. Sigrid Elisabeth",female,11.0,4,2,347082,31.275,,S
|
||||
884,0,2,"Banfield, Mr. Frederick James",male,28.0,0,0,C.A./SOTON 34068,10.5,,S
|
||||
877,0,3,"Gustafsson, Mr. Alfred Ossian",male,20.0,0,0,7534,9.8458,,S
|
||||
109,0,3,"Rekic, Mr. Tido",male,38.0,0,0,349249,7.8958,,S
|
||||
603,0,1,"Harrington, Mr. Charles H",male,,0,0,113796,42.4,,S
|
||||
575,0,3,"Rush, Mr. Alfred George John",male,16.0,0,0,A/4. 20589,8.05,,S
|
||||
253,0,1,"Stead, Mr. William Thomas",male,62.0,0,0,113514,26.55,C87,S
|
||||
712,0,1,"Klaber, Mr. Herman",male,,0,0,113028,26.55,C124,S
|
||||
397,0,3,"Olsson, Miss. Elina",female,31.0,0,0,350407,7.8542,,S
|
||||
194,1,2,"Navratil, Master. Michel M",male,3.0,1,1,230080,26.0,F2,S
|
||||
567,0,3,"Stoytcheff, Mr. Ilia",male,19.0,0,0,349205,7.8958,,S
|
||||
204,0,3,"Youseff, Mr. Gerious",male,45.5,0,0,2628,7.225,,C
|
||||
491,0,3,"Hagland, Mr. Konrad Mathias Reiersen",male,,1,0,65304,19.9667,,S
|
||||
815,0,3,"Tomlin, Mr. Ernest Portage",male,30.5,0,0,364499,8.05,,S
|
||||
219,1,1,"Bazzani, Miss. Albina",female,32.0,0,0,11813,76.2917,D15,C
|
||||
446,1,1,"Dodge, Master. Washington",male,4.0,0,2,33638,81.8583,A34,S
|
||||
490,1,3,"Coutts, Master. Eden Leslie ""Neville""",male,9.0,1,1,C.A. 37671,15.9,,S
|
||||
112,0,3,"Zabour, Miss. Hileni",female,14.5,1,0,2665,14.4542,,C
|
||||
731,1,1,"Allen, Miss. Elisabeth Walton",female,29.0,0,0,24160,211.3375,B5,S
|
||||
106,0,3,"Mionoff, Mr. Stoytcho",male,28.0,0,0,349207,7.8958,,S
|
||||
480,1,3,"Hirvonen, Miss. Hildur E",female,2.0,0,1,3101298,12.2875,,S
|
||||
278,0,2,"Parkes, Mr. Francis ""Frank""",male,,0,0,239853,0.0,,S
|
||||
70,0,3,"Kink, Mr. Vincenz",male,26.0,2,0,315151,8.6625,,S
|
||||
86,1,3,"Backstrom, Mrs. Karl Alfred (Maria Mathilda Gustafsson)",female,33.0,3,0,3101278,15.85,,S
|
||||
795,0,3,"Dantcheff, Mr. Ristiu",male,25.0,0,0,349203,7.8958,,S
|
||||
162,1,2,"Watt, Mrs. James (Elizabeth ""Bessie"" Inglis Milne)",female,40.0,0,0,C.A. 33595,15.75,,S
|
||||
816,0,1,"Fry, Mr. Richard",male,,0,0,112058,0.0,B102,S
|
||||
517,1,2,"Lemore, Mrs. (Amelia Milley)",female,34.0,0,0,C.A. 34260,10.5,F33,S
|
||||
300,1,1,"Baxter, Mrs. James (Helene DeLaudeniere Chaput)",female,50.0,0,1,PC 17558,247.5208,B58 B60,C
|
||||
455,0,3,"Peduzzi, Mr. Joseph",male,,0,0,A/5 2817,8.05,,S
|
||||
60,0,3,"Goodwin, Master. William Frederick",male,11.0,5,2,CA 2144,46.9,,S
|
||||
880,1,1,"Potter, Mrs. Thomas Jr (Lily Alexenia Wilson)",female,56.0,0,1,11767,83.1583,C50,C
|
||||
43,0,3,"Kraeff, Mr. Theodor",male,,0,0,349253,7.8958,,C
|
||||
500,0,3,"Svensson, Mr. Olof",male,24.0,0,0,350035,7.7958,,S
|
||||
236,0,3,"Harknett, Miss. Alice Phoebe",female,,0,0,W./C. 6609,7.55,,S
|
||||
255,0,3,"Rosblom, Mrs. Viktor (Helena Wilhelmina)",female,41.0,0,2,370129,20.2125,,S
|
||||
346,1,2,"Brown, Miss. Amelia ""Mildred""",female,24.0,0,0,248733,13.0,F33,S
|
||||
105,0,3,"Gustafsson, Mr. Anders Vilhelm",male,37.0,2,0,3101276,7.925,,S
|
||||
316,1,3,"Nilsson, Miss. Helmina Josefina",female,26.0,0,0,347470,7.8542,,S
|
||||
873,0,1,"Carlsson, Mr. Frans Olof",male,33.0,0,0,695,5.0,B51 B53 B55,S
|
||||
4,1,1,"Futrelle, Mrs. Jacques Heath (Lily May Peel)",female,35.0,1,0,113803,53.1,C123,S
|
||||
805,1,3,"Hedman, Mr. Oskar Arvid",male,27.0,0,0,347089,6.975,,S
|
||||
225,1,1,"Hoyt, Mr. Frederick Maxfield",male,38.0,1,0,19943,90.0,C93,S
|
||||
772,0,3,"Jensen, Mr. Niels Peder",male,48.0,0,0,350047,7.8542,,S
|
||||
539,0,3,"Risien, Mr. Samuel Beard",male,,0,0,364498,14.5,,S
|
||||
249,1,1,"Beckwith, Mr. Richard Leonard",male,37.0,1,1,11751,52.5542,D35,S
|
||||
32,1,1,"Spencer, Mrs. William Augustus (Marie Eugenie)",female,,1,0,PC 17569,146.5208,B78,C
|
||||
268,1,3,"Persson, Mr. Ernst Ulrik",male,25.0,1,0,347083,7.775,,S
|
||||
544,1,2,"Beane, Mr. Edward",male,32.0,1,0,2908,26.0,,S
|
||||
685,0,2,"Brown, Mr. Thomas William Solomon",male,60.0,1,1,29750,39.0,,S
|
||||
608,1,1,"Daniel, Mr. Robert Williams",male,27.0,0,0,113804,30.5,,S
|
||||
749,0,1,"Marvin, Mr. Daniel Warner",male,19.0,1,0,113773,53.1,D30,S
|
||||
234,1,3,"Asplund, Miss. Lillian Gertrud",female,5.0,4,2,347077,31.3875,,S
|
||||
641,0,3,"Jensen, Mr. Hans Peder",male,20.0,0,0,350050,7.8542,,S
|
||||
707,1,2,"Kelly, Mrs. Florence ""Fannie""",female,45.0,0,0,223596,13.5,,S
|
||||
611,0,3,"Andersson, Mrs. Anders Johan (Alfrida Konstantia Brogren)",female,39.0,1,5,347082,31.275,,S
|
||||
647,0,3,"Cor, Mr. Liudevit",male,19.0,0,0,349231,7.8958,,S
|
||||
148,0,3,"Ford, Miss. Robina Maggie ""Ruby""",female,9.0,2,2,W./C. 6608,34.375,,S
|
||||
574,1,3,"Kelly, Miss. Mary",female,,0,0,14312,7.75,,Q
|
||||
809,0,2,"Meyer, Mr. August",male,39.0,0,0,248723,13.0,,S
|
||||
535,0,3,"Cacic, Miss. Marija",female,30.0,0,0,315084,8.6625,,S
|
||||
588,1,1,"Frolicher-Stehli, Mr. Maxmillian",male,60.0,1,1,13567,79.2,B41,C
|
||||
331,1,3,"McCoy, Miss. Agnes",female,,2,0,367226,23.25,,Q
|
||||
569,0,3,"Doharr, Mr. Tannous",male,,0,0,2686,7.2292,,C
|
||||
725,1,1,"Chambers, Mr. Norman Campbell",male,27.0,1,0,113806,53.1,E8,S
|
||||
100,0,2,"Kantor, Mr. Sinai",male,34.0,1,0,244367,26.0,,S
|
||||
708,1,1,"Calderhead, Mr. Edward Pennington",male,42.0,0,0,PC 17476,26.2875,E24,S
|
||||
277,0,3,"Lindblom, Miss. Augusta Charlotta",female,45.0,0,0,347073,7.75,,S
|
||||
418,1,2,"Silven, Miss. Lyyli Karoliina",female,18.0,0,2,250652,13.0,,S
|
||||
463,0,1,"Gee, Mr. Arthur H",male,47.0,0,0,111320,38.5,E63,S
|
||||
665,1,3,"Lindqvist, Mr. Eino William",male,20.0,1,0,STON/O 2. 3101285,7.925,,S
|
||||
718,1,2,"Troutt, Miss. Edwina Celia ""Winnie""",female,27.0,0,0,34218,10.5,E101,S
|
||||
850,1,1,"Goldenberg, Mrs. Samuel L (Edwiga Grabowska)",female,,1,0,17453,89.1042,C92,C
|
||||
516,0,1,"Walker, Mr. William Anderson",male,47.0,0,0,36967,34.0208,D46,S
|
||||
633,1,1,"Stahelin-Maeglin, Dr. Max",male,32.0,0,0,13214,30.5,B50,C
|
||||
538,1,1,"LeRoy, Miss. Bertha",female,30.0,0,0,PC 17761,106.425,,C
|
||||
151,0,2,"Bateman, Rev. Robert James",male,51.0,0,0,S.O.P. 1166,12.525,,S
|
||||
79,1,2,"Caldwell, Master. Alden Gates",male,0.83,0,2,248738,29.0,,S
|
||||
10,1,2,"Nasser, Mrs. Nicholas (Adele Achem)",female,14.0,1,0,237736,30.0708,,C
|
||||
143,1,3,"Hakkarainen, Mrs. Pekka Pietari (Elin Matilda Dolck)",female,24.0,1,0,STON/O2. 3101279,15.85,,S
|
||||
76,0,3,"Moen, Mr. Sigurd Hansen",male,25.0,0,0,348123,7.65,F G73,S
|
||||
254,0,3,"Lobb, Mr. William Arthur",male,30.0,1,0,A/5. 3336,16.1,,S
|
||||
30,0,3,"Todoroff, Mr. Lalio",male,,0,0,349216,7.8958,,S
|
||||
170,0,3,"Ling, Mr. Lee",male,28.0,0,0,1601,56.4958,,S
|
||||
747,0,3,"Abbott, Mr. Rossmore Edward",male,16.0,1,1,C.A. 2673,20.25,,S
|
||||
212,1,2,"Cameron, Miss. Clear Annie",female,35.0,0,0,F.C.C. 13528,21.0,,S
|
||||
636,1,2,"Davis, Miss. Mary",female,28.0,0,0,237668,13.0,,S
|
||||
689,0,3,"Fischer, Mr. Eberhard Thelander",male,18.0,0,0,350036,7.7958,,S
|
||||
600,1,1,"Duff Gordon, Sir. Cosmo Edmund (""Mr Morgan"")",male,49.0,1,0,PC 17485,56.9292,A20,C
|
||||
423,0,3,"Zimmerman, Mr. Leo",male,29.0,0,0,315082,7.875,,S
|
||||
59,1,2,"West, Miss. Constance Mirium",female,5.0,1,2,C.A. 34651,27.75,,S
|
||||
504,0,3,"Laitinen, Miss. Kristina Sofia",female,37.0,0,0,4135,9.5875,,S
|
||||
352,0,1,"Williams-Lambert, Mr. Fletcher Fellows",male,,0,0,113510,35.0,C128,S
|
||||
542,0,3,"Andersson, Miss. Ingeborg Constanzia",female,9.0,4,2,347082,31.275,,S
|
||||
89,1,1,"Fortune, Miss. Mabel Helen",female,23.0,3,2,19950,263.0,C23 C25 C27,S
|
||||
433,1,2,"Louch, Mrs. Charles Alexander (Alice Adelaide Slow)",female,42.0,1,0,SC/AH 3085,26.0,,S
|
||||
566,0,3,"Davies, Mr. Alfred J",male,24.0,2,0,A/4 48871,24.15,,S
|
||||
502,0,3,"Canavan, Miss. Mary",female,21.0,0,0,364846,7.75,,Q
|
||||
128,1,3,"Madsen, Mr. Fridtjof Arne",male,24.0,0,0,C 17369,7.1417,,S
|
||||
688,0,3,"Dakic, Mr. Branko",male,19.0,0,0,349228,10.1708,,S
|
||||
329,1,3,"Goldsmith, Mrs. Frank John (Emily Alice Brown)",female,31.0,1,1,363291,20.525,,S
|
||||
845,0,3,"Culumovic, Mr. Jeso",male,17.0,0,0,315090,8.6625,,S
|
||||
886,0,3,"Rice, Mrs. William (Margaret Norton)",female,39.0,0,5,382652,29.125,,Q
|
||||
581,1,2,"Christy, Miss. Julie Rachel",female,25.0,1,1,237789,30.0,,S
|
||||
568,0,3,"Palsson, Mrs. Nils (Alma Cornelia Berglund)",female,29.0,0,4,349909,21.075,,S
|
||||
152,1,1,"Pears, Mrs. Thomas (Edith Wearne)",female,22.0,1,0,113776,66.6,C2,S
|
||||
342,1,1,"Fortune, Miss. Alice Elizabeth",female,24.0,3,2,19950,263.0,C23 C25 C27,S
|
||||
272,1,3,"Tornquist, Mr. William Henry",male,25.0,0,0,LINE,0.0,,S
|
||||
737,0,3,"Ford, Mrs. Edward (Margaret Ann Watson)",female,48.0,1,3,W./C. 6608,34.375,,S
|
||||
700,0,3,"Humblen, Mr. Adolf Mathias Nicolai Olsen",male,42.0,0,0,348121,7.65,F G63,S
|
||||
291,1,1,"Barber, Miss. Ellen ""Nellie""",female,26.0,0,0,19877,78.85,,S
|
||||
141,0,3,"Boulos, Mrs. Joseph (Sultana)",female,,0,2,2678,15.2458,,C
|
||||
261,0,3,"Smith, Mr. Thomas",male,,0,0,384461,7.75,,Q
|
||||
163,0,3,"Bengtsson, Mr. John Viktor",male,26.0,0,0,347068,7.775,,S
|
||||
232,0,3,"Larsson, Mr. Bengt Edvin",male,29.0,0,0,347067,7.775,,S
|
||||
802,1,2,"Collyer, Mrs. Harvey (Charlotte Annie Tate)",female,31.0,1,1,C.A. 31921,26.25,,S
|
||||
844,0,3,"Lemberopolous, Mr. Peter L",male,34.5,0,0,2683,6.4375,,C
|
||||
691,1,1,"Dick, Mr. Albert Adrian",male,31.0,1,0,17474,57.0,B20,S
|
||||
649,0,3,"Willey, Mr. Edward",male,,0,0,S.O./P.P. 751,7.55,,S
|
||||
137,1,1,"Newsom, Miss. Helen Monypeny",female,19.0,0,2,11752,26.2833,D47,S
|
||||
570,1,3,"Jonsson, Mr. Carl",male,32.0,0,0,350417,7.8542,,S
|
||||
862,0,2,"Giles, Mr. Frederick Edward",male,21.0,1,0,28134,11.5,,S
|
||||
445,1,3,"Johannesen-Bratthammer, Mr. Bernt",male,,0,0,65306,8.1125,,S
|
||||
697,0,3,"Kelly, Mr. James",male,44.0,0,0,363592,8.05,,S
|
||||
674,1,2,"Wilhelms, Mr. Charles",male,31.0,0,0,244270,13.0,,S
|
||||
748,1,2,"Sinkkonen, Miss. Anna",female,30.0,0,0,250648,13.0,,S
|
||||
367,1,1,"Warren, Mrs. Frank Manley (Anna Sophia Atkinson)",female,60.0,1,0,110813,75.25,D37,C
|
||||
626,0,1,"Sutton, Mr. Frederick",male,61.0,0,0,36963,32.3208,D50,S
|
||||
741,1,1,"Hawksford, Mr. Walter James",male,,0,0,16988,30.0,D45,S
|
||||
821,1,1,"Hays, Mrs. Charles Melville (Clara Jennings Gregg)",female,52.0,1,1,12749,93.5,B69,S
|
||||
282,0,3,"Olsson, Mr. Nils Johan Goransson",male,28.0,0,0,347464,7.8542,,S
|
||||
546,0,1,"Nicholson, Mr. Arthur Ernest",male,64.0,0,0,693,26.0,,S
|
||||
237,0,2,"Hold, Mr. Stephen",male,44.0,1,0,26707,26.0,,S
|
||||
16,1,2,"Hewlett, Mrs. (Mary D Kingcome) ",female,55.0,0,0,248706,16.0,,S
|
||||
565,0,3,"Meanwell, Miss. (Marion Ogden)",female,,0,0,SOTON/O.Q. 392087,8.05,,S
|
||||
798,1,3,"Osman, Mrs. Mara",female,31.0,0,0,349244,8.6833,,S
|
||||
740,0,3,"Nankoff, Mr. Minko",male,,0,0,349218,7.8958,,S
|
||||
549,0,3,"Goldsmith, Mr. Frank John",male,33.0,1,1,363291,20.525,,S
|
||||
663,0,1,"Colley, Mr. Edward Pomeroy",male,47.0,0,0,5727,25.5875,E58,S
|
||||
482,0,2,"Frost, Mr. Anthony Wood ""Archie""",male,,0,0,239854,0.0,,S
|
||||
113,0,3,"Barton, Mr. David John",male,22.0,0,0,324669,8.05,,S
|
||||
458,1,1,"Kenyon, Mrs. Frederick R (Marion)",female,,1,0,17464,51.8625,D21,S
|
||||
842,0,2,"Mudd, Mr. Thomas Charles",male,16.0,0,0,S.O./P.P. 3,10.5,,S
|
||||
518,0,3,"Ryan, Mr. Patrick",male,,0,0,371110,24.15,,Q
|
||||
553,0,3,"O'Brien, Mr. Timothy",male,,0,0,330979,7.8292,,Q
|
||||
388,1,2,"Buss, Miss. Kate",female,36.0,0,0,27849,13.0,,S
|
||||
514,1,1,"Rothschild, Mrs. Martin (Elizabeth L. Barrett)",female,54.0,1,0,PC 17603,59.4,,C
|
||||
560,1,3,"de Messemaeker, Mrs. Guillaume Joseph (Emma)",female,36.0,1,0,345572,17.4,,S
|
||||
701,1,1,"Astor, Mrs. John Jacob (Madeleine Talmadge Force)",female,18.0,1,0,PC 17757,227.525,C62 C64,C
|
||||
241,0,3,"Zabour, Miss. Thamine",female,,1,0,2665,14.4542,,C
|
||||
428,1,2,"Phillips, Miss. Kate Florence (""Mrs Kate Louise Phillips Marshall"")",female,19.0,0,0,250655,26.0,,S
|
||||
593,0,3,"Elsbury, Mr. William James",male,47.0,0,0,A/5 3902,7.25,,S
|
||||
116,0,3,"Pekoniemi, Mr. Edvard",male,21.0,0,0,STON/O 2. 3101294,7.925,,S
|
||||
686,0,2,"Laroche, Mr. Joseph Philippe Lemercier",male,25.0,1,2,SC/Paris 2123,41.5792,,C
|
||||
155,0,3,"Olsen, Mr. Ole Martin",male,,0,0,Fa 265302,7.3125,,S
|
||||
308,1,1,"Penasco y Castellana, Mrs. Victor de Satode (Maria Josefa Perez de Soto y Vallejo)",female,17.0,1,0,PC 17758,108.9,C65,C
|
||||
765,0,3,"Eklund, Mr. Hans Linus",male,16.0,0,0,347074,7.775,,S
|
||||
597,1,2,"Leitch, Miss. Jessie Wills",female,,0,0,248727,33.0,,S
|
||||
242,1,3,"Murphy, Miss. Katherine ""Kate""",female,,1,0,367230,15.5,,Q
|
||||
823,0,1,"Reuchlin, Jonkheer. John George",male,38.0,0,0,19972,0.0,,S
|
||||
380,0,3,"Gustafsson, Mr. Karl Gideon",male,19.0,0,0,347069,7.775,,S
|
||||
336,0,3,"Denkoff, Mr. Mitto",male,,0,0,349225,7.8958,,S
|
||||
488,0,1,"Kent, Mr. Edward Austin",male,58.0,0,0,11771,29.7,B37,C
|
||||
672,0,1,"Davidson, Mr. Thornton",male,31.0,1,0,F.C. 12750,52.0,B71,S
|
||||
791,0,3,"Keane, Mr. Andrew ""Andy""",male,,0,0,12460,7.75,,Q
|
||||
340,0,1,"Blackwell, Mr. Stephen Weart",male,45.0,0,0,113784,35.5,T,S
|
||||
879,0,3,"Laleff, Mr. Kristo",male,,0,0,349217,7.8958,,S
|
||||
464,0,2,"Milling, Mr. Jacob Christian",male,48.0,0,0,234360,13.0,,S
|
||||
717,1,1,"Endres, Miss. Caroline Louise",female,38.0,0,0,PC 17757,227.525,C45,C
|
||||
343,0,2,"Collander, Mr. Erik Gustaf",male,28.0,0,0,248740,13.0,,S
|
||||
276,1,1,"Andrews, Miss. Kornelia Theodosia",female,63.0,1,0,13502,77.9583,D7,S
|
||||
530,0,2,"Hocking, Mr. Richard George",male,23.0,2,1,29104,11.5,,S
|
||||
861,0,3,"Hansen, Mr. Claus Peter",male,41.0,2,0,350026,14.1083,,S
|
||||
8,0,3,"Palsson, Master. Gosta Leonard",male,2.0,3,1,349909,21.075,,S
|
||||
841,0,3,"Alhomaki, Mr. Ilmari Rudolf",male,20.0,0,0,SOTON/O2 3101287,7.925,,S
|
||||
231,1,1,"Harris, Mrs. Henry Birkhardt (Irene Wallach)",female,35.0,1,0,36973,83.475,C83,S
|
||||
338,1,1,"Burns, Miss. Elizabeth Margaret",female,41.0,0,0,16966,134.5,E40,C
|
||||
286,0,3,"Stankovic, Mr. Ivan",male,33.0,0,0,349239,8.6625,,C
|
||||
381,1,1,"Bidois, Miss. Rosalie",female,42.0,0,0,PC 17757,227.525,,C
|
||||
468,0,1,"Smart, Mr. John Montgomery",male,56.0,0,0,113792,26.55,,S
|
||||
838,0,3,"Sirota, Mr. Maurice",male,,0,0,392092,8.05,,S
|
||||
742,0,1,"Cavendish, Mr. Tyrell William",male,36.0,1,0,19877,78.85,C46,S
|
||||
617,0,3,"Danbom, Mr. Ernst Gilbert",male,34.0,1,1,347080,14.4,,S
|
||||
485,1,1,"Bishop, Mr. Dickinson H",male,25.0,1,0,11967,91.0792,B49,C
|
||||
437,0,3,"Ford, Miss. Doolina Margaret ""Daisy""",female,21.0,2,2,W./C. 6608,34.375,,S
|
||||
885,0,3,"Sutehall, Mr. Henry Jr",male,25.0,0,0,SOTON/OQ 392076,7.05,,S
|
||||
28,0,1,"Fortune, Mr. Charles Alexander",male,19.0,3,2,19950,263.0,C23 C25 C27,S
|
||||
751,1,2,"Wells, Miss. Joan",female,4.0,1,1,29103,23.0,,S
|
||||
97,0,1,"Goldschmidt, Mr. George B",male,71.0,0,0,PC 17754,34.6542,A5,C
|
||||
6,0,3,"Moran, Mr. James",male,,0,0,330877,8.4583,,Q
|
||||
271,0,1,"Cairns, Mr. Alexander",male,,0,0,113798,31.0,,S
|
||||
301,1,3,"Kelly, Miss. Anna Katherine ""Annie Kate""",female,,0,0,9234,7.75,,Q
|
||||
366,0,3,"Adahl, Mr. Mauritz Nils Martin",male,30.0,0,0,C 7076,7.25,,S
|
||||
200,0,2,"Yrois, Miss. Henriette (""Mrs Harbeck"")",female,24.0,0,0,248747,13.0,,S
|
||||
776,0,3,"Myhrman, Mr. Pehr Fabian Oliver Malkolm",male,18.0,0,0,347078,7.75,,S
|
||||
178,0,1,"Isham, Miss. Ann Elizabeth",female,50.0,0,0,PC 17595,28.7125,C49,C
|
||||
728,1,3,"Mannion, Miss. Margareth",female,,0,0,36866,7.7375,,Q
|
||||
167,1,1,"Chibnall, Mrs. (Edith Martha Bowerman)",female,,0,1,113505,55.0,E33,S
|
||||
869,0,3,"van Melkebeke, Mr. Philemon",male,,0,0,345777,9.5,,S
|
||||
313,0,2,"Lahtinen, Mrs. William (Anna Sylfven)",female,26.0,1,1,250651,26.0,,S
|
||||
285,0,1,"Smith, Mr. Richard William",male,,0,0,113056,26.0,A19,S
|
||||
495,0,3,"Stanley, Mr. Edward Roland",male,21.0,0,0,A/4 45380,8.05,,S
|
||||
33,1,3,"Glynn, Miss. Mary Agatha",female,,0,0,335677,7.75,,Q
|
||||
417,1,2,"Drew, Mrs. James Vivian (Lulu Thorne Christian)",female,34.0,1,1,28220,32.5,,S
|
||||
887,0,2,"Montvila, Rev. Juozas",male,27.0,0,0,211536,13.0,,S
|
||||
559,1,1,"Taussig, Mrs. Emil (Tillie Mandelbaum)",female,39.0,1,1,110413,79.65,E67,S
|
||||
806,0,3,"Johansson, Mr. Karl Johan",male,31.0,0,0,347063,7.775,,S
|
||||
294,0,3,"Haas, Miss. Aloisia",female,24.0,0,0,349236,8.85,,S
|
||||
209,1,3,"Carr, Miss. Helen ""Ellen""",female,16.0,0,0,367231,7.75,,Q
|
||||
85,1,2,"Ilett, Miss. Bertha",female,17.0,0,0,SO/C 14885,10.5,,S
|
||||
38,0,3,"Cann, Mr. Ernest Charles",male,21.0,0,0,A./5. 2152,8.05,,S
|
||||
7,0,1,"McCarthy, Mr. Timothy J",male,54.0,0,0,17463,51.8625,E46,S
|
||||
426,0,3,"Wiseman, Mr. Phillippe",male,,0,0,A/4. 34244,7.25,,S
|
||||
790,0,1,"Guggenheim, Mr. Benjamin",male,46.0,0,0,PC 17593,79.2,B82 B84,C
|
||||
389,0,3,"Sadlier, Mr. Matthew",male,,0,0,367655,7.7292,,Q
|
||||
258,1,1,"Cherry, Miss. Gladys",female,30.0,0,0,110152,86.5,B77,S
|
||||
643,0,3,"Skoog, Miss. Margit Elizabeth",female,2.0,3,2,347088,27.9,,S
|
||||
355,0,3,"Yousif, Mr. Wazli",male,,0,0,2647,7.225,,C
|
||||
830,1,1,"Stone, Mrs. George Nelson (Martha Evelyn)",female,62.0,0,0,113572,80.0,B28,
|
||||
781,1,3,"Ayoub, Miss. Banoura",female,13.0,0,0,2687,7.2292,,C
|
||||
267,0,3,"Panula, Mr. Ernesti Arvid",male,16.0,4,1,3101295,39.6875,,S
|
||||
506,0,1,"Penasco y Castellana, Mr. Victor de Satode",male,18.0,1,0,PC 17758,108.9,C65,C
|
||||
52,0,3,"Nosworthy, Mr. Richard Cater",male,21.0,0,0,A/4. 39886,7.8,,S
|
||||
401,1,3,"Niskanen, Mr. Juha",male,39.0,0,0,STON/O 2. 3101289,7.925,,S
|
||||
533,0,3,"Elias, Mr. Joseph Jr",male,17.0,1,1,2690,7.2292,,C
|
||||
283,0,3,"de Pelsmaeker, Mr. Alfons",male,16.0,0,0,345778,9.5,,S
|
||||
442,0,3,"Hampe, Mr. Leon",male,20.0,0,0,345769,9.5,,S
|
||||
361,0,3,"Skoog, Mr. Wilhelm",male,40.0,1,4,347088,27.9,,S
|
||||
840,1,1,"Marechal, Mr. Pierre",male,,0,0,11774,29.7,C47,C
|
||||
509,0,3,"Olsen, Mr. Henry Margido",male,28.0,0,0,C 4001,22.525,,S
|
||||
121,0,2,"Hickman, Mr. Stanley George",male,21.0,2,0,S.O.C. 14879,73.5,,S
|
||||
320,1,1,"Spedden, Mrs. Frederic Oakley (Margaretta Corning Stone)",female,40.0,1,1,16966,134.5,E34,C
|
||||
858,1,1,"Daly, Mr. Peter Denis ",male,51.0,0,0,113055,26.55,E17,S
|
||||
501,0,3,"Calic, Mr. Petar",male,17.0,0,0,315086,8.6625,,S
|
||||
91,0,3,"Christmann, Mr. Emil",male,29.0,0,0,343276,8.05,,S
|
||||
727,1,2,"Renouf, Mrs. Peter Henry (Lillian Jefferys)",female,30.0,3,0,31027,21.0,,S
|
||||
671,1,2,"Brown, Mrs. Thomas William Solomon (Elizabeth Catherine Ford)",female,40.0,1,1,29750,39.0,,S
|
||||
456,1,3,"Jalsevac, Mr. Ivan",male,29.0,0,0,349240,7.8958,,C
|
||||
427,1,2,"Clarke, Mrs. Charles V (Ada Maria Winfield)",female,28.0,1,0,2003,26.0,,S
|
||||
63,0,1,"Harris, Mr. Henry Birkhardt",male,45.0,1,0,36973,83.475,C83,S
|
||||
51,0,3,"Panula, Master. Juha Niilo",male,7.0,4,1,3101295,39.6875,,S
|
||||
454,1,1,"Goldenberg, Mr. Samuel L",male,49.0,1,0,17453,89.1042,C92,C
|
||||
394,1,1,"Newell, Miss. Marjorie",female,23.0,1,0,35273,113.275,D36,C
|
||||
188,1,1,"Romaine, Mr. Charles Hallace (""Mr C Rolmane"")",male,45.0,0,0,111428,26.55,,S
|
||||
368,1,3,"Moussa, Mrs. (Mantoura Boulos)",female,,0,0,2626,7.2292,,C
|
||||
759,0,3,"Theobald, Mr. Thomas Leonard",male,34.0,0,0,363294,8.05,,S
|
||||
804,1,3,"Thomas, Master. Assad Alexander",male,0.42,0,1,2625,8.5167,,C
|
||||
510,1,3,"Lang, Mr. Fang",male,26.0,0,0,1601,56.4958,,S
|
||||
788,0,3,"Rice, Master. George Hugh",male,8.0,4,1,382652,29.125,,Q
|
||||
298,0,1,"Allison, Miss. Helen Loraine",female,2.0,1,2,113781,151.55,C22 C26,S
|
||||
92,0,3,"Andreasson, Mr. Paul Edvin",male,20.0,0,0,347466,7.8542,,S
|
||||
754,0,3,"Jonkoff, Mr. Lalio",male,23.0,0,0,349204,7.8958,,S
|
||||
547,1,2,"Beane, Mrs. Edward (Ethel Clarke)",female,19.0,1,0,2908,26.0,,S
|
||||
492,0,3,"Windelov, Mr. Einar",male,21.0,0,0,SOTON/OQ 3101317,7.25,,S
|
||||
2,1,1,"Cumings, Mrs. John Bradley (Florence Briggs Thayer)",female,38.0,1,0,PC 17599,71.2833,C85,C
|
||||
777,0,3,"Tobin, Mr. Roger",male,,0,0,383121,7.75,F38,Q
|
||||
473,1,2,"West, Mrs. Edwy Arthur (Ada Mary Worth)",female,33.0,1,2,C.A. 34651,27.75,,S
|
||||
252,0,3,"Strom, Mrs. Wilhelm (Elna Matilda Persson)",female,29.0,1,1,347054,10.4625,G6,S
|
||||
93,0,1,"Chaffee, Mr. Herbert Fuller",male,46.0,1,0,W.E.P. 5734,61.175,E31,S
|
||||
635,0,3,"Skoog, Miss. Mabel",female,9.0,3,2,347088,27.9,,S
|
||||
44,1,2,"Laroche, Miss. Simonne Marie Anne Andree",female,3.0,1,2,SC/Paris 2123,41.5792,,C
|
||||
835,0,3,"Allum, Mr. Owen George",male,18.0,0,0,2223,8.3,,S
|
||||
48,1,3,"O'Driscoll, Miss. Bridget",female,,0,0,14311,7.75,,Q
|
||||
891,0,3,"Dooley, Mr. Patrick",male,32.0,0,0,370376,7.75,,Q
|
||||
264,0,1,"Harrison, Mr. William",male,40.0,0,0,112059,0.0,B94,S
|
||||
356,0,3,"Vanden Steen, Mr. Leo Peter",male,28.0,0,0,345783,9.5,,S
|
||||
528,0,1,"Farthing, Mr. John",male,,0,0,PC 17483,221.7792,C95,S
|
||||
339,1,3,"Dahl, Mr. Karl Edwart",male,45.0,0,0,7598,8.05,,S
|
||||
780,1,1,"Robert, Mrs. Edward Scott (Elisabeth Walton McMillan)",female,43.0,0,1,24160,211.3375,B3,S
|
||||
21,0,2,"Fynney, Mr. Joseph J",male,35.0,0,0,239865,26.0,,S
|
||||
723,0,2,"Gillespie, Mr. William Henry",male,34.0,0,0,12233,13.0,,S
|
||||
677,0,3,"Sawyer, Mr. Frederick Charles",male,24.5,0,0,342826,8.05,,S
|
||||
349,1,3,"Coutts, Master. William Loch ""William""",male,3.0,1,1,C.A. 37671,15.9,,S
|
||||
817,0,3,"Heininen, Miss. Wendla Maria",female,23.0,0,0,STON/O2. 3101290,7.925,,S
|
||||
334,0,3,"Vander Planke, Mr. Leo Edmondus",male,16.0,2,0,345764,18.0,,S
|
||||
470,1,3,"Baclini, Miss. Helene Barbara",female,0.75,2,1,2666,19.2583,,C
|
||||
130,0,3,"Ekstrom, Mr. Johan",male,45.0,0,0,347061,6.975,,S
|
||||
191,1,2,"Pinsky, Mrs. (Rosa)",female,32.0,0,0,234604,13.0,,S
|
||||
760,1,1,"Rothes, the Countess. of (Lucy Noel Martha Dyer-Edwards)",female,33.0,0,0,110152,86.5,B77,S
|
||||
520,0,3,"Pavlovic, Mr. Stefo",male,32.0,0,0,349242,7.8958,,S
|
||||
67,1,2,"Nye, Mrs. (Elizabeth Ramell)",female,29.0,0,0,C.A. 29395,10.5,F33,S
|
||||
487,1,1,"Hoyt, Mrs. Frederick Maxfield (Jane Anne Forby)",female,35.0,1,0,19943,90.0,C93,S
|
||||
19,0,3,"Vander Planke, Mrs. Julius (Emelia Maria Vandemoortele)",female,31.0,1,0,345763,18.0,,S
|
||||
702,1,1,"Silverthorne, Mr. Spencer Victor",male,35.0,0,0,PC 17475,26.2875,E24,S
|
||||
826,0,3,"Flynn, Mr. John",male,,0,0,368323,6.95,,Q
|
||||
333,0,1,"Graham, Mr. George Edward",male,38.0,0,1,PC 17582,153.4625,C91,S
|
||||
855,0,2,"Carter, Mrs. Ernest Courtenay (Lilian Hughes)",female,44.0,1,0,244252,26.0,,S
|
||||
441,1,2,"Hart, Mrs. Benjamin (Esther Ada Bloomfield)",female,45.0,1,1,F.C.C. 13529,26.25,,S
|
||||
775,1,2,"Hocking, Mrs. Elizabeth (Eliza Needs)",female,54.0,1,3,29105,23.0,,S
|
||||
675,0,2,"Watson, Mr. Ennis Hastings",male,,0,0,239856,0.0,,S
|
||||
552,0,2,"Sharp, Mr. Percival James R",male,27.0,0,0,244358,26.0,,S
|
||||
56,1,1,"Woolner, Mr. Hugh",male,,0,0,19947,35.5,C52,S
|
||||
653,0,3,"Kalvik, Mr. Johannes Halvorsen",male,21.0,0,0,8475,8.4333,,S
|
||||
849,0,2,"Harper, Rev. John",male,28.0,0,1,248727,33.0,,S
|
||||
730,0,3,"Ilmakangas, Miss. Pieta Sofia",female,25.0,1,0,STON/O2. 3101271,7.925,,S
|
||||
233,0,2,"Sjostedt, Mr. Ernst Adolf",male,59.0,0,0,237442,13.5,,S
|
||||
660,0,1,"Newell, Mr. Arthur Webster",male,58.0,0,2,35273,113.275,D48,C
|
||||
243,0,2,"Coleridge, Mr. Reginald Charles",male,29.0,0,0,W./C. 14263,10.5,,S
|
||||
36,0,1,"Holverson, Mr. Alexander Oskar",male,42.0,1,0,113789,52.0,,S
|
||||
541,1,1,"Crosby, Miss. Harriet R",female,36.0,0,2,WE/P 5735,71.0,B22,S
|
||||
719,0,3,"McEvoy, Mr. Michael",male,,0,0,36568,15.5,,Q
|
||||
752,1,3,"Moor, Master. Meier",male,6.0,0,1,392096,12.475,E121,S
|
||||
888,1,1,"Graham, Miss. Margaret Edith",female,19.0,0,0,112053,30.0,B42,S
|
||||
122,0,3,"Moore, Mr. Leonard Charles",male,,0,0,A4. 54510,8.05,,S
|
||||
411,0,3,"Sdycoff, Mr. Todor",male,,0,0,349222,7.8958,,S
|
||||
353,0,3,"Elias, Mr. Tannous",male,15.0,1,1,2695,7.2292,,C
|
||||
34,0,2,"Wheadon, Mr. Edward H",male,66.0,0,0,C.A. 24579,10.5,,S
|
||||
180,0,3,"Leonard, Mr. Lionel",male,36.0,0,0,LINE,0.0,,S
|
||||
646,1,1,"Harper, Mr. Henry Sleeper",male,48.0,1,0,PC 17572,76.7292,D33,C
|
||||
819,0,3,"Holm, Mr. John Fredrik Alexander",male,43.0,0,0,C 7075,6.45,,S
|
||||
22,1,2,"Beesley, Mr. Lawrence",male,34.0,0,0,248698,13.0,D56,S
|
||||
412,0,3,"Hart, Mr. Henry",male,,0,0,394140,6.8583,,Q
|
||||
422,0,3,"Charters, Mr. David",male,21.0,0,0,A/5. 13032,7.7333,,Q
|
||||
584,0,1,"Ross, Mr. John Hugo",male,36.0,0,0,13049,40.125,A10,C
|
||||
729,0,2,"Bryhl, Mr. Kurt Arnold Gottfrid",male,25.0,1,0,236853,26.0,,S
|
||||
813,0,2,"Slemen, Mr. Richard James",male,35.0,0,0,28206,10.5,,S
|
||||
562,0,3,"Sivic, Mr. Husein",male,40.0,0,0,349251,7.8958,,S
|
||||
332,0,1,"Partner, Mr. Austen",male,45.5,0,0,113043,28.5,C124,S
|
||||
341,1,2,"Navratil, Master. Edmond Roger",male,2.0,1,1,230080,26.0,F2,S
|
||||
247,0,3,"Lindahl, Miss. Agda Thorilda Viktoria",female,25.0,0,0,347071,7.775,,S
|
||||
127,0,3,"McMahon, Mr. Martin",male,,0,0,370372,7.75,,Q
|
||||
324,1,2,"Caldwell, Mrs. Albert Francis (Sylvia Mae Harbaugh)",female,22.0,1,1,248738,29.0,,S
|
||||
398,0,2,"McKane, Mr. Peter David",male,46.0,0,0,28403,26.0,,S
|
||||
46,0,3,"Rogers, Mr. William John",male,,0,0,S.C./A.4. 23567,8.05,,S
|
||||
65,0,1,"Stewart, Mr. Albert A",male,,0,0,PC 17605,27.7208,,C
|
||||
262,1,3,"Asplund, Master. Edvin Rojj Felix",male,3.0,4,2,347077,31.3875,,S
|
||||
372,0,3,"Wiklund, Mr. Jakob Alfred",male,18.0,1,0,3101267,6.4958,,S
|
||||
376,1,1,"Meyer, Mrs. Edgar Joseph (Leila Saks)",female,,1,0,PC 17604,82.1708,,C
|
||||
676,0,3,"Edvardsson, Mr. Gustaf Hjalmar",male,18.0,0,0,349912,7.775,,S
|
||||
471,0,3,"Keefe, Mr. Arthur",male,,0,0,323592,7.25,,S
|
||||
210,1,1,"Blank, Mr. Henry",male,40.0,0,0,112277,31.0,A31,C
|
||||
733,0,2,"Knight, Mr. Robert J",male,,0,0,239855,0.0,,S
|
||||
81,0,3,"Waelens, Mr. Achille",male,22.0,0,0,345767,9.0,,S
|
||||
609,1,2,"Laroche, Mrs. Joseph (Juliette Marie Louise Lafargue)",female,22.0,1,2,SC/Paris 2123,41.5792,,C
|
||||
874,0,3,"Vander Cruyssen, Mr. Victor",male,47.0,0,0,345765,9.0,,S
|
||||
435,0,1,"Silvey, Mr. William Baird",male,50.0,1,0,13507,55.9,E44,S
|
||||
767,0,1,"Brewe, Dr. Arthur Jackson",male,,0,0,112379,39.6,,C
|
||||
768,0,3,"Mangan, Miss. Mary",female,30.5,0,0,364850,7.75,,Q
|
||||
168,0,3,"Skoog, Mrs. William (Anna Bernhardina Karlsson)",female,45.0,1,4,347088,27.9,,S
|
||||
709,1,1,"Cleaver, Miss. Alice",female,22.0,0,0,113781,151.55,,S
|
||||
327,0,3,"Nysveen, Mr. Johan Hansen",male,61.0,0,0,345364,6.2375,,S
|
||||
843,1,1,"Serepeca, Miss. Augusta",female,30.0,0,0,113798,31.0,,C
|
||||
211,0,3,"Ali, Mr. Ahmed",male,24.0,0,0,SOTON/O.Q. 3101311,7.05,,S
|
||||
159,0,3,"Smiljanic, Mr. Mile",male,,0,0,315037,8.6625,,S
|
||||
378,0,1,"Widener, Mr. Harry Elkins",male,27.0,0,2,113503,211.5,C82,C
|
||||
778,1,3,"Emanuel, Miss. Virginia Ethel",female,5.0,0,0,364516,12.475,,S
|
||||
457,0,1,"Millet, Mr. Francis Davis",male,65.0,0,0,13509,26.55,E38,S
|
||||
769,0,3,"Moran, Mr. Daniel J",male,,1,0,371110,24.15,,Q
|
||||
362,0,2,"del Carlo, Mr. Sebastiano",male,29.0,1,0,SC/PARIS 2167,27.7208,,C
|
||||
655,0,3,"Hegarty, Miss. Hanora ""Nora""",female,18.0,0,0,365226,6.75,,Q
|
||||
698,1,3,"Mullens, Miss. Katherine ""Katie""",female,,0,0,35852,7.7333,,Q
|
||||
444,1,2,"Reynaldo, Ms. Encarnacion",female,28.0,0,0,230434,13.0,,S
|
||||
203,0,3,"Johanson, Mr. Jakob Alfred",male,34.0,0,0,3101264,6.4958,,S
|
||||
606,0,3,"Lindell, Mr. Edvard Bengtsson",male,36.0,1,0,349910,15.55,,S
|
||||
673,0,2,"Mitchell, Mr. Henry Michael",male,70.0,0,0,C.A. 24580,10.5,,S
|
||||
846,0,3,"Abbing, Mr. Anthony",male,42.0,0,0,C.A. 5547,7.55,,S
|
||||
374,0,1,"Ringhini, Mr. Sante",male,22.0,0,0,PC 17760,135.6333,,C
|
||||
667,0,2,"Butler, Mr. Reginald Fenton",male,25.0,0,0,234686,13.0,,S
|
||||
61,0,3,"Sirayanian, Mr. Orsen",male,22.0,0,0,2669,7.2292,,C
|
||||
642,1,1,"Sagesser, Mlle. Emma",female,24.0,0,0,PC 17477,69.3,B35,C
|
||||
469,0,3,"Scanlan, Mr. James",male,,0,0,36209,7.725,,Q
|
||||
792,0,2,"Gaskell, Mr. Alfred",male,16.0,0,0,239865,26.0,,S
|
||||
465,0,3,"Maisner, Mr. Simon",male,,0,0,A/S 2816,8.05,,S
|
||||
551,1,1,"Thayer, Mr. John Borland Jr",male,17.0,0,2,17421,110.8833,C70,C
|
||||
523,0,3,"Lahoud, Mr. Sarkis",male,,0,0,2624,7.225,,C
|
||||
369,1,3,"Jermyn, Miss. Annie",female,,0,0,14313,7.75,,Q
|
||||
864,0,3,"Sage, Miss. Dorothy Edith ""Dolly""",female,,8,2,CA. 2343,69.55,,S
|
||||
839,1,3,"Chip, Mr. Chang",male,32.0,0,0,1601,56.4958,,S
|
||||
590,0,3,"Murdlin, Mr. Joseph",male,,0,0,A./5. 3235,8.05,,S
|
||||
9,1,3,"Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg)",female,27.0,0,2,347742,11.1333,,S
|
||||
505,1,1,"Maioni, Miss. Roberta",female,16.0,0,0,110152,86.5,B79,S
|
||||
572,1,1,"Appleton, Mrs. Edward Dale (Charlotte Lamson)",female,53.0,2,0,11769,51.4792,C101,S
|
||||
235,0,2,"Leyson, Mr. Robert William Norman",male,24.0,0,0,C.A. 29566,10.5,,S
|
||||
345,0,2,"Fox, Mr. Stanley Hubert",male,36.0,0,0,229236,13.0,,S
|
||||
714,0,3,"Larsson, Mr. August Viktor",male,29.0,0,0,7545,9.4833,,S
|
||||
477,0,2,"Renouf, Mr. Peter Henry",male,34.0,1,0,31027,21.0,,S
|
||||
587,0,2,"Jarvis, Mr. John Denzil",male,47.0,0,0,237565,15.0,,S
|
||||
630,0,3,"O'Connell, Mr. Patrick D",male,,0,0,334912,7.7333,,Q
|
||||
133,0,3,"Robins, Mrs. Alexander A (Grace Charity Laury)",female,47.0,1,0,A/5. 3337,14.5,,S
|
||||
27,0,3,"Emir, Mr. Farred Chehab",male,,0,0,2631,7.225,,C
|
||||
612,0,3,"Jardin, Mr. Jose Neto",male,,0,0,SOTON/O.Q. 3101305,7.05,,S
|
||||
292,1,1,"Bishop, Mrs. Dickinson H (Helen Walton)",female,19.0,1,0,11967,91.0792,B49,C
|
||||
293,0,2,"Levy, Mr. Rene Jacques",male,36.0,0,0,SC/Paris 2163,12.875,D,C
|
||||
40,1,3,"Nicola-Yarred, Miss. Jamila",female,14.0,1,0,2651,11.2417,,C
|
||||
205,1,3,"Cohen, Mr. Gurshon ""Gus""",male,18.0,0,0,A/5 3540,8.05,,S
|
||||
832,1,2,"Richards, Master. George Sibley",male,0.83,1,1,29106,18.75,,S
|
||||
716,0,3,"Soholt, Mr. Peter Andreas Lauritz Andersen",male,19.0,0,0,348124,7.65,F G73,S
|
||||
596,0,3,"Van Impe, Mr. Jean Baptiste",male,36.0,1,1,345773,24.15,,S
|
||||
344,0,2,"Sedgwick, Mr. Charles Frederick Waddington",male,25.0,0,0,244361,13.0,,S
|
||||
687,0,3,"Panula, Mr. Jaako Arnold",male,14.0,4,1,3101295,39.6875,,S
|
||||
662,0,3,"Badt, Mr. Mohamed",male,40.0,0,0,2623,7.225,,C
|
||||
66,1,3,"Moubarek, Master. Gerios",male,,1,1,2661,15.2458,,C
|
||||
820,0,3,"Skoog, Master. Karl Thorsten",male,10.0,3,2,347088,27.9,,S
|
||||
865,0,2,"Gill, Mr. John William",male,24.0,0,0,233866,13.0,,S
|
||||
323,1,2,"Slayter, Miss. Hilda Mary",female,30.0,0,0,234818,12.35,,Q
|
||||
358,0,2,"Funk, Miss. Annie Clemmer",female,38.0,0,0,237671,13.0,,S
|
||||
129,1,3,"Peter, Miss. Anna",female,,1,1,2668,22.3583,F E69,C
|
||||
166,1,3,"Goldsmith, Master. Frank John William ""Frankie""",male,9.0,0,2,363291,20.525,,S
|
||||
799,0,3,"Ibrahim Shawah, Mr. Yousseff",male,30.0,0,0,2685,7.2292,,C
|
||||
770,0,3,"Gronnestad, Mr. Daniel Danielsen",male,32.0,0,0,8471,8.3625,,S
|
||||
785,0,3,"Ali, Mr. William",male,25.0,0,0,SOTON/O.Q. 3101312,7.05,,S
|
||||
399,0,2,"Pain, Dr. Alfred",male,23.0,0,0,244278,10.5,,S
|
||||
746,0,1,"Crosby, Capt. Edward Gifford",male,70.0,1,1,WE/P 5735,71.0,B22,S
|
||||
498,0,3,"Shellard, Mr. Frederick William",male,,0,0,C.A. 6212,15.1,,S
|
||||
297,0,3,"Hanna, Mr. Mansour",male,23.5,0,0,2693,7.2292,,C
|
||||
295,0,3,"Mineff, Mr. Ivan",male,24.0,0,0,349233,7.8958,,S
|
||||
545,0,1,"Douglas, Mr. Walter Donald",male,50.0,1,0,PC 17761,106.425,C86,C
|
||||
755,1,2,"Herman, Mrs. Samuel (Jane Laver)",female,48.0,1,2,220845,65.0,,S
|
||||
305,0,3,"Williams, Mr. Howard Hugh ""Harry""",male,,0,0,A/5 2466,8.05,,S
|
||||
682,1,1,"Hassab, Mr. Hammad",male,27.0,0,0,PC 17572,76.7292,D49,C
|
||||
124,1,2,"Webber, Miss. Susan",female,32.5,0,0,27267,13.0,E101,S
|
||||
499,0,1,"Allison, Mrs. Hudson J C (Bessie Waldo Daniels)",female,25.0,1,2,113781,151.55,C22 C26,S
|
||||
870,1,3,"Johnson, Master. Harold Theodor",male,4.0,1,1,347742,11.1333,,S
|
||||
72,0,3,"Goodwin, Miss. Lillian Amy",female,16.0,5,2,CA 2144,46.9,,S
|
||||
120,0,3,"Andersson, Miss. Ellis Anna Maria",female,2.0,4,2,347082,31.275,,S
|
||||
325,0,3,"Sage, Mr. George John Jr",male,,8,2,CA. 2343,69.55,,S
|
||||
383,0,3,"Tikkanen, Mr. Juho",male,32.0,0,0,STON/O 2. 3101293,7.925,,S
|
||||
628,1,1,"Longley, Miss. Gretchen Fiske",female,21.0,0,0,13502,77.9583,D9,S
|
||||
744,0,3,"McNamee, Mr. Neal",male,24.0,1,0,376566,16.1,,S
|
||||
684,0,3,"Goodwin, Mr. Charles Edward",male,14.0,5,2,CA 2144,46.9,,S
|
||||
598,0,3,"Johnson, Mr. Alfred",male,49.0,0,0,LINE,0.0,,S
|
||||
866,1,2,"Bystrom, Mrs. (Karolina)",female,42.0,0,0,236852,13.0,,S
|
||||
53,1,1,"Harper, Mrs. Henry Sleeper (Myna Haxtun)",female,49.0,1,0,PC 17572,76.7292,D33,C
|
||||
732,0,3,"Hassan, Mr. Houssein G N",male,11.0,0,0,2699,18.7875,,C
|
||||
306,1,1,"Allison, Master. Hudson Trevor",male,0.92,1,2,113781,151.55,C22 C26,S
|
||||
140,0,1,"Giglio, Mr. Victor",male,24.0,0,0,PC 17593,79.2,B86,C
|
||||
814,0,3,"Andersson, Miss. Ebba Iris Alfrida",female,6.0,4,2,347082,31.275,,S
|
||||
310,1,1,"Francatelli, Miss. Laura Mabel",female,30.0,0,0,PC 17485,56.9292,E36,C
|
||||
71,0,2,"Jenkin, Mr. Stephen Curnow",male,32.0,0,0,C.A. 33111,10.5,,S
|
||||
529,0,3,"Salonen, Mr. Johan Werner",male,39.0,0,0,3101296,7.925,,S
|
||||
466,0,3,"Goncalves, Mr. Manuel Estanslas",male,38.0,0,0,SOTON/O.Q. 3101306,7.05,,S
|
||||
319,1,1,"Wick, Miss. Mary Natalie",female,31.0,0,2,36928,164.8667,C7,S
|
||||
259,1,1,"Ward, Miss. Anna",female,35.0,0,0,PC 17755,512.3292,,C
|
||||
114,0,3,"Jussila, Miss. Katriina",female,20.0,1,0,4136,9.825,,S
|
||||
625,0,3,"Bowen, Mr. David John ""Dai""",male,21.0,0,0,54636,16.1,,S
|
||||
555,1,3,"Ohman, Miss. Velin",female,22.0,0,0,347085,7.775,,S
|
||||
357,1,1,"Bowerman, Miss. Elsie Edith",female,22.0,0,1,113505,55.0,E33,S
|
||||
837,0,3,"Pasic, Mr. Jakob",male,21.0,0,0,315097,8.6625,,S
|
||||
84,0,1,"Carrau, Mr. Francisco M",male,28.0,0,0,113059,47.1,,S
|
||||
184,1,2,"Becker, Master. Richard F",male,1.0,2,1,230136,39.0,F4,S
|
||||
183,0,3,"Asplund, Master. Clarence Gustaf Hugo",male,9.0,4,2,347077,31.3875,,S
|
||||
145,0,2,"Andrew, Mr. Edgardo Samuel",male,18.0,0,0,231945,11.5,,S
|
||||
859,1,3,"Baclini, Mrs. Solomon (Latifa Qurban)",female,24.0,0,3,2666,19.2583,,C
|
||||
299,1,1,"Saalfeld, Mr. Adolphe",male,,0,0,19988,30.5,C106,S
|
||||
658,0,3,"Bourke, Mrs. John (Catherine)",female,32.0,1,1,364849,15.5,,Q
|
||||
507,1,2,"Quick, Mrs. Frederick Charles (Jane Richards)",female,33.0,0,2,26360,26.0,,S
|
||||
692,1,3,"Karun, Miss. Manca",female,4.0,0,1,349256,13.4167,,C
|
||||
88,0,3,"Slocovski, Mr. Selman Francis",male,,0,0,SOTON/OQ 392086,8.05,,S
|
||||
314,0,3,"Hendekovic, Mr. Ignjac",male,28.0,0,0,349243,7.8958,,S
|
||||
800,0,3,"Van Impe, Mrs. Jean Baptiste (Rosalie Paula Govaert)",female,30.0,1,1,345773,24.15,,S
|
||||
614,0,3,"Horgan, Mr. John",male,,0,0,370377,7.75,,Q
|
||||
12,1,1,"Bonnell, Miss. Elizabeth",female,58.0,0,0,113783,26.55,C103,S
|
||||
771,0,3,"Lievens, Mr. Rene Aime",male,24.0,0,0,345781,9.5,,S
|
||||
365,0,3,"O'Brien, Mr. Thomas",male,,1,0,370365,15.5,,Q
|
||||
876,1,3,"Najib, Miss. Adele Kiamie ""Jane""",female,15.0,0,0,2667,7.225,,C
|
||||
195,1,1,"Brown, Mrs. James Joseph (Margaret Tobin)",female,44.0,0,0,PC 17610,27.7208,B4,C
|
||||
594,0,3,"Bourke, Miss. Mary",female,,0,2,364848,7.75,,Q
|
||||
654,1,3,"O'Leary, Miss. Hanora ""Norah""",female,,0,0,330919,7.8292,,Q
|
||||
402,0,3,"Adams, Mr. John",male,26.0,0,0,341826,8.05,,S
|
||||
83,1,3,"McDermott, Miss. Brigdet Delia",female,,0,0,330932,7.7875,,Q
|
||||
669,0,3,"Cook, Mr. Jacob",male,43.0,0,0,A/5 3536,8.05,,S
|
||||
878,0,3,"Petroff, Mr. Nedelio",male,19.0,0,0,349212,7.8958,,S
|
||||
833,0,3,"Saad, Mr. Amin",male,,0,0,2671,7.2292,,C
|
||||
75,1,3,"Bing, Mr. Lee",male,32.0,0,0,1601,56.4958,,S
|
||||
722,0,3,"Jensen, Mr. Svend Lauritz",male,17.0,1,0,350048,7.0542,,S
|
||||
251,0,3,"Reed, Mr. James George",male,,0,0,362316,7.25,,S
|
||||
238,1,2,"Collyer, Miss. Marjorie ""Lottie""",female,8.0,0,2,C.A. 31921,26.25,,S
|
||||
146,0,2,"Nicholls, Mr. Joseph Charles",male,19.0,1,1,C.A. 33112,36.75,,S
|
||||
808,0,3,"Pettersson, Miss. Ellen Natalia",female,18.0,0,0,347087,7.775,,S
|
||||
131,0,3,"Drazenoic, Mr. Jozef",male,33.0,0,0,349241,7.8958,,C
|
||||
576,0,3,"Patchett, Mr. George",male,19.0,0,0,358585,14.5,,S
|
||||
515,0,3,"Coleff, Mr. Satio",male,24.0,0,0,349209,7.4958,,S
|
||||
847,0,3,"Sage, Mr. Douglas Bullen",male,,8,2,CA. 2343,69.55,,S
|
||||
648,1,1,"Simonius-Blumer, Col. Oberst Alfons",male,56.0,0,0,13213,35.5,A26,C
|
||||
443,0,3,"Petterson, Mr. Johan Emil",male,25.0,1,0,347076,7.775,,S
|
||||
478,0,3,"Braund, Mr. Lewis Richard",male,29.0,1,0,3460,7.0458,,S
|
||||
537,0,1,"Butt, Major. Archibald Willingham",male,45.0,0,0,113050,26.55,B38,S
|
||||
169,0,1,"Baumann, Mr. John D",male,,0,0,PC 17318,25.925,,S
|
||||
149,0,2,"Navratil, Mr. Michel (""Louis M Hoffman"")",male,36.5,0,2,230080,26.0,F2,S
|
||||
290,1,3,"Connolly, Miss. Kate",female,22.0,0,0,370373,7.75,,Q
|
||||
15,0,3,"Vestrom, Miss. Hulda Amanda Adolfina",female,14.0,0,0,350406,7.8542,,S
|
||||
386,0,2,"Davies, Mr. Charles Henry",male,18.0,0,0,S.O.C. 14879,73.5,,S
|
||||
811,0,3,"Alexander, Mr. William",male,26.0,0,0,3474,7.8875,,S
|
||||
78,0,3,"Moutal, Mr. Rahamin Haim",male,,0,0,374746,8.05,,S
|
||||
738,1,1,"Lesurer, Mr. Gustave J",male,35.0,0,0,PC 17755,512.3292,B101,C
|
||||
452,0,3,"Hagland, Mr. Ingvald Olai Olsen",male,,1,0,65303,19.9667,,S
|
||||
35,0,1,"Meyer, Mr. Edgar Joseph",male,28.0,1,0,PC 17604,82.1708,,C
|
||||
347,1,2,"Smith, Miss. Marion Elsie",female,40.0,0,0,31418,13.0,,S
|
||||
436,1,1,"Carter, Miss. Lucile Polk",female,14.0,1,2,113760,120.0,B96 B98,S
|
||||
390,1,2,"Lehmann, Miss. Bertha",female,17.0,0,0,SC 1748,12.0,,C
|
||||
657,0,3,"Radeff, Mr. Alexander",male,,0,0,349223,7.8958,,S
|
||||
695,0,1,"Weir, Col. John",male,60.0,0,0,113800,26.55,,S
|
||||
586,1,1,"Taussig, Miss. Ruth",female,18.0,0,2,110413,79.65,E68,S
|
||||
384,1,1,"Holverson, Mrs. Alexander Oskar (Mary Aline Towner)",female,35.0,1,0,113789,52.0,,S
|
||||
58,0,3,"Novel, Mr. Mansouer",male,28.5,0,0,2697,7.2292,,C
|
||||
246,0,1,"Minahan, Dr. William Edward",male,44.0,2,0,19928,90.0,C78,Q
|
||||
557,1,1,"Duff Gordon, Lady. (Lucille Christiana Sutherland) (""Mrs Morgan"")",female,48.0,1,0,11755,39.6,A16,C
|
||||
605,1,1,"Homer, Mr. Harry (""Mr E Haven"")",male,35.0,0,0,111426,26.55,,C
|
||||
350,0,3,"Dimic, Mr. Jovan",male,42.0,0,0,315088,8.6625,,S
|
||||
659,0,2,"Eitemiller, Mr. George Floyd",male,23.0,0,0,29751,13.0,,S
|
||||
415,1,3,"Sundman, Mr. Johan Julian",male,44.0,0,0,STON/O 2. 3101269,7.925,,S
|
||||
713,1,1,"Taylor, Mr. Elmer Zebley",male,48.0,1,0,19996,52.0,C126,S
|
||||
474,1,2,"Jerwan, Mrs. Amin S (Marie Marthe Thuillard)",female,23.0,0,0,SC/AH Basle 541,13.7917,D,C
|
||||
139,0,3,"Osen, Mr. Olaf Elon",male,16.0,0,0,7534,9.2167,,S
|
||||
224,0,3,"Nenkoff, Mr. Christo",male,,0,0,349234,7.8958,,S
|
||||
221,1,3,"Sunderland, Mr. Victor Francis",male,16.0,0,0,SOTON/OQ 392089,8.05,,S
|
||||
68,0,3,"Crease, Mr. Ernest James",male,19.0,0,0,S.P. 3464,8.1583,,S
|
||||
622,1,1,"Kimball, Mr. Edwin Nelson Jr",male,42.0,1,0,11753,52.5542,D19,S
|
||||
467,0,2,"Campbell, Mr. William",male,,0,0,239853,0.0,,S
|
||||
525,0,3,"Kassem, Mr. Fared",male,,0,0,2700,7.2292,,C
|
||||
17,0,3,"Rice, Master. Eugene",male,2.0,4,1,382652,29.125,,Q
|
||||
430,1,3,"Pickard, Mr. Berk (Berk Trembisky)",male,32.0,0,0,SOTON/O.Q. 392078,8.05,E10,S
|
||||
90,0,3,"Celotti, Mr. Francesco",male,24.0,0,0,343275,8.05,,S
|
||||
486,0,3,"Lefebre, Miss. Jeannie",female,,3,1,4133,25.4667,,S
|
||||
831,1,3,"Yasbeck, Mrs. Antoni (Selini Alexander)",female,15.0,1,0,2659,14.4542,,C
|
||||
440,0,2,"Kvillner, Mr. Johan Henrik Johannesson",male,31.0,0,0,C.A. 18723,10.5,,S
|
||||
244,0,3,"Maenpaa, Mr. Matti Alexanteri",male,22.0,0,0,STON/O 2. 3101275,7.125,,S
|
||||
882,0,3,"Markun, Mr. Johann",male,33.0,0,0,349257,7.8958,,S
|
||||
287,1,3,"de Mulder, Mr. Theodore",male,30.0,0,0,345774,9.5,,S
|
||||
735,0,2,"Troupiansky, Mr. Moses Aaron",male,23.0,0,0,233639,13.0,,S
|
||||
620,0,2,"Gavey, Mr. Lawrence",male,26.0,0,0,31028,10.5,,S
|
||||
296,0,1,"Lewy, Mr. Ervin G",male,,0,0,PC 17612,27.7208,,C
|
||||
187,1,3,"O'Brien, Mrs. Thomas (Johanna ""Hannah"" Godfrey)",female,,1,0,370365,15.5,,Q
|
||||
629,0,3,"Bostandyeff, Mr. Guentcho",male,26.0,0,0,349224,7.8958,,S
|
||||
123,0,2,"Nasser, Mr. Nicholas",male,32.5,1,0,237736,30.0708,,C
|
||||
678,1,3,"Turja, Miss. Anna Sofia",female,18.0,0,0,4138,9.8417,,S
|
||||
263,0,1,"Taussig, Mr. Emil",male,52.0,1,1,110413,79.65,E67,S
|
||||
439,0,1,"Fortune, Mr. Mark",male,64.0,1,4,19950,263.0,C23 C25 C27,S
|
||||
410,0,3,"Lefebre, Miss. Ida",female,,3,1,4133,25.4667,,S
|
||||
497,1,1,"Eustis, Miss. Elizabeth Mussey",female,54.0,1,0,36947,78.2667,D20,C
|
||||
522,0,3,"Vovk, Mr. Janko",male,22.0,0,0,349252,7.8958,,S
|
||||
766,1,1,"Hogeboom, Mrs. John C (Anna Andrews)",female,51.0,1,0,13502,77.9583,D11,S
|
||||
408,1,2,"Richards, Master. William Rowe",male,3.0,1,1,29106,18.75,,S
|
||||
420,0,3,"Van Impe, Miss. Catharina",female,10.0,0,2,345773,24.15,,S
|
||||
453,0,1,"Foreman, Mr. Benjamin Laventall",male,30.0,0,0,113051,27.75,C111,C
|
||||
447,1,2,"Mellinger, Miss. Madeleine Violet",female,13.0,0,1,250644,19.5,,S
|
||||
197,0,3,"Mernagh, Mr. Robert",male,,0,0,368703,7.75,,Q
|
||||
227,1,2,"Mellors, Mr. William John",male,19.0,0,0,SW/PP 751,10.5,,S
|
||||
852,0,3,"Svensson, Mr. Johan",male,74.0,0,0,347060,7.775,,S
|
||||
763,1,3,"Barah, Mr. Hanna Assi",male,20.0,0,0,2663,7.2292,,C
|
||||
257,1,1,"Thorne, Mrs. Gertrude Maybelle",female,,0,0,PC 17585,79.2,,C
|
||||
407,0,3,"Widegren, Mr. Carl/Charles Peter",male,51.0,0,0,347064,7.75,,S
|
||||
103,0,1,"White, Mr. Richard Frasar",male,21.0,0,1,35281,77.2875,D26,S
|
||||
315,0,2,"Hart, Mr. Benjamin",male,43.0,1,1,F.C.C. 13529,26.25,,S
|
||||
77,0,3,"Staneff, Mr. Ivan",male,,0,0,349208,7.8958,,S
|
||||
632,0,3,"Lundahl, Mr. Johan Svensson",male,51.0,0,0,347743,7.0542,,S
|
||||
750,0,3,"Connaghton, Mr. Michael",male,31.0,0,0,335097,7.75,,Q
|
||||
627,0,2,"Kirkland, Rev. Charles Leonard",male,57.0,0,0,219533,12.35,,Q
|
||||
96,0,3,"Shorney, Mr. Charles Joseph",male,,0,0,374910,8.05,,S
|
||||
171,0,1,"Van der hoef, Mr. Wyckoff",male,61.0,0,0,111240,33.5,B19,S
|
||||
881,1,2,"Shelley, Mrs. William (Imanita Parrish Hall)",female,25.0,0,1,230433,26.0,,S
|
||||
95,0,3,"Coxon, Mr. Daniel",male,59.0,0,0,364500,7.25,,S
|
||||
215,0,3,"Kiernan, Mr. Philip",male,,1,0,367229,7.75,,Q
|
||||
39,0,3,"Vander Planke, Miss. Augusta Maria",female,18.0,2,0,345764,18.0,,S
|
||||
774,0,3,"Elias, Mr. Dibo",male,,0,0,2674,7.225,,C
|
||||
37,1,3,"Mamee, Mr. Hanna",male,,0,0,2677,7.2292,,C
|
||||
181,0,3,"Sage, Miss. Constance Gladys",female,,8,2,CA. 2343,69.55,,S
|
||||
177,0,3,"Lefebre, Master. Henry Forbes",male,,3,1,4133,25.4667,,S
|
||||
812,0,3,"Lester, Mr. James",male,39.0,0,0,A/4 48871,24.15,,S
|
||||
496,0,3,"Yousseff, Mr. Gerious",male,,0,0,2627,14.4583,,C
|
||||
503,0,3,"O'Sullivan, Miss. Bridget Mary",female,,0,0,330909,7.6292,,Q
|
||||
216,1,1,"Newell, Miss. Madeleine",female,31.0,1,0,35273,113.275,D36,C
|
||||
395,1,3,"Sandstrom, Mrs. Hjalmar (Agnes Charlotta Bengtsson)",female,24.0,0,2,PP 9549,16.7,G6,S
|
||||
720,0,3,"Johnson, Mr. Malkolm Joackim",male,33.0,0,0,347062,7.775,,S
|
||||
213,0,3,"Perkin, Mr. John Henry",male,22.0,0,0,A/5 21174,7.25,,S
|
||||
644,1,3,"Foo, Mr. Choong",male,,0,0,1601,56.4958,,S
|
||||
583,0,2,"Downton, Mr. William James",male,54.0,0,0,28403,26.0,,S
|
||||
132,0,3,"Coelho, Mr. Domingos Fernandeo",male,20.0,0,0,SOTON/O.Q. 3101307,7.05,,S
|
||||
363,0,3,"Barbara, Mrs. (Catherine David)",female,45.0,0,1,2691,14.4542,,C
|
||||
461,1,1,"Anderson, Mr. Harry",male,48.0,0,0,19952,26.55,E12,S
|
||||
186,0,1,"Rood, Mr. Hugh Roscoe",male,,0,0,113767,50.0,A32,S
|
||||
14,0,3,"Andersson, Mr. Anders Johan",male,39.0,1,5,347082,31.275,,S
|
||||
1,0,3,"Braund, Mr. Owen Harris",male,22.0,1,0,A/5 21171,7.25,,S
|
||||
694,0,3,"Saad, Mr. Khalil",male,25.0,0,0,2672,7.225,,C
|
||||
476,0,1,"Clifford, Mr. George Quincy",male,,0,0,110465,52.0,A14,S
|
||||
348,1,3,"Davison, Mrs. Thomas Henry (Mary E Finck)",female,,1,0,386525,16.1,,S
|
||||
489,0,3,"Somerton, Mr. Francis William",male,30.0,0,0,A.5. 18509,8.05,,S
|
||||
69,1,3,"Andersson, Miss. Erna Alexandra",female,17.0,4,2,3101281,7.925,,S
|
||||
883,0,3,"Dahlberg, Miss. Gerda Ulrika",female,22.0,0,0,7552,10.5167,,S
|
||||
18,1,2,"Williams, Mr. Charles Eugene",male,,0,0,244373,13.0,,S
|
||||
31,0,1,"Uruchurtu, Don. Manuel E",male,40.0,0,0,PC 17601,27.7208,,C
|
||||
619,1,2,"Becker, Miss. Marion Louise",female,4.0,2,1,230136,39.0,F4,S
|
||||
526,0,3,"Farrell, Mr. James",male,40.5,0,0,367232,7.75,,Q
|
||||
585,0,3,"Paulner, Mr. Uscher",male,,0,0,3411,8.7125,,C
|
||||
274,0,1,"Natsch, Mr. Charles H",male,37.0,0,1,PC 17596,29.7,C118,C
|
||||
715,0,2,"Greenberg, Mr. Samuel",male,52.0,0,0,250647,13.0,,S
|
||||
438,1,2,"Richards, Mrs. Sidney (Emily Hocking)",female,24.0,2,3,29106,18.75,,S
|
||||
193,1,3,"Andersen-Jensen, Miss. Carla Christine Nielsine",female,19.0,1,0,350046,7.8542,,S
|
||||
275,1,3,"Healy, Miss. Hanora ""Nora""",female,,0,0,370375,7.75,,Q
|
||||
173,1,3,"Johnson, Miss. Eleanor Ileen",female,1.0,1,1,347742,11.1333,,S
|
||||
807,0,1,"Andrews, Mr. Thomas Jr",male,39.0,0,0,112050,0.0,A36,S
|
||||
680,1,1,"Cardeza, Mr. Thomas Drake Martinez",male,36.0,0,1,PC 17755,512.3292,B51 B53 B55,C
|
||||
304,1,2,"Keane, Miss. Nora A",female,,0,0,226593,12.35,E101,Q
|
||||
370,1,1,"Aubart, Mme. Leontine Pauline",female,24.0,0,0,PC 17477,69.3,B35,C
|
||||
239,0,2,"Pengelly, Mr. Frederick William",male,19.0,0,0,28665,10.5,,S
|
||||
825,0,3,"Panula, Master. Urho Abraham",male,2.0,4,1,3101295,39.6875,,S
|
||||
284,1,3,"Dorking, Mr. Edward Arthur",male,19.0,0,0,A/5. 10482,8.05,,S
|
||||
182,0,2,"Pernot, Mr. Rene",male,,0,0,SC/PARIS 2131,15.05,,C
|
||||
64,0,3,"Skoog, Master. Harald",male,4.0,3,2,347088,27.9,,S
|
||||
404,0,3,"Hakkarainen, Mr. Pekka Pietari",male,28.0,1,0,STON/O2. 3101279,15.85,,S
|
||||
479,0,3,"Karlsson, Mr. Nils August",male,22.0,0,0,350060,7.5208,,S
|
||||
618,0,3,"Lobb, Mrs. William Arthur (Cordelia K Stanlick)",female,26.0,1,0,A/5. 3336,16.1,,S
|
||||
3,1,3,"Heikkinen, Miss. Laina",female,26.0,0,0,STON/O2. 3101282,7.925,,S
|
||||
337,0,1,"Pears, Mr. Thomas Clinton",male,29.0,1,0,113776,66.6,C2,S
|
||||
764,1,1,"Carter, Mrs. William Ernest (Lucile Polk)",female,36.0,1,2,113760,120.0,B96 B98,S
|
||||
696,0,2,"Chapman, Mr. Charles Henry",male,52.0,0,0,248731,13.5,,S
|
||||
783,0,1,"Long, Mr. Milton Clyde",male,29.0,0,0,113501,30.0,D6,S
|
||||
318,0,2,"Moraweck, Dr. Ernest",male,54.0,0,0,29011,14.0,,S
|
||||
706,0,2,"Morley, Mr. Henry Samuel (""Mr Henry Marshall"")",male,39.0,0,0,250655,26.0,,S
|
||||
432,1,3,"Thorneycroft, Mrs. Percival (Florence Kate White)",female,,1,0,376564,16.1,,S
|
||||
50,0,3,"Arnold-Franchi, Mrs. Josef (Josefine Franchi)",female,18.0,1,0,349237,17.8,,S
|
||||
136,0,2,"Richard, Mr. Emile",male,23.0,0,0,SC/PARIS 2133,15.0458,,C
|
||||
889,0,3,"Johnston, Miss. Catherine Helen ""Carrie""",female,,1,2,W./C. 6607,23.45,,S
|
||||
604,0,3,"Torber, Mr. Ernst William",male,44.0,0,0,364511,8.05,,S
|
||||
5,0,3,"Allen, Mr. William Henry",male,35.0,0,0,373450,8.05,,S
|
||||
613,1,3,"Murphy, Miss. Margaret Jane",female,,1,0,367230,15.5,,Q
|
||||
724,0,2,"Hodges, Mr. Henry Price",male,50.0,0,0,250643,13.0,,S
|
||||
758,0,2,"Bailey, Mr. Percy Andrew",male,18.0,0,0,29108,11.5,,S
|
||||
142,1,3,"Nysten, Miss. Anna Sofia",female,22.0,0,0,347081,7.75,,S
|
||||
416,0,3,"Meek, Mrs. Thomas (Annie Louise Rowley)",female,,0,0,343095,8.05,,S
|
||||
668,0,3,"Rommetvedt, Mr. Knud Paust",male,,0,0,312993,7.775,,S
|
||||
387,0,3,"Goodwin, Master. Sidney Leonard",male,1.0,5,2,CA 2144,46.9,,S
|
||||
87,0,3,"Ford, Mr. William Neal",male,16.0,1,3,W./C. 6608,34.375,,S
|
||||
94,0,3,"Dean, Mr. Bertram Frank",male,26.0,1,2,C.A. 2315,20.575,,S
|
||||
650,1,3,"Stanley, Miss. Amy Zillah Elsie",female,23.0,0,0,CA. 2314,7.55,,S
|
||||
508,1,1,"Bradley, Mr. George (""George Arthur Brayton"")",male,,0,0,111427,26.55,,S
|
||||
571,1,2,"Harris, Mr. George",male,62.0,0,0,S.W./PP 752,10.5,,S
|
||||
317,1,2,"Kantor, Mrs. Sinai (Miriam Sternin)",female,24.0,1,0,244367,26.0,,S
|
||||
229,0,2,"Fahlstrom, Mr. Arne Jonas",male,18.0,0,0,236171,13.0,,S
|
||||
656,0,2,"Hickman, Mr. Leonard Mark",male,24.0,2,0,S.O.C. 14879,73.5,,S
|
||||
281,0,3,"Duane, Mr. Frank",male,65.0,0,0,336439,7.75,,Q
|
||||
753,0,3,"Vande Velde, Mr. Johannes Joseph",male,33.0,0,0,345780,9.5,,S
|
||||
803,1,1,"Carter, Master. William Thornton II",male,11.0,1,2,113760,120.0,B96 B98,S
|
||||
527,1,2,"Ridsdale, Miss. Lucy",female,50.0,0,0,W./C. 14258,10.5,,S
|
||||
739,0,3,"Ivanoff, Mr. Kanio",male,,0,0,349201,7.8958,,S
|
||||
579,0,3,"Caram, Mrs. Joseph (Maria Elias)",female,,1,0,2689,14.4583,,C
|
||||
54,1,2,"Faunthorpe, Mrs. Lizzie (Elizabeth Anne Wilkinson)",female,29.0,1,0,2926,26.0,,S
|
||||
867,1,2,"Duran y More, Miss. Asuncion",female,27.0,1,0,SC/PARIS 2149,13.8583,,C
|
||||
351,0,3,"Odahl, Mr. Nils Martin",male,23.0,0,0,7267,9.225,,S
|
||||
80,1,3,"Dowdell, Miss. Elizabeth",female,30.0,0,0,364516,12.475,,S
|
||||
856,1,3,"Aks, Mrs. Sam (Leah Rosen)",female,18.0,0,1,392091,9.35,,S
|
||||
872,1,1,"Beckwith, Mrs. Richard Leonard (Sallie Monypeny)",female,47.0,1,1,11751,52.5542,D35,S
|
||||
836,1,1,"Compton, Miss. Sara Rebecca",female,39.0,1,1,PC 17756,83.1583,E49,C
|
||||
793,0,3,"Sage, Miss. Stella Anna",female,,8,2,CA. 2343,69.55,,S
|
||||
521,1,1,"Perreault, Miss. Anne",female,30.0,0,0,12749,93.5,B73,S
|
||||
|
1
tests/data/openai/embedding.json
Normal file
1
tests/data/openai/embedding.json
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
879
tests/data/search_rsp_cache.json
Normal file
879
tests/data/search_rsp_cache.json
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -11,7 +11,7 @@ import pytest
|
|||
from pydantic import ValidationError
|
||||
|
||||
from metagpt.actions import Action
|
||||
from metagpt.actions.action_node import ActionNode
|
||||
from metagpt.actions.action_node import ActionNode, ReviewMode, ReviseMode
|
||||
from metagpt.environment import Environment
|
||||
from metagpt.llm import LLM
|
||||
from metagpt.roles import Role
|
||||
|
|
@ -23,14 +23,12 @@ from metagpt.team import Team
|
|||
async def test_debate_two_roles():
|
||||
action1 = Action(name="AlexSay", instruction="Express your opinion with emotion and don't repeat it")
|
||||
action2 = Action(name="BobSay", instruction="Express your opinion with emotion and don't repeat it")
|
||||
biden = Role(
|
||||
alex = Role(
|
||||
name="Alex", profile="Democratic candidate", goal="Win the election", actions=[action1], watch=[action2]
|
||||
)
|
||||
trump = Role(
|
||||
name="Bob", profile="Republican candidate", goal="Win the election", actions=[action2], watch=[action1]
|
||||
)
|
||||
bob = Role(name="Bob", profile="Republican candidate", goal="Win the election", actions=[action2], watch=[action1])
|
||||
env = Environment(desc="US election live broadcast")
|
||||
team = Team(investment=10.0, env=env, roles=[biden, trump])
|
||||
team = Team(investment=10.0, env=env, roles=[alex, bob])
|
||||
|
||||
history = await team.run(idea="Topic: climate change. Under 80 words per message.", send_to="Alex", n_round=3)
|
||||
assert "Alex" in history
|
||||
|
|
@ -39,9 +37,9 @@ async def test_debate_two_roles():
|
|||
@pytest.mark.asyncio
|
||||
async def test_debate_one_role_in_env():
|
||||
action = Action(name="Debate", instruction="Express your opinion with emotion and don't repeat it")
|
||||
biden = Role(name="Alex", profile="Democratic candidate", goal="Win the election", actions=[action])
|
||||
alex = Role(name="Alex", profile="Democratic candidate", goal="Win the election", actions=[action])
|
||||
env = Environment(desc="US election live broadcast")
|
||||
team = Team(investment=10.0, env=env, roles=[biden])
|
||||
team = Team(investment=10.0, env=env, roles=[alex])
|
||||
history = await team.run(idea="Topic: climate change. Under 80 words per message.", send_to="Alex", n_round=3)
|
||||
assert "Alex" in history
|
||||
|
||||
|
|
@ -49,8 +47,8 @@ async def test_debate_one_role_in_env():
|
|||
@pytest.mark.asyncio
|
||||
async def test_debate_one_role():
|
||||
action = Action(name="Debate", instruction="Express your opinion with emotion and don't repeat it")
|
||||
biden = Role(name="Alex", profile="Democratic candidate", goal="Win the election", actions=[action])
|
||||
msg: Message = await biden.run("Topic: climate change. Under 80 words per message.")
|
||||
alex = Role(name="Alex", profile="Democratic candidate", goal="Win the election", actions=[action])
|
||||
msg: Message = await alex.run("Topic: climate change. Under 80 words per message.")
|
||||
|
||||
assert len(msg.content) > 10
|
||||
assert msg.sent_from == "metagpt.roles.role.Role"
|
||||
|
|
@ -98,6 +96,83 @@ async def test_action_node_two_layer():
|
|||
assert "579" in answer2.content
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_action_node_review():
|
||||
key = "Project Name"
|
||||
node_a = ActionNode(
|
||||
key=key,
|
||||
expected_type=str,
|
||||
instruction='According to the content of "Original Requirements," name the project using snake case style '
|
||||
"with underline, like 'game_2048' or 'simple_crm.",
|
||||
example="game_2048",
|
||||
)
|
||||
|
||||
with pytest.raises(RuntimeError):
|
||||
_ = await node_a.review()
|
||||
|
||||
_ = await node_a.fill(context=None, llm=LLM())
|
||||
setattr(node_a.instruct_content, key, "game snake") # wrong content to review
|
||||
|
||||
review_comments = await node_a.review(review_mode=ReviewMode.AUTO)
|
||||
assert len(review_comments) == 1
|
||||
assert list(review_comments.keys())[0] == key
|
||||
|
||||
review_comments = await node_a.review(strgy="complex", review_mode=ReviewMode.AUTO)
|
||||
assert len(review_comments) == 0
|
||||
|
||||
node = ActionNode.from_children(key="WritePRD", nodes=[node_a])
|
||||
with pytest.raises(RuntimeError):
|
||||
_ = await node.review()
|
||||
|
||||
_ = await node.fill(context=None, llm=LLM())
|
||||
|
||||
review_comments = await node.review(review_mode=ReviewMode.AUTO)
|
||||
assert len(review_comments) == 1
|
||||
assert list(review_comments.keys())[0] == key
|
||||
|
||||
review_comments = await node.review(strgy="complex", review_mode=ReviewMode.AUTO)
|
||||
assert len(review_comments) == 1
|
||||
assert list(review_comments.keys())[0] == key
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_action_node_revise():
|
||||
key = "Project Name"
|
||||
node_a = ActionNode(
|
||||
key=key,
|
||||
expected_type=str,
|
||||
instruction='According to the content of "Original Requirements," name the project using snake case style '
|
||||
"with underline, like 'game_2048' or 'simple_crm.",
|
||||
example="game_2048",
|
||||
)
|
||||
|
||||
with pytest.raises(RuntimeError):
|
||||
_ = await node_a.review()
|
||||
|
||||
_ = await node_a.fill(context=None, llm=LLM())
|
||||
setattr(node_a.instruct_content, key, "game snake") # wrong content to revise
|
||||
revise_contents = await node_a.revise(revise_mode=ReviseMode.AUTO)
|
||||
assert len(revise_contents) == 1
|
||||
assert "game_snake" in getattr(node_a.instruct_content, key)
|
||||
|
||||
revise_contents = await node_a.revise(strgy="complex", revise_mode=ReviseMode.AUTO)
|
||||
assert len(revise_contents) == 0
|
||||
|
||||
node = ActionNode.from_children(key="WritePRD", nodes=[node_a])
|
||||
with pytest.raises(RuntimeError):
|
||||
_ = await node.revise()
|
||||
|
||||
_ = await node.fill(context=None, llm=LLM())
|
||||
setattr(node.instruct_content, key, "game snake")
|
||||
revise_contents = await node.revise(revise_mode=ReviseMode.AUTO)
|
||||
assert len(revise_contents) == 1
|
||||
assert "game_snake" in getattr(node.instruct_content, key)
|
||||
|
||||
revise_contents = await node.revise(strgy="complex", revise_mode=ReviseMode.AUTO)
|
||||
assert len(revise_contents) == 1
|
||||
assert "game_snake" in getattr(node.instruct_content, key)
|
||||
|
||||
|
||||
t_dict = {
|
||||
"Required Python third-party packages": '"""\nflask==1.1.2\npygame==2.0.1\n"""\n',
|
||||
"Required Other language third-party packages": '"""\nNo third-party packages required for other languages.\n"""\n',
|
||||
|
|
@ -138,10 +213,10 @@ def test_create_model_class():
|
|||
assert test_class.__name__ == "test_class"
|
||||
|
||||
output = test_class(**t_dict)
|
||||
print(output.schema())
|
||||
assert output.schema()["title"] == "test_class"
|
||||
assert output.schema()["type"] == "object"
|
||||
assert output.schema()["properties"]["Full API spec"]
|
||||
print(output.model_json_schema())
|
||||
assert output.model_json_schema()["title"] == "test_class"
|
||||
assert output.model_json_schema()["type"] == "object"
|
||||
assert output.model_json_schema()["properties"]["Full API spec"]
|
||||
|
||||
|
||||
def test_create_model_class_with_fields_unrecognized():
|
||||
|
|
|
|||
46
tests/metagpt/actions/test_action_outcls_registry.py
Normal file
46
tests/metagpt/actions/test_action_outcls_registry.py
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# @Desc : unittest of action_outcls_registry
|
||||
|
||||
from typing import List
|
||||
|
||||
from metagpt.actions.action_node import ActionNode
|
||||
|
||||
|
||||
def test_action_outcls_registry():
|
||||
class_name = "test"
|
||||
out_mapping = {"field": (list[str], ...), "field1": (str, ...)}
|
||||
out_data = {"field": ["field value1", "field value2"], "field1": "field1 value1"}
|
||||
|
||||
outcls = ActionNode.create_model_class(class_name, mapping=out_mapping)
|
||||
outinst = outcls(**out_data)
|
||||
|
||||
outcls1 = ActionNode.create_model_class(class_name=class_name, mapping=out_mapping)
|
||||
outinst1 = outcls1(**out_data)
|
||||
assert outinst1 == outinst
|
||||
|
||||
outcls2 = ActionNode(key="", expected_type=str, instruction="", example="").create_model_class(
|
||||
class_name, out_mapping
|
||||
)
|
||||
outinst2 = outcls2(**out_data)
|
||||
assert outinst2 == outinst
|
||||
|
||||
out_mapping = {"field1": (str, ...), "field": (list[str], ...)} # different order
|
||||
outcls3 = ActionNode.create_model_class(class_name=class_name, mapping=out_mapping)
|
||||
outinst3 = outcls3(**out_data)
|
||||
assert outinst3 == outinst
|
||||
|
||||
out_mapping2 = {"field1": (str, ...), "field": (List[str], ...)} # typing case
|
||||
outcls4 = ActionNode.create_model_class(class_name=class_name, mapping=out_mapping2)
|
||||
outinst4 = outcls4(**out_data)
|
||||
assert outinst4 == outinst
|
||||
|
||||
out_data2 = {"field2": ["field2 value1", "field2 value2"], "field1": "field1 value1"}
|
||||
out_mapping = {"field1": (str, ...), "field2": (List[str], ...)} # List first
|
||||
outcls5 = ActionNode.create_model_class(class_name, out_mapping)
|
||||
outinst5 = outcls5(**out_data2)
|
||||
|
||||
out_mapping = {"field1": (str, ...), "field2": (list[str], ...)}
|
||||
outcls6 = ActionNode.create_model_class(class_name, out_mapping)
|
||||
outinst6 = outcls6(**out_data2)
|
||||
assert outinst5 == outinst6
|
||||
|
|
@ -48,7 +48,7 @@ def sort_array(arr):
|
|||
async def test_debug_code():
|
||||
debug_context = Message(content=DebugContext)
|
||||
new_code = await DebugCode().run(context=debug_context, code=CODE, runtime_result=ErrorStr)
|
||||
assert "def sort_array(arr)" in new_code
|
||||
assert "def sort_array(arr)" in new_code["code"]
|
||||
|
||||
|
||||
def test_messages_to_str():
|
||||
|
|
|
|||
|
|
@ -11,10 +11,7 @@ import uuid
|
|||
import pytest
|
||||
|
||||
from metagpt.actions.debug_error import DebugError
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.const import TEST_CODES_FILE_REPO, TEST_OUTPUTS_FILE_REPO
|
||||
from metagpt.schema import RunCodeContext, RunCodeResult
|
||||
from metagpt.utils.file_repository import FileRepository
|
||||
|
||||
CODE_CONTENT = '''
|
||||
from typing import List
|
||||
|
|
@ -117,8 +114,8 @@ if __name__ == '__main__':
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_debug_error():
|
||||
CONFIG.src_workspace = CONFIG.git_repo.workdir / uuid.uuid4().hex
|
||||
async def test_debug_error(context):
|
||||
context.src_workspace = context.git_repo.workdir / uuid.uuid4().hex
|
||||
ctx = RunCodeContext(
|
||||
code_filename="player.py",
|
||||
test_filename="test_player.py",
|
||||
|
|
@ -126,8 +123,8 @@ async def test_debug_error():
|
|||
output_filename="output.log",
|
||||
)
|
||||
|
||||
await FileRepository.save_file(filename=ctx.code_filename, content=CODE_CONTENT, relative_path=CONFIG.src_workspace)
|
||||
await FileRepository.save_file(filename=ctx.test_filename, content=TEST_CONTENT, relative_path=TEST_CODES_FILE_REPO)
|
||||
await context.repo.with_src_path(context.src_workspace).srcs.save(filename=ctx.code_filename, content=CODE_CONTENT)
|
||||
await context.repo.tests.save(filename=ctx.test_filename, content=TEST_CONTENT)
|
||||
output_data = RunCodeResult(
|
||||
stdout=";",
|
||||
stderr="",
|
||||
|
|
@ -141,24 +138,11 @@ async def test_debug_error():
|
|||
"----------------------------------------------------------------------\n"
|
||||
"Ran 5 tests in 0.007s\n\nFAILED (failures=1)\n;\n",
|
||||
)
|
||||
await FileRepository.save_file(
|
||||
filename=ctx.output_filename, content=output_data.model_dump_json(), relative_path=TEST_OUTPUTS_FILE_REPO
|
||||
)
|
||||
debug_error = DebugError(context=ctx)
|
||||
await context.repo.test_outputs.save(filename=ctx.output_filename, content=output_data.model_dump_json())
|
||||
debug_error = DebugError(i_context=ctx, context=context)
|
||||
|
||||
rsp = await debug_error.run()
|
||||
|
||||
assert "class Player" in rsp # rewrite the same class
|
||||
# Problematic code:
|
||||
# ```
|
||||
# if self.score > 21 and any(card.rank == 'A' for card in self.hand):
|
||||
# self.score -= 10
|
||||
# ```
|
||||
# Should rewrite to (used "gpt-3.5-turbo-1106"):
|
||||
# ```
|
||||
# ace_count = sum(1 for card in self.hand if card.rank == 'A')
|
||||
# while self.score > 21 and ace_count > 0:
|
||||
# self.score -= 10
|
||||
# ace_count -= 1
|
||||
# ```
|
||||
assert "while self.score > 21" in rsp
|
||||
# a key logic to rewrite to (original one is "if self.score > 12")
|
||||
assert "self.score" in rsp
|
||||
|
|
|
|||
|
|
@ -9,20 +9,17 @@
|
|||
import pytest
|
||||
|
||||
from metagpt.actions.design_api import WriteDesign
|
||||
from metagpt.const import PRDS_FILE_REPO
|
||||
from metagpt.logs import logger
|
||||
from metagpt.schema import Message
|
||||
from metagpt.utils.file_repository import FileRepository
|
||||
from tests.metagpt.actions.mock_markdown import PRD_SAMPLE
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_design_api():
|
||||
inputs = ["我们需要一个音乐播放器,它应该有播放、暂停、上一曲、下一曲等功能。", PRD_SAMPLE]
|
||||
async def test_design_api(context):
|
||||
inputs = ["我们需要一个音乐播放器,它应该有播放、暂停、上一曲、下一曲等功能。"] # PRD_SAMPLE
|
||||
for prd in inputs:
|
||||
await FileRepository.save_file("new_prd.txt", content=prd, relative_path=PRDS_FILE_REPO)
|
||||
await context.repo.docs.prd.save(filename="new_prd.txt", content=prd)
|
||||
|
||||
design_api = WriteDesign()
|
||||
design_api = WriteDesign(context=context)
|
||||
|
||||
result = await design_api.run(Message(content=prd, instruct_content=None))
|
||||
logger.info(result)
|
||||
|
|
|
|||
46
tests/metagpt/actions/test_design_api_an.py
Normal file
46
tests/metagpt/actions/test_design_api_an.py
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
@Time : 2024/01/03
|
||||
@Author : mannaandpoem
|
||||
@File : test_design_api_an.py
|
||||
"""
|
||||
import pytest
|
||||
from openai._models import BaseModel
|
||||
|
||||
from metagpt.actions.action_node import ActionNode, dict_to_markdown
|
||||
from metagpt.actions.design_api import NEW_REQ_TEMPLATE
|
||||
from metagpt.actions.design_api_an import REFINED_DESIGN_NODE
|
||||
from metagpt.llm import LLM
|
||||
from tests.data.incremental_dev_project.mock import (
|
||||
DESIGN_SAMPLE,
|
||||
REFINED_DESIGN_JSON,
|
||||
REFINED_PRD_JSON,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def llm():
|
||||
return LLM()
|
||||
|
||||
|
||||
def mock_refined_design_json():
|
||||
return REFINED_DESIGN_JSON
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_write_design_an(mocker):
|
||||
root = ActionNode.from_children(
|
||||
"RefinedDesignAPI", [ActionNode(key="", expected_type=str, instruction="", example="")]
|
||||
)
|
||||
root.instruct_content = BaseModel()
|
||||
root.instruct_content.model_dump = mock_refined_design_json
|
||||
mocker.patch("metagpt.actions.design_api_an.REFINED_DESIGN_NODE.fill", return_value=root)
|
||||
|
||||
prompt = NEW_REQ_TEMPLATE.format(old_design=DESIGN_SAMPLE, context=dict_to_markdown(REFINED_PRD_JSON))
|
||||
node = await REFINED_DESIGN_NODE.fill(prompt, llm)
|
||||
|
||||
assert "Refined Implementation Approach" in node.instruct_content.model_dump()
|
||||
assert "Refined File list" in node.instruct_content.model_dump()
|
||||
assert "Refined Data structures and interfaces" in node.instruct_content.model_dump()
|
||||
assert "Refined Program call flow" in node.instruct_content.model_dump()
|
||||
|
|
@ -11,7 +11,7 @@ from metagpt.actions.design_api_review import DesignReview
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_design_api_review():
|
||||
async def test_design_api_review(context):
|
||||
prd = "我们需要一个音乐播放器,它应该有播放、暂停、上一曲、下一曲等功能。"
|
||||
api_design = """
|
||||
数据结构:
|
||||
|
|
@ -26,7 +26,7 @@ API列表:
|
|||
"""
|
||||
_ = "API设计看起来非常合理,满足了PRD中的所有需求。"
|
||||
|
||||
design_api_review = DesignReview()
|
||||
design_api_review = DesignReview(context=context)
|
||||
|
||||
result = await design_api_review.run(prd, api_design)
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,6 @@ from metagpt.actions.fix_bug import FixBug
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_fix_bug():
|
||||
fix_bug = FixBug()
|
||||
async def test_fix_bug(context):
|
||||
fix_bug = FixBug(context=context)
|
||||
assert fix_bug.name == "FixBug"
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import pytest
|
|||
from metagpt.actions.generate_questions import GenerateQuestions
|
||||
from metagpt.logs import logger
|
||||
|
||||
context = """
|
||||
msg = """
|
||||
## topic
|
||||
如何做一个生日蛋糕
|
||||
|
||||
|
|
@ -20,9 +20,9 @@ context = """
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_generate_questions():
|
||||
action = GenerateQuestions()
|
||||
rsp = await action.run(context)
|
||||
async def test_generate_questions(context):
|
||||
action = GenerateQuestions(context=context)
|
||||
rsp = await action.run(msg)
|
||||
logger.info(f"{rsp.content=}")
|
||||
|
||||
assert "Questions" in rsp.content
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@ from metagpt.const import TEST_DATA_PATH
|
|||
Path("invoices/invoice-4.zip"),
|
||||
],
|
||||
)
|
||||
async def test_invoice_ocr(invoice_path: Path):
|
||||
async def test_invoice_ocr(invoice_path: Path, context):
|
||||
invoice_path = TEST_DATA_PATH / invoice_path
|
||||
resp = await InvoiceOCR().run(file_path=Path(invoice_path))
|
||||
resp = await InvoiceOCR(context=context).run(file_path=Path(invoice_path))
|
||||
assert isinstance(resp, list)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,52 +0,0 @@
|
|||
import pytest
|
||||
|
||||
from metagpt.actions.execute_code import ExecutePyCode
|
||||
from metagpt.actions.write_analysis_code import MakeTools
|
||||
from metagpt.logs import logger
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_make_tools():
|
||||
code = "import yfinance as yf\n\n# Collect Alibaba stock data\nalibaba = yf.Ticker('BABA')\ndata = alibaba.history(period='1d', start='2022-01-01', end='2022-12-31')\nprint(data.head())"
|
||||
msgs = [{"role": "assistant", "content": code}]
|
||||
mt = MakeTools()
|
||||
tool_code = await mt.run(msgs)
|
||||
logger.debug(tool_code)
|
||||
ep = ExecutePyCode()
|
||||
tool_code = "!pip install yfinance\n" + tool_code
|
||||
result, res_type = await ep.run(tool_code)
|
||||
assert res_type is True
|
||||
logger.debug(result)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_make_tools2():
|
||||
code = """import pandas as pd\npath = "./tests/data/test.csv"\ndf = pd.read_csv(path)\ndata = df.copy()\n
|
||||
data['started_at'] = data['started_at'].apply(lambda r: pd.to_datetime(r))\n
|
||||
data['ended_at'] = data['ended_at'].apply(lambda r: pd.to_datetime(r))\ndata.head()"""
|
||||
msgs = [{"role": "assistant", "content": code}]
|
||||
mt = MakeTools()
|
||||
tool_code = await mt.run(msgs)
|
||||
logger.debug(tool_code)
|
||||
ep = ExecutePyCode()
|
||||
tool_code = tool_code
|
||||
result, res_type = await ep.run(tool_code)
|
||||
assert res_type is True
|
||||
logger.debug(result)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_make_tools3():
|
||||
code = """import pandas as pd\npath = "./tests/data/test.csv"\ndf = pd.read_csv(path)\ndata = df.copy()\n
|
||||
data['started_at'] = data['started_at'].apply(lambda r: pd.to_datetime(r))\n
|
||||
data['ended_at'] = data['ended_at'].apply(lambda r: pd.to_datetime(r))\n
|
||||
data['duration_hour'] = (data['ended_at'] - data['started_at']).dt.seconds/3600\ndata.head()"""
|
||||
msgs = [{"role": "assistant", "content": code}]
|
||||
mt = MakeTools()
|
||||
tool_code = await mt.run(msgs)
|
||||
logger.debug(tool_code)
|
||||
ep = ExecutePyCode()
|
||||
tool_code = tool_code
|
||||
result, res_type = await ep.run(tool_code)
|
||||
assert res_type is True
|
||||
logger.debug(result)
|
||||
46
tests/metagpt/actions/test_ml_action.py
Normal file
46
tests/metagpt/actions/test_ml_action.py
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
import pytest
|
||||
|
||||
from metagpt.actions.ml_action import WriteCodeWithToolsML
|
||||
from metagpt.schema import Plan, Task
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_write_code_with_tools():
|
||||
write_code_ml = WriteCodeWithToolsML()
|
||||
|
||||
task_map = {
|
||||
"1": Task(
|
||||
task_id="1",
|
||||
instruction="随机生成一个pandas DataFrame数据集",
|
||||
task_type="other",
|
||||
dependent_task_ids=[],
|
||||
code="""
|
||||
import pandas as pd
|
||||
df = pd.DataFrame({
|
||||
'a': [1, 2, 3, 4, 5],
|
||||
'b': [1.1, 2.2, 3.3, 4.4, np.nan],
|
||||
'c': ['aa', 'bb', 'cc', 'dd', 'ee'],
|
||||
'd': [1, 2, 3, 4, 5]
|
||||
})
|
||||
""",
|
||||
is_finished=True,
|
||||
),
|
||||
"2": Task(
|
||||
task_id="2",
|
||||
instruction="对数据集进行数据清洗",
|
||||
task_type="data_preprocess",
|
||||
dependent_task_ids=["1"],
|
||||
),
|
||||
}
|
||||
plan = Plan(
|
||||
goal="构造数据集并进行数据清洗",
|
||||
tasks=list(task_map.values()),
|
||||
task_map=task_map,
|
||||
current_task_id="2",
|
||||
)
|
||||
column_info = ""
|
||||
|
||||
_, code_with_ml = await write_code_ml.run([], plan, column_info)
|
||||
code_with_ml = code_with_ml["code"]
|
||||
assert len(code_with_ml) > 0
|
||||
print(code_with_ml)
|
||||
|
|
@ -9,22 +9,19 @@
|
|||
import pytest
|
||||
|
||||
from metagpt.actions.prepare_documents import PrepareDocuments
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.const import DOCS_FILE_REPO, REQUIREMENT_FILENAME
|
||||
from metagpt.const import REQUIREMENT_FILENAME
|
||||
from metagpt.context import Context
|
||||
from metagpt.schema import Message
|
||||
from metagpt.utils.file_repository import FileRepository
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_prepare_documents():
|
||||
msg = Message(content="New user requirements balabala...")
|
||||
context = Context()
|
||||
|
||||
if CONFIG.git_repo:
|
||||
CONFIG.git_repo.delete_repository()
|
||||
CONFIG.git_repo = None
|
||||
|
||||
await PrepareDocuments().run(with_messages=[msg])
|
||||
assert CONFIG.git_repo
|
||||
doc = await FileRepository.get_file(filename=REQUIREMENT_FILENAME, relative_path=DOCS_FILE_REPO)
|
||||
await PrepareDocuments(context=context).run(with_messages=[msg])
|
||||
assert context.git_repo
|
||||
assert context.repo
|
||||
doc = await context.repo.docs.get(filename=REQUIREMENT_FILENAME)
|
||||
assert doc
|
||||
assert doc.content == msg.content
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ from metagpt.logs import logger
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_prepare_interview():
|
||||
action = PrepareInterview()
|
||||
async def test_prepare_interview(context):
|
||||
action = PrepareInterview(context=context)
|
||||
rsp = await action.run("I just graduated and hope to find a job as a Python engineer")
|
||||
logger.info(f"{rsp.content=}")
|
||||
|
||||
|
|
|
|||
|
|
@ -9,21 +9,18 @@
|
|||
import pytest
|
||||
|
||||
from metagpt.actions.project_management import WriteTasks
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.const import PRDS_FILE_REPO, SYSTEM_DESIGN_FILE_REPO
|
||||
from metagpt.logs import logger
|
||||
from metagpt.schema import Message
|
||||
from metagpt.utils.file_repository import FileRepository
|
||||
from tests.metagpt.actions.mock_json import DESIGN, PRD
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_design_api():
|
||||
await FileRepository.save_file("1.txt", content=str(PRD), relative_path=PRDS_FILE_REPO)
|
||||
await FileRepository.save_file("1.txt", content=str(DESIGN), relative_path=SYSTEM_DESIGN_FILE_REPO)
|
||||
logger.info(CONFIG.git_repo)
|
||||
async def test_design_api(context):
|
||||
await context.repo.docs.prd.save("1.txt", content=str(PRD))
|
||||
await context.repo.docs.system_design.save("1.txt", content=str(DESIGN))
|
||||
logger.info(context.git_repo)
|
||||
|
||||
action = WriteTasks()
|
||||
action = WriteTasks(context=context)
|
||||
|
||||
result = await action.run(Message(content="", instruct_content=None))
|
||||
logger.info(result)
|
||||
|
|
|
|||
45
tests/metagpt/actions/test_project_management_an.py
Normal file
45
tests/metagpt/actions/test_project_management_an.py
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
@Time : 2024/01/03
|
||||
@Author : mannaandpoem
|
||||
@File : test_project_management_an.py
|
||||
"""
|
||||
import pytest
|
||||
from openai._models import BaseModel
|
||||
|
||||
from metagpt.actions.action_node import ActionNode, dict_to_markdown
|
||||
from metagpt.actions.project_management import NEW_REQ_TEMPLATE
|
||||
from metagpt.actions.project_management_an import REFINED_PM_NODE
|
||||
from metagpt.llm import LLM
|
||||
from tests.data.incremental_dev_project.mock import (
|
||||
REFINED_DESIGN_JSON,
|
||||
REFINED_TASKS_JSON,
|
||||
TASKS_SAMPLE,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def llm():
|
||||
return LLM()
|
||||
|
||||
|
||||
def mock_refined_tasks_json():
|
||||
return REFINED_TASKS_JSON
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_project_management_an(mocker):
|
||||
root = ActionNode.from_children(
|
||||
"RefinedProjectManagement", [ActionNode(key="", expected_type=str, instruction="", example="")]
|
||||
)
|
||||
root.instruct_content = BaseModel()
|
||||
root.instruct_content.model_dump = mock_refined_tasks_json
|
||||
mocker.patch("metagpt.actions.project_management_an.REFINED_PM_NODE.fill", return_value=root)
|
||||
|
||||
prompt = NEW_REQ_TEMPLATE.format(old_task=TASKS_SAMPLE, context=dict_to_markdown(REFINED_DESIGN_JSON))
|
||||
node = await REFINED_PM_NODE.fill(prompt, llm)
|
||||
|
||||
assert "Refined Logic Analysis" in node.instruct_content.model_dump()
|
||||
assert "Refined Task list" in node.instruct_content.model_dump()
|
||||
assert "Refined Shared Knowledge" in node.instruct_content.model_dump()
|
||||
|
|
@ -11,19 +11,19 @@ from pathlib import Path
|
|||
import pytest
|
||||
|
||||
from metagpt.actions.rebuild_class_view import RebuildClassView
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.const import GRAPH_REPO_FILE_REPO
|
||||
from metagpt.llm import LLM
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_rebuild():
|
||||
async def test_rebuild(context):
|
||||
action = RebuildClassView(
|
||||
name="RedBean", context=str(Path(__file__).parent.parent.parent.parent / "metagpt"), llm=LLM()
|
||||
name="RedBean",
|
||||
i_context=str(Path(__file__).parent.parent.parent.parent / "metagpt"),
|
||||
llm=LLM(),
|
||||
context=context,
|
||||
)
|
||||
await action.run()
|
||||
graph_file_repo = CONFIG.git_repo.new_file_repository(relative_path=GRAPH_REPO_FILE_REPO)
|
||||
assert graph_file_repo.changed_files
|
||||
assert context.repo.docs.graph_repo.changed_files
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
|
|
|||
|
|
@ -10,33 +10,30 @@ from pathlib import Path
|
|||
import pytest
|
||||
|
||||
from metagpt.actions.rebuild_sequence_view import RebuildSequenceView
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.const import GRAPH_REPO_FILE_REPO
|
||||
from metagpt.llm import LLM
|
||||
from metagpt.utils.common import aread
|
||||
from metagpt.utils.file_repository import FileRepository
|
||||
from metagpt.utils.git_repository import ChangeType
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_rebuild():
|
||||
@pytest.mark.skip
|
||||
async def test_rebuild(context):
|
||||
# Mock
|
||||
data = await aread(filename=Path(__file__).parent / "../../data/graph_db/networkx.json")
|
||||
graph_db_filename = Path(CONFIG.git_repo.workdir.name).with_suffix(".json")
|
||||
await FileRepository.save_file(
|
||||
filename=str(graph_db_filename),
|
||||
relative_path=GRAPH_REPO_FILE_REPO,
|
||||
content=data,
|
||||
)
|
||||
CONFIG.git_repo.add_change({f"{GRAPH_REPO_FILE_REPO}/{graph_db_filename}": ChangeType.UNTRACTED})
|
||||
CONFIG.git_repo.commit("commit1")
|
||||
graph_db_filename = Path(context.repo.workdir.name).with_suffix(".json")
|
||||
await context.repo.docs.graph_repo.save(filename=str(graph_db_filename), content=data)
|
||||
context.git_repo.add_change({f"{GRAPH_REPO_FILE_REPO}/{graph_db_filename}": ChangeType.UNTRACTED})
|
||||
context.git_repo.commit("commit1")
|
||||
|
||||
action = RebuildSequenceView(
|
||||
name="RedBean", context=str(Path(__file__).parent.parent.parent.parent / "metagpt"), llm=LLM()
|
||||
name="RedBean",
|
||||
i_context=str(Path(__file__).parent.parent.parent.parent / "metagpt"),
|
||||
llm=LLM(),
|
||||
context=context,
|
||||
)
|
||||
await action.run()
|
||||
graph_file_repo = CONFIG.git_repo.new_file_repository(relative_path=GRAPH_REPO_FILE_REPO)
|
||||
assert graph_file_repo.changed_files
|
||||
assert context.repo.docs.graph_repo.changed_files
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
|
|
|||
|
|
@ -9,10 +9,12 @@
|
|||
import pytest
|
||||
|
||||
from metagpt.actions import research
|
||||
from metagpt.tools import SearchEngineType
|
||||
from metagpt.tools.search_engine import SearchEngine
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_collect_links(mocker):
|
||||
async def test_collect_links(mocker, search_engine_mocker, context):
|
||||
async def mock_llm_ask(self, prompt: str, system_msgs):
|
||||
if "Please provide up to 2 necessary keywords" in prompt:
|
||||
return '["metagpt", "llm"]'
|
||||
|
|
@ -26,13 +28,15 @@ async def test_collect_links(mocker):
|
|||
return "[1,2]"
|
||||
|
||||
mocker.patch("metagpt.provider.base_llm.BaseLLM.aask", mock_llm_ask)
|
||||
resp = await research.CollectLinks().run("The application of MetaGPT")
|
||||
resp = await research.CollectLinks(search_engine=SearchEngine(SearchEngineType.DUCK_DUCK_GO), context=context).run(
|
||||
"The application of MetaGPT"
|
||||
)
|
||||
for i in ["MetaGPT use cases", "The roadmap of MetaGPT", "The function of MetaGPT", "What llm MetaGPT support"]:
|
||||
assert i in resp
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_collect_links_with_rank_func(mocker):
|
||||
async def test_collect_links_with_rank_func(mocker, search_engine_mocker, context):
|
||||
rank_before = []
|
||||
rank_after = []
|
||||
url_per_query = 4
|
||||
|
|
@ -45,14 +49,16 @@ async def test_collect_links_with_rank_func(mocker):
|
|||
return results
|
||||
|
||||
mocker.patch("metagpt.provider.base_llm.BaseLLM.aask", mock_collect_links_llm_ask)
|
||||
resp = await research.CollectLinks(rank_func=rank_func).run("The application of MetaGPT")
|
||||
resp = await research.CollectLinks(
|
||||
search_engine=SearchEngine(SearchEngineType.DUCK_DUCK_GO), rank_func=rank_func, context=context
|
||||
).run("The application of MetaGPT")
|
||||
for x, y, z in zip(rank_before, rank_after, resp.values()):
|
||||
assert x[::-1] == y
|
||||
assert [i["link"] for i in y] == z
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_web_browse_and_summarize(mocker):
|
||||
async def test_web_browse_and_summarize(mocker, context):
|
||||
async def mock_llm_ask(*args, **kwargs):
|
||||
return "metagpt"
|
||||
|
||||
|
|
@ -60,20 +66,20 @@ async def test_web_browse_and_summarize(mocker):
|
|||
url = "https://github.com/geekan/MetaGPT"
|
||||
url2 = "https://github.com/trending"
|
||||
query = "What's new in metagpt"
|
||||
resp = await research.WebBrowseAndSummarize().run(url, query=query)
|
||||
resp = await research.WebBrowseAndSummarize(context=context).run(url, query=query)
|
||||
|
||||
assert len(resp) == 1
|
||||
assert url in resp
|
||||
assert resp[url] == "metagpt"
|
||||
|
||||
resp = await research.WebBrowseAndSummarize().run(url, url2, query=query)
|
||||
resp = await research.WebBrowseAndSummarize(context=context).run(url, url2, query=query)
|
||||
assert len(resp) == 2
|
||||
|
||||
async def mock_llm_ask(*args, **kwargs):
|
||||
return "Not relevant."
|
||||
|
||||
mocker.patch("metagpt.provider.base_llm.BaseLLM.aask", mock_llm_ask)
|
||||
resp = await research.WebBrowseAndSummarize().run(url, query=query)
|
||||
resp = await research.WebBrowseAndSummarize(context=context).run(url, query=query)
|
||||
|
||||
assert len(resp) == 1
|
||||
assert url in resp
|
||||
|
|
@ -81,7 +87,7 @@ async def test_web_browse_and_summarize(mocker):
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_conduct_research(mocker):
|
||||
async def test_conduct_research(mocker, context):
|
||||
data = None
|
||||
|
||||
async def mock_llm_ask(*args, **kwargs):
|
||||
|
|
@ -95,7 +101,7 @@ async def test_conduct_research(mocker):
|
|||
"outputs user stories / competitive analysis / requirements / data structures / APIs / documents, etc."
|
||||
)
|
||||
|
||||
resp = await research.ConductResearch().run("The application of MetaGPT", content)
|
||||
resp = await research.ConductResearch(context=context).run("The application of MetaGPT", content)
|
||||
assert resp == data
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -24,19 +24,19 @@ async def test_run_text():
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_run_script():
|
||||
async def test_run_script(context):
|
||||
# Successful command
|
||||
out, err = await RunCode.run_script(".", command=["echo", "Hello World"])
|
||||
out, err = await RunCode(context=context).run_script(".", command=["echo", "Hello World"])
|
||||
assert out.strip() == "Hello World"
|
||||
assert err == ""
|
||||
|
||||
# Unsuccessful command
|
||||
out, err = await RunCode.run_script(".", command=["python", "-c", "print(1/0)"])
|
||||
out, err = await RunCode(context=context).run_script(".", command=["python", "-c", "print(1/0)"])
|
||||
assert "ZeroDivisionError" in err
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_run():
|
||||
async def test_run(context):
|
||||
inputs = [
|
||||
(RunCodeContext(mode="text", code_filename="a.txt", code="print('Hello, World')"), "PASS"),
|
||||
(
|
||||
|
|
@ -61,5 +61,5 @@ async def test_run():
|
|||
),
|
||||
]
|
||||
for ctx, result in inputs:
|
||||
rsp = await RunCode(context=ctx).run()
|
||||
rsp = await RunCode(i_context=ctx, context=context).run()
|
||||
assert result in rsp.summary
|
||||
|
|
|
|||
|
|
@ -47,18 +47,18 @@ class TestSkillAction:
|
|||
assert args.get("size_type") == "512x512"
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_parser_action(self, mocker):
|
||||
async def test_parser_action(self, mocker, context):
|
||||
# mock
|
||||
mocker.patch("metagpt.learn.text_to_image", return_value="https://mock.com/xxx")
|
||||
|
||||
parser_action = ArgumentsParingAction(skill=self.skill, ask="Draw an apple")
|
||||
parser_action = ArgumentsParingAction(skill=self.skill, ask="Draw an apple", context=context)
|
||||
rsp = await parser_action.run()
|
||||
assert rsp
|
||||
assert parser_action.args
|
||||
assert parser_action.args.get("text") == "Draw an apple"
|
||||
assert parser_action.args.get("size_type") == "512x512"
|
||||
|
||||
action = SkillAction(skill=self.skill, args=parser_action.args)
|
||||
action = SkillAction(skill=self.skill, args=parser_action.args, context=context)
|
||||
rsp = await action.run()
|
||||
assert rsp
|
||||
assert "image/png;base64," in rsp.content or "http" in rsp.content
|
||||
|
|
@ -81,8 +81,8 @@ class TestSkillAction:
|
|||
await SkillAction.find_and_call_function("dummy_call", {"a": 1})
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_skill_action_error(self):
|
||||
action = SkillAction(skill=self.skill, args={})
|
||||
async def test_skill_action_error(self, context):
|
||||
action = SkillAction(skill=self.skill, args={}, context=context)
|
||||
rsp = await action.run()
|
||||
assert "Error" in rsp.content
|
||||
|
||||
|
|
|
|||
|
|
@ -6,14 +6,14 @@
|
|||
@File : test_summarize_code.py
|
||||
@Modifiled By: mashenquan, 2023-12-6. Unit test for summarize_code.py
|
||||
"""
|
||||
import uuid
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from metagpt.actions.summarize_code import SummarizeCode
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.const import SYSTEM_DESIGN_FILE_REPO, TASK_FILE_REPO
|
||||
from metagpt.logs import logger
|
||||
from metagpt.schema import CodeSummarizeContext
|
||||
from metagpt.utils.file_repository import FileRepository
|
||||
|
||||
DESIGN_CONTENT = """
|
||||
{"Implementation approach": "To develop this snake game, we will use the Python language and choose the Pygame library. Pygame is an open-source Python module collection specifically designed for writing video games. It provides functionalities such as displaying images and playing sounds, making it suitable for creating intuitive and responsive user interfaces. We will ensure efficient game logic to prevent any delays during gameplay. The scoring system will be simple, with the snake gaining points for each food it eats. We will use Pygame's event handling system to implement pause and resume functionality, as well as high-score tracking. The difficulty will increase by speeding up the snake's movement. In the initial version, we will focus on single-player mode and consider adding multiplayer mode and customizable skins in future updates. Based on the new requirement, we will also add a moving obstacle that appears randomly. If the snake eats this obstacle, the game will end. If the snake does not eat the obstacle, it will disappear after 5 seconds. For this, we need to add mechanisms for obstacle generation, movement, and disappearance in the game logic.", "Project_name": "snake_game", "File list": ["main.py", "game.py", "snake.py", "food.py", "obstacle.py", "scoreboard.py", "constants.py", "assets/styles.css", "assets/index.html"], "Data structures and interfaces": "```mermaid\n classDiagram\n class Game{\n +int score\n +int speed\n +bool game_over\n +bool paused\n +Snake snake\n +Food food\n +Obstacle obstacle\n +Scoreboard scoreboard\n +start_game() void\n +pause_game() void\n +resume_game() void\n +end_game() void\n +increase_difficulty() void\n +update() void\n +render() void\n Game()\n }\n class Snake{\n +list body_parts\n +str direction\n +bool grow\n +move() void\n +grow() void\n +check_collision() bool\n Snake()\n }\n class Food{\n +tuple position\n +spawn() void\n Food()\n }\n class Obstacle{\n +tuple position\n +int lifetime\n +bool active\n +spawn() void\n +move() void\n +check_collision() bool\n +disappear() void\n Obstacle()\n }\n class Scoreboard{\n +int high_score\n +update_score(int) void\n +reset_score() void\n +load_high_score() void\n +save_high_score() void\n Scoreboard()\n }\n class Constants{\n }\n Game \"1\" -- \"1\" Snake: has\n Game \"1\" -- \"1\" Food: has\n Game \"1\" -- \"1\" Obstacle: has\n Game \"1\" -- \"1\" Scoreboard: has\n ```", "Program call flow": "```sequenceDiagram\n participant M as Main\n participant G as Game\n participant S as Snake\n participant F as Food\n participant O as Obstacle\n participant SB as Scoreboard\n M->>G: start_game()\n loop game loop\n G->>S: move()\n G->>S: check_collision()\n G->>F: spawn()\n G->>O: spawn()\n G->>O: move()\n G->>O: check_collision()\n G->>O: disappear()\n G->>SB: update_score(score)\n G->>G: update()\n G->>G: render()\n alt if paused\n M->>G: pause_game()\n M->>G: resume_game()\n end\n alt if game_over\n G->>M: end_game()\n end\n end\n```", "Anything UNCLEAR": "There is no need for further clarification as the requirements are already clear."}
|
||||
|
|
@ -177,19 +177,28 @@ class Snake:
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_summarize_code():
|
||||
CONFIG.src_workspace = CONFIG.git_repo.workdir / "src"
|
||||
await FileRepository.save_file(filename="1.json", relative_path=SYSTEM_DESIGN_FILE_REPO, content=DESIGN_CONTENT)
|
||||
await FileRepository.save_file(filename="1.json", relative_path=TASK_FILE_REPO, content=TASK_CONTENT)
|
||||
await FileRepository.save_file(filename="food.py", relative_path=CONFIG.src_workspace, content=FOOD_PY)
|
||||
await FileRepository.save_file(filename="game.py", relative_path=CONFIG.src_workspace, content=GAME_PY)
|
||||
await FileRepository.save_file(filename="main.py", relative_path=CONFIG.src_workspace, content=MAIN_PY)
|
||||
await FileRepository.save_file(filename="snake.py", relative_path=CONFIG.src_workspace, content=SNAKE_PY)
|
||||
async def test_summarize_code(context):
|
||||
git_dir = Path(__file__).parent / f"unittest/{uuid.uuid4().hex}"
|
||||
git_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
src_file_repo = CONFIG.git_repo.new_file_repository(relative_path=CONFIG.src_workspace)
|
||||
all_files = src_file_repo.all_files
|
||||
ctx = CodeSummarizeContext(design_filename="1.json", task_filename="1.json", codes_filenames=all_files)
|
||||
action = SummarizeCode(context=ctx)
|
||||
context.src_workspace = context.git_repo.workdir / "src"
|
||||
await context.repo.docs.system_design.save(filename="1.json", content=DESIGN_CONTENT)
|
||||
await context.repo.docs.task.save(filename="1.json", content=TASK_CONTENT)
|
||||
await context.repo.with_src_path(context.src_workspace).srcs.save(filename="food.py", content=FOOD_PY)
|
||||
assert context.repo.srcs.workdir == context.src_workspace
|
||||
await context.repo.srcs.save(filename="game.py", content=GAME_PY)
|
||||
await context.repo.srcs.save(filename="main.py", content=MAIN_PY)
|
||||
await context.repo.srcs.save(filename="snake.py", content=SNAKE_PY)
|
||||
|
||||
all_files = context.repo.srcs.all_files
|
||||
summarization_context = CodeSummarizeContext(
|
||||
design_filename="1.json", task_filename="1.json", codes_filenames=all_files
|
||||
)
|
||||
action = SummarizeCode(context=context, i_context=summarization_context)
|
||||
rsp = await action.run()
|
||||
assert rsp
|
||||
logger.info(rsp)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pytest.main([__file__, "-s"])
|
||||
|
|
|
|||
|
|
@ -9,13 +9,12 @@
|
|||
import pytest
|
||||
|
||||
from metagpt.actions.talk_action import TalkAction
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.schema import Message
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize(
|
||||
("agent_description", "language", "context", "knowledge", "history_summary"),
|
||||
("agent_description", "language", "talk_context", "knowledge", "history_summary"),
|
||||
[
|
||||
(
|
||||
"mathematician",
|
||||
|
|
@ -33,12 +32,12 @@ from metagpt.schema import Message
|
|||
),
|
||||
],
|
||||
)
|
||||
async def test_prompt(agent_description, language, context, knowledge, history_summary):
|
||||
async def test_prompt(agent_description, language, talk_context, knowledge, history_summary, context):
|
||||
# Prerequisites
|
||||
CONFIG.agent_description = agent_description
|
||||
CONFIG.language = language
|
||||
context.kwargs.agent_description = agent_description
|
||||
context.kwargs.language = language
|
||||
|
||||
action = TalkAction(context=context, knowledge=knowledge, history_summary=history_summary)
|
||||
action = TalkAction(i_context=talk_context, knowledge=knowledge, history_summary=history_summary, context=context)
|
||||
assert "{" not in action.prompt
|
||||
assert "{" not in action.prompt_gpt4
|
||||
|
||||
|
|
|
|||
|
|
@ -3,16 +3,13 @@ import asyncio
|
|||
import pytest
|
||||
|
||||
from metagpt.actions.execute_code import ExecutePyCode
|
||||
from metagpt.actions.write_analysis_code import (
|
||||
WriteCodeByGenerate,
|
||||
WriteCodeWithTools,
|
||||
WriteCodeWithToolsML,
|
||||
)
|
||||
from metagpt.actions.write_analysis_code import WriteCodeByGenerate, WriteCodeWithTools
|
||||
from metagpt.logs import logger
|
||||
from metagpt.plan.planner import STRUCTURAL_CONTEXT
|
||||
from metagpt.schema import Message, Plan, Task
|
||||
|
||||
|
||||
@pytest.mark.skip
|
||||
@pytest.mark.asyncio
|
||||
async def test_write_code_by_list_plan():
|
||||
write_code = WriteCodeByGenerate()
|
||||
|
|
@ -23,35 +20,31 @@ async def test_write_code_by_list_plan():
|
|||
print(f"\n任务: {task}\n\n")
|
||||
messages.append(Message(task, role="assistant"))
|
||||
code = await write_code.run(messages)
|
||||
messages.append(Message(code, role="assistant"))
|
||||
messages.append(Message(code["code"], role="assistant"))
|
||||
assert len(code) > 0
|
||||
output = await execute_code.run(code)
|
||||
output = await execute_code.run(code["code"])
|
||||
print(f"\n[Output]: 任务{task}的执行结果是: \n{output}\n")
|
||||
messages.append(output[0])
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_tool_recommendation():
|
||||
task = "对已经读取的数据集进行数据清洗"
|
||||
code_steps = """
|
||||
step 1: 对数据集进行去重
|
||||
step 2: 对数据集进行缺失值处理
|
||||
"""
|
||||
task = "clean and preprocess the data"
|
||||
code_steps = ""
|
||||
available_tools = {
|
||||
"fill_missing_value": "Completing missing values with simple strategies",
|
||||
"split_bins": "Bin continuous data into intervals and return the bin identifier encoded as an integer value",
|
||||
"FillMissingValue": "Filling missing values",
|
||||
"SplitBins": "Bin continuous data into intervals and return the bin identifier encoded as an integer value",
|
||||
}
|
||||
write_code = WriteCodeWithTools()
|
||||
tools = await write_code._tool_recommendation(task, code_steps, available_tools)
|
||||
tools = await write_code._recommend_tool(task, code_steps, available_tools)
|
||||
|
||||
assert len(tools) == 1
|
||||
assert tools[0] == "fill_missing_value"
|
||||
assert "FillMissingValue" in tools
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_write_code_with_tools():
|
||||
write_code = WriteCodeWithTools()
|
||||
write_code_ml = WriteCodeWithToolsML()
|
||||
|
||||
requirement = "构造数据集并进行数据清洗"
|
||||
task_map = {
|
||||
|
|
@ -84,7 +77,6 @@ async def test_write_code_with_tools():
|
|||
task_map=task_map,
|
||||
current_task_id="2",
|
||||
)
|
||||
column_info = ""
|
||||
|
||||
context = STRUCTURAL_CONTEXT.format(
|
||||
user_requirement=requirement,
|
||||
|
|
@ -95,13 +87,10 @@ async def test_write_code_with_tools():
|
|||
context_msg = [Message(content=context, role="user")]
|
||||
|
||||
code = await write_code.run(context_msg, plan)
|
||||
code = code["code"]
|
||||
assert len(code) > 0
|
||||
print(code)
|
||||
|
||||
code_with_ml = await write_code_ml.run([], plan, column_info)
|
||||
assert len(code_with_ml) > 0
|
||||
print(code_with_ml)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_write_code_to_correct_error():
|
||||
|
|
@ -150,6 +139,7 @@ async def test_write_code_to_correct_error():
|
|||
Message(content=error, role="user"),
|
||||
]
|
||||
new_code = await WriteCodeByGenerate().run(context=context)
|
||||
new_code = new_code["code"]
|
||||
print(new_code)
|
||||
assert "read_csv" in new_code # should correct read_excel to read_csv
|
||||
|
||||
|
|
@ -189,10 +179,12 @@ async def test_write_code_reuse_code_simple():
|
|||
Message(content=structural_context, role="user"),
|
||||
]
|
||||
code = await WriteCodeByGenerate().run(context=context)
|
||||
code = code["code"]
|
||||
print(code)
|
||||
assert "pandas" not in code and "read_csv" not in code # should reuse import and read statement from previous one
|
||||
|
||||
|
||||
@pytest.mark.skip
|
||||
@pytest.mark.asyncio
|
||||
async def test_write_code_reuse_code_long():
|
||||
"""test code reuse for long context"""
|
||||
|
|
@ -245,13 +237,14 @@ async def test_write_code_reuse_code_long():
|
|||
trial_results = await asyncio.gather(*trials)
|
||||
print(*trial_results, sep="\n\n***\n\n")
|
||||
success = [
|
||||
"load_iris" not in result and "iris_data" in result for result in trial_results
|
||||
"load_iris" not in result["code"] and "iris_data" in result["code"] for result in trial_results
|
||||
] # should reuse iris_data from previous tasks
|
||||
success_rate = sum(success) / trials_num
|
||||
logger.info(f"success rate: {success_rate :.2f}")
|
||||
assert success_rate >= 0.8
|
||||
|
||||
|
||||
@pytest.mark.skip
|
||||
@pytest.mark.asyncio
|
||||
async def test_write_code_reuse_code_long_for_wine():
|
||||
"""test code reuse for long context"""
|
||||
|
|
@ -318,7 +311,7 @@ async def test_write_code_reuse_code_long_for_wine():
|
|||
trial_results = await asyncio.gather(*trials)
|
||||
print(*trial_results, sep="\n\n***\n\n")
|
||||
success = [
|
||||
"load_wine" not in result and "wine_data" in result for result in trial_results
|
||||
"load_wine" not in result["code"] and "wine_data" in result["code"] for result in trial_results
|
||||
] # should reuse iris_data from previous tasks
|
||||
success_rate = sum(success) / trials_num
|
||||
logger.info(f"success rate: {success_rate :.2f}")
|
||||
|
|
|
|||
|
|
@ -12,28 +12,22 @@ from pathlib import Path
|
|||
import pytest
|
||||
|
||||
from metagpt.actions.write_code import WriteCode
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.const import (
|
||||
CODE_SUMMARIES_FILE_REPO,
|
||||
SYSTEM_DESIGN_FILE_REPO,
|
||||
TASK_FILE_REPO,
|
||||
TEST_OUTPUTS_FILE_REPO,
|
||||
)
|
||||
from metagpt.logs import logger
|
||||
from metagpt.provider.openai_api import OpenAILLM as LLM
|
||||
from metagpt.schema import CodingContext, Document
|
||||
from metagpt.utils.common import aread
|
||||
from metagpt.utils.file_repository import FileRepository
|
||||
from tests.metagpt.actions.mock_markdown import TASKS_2, WRITE_CODE_PROMPT_SAMPLE
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_write_code():
|
||||
context = CodingContext(
|
||||
async def test_write_code(context):
|
||||
# Prerequisites
|
||||
context.src_workspace = context.git_repo.workdir / "writecode"
|
||||
|
||||
coding_ctx = CodingContext(
|
||||
filename="task_filename.py", design_doc=Document(content="设计一个名为'add'的函数,该函数接受两个整数作为输入,并返回它们的和。")
|
||||
)
|
||||
doc = Document(content=context.model_dump_json())
|
||||
write_code = WriteCode(context=doc)
|
||||
doc = Document(content=coding_ctx.model_dump_json())
|
||||
write_code = WriteCode(i_context=doc, context=context)
|
||||
|
||||
code = await write_code.run()
|
||||
logger.info(code.model_dump_json())
|
||||
|
|
@ -44,48 +38,44 @@ async def test_write_code():
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_write_code_directly():
|
||||
async def test_write_code_directly(context):
|
||||
prompt = WRITE_CODE_PROMPT_SAMPLE + "\n" + TASKS_2[0]
|
||||
llm = LLM()
|
||||
llm = context.llm_with_cost_manager_from_llm_config(context.config.llm)
|
||||
rsp = await llm.aask(prompt)
|
||||
logger.info(rsp)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_write_code_deps():
|
||||
async def test_write_code_deps(context):
|
||||
# Prerequisites
|
||||
CONFIG.src_workspace = CONFIG.git_repo.workdir / "snake1/snake1"
|
||||
context.src_workspace = context.git_repo.workdir / "snake1/snake1"
|
||||
demo_path = Path(__file__).parent / "../../data/demo_project"
|
||||
await FileRepository.save_file(
|
||||
filename="test_game.py.json",
|
||||
content=await aread(str(demo_path / "test_game.py.json")),
|
||||
relative_path=TEST_OUTPUTS_FILE_REPO,
|
||||
await context.repo.test_outputs.save(
|
||||
filename="test_game.py.json", content=await aread(str(demo_path / "test_game.py.json"))
|
||||
)
|
||||
await FileRepository.save_file(
|
||||
await context.repo.docs.code_summary.save(
|
||||
filename="20231221155954.json",
|
||||
content=await aread(str(demo_path / "code_summaries.json")),
|
||||
relative_path=CODE_SUMMARIES_FILE_REPO,
|
||||
)
|
||||
await FileRepository.save_file(
|
||||
await context.repo.docs.system_design.save(
|
||||
filename="20231221155954.json",
|
||||
content=await aread(str(demo_path / "system_design.json")),
|
||||
relative_path=SYSTEM_DESIGN_FILE_REPO,
|
||||
)
|
||||
await FileRepository.save_file(
|
||||
filename="20231221155954.json", content=await aread(str(demo_path / "tasks.json")), relative_path=TASK_FILE_REPO
|
||||
await context.repo.docs.task.save(
|
||||
filename="20231221155954.json", content=await aread(str(demo_path / "tasks.json"))
|
||||
)
|
||||
await FileRepository.save_file(
|
||||
filename="main.py", content='if __name__ == "__main__":\nmain()', relative_path=CONFIG.src_workspace
|
||||
await context.repo.with_src_path(context.src_workspace).srcs.save(
|
||||
filename="main.py", content='if __name__ == "__main__":\nmain()'
|
||||
)
|
||||
context = CodingContext(
|
||||
ccontext = CodingContext(
|
||||
filename="game.py",
|
||||
design_doc=await FileRepository.get_file(filename="20231221155954.json", relative_path=SYSTEM_DESIGN_FILE_REPO),
|
||||
task_doc=await FileRepository.get_file(filename="20231221155954.json", relative_path=TASK_FILE_REPO),
|
||||
design_doc=await context.repo.docs.system_design.get(filename="20231221155954.json"),
|
||||
task_doc=await context.repo.docs.task.get(filename="20231221155954.json"),
|
||||
code_doc=Document(filename="game.py", content="", root_path="snake1"),
|
||||
)
|
||||
coding_doc = Document(root_path="snake1", filename="game.py", content=context.json())
|
||||
coding_doc = Document(root_path="snake1", filename="game.py", content=ccontext.json())
|
||||
|
||||
action = WriteCode(context=coding_doc)
|
||||
action = WriteCode(i_context=coding_doc, context=context)
|
||||
rsp = await action.run()
|
||||
assert rsp
|
||||
assert rsp.code_doc.content
|
||||
|
|
|
|||
71
tests/metagpt/actions/test_write_code_plan_and_change_an.py
Normal file
71
tests/metagpt/actions/test_write_code_plan_and_change_an.py
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
@Time : 2024/01/03
|
||||
@Author : mannaandpoem
|
||||
@File : test_write_code_plan_and_change_an.py
|
||||
"""
|
||||
import pytest
|
||||
from openai._models import BaseModel
|
||||
|
||||
from metagpt.actions.action_node import ActionNode
|
||||
from metagpt.actions.write_code import WriteCode
|
||||
from metagpt.actions.write_code_plan_and_change_an import (
|
||||
REFINED_TEMPLATE,
|
||||
WriteCodePlanAndChange,
|
||||
)
|
||||
from metagpt.schema import CodePlanAndChangeContext
|
||||
from tests.data.incremental_dev_project.mock import (
|
||||
CODE_PLAN_AND_CHANGE_SAMPLE,
|
||||
DESIGN_SAMPLE,
|
||||
NEW_REQUIREMENT_SAMPLE,
|
||||
REFINED_CODE_INPUT_SAMPLE,
|
||||
REFINED_CODE_SAMPLE,
|
||||
TASKS_SAMPLE,
|
||||
)
|
||||
|
||||
|
||||
def mock_code_plan_and_change():
|
||||
return CODE_PLAN_AND_CHANGE_SAMPLE
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_write_code_plan_and_change_an(mocker):
|
||||
root = ActionNode.from_children(
|
||||
"WriteCodePlanAndChange", [ActionNode(key="", expected_type=str, instruction="", example="")]
|
||||
)
|
||||
root.instruct_content = BaseModel()
|
||||
root.instruct_content.model_dump = mock_code_plan_and_change
|
||||
mocker.patch("metagpt.actions.write_code_plan_and_change_an.WriteCodePlanAndChange.run", return_value=root)
|
||||
|
||||
requirement = "New requirement"
|
||||
prd_filename = "prd.md"
|
||||
design_filename = "design.md"
|
||||
task_filename = "task.md"
|
||||
code_plan_and_change_context = CodePlanAndChangeContext(
|
||||
requirement=requirement,
|
||||
prd_filename=prd_filename,
|
||||
design_filename=design_filename,
|
||||
task_filename=task_filename,
|
||||
)
|
||||
node = await WriteCodePlanAndChange(i_context=code_plan_and_change_context).run()
|
||||
|
||||
assert "Code Plan And Change" in node.instruct_content.model_dump()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_refine_code(mocker):
|
||||
mocker.patch.object(WriteCode, "_aask", return_value=REFINED_CODE_SAMPLE)
|
||||
prompt = REFINED_TEMPLATE.format(
|
||||
user_requirement=NEW_REQUIREMENT_SAMPLE,
|
||||
code_plan_and_change=CODE_PLAN_AND_CHANGE_SAMPLE,
|
||||
design=DESIGN_SAMPLE,
|
||||
task=TASKS_SAMPLE,
|
||||
code=REFINED_CODE_INPUT_SAMPLE,
|
||||
logs="",
|
||||
feedback="",
|
||||
filename="game.py",
|
||||
summary_log="",
|
||||
)
|
||||
code = await WriteCode().write_code(prompt=prompt)
|
||||
assert "def" in code
|
||||
|
|
@ -12,28 +12,25 @@ from metagpt.schema import CodingContext, Document
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_write_code_review(capfd):
|
||||
async def test_write_code_review(capfd, context):
|
||||
context.src_workspace = context.repo.workdir / "srcs"
|
||||
code = """
|
||||
def add(a, b):
|
||||
return a +
|
||||
"""
|
||||
context = CodingContext(
|
||||
coding_context = CodingContext(
|
||||
filename="math.py", design_doc=Document(content="编写一个从a加b的函数,返回a+b"), code_doc=Document(content=code)
|
||||
)
|
||||
|
||||
context = await WriteCodeReview(context=context).run()
|
||||
await WriteCodeReview(i_context=coding_context, context=context).run()
|
||||
|
||||
# 我们不能精确地预测生成的代码评审,但我们可以检查返回的是否为字符串
|
||||
assert isinstance(context.code_doc.content, str)
|
||||
assert len(context.code_doc.content) > 0
|
||||
assert isinstance(coding_context.code_doc.content, str)
|
||||
assert len(coding_context.code_doc.content) > 0
|
||||
|
||||
captured = capfd.readouterr()
|
||||
print(f"输出内容: {captured.out}")
|
||||
|
||||
|
||||
# @pytest.mark.asyncio
|
||||
# async def test_write_code_review_directly():
|
||||
# code = SEARCH_CODE_SAMPLE
|
||||
# write_code_review = WriteCodeReview("write_code_review")
|
||||
# review = await write_code_review.run(code)
|
||||
# logger.info(review)
|
||||
if __name__ == "__main__":
|
||||
pytest.main([__file__, "-s"])
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ class Person:
|
|||
],
|
||||
ids=["google", "numpy", "sphinx"],
|
||||
)
|
||||
async def test_write_docstring(style: str, part: str):
|
||||
ret = await WriteDocstring().run(code, style=style)
|
||||
async def test_write_docstring(style: str, part: str, context):
|
||||
ret = await WriteDocstring(context=context).run(code, style=style)
|
||||
assert part in ret
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -9,21 +9,19 @@
|
|||
import pytest
|
||||
|
||||
from metagpt.actions import UserRequirement, WritePRD
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.const import DOCS_FILE_REPO, PRDS_FILE_REPO, REQUIREMENT_FILENAME
|
||||
from metagpt.const import REQUIREMENT_FILENAME
|
||||
from metagpt.logs import logger
|
||||
from metagpt.roles.product_manager import ProductManager
|
||||
from metagpt.roles.role import RoleReactMode
|
||||
from metagpt.schema import Message
|
||||
from metagpt.utils.common import any_to_str
|
||||
from metagpt.utils.file_repository import FileRepository
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_write_prd(new_filename):
|
||||
product_manager = ProductManager()
|
||||
async def test_write_prd(new_filename, context):
|
||||
product_manager = ProductManager(context=context)
|
||||
requirements = "开发一个基于大语言模型与私有知识库的搜索引擎,希望可以基于大语言模型进行搜索总结"
|
||||
await FileRepository.save_file(filename=REQUIREMENT_FILENAME, content=requirements, relative_path=DOCS_FILE_REPO)
|
||||
await context.repo.docs.save(filename=REQUIREMENT_FILENAME, content=requirements)
|
||||
product_manager.rc.react_mode = RoleReactMode.BY_ORDER
|
||||
prd = await product_manager.run(Message(content=requirements, cause_by=UserRequirement))
|
||||
assert prd.cause_by == any_to_str(WritePRD)
|
||||
|
|
@ -33,7 +31,7 @@ async def test_write_prd(new_filename):
|
|||
# Assert the prd is not None or empty
|
||||
assert prd is not None
|
||||
assert prd.content != ""
|
||||
assert CONFIG.git_repo.new_file_repository(relative_path=PRDS_FILE_REPO).changed_files
|
||||
assert product_manager.context.repo.docs.prd.changed_files
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
|||
48
tests/metagpt/actions/test_write_prd_an.py
Normal file
48
tests/metagpt/actions/test_write_prd_an.py
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
@Time : 2024/01/03
|
||||
@Author : mannaandpoem
|
||||
@File : test_write_prd_an.py
|
||||
"""
|
||||
import pytest
|
||||
from openai._models import BaseModel
|
||||
|
||||
from metagpt.actions.action_node import ActionNode
|
||||
from metagpt.actions.write_prd import NEW_REQ_TEMPLATE
|
||||
from metagpt.actions.write_prd_an import REFINED_PRD_NODE
|
||||
from metagpt.llm import LLM
|
||||
from tests.data.incremental_dev_project.mock import (
|
||||
NEW_REQUIREMENT_SAMPLE,
|
||||
PRD_SAMPLE,
|
||||
REFINED_PRD_JSON,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def llm():
|
||||
return LLM()
|
||||
|
||||
|
||||
def mock_refined_prd_json():
|
||||
return REFINED_PRD_JSON
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_write_prd_an(mocker):
|
||||
root = ActionNode.from_children("RefinedPRD", [ActionNode(key="", expected_type=str, instruction="", example="")])
|
||||
root.instruct_content = BaseModel()
|
||||
root.instruct_content.model_dump = mock_refined_prd_json
|
||||
mocker.patch("metagpt.actions.write_prd_an.REFINED_PRD_NODE.fill", return_value=root)
|
||||
|
||||
prompt = NEW_REQ_TEMPLATE.format(
|
||||
requirements=NEW_REQUIREMENT_SAMPLE,
|
||||
old_prd=PRD_SAMPLE,
|
||||
)
|
||||
node = await REFINED_PRD_NODE.fill(prompt, llm)
|
||||
|
||||
assert "Refined Requirements" in node.instruct_content.model_dump()
|
||||
assert "Refined Product Goals" in node.instruct_content.model_dump()
|
||||
assert "Refined User Stories" in node.instruct_content.model_dump()
|
||||
assert "Refined Requirement Analysis" in node.instruct_content.model_dump()
|
||||
assert "Refined Requirement Pool" in node.instruct_content.model_dump()
|
||||
|
|
@ -11,7 +11,7 @@ from metagpt.actions.write_prd_review import WritePRDReview
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_write_prd_review():
|
||||
async def test_write_prd_review(context):
|
||||
prd = """
|
||||
Introduction: This is a new feature for our product.
|
||||
Goals: The goal is to improve user engagement.
|
||||
|
|
@ -23,7 +23,7 @@ async def test_write_prd_review():
|
|||
Timeline: The feature should be ready for testing in 1.5 months.
|
||||
"""
|
||||
|
||||
write_prd_review = WritePRDReview(name="write_prd_review")
|
||||
write_prd_review = WritePRDReview(name="write_prd_review", context=context)
|
||||
|
||||
prd_review = await write_prd_review.run(prd)
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import pytest
|
|||
|
||||
from metagpt.actions.write_review import WriteReview
|
||||
|
||||
CONTEXT = """
|
||||
TEMPLATE_CONTEXT = """
|
||||
{
|
||||
"Language": "zh_cn",
|
||||
"Programming Language": "Python",
|
||||
|
|
@ -46,8 +46,8 @@ CONTEXT = """
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_write_review():
|
||||
write_review = WriteReview()
|
||||
review = await write_review.run(CONTEXT)
|
||||
async def test_write_review(context):
|
||||
write_review = WriteReview(context=context)
|
||||
review = await write_review.run(TEMPLATE_CONTEXT)
|
||||
assert review.instruct_content
|
||||
assert review.get("LGTM") in ["LGTM", "LBTM"]
|
||||
|
|
|
|||
|
|
@ -13,11 +13,11 @@ from metagpt.actions.write_teaching_plan import WriteTeachingPlanPart
|
|||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize(
|
||||
("topic", "context"),
|
||||
("topic", "content"),
|
||||
[("Title", "Lesson 1: Learn to draw an apple."), ("Teaching Content", "Lesson 1: Learn to draw an apple.")],
|
||||
)
|
||||
async def test_write_teaching_plan_part(topic, context):
|
||||
action = WriteTeachingPlanPart(topic=topic, context=context)
|
||||
async def test_write_teaching_plan_part(topic, content, context):
|
||||
action = WriteTeachingPlanPart(topic=topic, i_context=content, context=context)
|
||||
rsp = await action.run()
|
||||
assert rsp
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ from metagpt.schema import Document, TestingContext
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_write_test():
|
||||
async def test_write_test(context):
|
||||
code = """
|
||||
import random
|
||||
from typing import Tuple
|
||||
|
|
@ -25,8 +25,8 @@ async def test_write_test():
|
|||
def generate(self, max_y: int, max_x: int):
|
||||
self.position = (random.randint(1, max_y - 1), random.randint(1, max_x - 1))
|
||||
"""
|
||||
context = TestingContext(filename="food.py", code_doc=Document(filename="food.py", content=code))
|
||||
write_test = WriteTest(context=context)
|
||||
testing_context = TestingContext(filename="food.py", code_doc=Document(filename="food.py", content=code))
|
||||
write_test = WriteTest(i_context=testing_context, context=context)
|
||||
|
||||
context = await write_test.run()
|
||||
logger.info(context.model_dump_json())
|
||||
|
|
@ -39,12 +39,12 @@ async def test_write_test():
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_write_code_invalid_code(mocker):
|
||||
async def test_write_code_invalid_code(mocker, context):
|
||||
# Mock the _aask method to return an invalid code string
|
||||
mocker.patch.object(WriteTest, "_aask", return_value="Invalid Code String")
|
||||
|
||||
# Create an instance of WriteTest
|
||||
write_test = WriteTest()
|
||||
write_test = WriteTest(context=context)
|
||||
|
||||
# Call the write_code method
|
||||
code = await write_test.write_code("Some prompt:")
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ from metagpt.actions.write_tutorial import WriteContent, WriteDirectory
|
|||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize(("language", "topic"), [("English", "Write a tutorial about Python")])
|
||||
async def test_write_directory(language: str, topic: str):
|
||||
ret = await WriteDirectory(language=language).run(topic=topic)
|
||||
async def test_write_directory(language: str, topic: str, context):
|
||||
ret = await WriteDirectory(language=language, context=context).run(topic=topic)
|
||||
assert isinstance(ret, dict)
|
||||
assert "title" in ret
|
||||
assert "directory" in ret
|
||||
|
|
@ -29,8 +29,8 @@ async def test_write_directory(language: str, topic: str):
|
|||
("language", "topic", "directory"),
|
||||
[("English", "Write a tutorial about Python", {"Introduction": ["What is Python?", "Why learn Python?"]})],
|
||||
)
|
||||
async def test_write_content(language: str, topic: str, directory: Dict):
|
||||
ret = await WriteContent(language=language, directory=directory).run(topic=topic)
|
||||
async def test_write_content(language: str, topic: str, directory: Dict, context):
|
||||
ret = await WriteContent(language=language, directory=directory, context=context).run(topic=topic)
|
||||
assert isinstance(ret, str)
|
||||
assert list(directory.keys())[0] in ret
|
||||
for value in list(directory.values())[0]:
|
||||
|
|
|
|||
|
|
@ -10,13 +10,12 @@ from pathlib import Path
|
|||
|
||||
import pytest
|
||||
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.learn.skill_loader import SkillsDeclaration
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_suite():
|
||||
CONFIG.agent_skills = [
|
||||
async def test_suite(context):
|
||||
context.kwargs.agent_skills = [
|
||||
{"id": 1, "name": "text_to_speech", "type": "builtin", "config": {}, "enabled": True},
|
||||
{"id": 2, "name": "text_to_image", "type": "builtin", "config": {}, "enabled": True},
|
||||
{"id": 3, "name": "ai_call", "type": "builtin", "config": {}, "enabled": True},
|
||||
|
|
@ -27,7 +26,7 @@ async def test_suite():
|
|||
]
|
||||
pathname = Path(__file__).parent / "../../../docs/.well-known/skills.yaml"
|
||||
loader = await SkillsDeclaration.load(skill_yaml_file_name=pathname)
|
||||
skills = loader.get_skill_list()
|
||||
skills = loader.get_skill_list(context=context)
|
||||
assert skills
|
||||
assert len(skills) >= 3
|
||||
for desc, name in skills.items():
|
||||
|
|
|
|||
|
|
@ -6,19 +6,33 @@
|
|||
@File : test_text_to_embedding.py
|
||||
@Desc : Unit tests.
|
||||
"""
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.config2 import Config
|
||||
from metagpt.learn.text_to_embedding import text_to_embedding
|
||||
from metagpt.utils.common import aread
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_text_to_embedding():
|
||||
# Prerequisites
|
||||
assert CONFIG.OPENAI_API_KEY
|
||||
async def test_text_to_embedding(mocker):
|
||||
# mock
|
||||
config = Config.default()
|
||||
mock_post = mocker.patch("aiohttp.ClientSession.post")
|
||||
mock_response = mocker.AsyncMock()
|
||||
mock_response.status = 200
|
||||
data = await aread(Path(__file__).parent / "../../data/openai/embedding.json")
|
||||
mock_response.json.return_value = json.loads(data)
|
||||
mock_post.return_value.__aenter__.return_value = mock_response
|
||||
config.get_openai_llm().proxy = mocker.PropertyMock(return_value="http://mock.proxy")
|
||||
|
||||
v = await text_to_embedding(text="Panda emoji")
|
||||
# Prerequisites
|
||||
assert config.get_openai_llm().api_key
|
||||
assert config.get_openai_llm().proxy
|
||||
|
||||
v = await text_to_embedding(text="Panda emoji", config=config)
|
||||
assert len(v.data) > 0
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -6,11 +6,13 @@
|
|||
@File : test_text_to_image.py
|
||||
@Desc : Unit tests.
|
||||
"""
|
||||
import base64
|
||||
|
||||
|
||||
import openai
|
||||
import pytest
|
||||
from pydantic import BaseModel
|
||||
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.config2 import Config
|
||||
from metagpt.learn.text_to_image import text_to_image
|
||||
from metagpt.tools.metagpt_text_to_image import MetaGPTText2Image
|
||||
from metagpt.tools.openai_text_to_image import OpenAIText2Image
|
||||
|
|
@ -24,23 +26,37 @@ async def test_text_to_image(mocker):
|
|||
mocker.patch.object(OpenAIText2Image, "text_2_image", return_value=b"mock OpenAIText2Image")
|
||||
mocker.patch.object(S3, "cache", return_value="http://mock/s3")
|
||||
|
||||
# Prerequisites
|
||||
assert CONFIG.METAGPT_TEXT_TO_IMAGE_MODEL_URL
|
||||
assert CONFIG.OPENAI_API_KEY
|
||||
config = Config.default()
|
||||
assert config.METAGPT_TEXT_TO_IMAGE_MODEL_URL
|
||||
|
||||
data = await text_to_image("Panda emoji", size_type="512x512")
|
||||
data = await text_to_image("Panda emoji", size_type="512x512", config=config)
|
||||
assert "base64" in data or "http" in data
|
||||
|
||||
# Mock session env
|
||||
old_options = CONFIG.options.copy()
|
||||
new_options = old_options.copy()
|
||||
new_options["METAGPT_TEXT_TO_IMAGE_MODEL_URL"] = None
|
||||
CONFIG.set_context(new_options)
|
||||
try:
|
||||
data = await text_to_image("Panda emoji", size_type="512x512")
|
||||
assert "base64" in data or "http" in data
|
||||
finally:
|
||||
CONFIG.set_context(old_options)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_openai_text_to_image(mocker):
|
||||
# mocker
|
||||
mock_url = mocker.Mock()
|
||||
mock_url.url.return_value = "http://mock.com/0.png"
|
||||
|
||||
class _MockData(BaseModel):
|
||||
data: list
|
||||
|
||||
mock_data = _MockData(data=[mock_url])
|
||||
mocker.patch.object(openai.resources.images.AsyncImages, "generate", return_value=mock_data)
|
||||
mock_post = mocker.patch("aiohttp.ClientSession.get")
|
||||
mock_response = mocker.AsyncMock()
|
||||
mock_response.status = 200
|
||||
mock_response.read.return_value = base64.b64encode(b"success")
|
||||
mock_post.return_value.__aenter__.return_value = mock_response
|
||||
mocker.patch.object(S3, "cache", return_value="http://mock.s3.com/0.png")
|
||||
|
||||
config = Config.default()
|
||||
config.METAGPT_TEXT_TO_IMAGE_MODEL_URL = None
|
||||
assert config.get_openai_llm()
|
||||
|
||||
data = await text_to_image("Panda emoji", size_type="512x512", config=config)
|
||||
assert "base64" in data or "http" in data
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
|||
|
|
@ -8,35 +8,65 @@
|
|||
"""
|
||||
|
||||
import pytest
|
||||
from azure.cognitiveservices.speech import ResultReason, SpeechSynthesizer
|
||||
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.config2 import Config
|
||||
from metagpt.learn.text_to_speech import text_to_speech
|
||||
from metagpt.tools.iflytek_tts import IFlyTekTTS
|
||||
from metagpt.utils.s3 import S3
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_text_to_speech():
|
||||
# Prerequisites
|
||||
assert CONFIG.IFLYTEK_APP_ID
|
||||
assert CONFIG.IFLYTEK_API_KEY
|
||||
assert CONFIG.IFLYTEK_API_SECRET
|
||||
assert CONFIG.AZURE_TTS_SUBSCRIPTION_KEY and CONFIG.AZURE_TTS_SUBSCRIPTION_KEY != "YOUR_API_KEY"
|
||||
assert CONFIG.AZURE_TTS_REGION
|
||||
async def test_azure_text_to_speech(mocker):
|
||||
# mock
|
||||
config = Config.default()
|
||||
config.IFLYTEK_API_KEY = None
|
||||
config.IFLYTEK_API_SECRET = None
|
||||
config.IFLYTEK_APP_ID = None
|
||||
mock_result = mocker.Mock()
|
||||
mock_result.audio_data = b"mock audio data"
|
||||
mock_result.reason = ResultReason.SynthesizingAudioCompleted
|
||||
mock_data = mocker.Mock()
|
||||
mock_data.get.return_value = mock_result
|
||||
mocker.patch.object(SpeechSynthesizer, "speak_ssml_async", return_value=mock_data)
|
||||
mocker.patch.object(S3, "cache", return_value="http://mock.s3.com/1.wav")
|
||||
|
||||
# Prerequisites
|
||||
assert not config.IFLYTEK_APP_ID
|
||||
assert not config.IFLYTEK_API_KEY
|
||||
assert not config.IFLYTEK_API_SECRET
|
||||
assert config.AZURE_TTS_SUBSCRIPTION_KEY and config.AZURE_TTS_SUBSCRIPTION_KEY != "YOUR_API_KEY"
|
||||
assert config.AZURE_TTS_REGION
|
||||
|
||||
config.copy()
|
||||
# test azure
|
||||
data = await text_to_speech("panda emoji")
|
||||
data = await text_to_speech("panda emoji", config=config)
|
||||
assert "base64" in data or "http" in data
|
||||
|
||||
# test iflytek
|
||||
## Mock session env
|
||||
old_options = CONFIG.options.copy()
|
||||
new_options = old_options.copy()
|
||||
new_options["AZURE_TTS_SUBSCRIPTION_KEY"] = ""
|
||||
CONFIG.set_context(new_options)
|
||||
try:
|
||||
data = await text_to_speech("panda emoji")
|
||||
assert "base64" in data or "http" in data
|
||||
finally:
|
||||
CONFIG.set_context(old_options)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_iflytek_text_to_speech(mocker):
|
||||
# mock
|
||||
config = Config.default()
|
||||
config.AZURE_TTS_SUBSCRIPTION_KEY = None
|
||||
config.AZURE_TTS_REGION = None
|
||||
mocker.patch.object(IFlyTekTTS, "synthesize_speech", return_value=None)
|
||||
mock_data = mocker.AsyncMock()
|
||||
mock_data.read.return_value = b"mock iflytek"
|
||||
mock_reader = mocker.patch("aiofiles.open")
|
||||
mock_reader.return_value.__aenter__.return_value = mock_data
|
||||
mocker.patch.object(S3, "cache", return_value="http://mock.s3.com/1.mp3")
|
||||
|
||||
# Prerequisites
|
||||
assert config.IFLYTEK_APP_ID
|
||||
assert config.IFLYTEK_API_KEY
|
||||
assert config.IFLYTEK_API_SECRET
|
||||
assert not config.AZURE_TTS_SUBSCRIPTION_KEY or config.AZURE_TTS_SUBSCRIPTION_KEY == "YOUR_API_KEY"
|
||||
assert not config.AZURE_TTS_REGION
|
||||
|
||||
# test azure
|
||||
data = await text_to_speech("panda emoji", config=config)
|
||||
assert "base64" in data or "http" in data
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
import pytest
|
||||
|
||||
from metagpt.config import LLMProviderEnum
|
||||
from metagpt.llm import LLM
|
||||
from metagpt.memory.brain_memory import BrainMemory
|
||||
from metagpt.schema import Message
|
||||
|
|
@ -46,7 +45,7 @@ def test_extract_info(input, tag, val):
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize("llm", [LLM(provider=LLMProviderEnum.OPENAI), LLM(provider=LLMProviderEnum.METAGPT)])
|
||||
@pytest.mark.parametrize("llm", [LLM()])
|
||||
async def test_memory_llm(llm):
|
||||
memory = BrainMemory()
|
||||
for i in range(500):
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
@Desc : unittest of `metagpt/memory/longterm_memory.py`
|
||||
@Modified By: mashenquan, 2023/8/20. Remove global configuration `CONFIG`, enable configuration support for business isolation.
|
||||
"""
|
||||
|
||||
import os
|
||||
|
|
@ -10,17 +9,15 @@ import os
|
|||
import pytest
|
||||
|
||||
from metagpt.actions import UserRequirement
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.config2 import config
|
||||
from metagpt.memory.longterm_memory import LongTermMemory
|
||||
from metagpt.roles.role import RoleContext
|
||||
from metagpt.schema import Message
|
||||
|
||||
os.environ.setdefault("OPENAI_API_KEY", config.get_openai_llm().api_key)
|
||||
|
||||
|
||||
def test_ltm_search():
|
||||
assert hasattr(CONFIG, "long_term_memory") is True
|
||||
os.environ.setdefault("OPENAI_API_KEY", CONFIG.openai_api_key)
|
||||
assert len(CONFIG.openai_api_key) > 20
|
||||
|
||||
role_id = "UTUserLtm(Product Manager)"
|
||||
from metagpt.environment import Environment
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ def test_memory():
|
|||
messages = memory.get_by_action(UserRequirement)
|
||||
assert len(messages) == 2
|
||||
|
||||
messages = memory.get_by_actions([UserRequirement])
|
||||
messages = memory.get_by_actions({UserRequirement})
|
||||
assert len(messages) == 2
|
||||
|
||||
messages = memory.try_remember("test message")
|
||||
|
|
|
|||
|
|
@ -11,12 +11,12 @@ from typing import List
|
|||
|
||||
from metagpt.actions import UserRequirement, WritePRD
|
||||
from metagpt.actions.action_node import ActionNode
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.config2 import config
|
||||
from metagpt.const import DATA_PATH
|
||||
from metagpt.memory.memory_storage import MemoryStorage
|
||||
from metagpt.schema import Message
|
||||
|
||||
os.environ.setdefault("OPENAI_API_KEY", CONFIG.openai_api_key)
|
||||
os.environ.setdefault("OPENAI_API_KEY", config.get_openai_llm().api_key)
|
||||
|
||||
|
||||
def test_idea_message():
|
||||
|
|
|
|||
44
tests/metagpt/provider/mock_llm_config.py
Normal file
44
tests/metagpt/provider/mock_llm_config.py
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
@Time : 2024/1/8 17:03
|
||||
@Author : alexanderwu
|
||||
@File : mock_llm_config.py
|
||||
"""
|
||||
|
||||
from metagpt.configs.llm_config import LLMConfig
|
||||
|
||||
mock_llm_config = LLMConfig(
|
||||
llm_type="mock",
|
||||
api_key="mock_api_key",
|
||||
base_url="mock_base_url",
|
||||
app_id="mock_app_id",
|
||||
api_secret="mock_api_secret",
|
||||
domain="mock_domain",
|
||||
)
|
||||
|
||||
|
||||
mock_llm_config_proxy = LLMConfig(
|
||||
llm_type="mock",
|
||||
api_key="mock_api_key",
|
||||
base_url="mock_base_url",
|
||||
proxy="http://localhost:8080",
|
||||
)
|
||||
|
||||
|
||||
mock_llm_config_azure = LLMConfig(
|
||||
llm_type="azure",
|
||||
api_version="2023-09-01-preview",
|
||||
api_key="mock_api_key",
|
||||
base_url="mock_base_url",
|
||||
proxy="http://localhost:8080",
|
||||
)
|
||||
|
||||
|
||||
mock_llm_config_zhipu = LLMConfig(
|
||||
llm_type="zhipu",
|
||||
api_key="mock_api_key.zhipu",
|
||||
base_url="mock_base_url",
|
||||
model="mock_zhipu_model",
|
||||
proxy="http://localhost:8080",
|
||||
)
|
||||
|
|
@ -6,10 +6,8 @@
|
|||
import pytest
|
||||
from anthropic.resources.completions import Completion
|
||||
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.provider.anthropic_api import Claude2
|
||||
|
||||
CONFIG.anthropic_api_key = "xxx"
|
||||
from tests.metagpt.provider.mock_llm_config import mock_llm_config
|
||||
|
||||
prompt = "who are you"
|
||||
resp = "I'am Claude2"
|
||||
|
|
@ -25,10 +23,10 @@ async def mock_anthropic_acompletions_create(self, model: str, prompt: str, max_
|
|||
|
||||
def test_claude2_ask(mocker):
|
||||
mocker.patch("anthropic.resources.completions.Completions.create", mock_anthropic_completions_create)
|
||||
assert resp == Claude2().ask(prompt)
|
||||
assert resp == Claude2(mock_llm_config).ask(prompt)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_claude2_aask(mocker):
|
||||
mocker.patch("anthropic.resources.completions.AsyncCompletions.create", mock_anthropic_acompletions_create)
|
||||
assert resp == await Claude2().aask(prompt)
|
||||
assert resp == await Claude2(mock_llm_config).aask(prompt)
|
||||
|
|
|
|||
12
tests/metagpt/provider/test_azure_llm.py
Normal file
12
tests/metagpt/provider/test_azure_llm.py
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# @Desc :
|
||||
|
||||
from metagpt.provider import AzureOpenAILLM
|
||||
from tests.metagpt.provider.mock_llm_config import mock_llm_config_azure
|
||||
|
||||
|
||||
def test_azure_llm():
|
||||
llm = AzureOpenAILLM(mock_llm_config_azure)
|
||||
kwargs = llm._make_client_kwargs()
|
||||
assert kwargs["azure_endpoint"] == mock_llm_config_azure.base_url
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# @Desc :
|
||||
|
||||
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.provider.azure_openai_api import AzureOpenAILLM
|
||||
|
||||
CONFIG.OPENAI_API_VERSION = "xx"
|
||||
CONFIG.openai_proxy = "http://127.0.0.1:80" # fake value
|
||||
|
||||
|
||||
def test_azure_openai_api():
|
||||
_ = AzureOpenAILLM()
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
import pytest
|
||||
|
||||
from metagpt.configs.llm_config import LLMConfig
|
||||
from metagpt.provider.base_llm import BaseLLM
|
||||
from metagpt.schema import Message
|
||||
|
||||
|
|
@ -28,6 +29,9 @@ resp_content = default_chat_resp["choices"][0]["message"]["content"]
|
|||
|
||||
|
||||
class MockBaseLLM(BaseLLM):
|
||||
def __init__(self, config: LLMConfig = None):
|
||||
pass
|
||||
|
||||
def completion(self, messages: list[dict], timeout=3):
|
||||
return default_chat_resp
|
||||
|
||||
|
|
@ -102,5 +106,5 @@ async def test_async_base_llm():
|
|||
resp = await base_llm.aask_batch([prompt_msg])
|
||||
assert resp == resp_content
|
||||
|
||||
resp = await base_llm.aask_code([prompt_msg])
|
||||
assert resp == resp_content
|
||||
# resp = await base_llm.aask_code([prompt_msg])
|
||||
# assert resp == resp_content
|
||||
|
|
@ -13,17 +13,13 @@ from openai.types.chat.chat_completion_chunk import Choice as AChoice
|
|||
from openai.types.chat.chat_completion_chunk import ChoiceDelta
|
||||
from openai.types.completion_usage import CompletionUsage
|
||||
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.provider.fireworks_api import (
|
||||
MODEL_GRADE_TOKEN_COSTS,
|
||||
FireworksCostManager,
|
||||
FireworksLLM,
|
||||
)
|
||||
from metagpt.utils.cost_manager import Costs
|
||||
|
||||
CONFIG.fireworks_api_key = "xxx"
|
||||
CONFIG.max_budget = 10
|
||||
CONFIG.calc_usage = True
|
||||
from tests.metagpt.provider.mock_llm_config import mock_llm_config
|
||||
|
||||
resp_content = "I'm fireworks"
|
||||
default_resp = ChatCompletion(
|
||||
|
|
@ -92,7 +88,7 @@ async def mock_openai_acompletions_create(self, stream: bool = False, **kwargs)
|
|||
async def test_fireworks_acompletion(mocker):
|
||||
mocker.patch("openai.resources.chat.completions.AsyncCompletions.create", mock_openai_acompletions_create)
|
||||
|
||||
fireworks_gpt = FireworksLLM()
|
||||
fireworks_gpt = FireworksLLM(mock_llm_config)
|
||||
fireworks_gpt.model = "llama-v2-13b-chat"
|
||||
|
||||
fireworks_gpt._update_costs(
|
||||
|
|
@ -9,10 +9,8 @@ import pytest
|
|||
from google.ai import generativelanguage as glm
|
||||
from google.generativeai.types import content_types
|
||||
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.provider.google_gemini_api import GeminiLLM
|
||||
|
||||
CONFIG.gemini_api_key = "xx"
|
||||
from tests.metagpt.provider.mock_llm_config import mock_llm_config
|
||||
|
||||
|
||||
@dataclass
|
||||
|
|
@ -62,7 +60,7 @@ async def test_gemini_acompletion(mocker):
|
|||
mock_gemini_generate_content_async,
|
||||
)
|
||||
|
||||
gemini_gpt = GeminiLLM()
|
||||
gemini_gpt = GeminiLLM(mock_llm_config)
|
||||
|
||||
assert gemini_gpt._user_msg(prompt_msg) == {"role": "user", "parts": [prompt_msg]}
|
||||
assert gemini_gpt._assistant_msg(prompt_msg) == {"role": "model", "parts": [prompt_msg]}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
import pytest
|
||||
|
||||
from metagpt.provider.human_provider import HumanProvider
|
||||
from tests.metagpt.provider.mock_llm_config import mock_llm_config
|
||||
|
||||
resp_content = "test"
|
||||
resp_exit = "exit"
|
||||
|
|
@ -13,7 +14,7 @@ resp_exit = "exit"
|
|||
@pytest.mark.asyncio
|
||||
async def test_async_human_provider(mocker):
|
||||
mocker.patch("builtins.input", lambda _: resp_content)
|
||||
human_provider = HumanProvider()
|
||||
human_provider = HumanProvider(mock_llm_config)
|
||||
|
||||
resp = human_provider.ask(resp_content)
|
||||
assert resp == resp_content
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
@Time : 2023/12/28
|
||||
@Author : mashenquan
|
||||
@File : test_metagpt_api.py
|
||||
"""
|
||||
from metagpt.config import LLMProviderEnum
|
||||
from metagpt.llm import LLM
|
||||
|
||||
|
||||
def test_llm():
|
||||
llm = LLM(provider=LLMProviderEnum.METAGPT)
|
||||
assert llm
|
||||
|
|
@ -3,13 +3,14 @@
|
|||
"""
|
||||
@Time : 2023/8/30
|
||||
@Author : mashenquan
|
||||
@File : test_metagpt_llm_api.py
|
||||
@File : test_metagpt_llm.py
|
||||
"""
|
||||
from metagpt.provider.metagpt_api import MetaGPTLLM
|
||||
from tests.metagpt.provider.mock_llm_config import mock_llm_config
|
||||
|
||||
|
||||
def test_metagpt():
|
||||
llm = MetaGPTLLM()
|
||||
llm = MetaGPTLLM(mock_llm_config)
|
||||
assert llm
|
||||
|
||||
|
||||
|
|
@ -7,8 +7,8 @@ from typing import Any, Tuple
|
|||
|
||||
import pytest
|
||||
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.provider.ollama_api import OllamaLLM
|
||||
from tests.metagpt.provider.mock_llm_config import mock_llm_config
|
||||
|
||||
prompt_msg = "who are you"
|
||||
messages = [{"role": "user", "content": prompt_msg}]
|
||||
|
|
@ -16,9 +16,6 @@ messages = [{"role": "user", "content": prompt_msg}]
|
|||
resp_content = "I'm ollama"
|
||||
default_resp = {"message": {"role": "assistant", "content": resp_content}}
|
||||
|
||||
CONFIG.ollama_api_base = "http://xxx"
|
||||
CONFIG.max_budget = 10
|
||||
|
||||
|
||||
async def mock_ollama_arequest(self, stream: bool = False, **kwargs) -> Tuple[Any, Any, bool]:
|
||||
if stream:
|
||||
|
|
@ -44,7 +41,7 @@ async def mock_ollama_arequest(self, stream: bool = False, **kwargs) -> Tuple[An
|
|||
async def test_gemini_acompletion(mocker):
|
||||
mocker.patch("metagpt.provider.general_api_requestor.GeneralAPIRequestor.arequest", mock_ollama_arequest)
|
||||
|
||||
ollama_gpt = OllamaLLM()
|
||||
ollama_gpt = OllamaLLM(mock_llm_config)
|
||||
|
||||
resp = await ollama_gpt.acompletion(messages)
|
||||
assert resp["message"]["content"] == default_resp["message"]["content"]
|
||||
|
|
|
|||
|
|
@ -13,12 +13,9 @@ from openai.types.chat.chat_completion_chunk import Choice as AChoice
|
|||
from openai.types.chat.chat_completion_chunk import ChoiceDelta
|
||||
from openai.types.completion_usage import CompletionUsage
|
||||
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.provider.open_llm_api import OpenLLM
|
||||
from metagpt.utils.cost_manager import Costs
|
||||
|
||||
CONFIG.max_budget = 10
|
||||
CONFIG.calc_usage = True
|
||||
from tests.metagpt.provider.mock_llm_config import mock_llm_config
|
||||
|
||||
resp_content = "I'm llama2"
|
||||
default_resp = ChatCompletion(
|
||||
|
|
@ -71,7 +68,7 @@ async def mock_openai_acompletions_create(self, stream: bool = False, **kwargs)
|
|||
async def test_openllm_acompletion(mocker):
|
||||
mocker.patch("openai.resources.chat.completions.AsyncCompletions.create", mock_openai_acompletions_create)
|
||||
|
||||
openllm_gpt = OpenLLM()
|
||||
openllm_gpt = OpenLLM(mock_llm_config)
|
||||
openllm_gpt.model = "llama-v2-13b-chat"
|
||||
|
||||
openllm_gpt._update_costs(usage=CompletionUsage(prompt_tokens=100, completion_tokens=100, total_tokens=200))
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
from unittest.mock import Mock
|
||||
|
||||
import pytest
|
||||
from openai.types.chat import (
|
||||
ChatCompletion,
|
||||
|
|
@ -9,134 +7,92 @@ from openai.types.chat import (
|
|||
from openai.types.chat.chat_completion import Choice
|
||||
from openai.types.chat.chat_completion_message_tool_call import Function
|
||||
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.const import TEST_DATA_PATH
|
||||
from metagpt.llm import LLM
|
||||
from metagpt.logs import logger
|
||||
from metagpt.provider.openai_api import OpenAILLM
|
||||
from metagpt.provider import OpenAILLM
|
||||
from tests.metagpt.provider.mock_llm_config import (
|
||||
mock_llm_config,
|
||||
mock_llm_config_proxy,
|
||||
)
|
||||
|
||||
CONFIG.openai_proxy = None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_text_to_speech():
|
||||
llm = LLM()
|
||||
resp = await llm.atext_to_speech(
|
||||
model="tts-1",
|
||||
voice="alloy",
|
||||
input="人生说起来长,但直到一个岁月回头看,许多事件仅是仓促的。一段一段拼凑一起,合成了人生。苦难当头时,当下不免觉得是折磨;回头看,也不够是一段短短的人生旅程。",
|
||||
)
|
||||
assert 200 == resp.response.status_code
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_speech_to_text():
|
||||
llm = LLM()
|
||||
audio_file = open(f"{TEST_DATA_PATH}/audio/hello.mp3", "rb")
|
||||
resp = await llm.aspeech_to_text(file=audio_file, model="whisper-1")
|
||||
assert "你好" == resp.text
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def tool_calls_rsp():
|
||||
function_rsps = [
|
||||
Function(arguments='{\n"language": "python",\n"code": "print(\'hello world\')"}', name="execute"),
|
||||
Function(arguments='{\n"language": "python",\n"code": \'print("hello world")\'}', name="execute"),
|
||||
Function(arguments='{\n"language": \'python\',\n"code": "print(\'hello world\')"}', name="execute"),
|
||||
Function(arguments='{\n"language": "python",\n"code": "print(\'hello world\')"}', name="execute"),
|
||||
Function(arguments='{\n"language": "python",\n"code": ```print("hello world")```}', name="execute"),
|
||||
Function(arguments='{\n"language": "python",\n"code": """print("hello world")"""}', name="execute"),
|
||||
Function(arguments='\nprint("hello world")\\n', name="execute"),
|
||||
# only `{` in arguments
|
||||
Function(arguments='{\n"language": "python",\n"code": "print(\'hello world\')"', name="execute"),
|
||||
# no `{`, `}` in arguments
|
||||
Function(arguments='\n"language": "python",\n"code": "print(\'hello world\')"', name="execute"),
|
||||
]
|
||||
tool_calls = [
|
||||
ChatCompletionMessageToolCall(type="function", id=f"call_{i}", function=f) for i, f in enumerate(function_rsps)
|
||||
]
|
||||
messages = [ChatCompletionMessage(content=None, role="assistant", tool_calls=[t]) for t in tool_calls]
|
||||
# 添加一个纯文本响应
|
||||
messages.append(
|
||||
ChatCompletionMessage(content="Completed a python code for hello world!", role="assistant", tool_calls=None)
|
||||
)
|
||||
# 添加 openai tool calls respond bug, code 出现在ChatCompletionMessage.content中
|
||||
messages.extend(
|
||||
[
|
||||
ChatCompletionMessage(content="```python\nprint('hello world')```", role="assistant", tool_calls=None),
|
||||
ChatCompletionMessage(content="'''python\nprint('hello world')'''", role="assistant", tool_calls=None),
|
||||
ChatCompletionMessage(content='"""python\nprint(\'hello world\')"""', role="assistant", tool_calls=None),
|
||||
ChatCompletionMessage(content="'''python\nprint(\"hello world\")'''", role="assistant", tool_calls=None),
|
||||
ChatCompletionMessage(content="```python\nprint('hello world')```", role="assistant", tool_calls=None),
|
||||
]
|
||||
)
|
||||
choices = [
|
||||
Choice(finish_reason="tool_calls", logprobs=None, index=i, message=msg) for i, msg in enumerate(messages)
|
||||
]
|
||||
return [
|
||||
ChatCompletion(id=str(i), choices=[c], created=i, model="gpt-4", object="chat.completion")
|
||||
for i, c in enumerate(choices)
|
||||
]
|
||||
|
||||
|
||||
class TestOpenAI:
|
||||
@pytest.fixture
|
||||
def config(self):
|
||||
return Mock(
|
||||
openai_api_key="test_key",
|
||||
OPENAI_API_KEY="test_key",
|
||||
openai_base_url="test_url",
|
||||
OPENAI_BASE_URL="test_url",
|
||||
openai_proxy=None,
|
||||
openai_api_type="other",
|
||||
)
|
||||
|
||||
@pytest.fixture
|
||||
def config_azure(self):
|
||||
return Mock(
|
||||
openai_api_key="test_key",
|
||||
OPENAI_API_KEY="test_key",
|
||||
openai_api_version="test_version",
|
||||
openai_base_url="test_url",
|
||||
OPENAI_BASE_URL="test_url",
|
||||
openai_proxy=None,
|
||||
openai_api_type="azure",
|
||||
)
|
||||
|
||||
@pytest.fixture
|
||||
def config_proxy(self):
|
||||
return Mock(
|
||||
openai_api_key="test_key",
|
||||
OPENAI_API_KEY="test_key",
|
||||
openai_base_url="test_url",
|
||||
OPENAI_BASE_URL="test_url",
|
||||
openai_proxy="http://proxy.com",
|
||||
openai_api_type="other",
|
||||
)
|
||||
|
||||
@pytest.fixture
|
||||
def config_azure_proxy(self):
|
||||
return Mock(
|
||||
openai_api_key="test_key",
|
||||
OPENAI_API_KEY="test_key",
|
||||
openai_api_version="test_version",
|
||||
openai_base_url="test_url",
|
||||
OPENAI_BASE_URL="test_url",
|
||||
openai_proxy="http://proxy.com",
|
||||
openai_api_type="azure",
|
||||
)
|
||||
|
||||
@pytest.fixture
|
||||
def tool_calls_rsp(self):
|
||||
function_rsps = [
|
||||
Function(arguments='{\n"language": "python",\n"code": "print(\'hello world\')"}', name="execute"),
|
||||
Function(arguments='{\n"language": "python",\n"code": \'print("hello world")\'}', name="execute"),
|
||||
Function(arguments='{\n"language": \'python\',\n"code": "print(\'hello world\')"}', name="execute"),
|
||||
Function(arguments='{\n"language": "python",\n"code": "print(\'hello world\')"}', name="execute"),
|
||||
Function(arguments='{\n"language": "python",\n"code": ```print("hello world")```}', name="execute"),
|
||||
Function(arguments='{\n"language": "python",\n"code": """print("hello world")"""}', name="execute"),
|
||||
Function(arguments='\nprint("hello world")\\n', name="execute"),
|
||||
# only `{` in arguments
|
||||
Function(arguments='{\n"language": "python",\n"code": "print(\'hello world\')"', name="execute"),
|
||||
# no `{`, `}` in arguments
|
||||
Function(arguments='\n"language": "python",\n"code": "print(\'hello world\')"', name="execute"),
|
||||
]
|
||||
tool_calls = [
|
||||
ChatCompletionMessageToolCall(type="function", id=f"call_{i}", function=f)
|
||||
for i, f in enumerate(function_rsps)
|
||||
]
|
||||
messages = [ChatCompletionMessage(content=None, role="assistant", tool_calls=[t]) for t in tool_calls]
|
||||
# 添加一个纯文本响应
|
||||
messages.append(
|
||||
ChatCompletionMessage(content="Completed a python code for hello world!", role="assistant", tool_calls=None)
|
||||
)
|
||||
# 添加 openai tool calls respond bug, code 出现在ChatCompletionMessage.content中
|
||||
messages.extend(
|
||||
[
|
||||
ChatCompletionMessage(content="```python\nprint('hello world')```", role="assistant", tool_calls=None),
|
||||
ChatCompletionMessage(content="'''python\nprint('hello world')'''", role="assistant", tool_calls=None),
|
||||
ChatCompletionMessage(
|
||||
content='"""python\nprint(\'hello world\')"""', role="assistant", tool_calls=None
|
||||
),
|
||||
ChatCompletionMessage(
|
||||
content="'''python\nprint(\"hello world\")'''", role="assistant", tool_calls=None
|
||||
),
|
||||
ChatCompletionMessage(content="```python\nprint('hello world')```", role="assistant", tool_calls=None),
|
||||
]
|
||||
)
|
||||
choices = [
|
||||
Choice(finish_reason="tool_calls", logprobs=None, index=i, message=msg) for i, msg in enumerate(messages)
|
||||
]
|
||||
return [
|
||||
ChatCompletion(id=str(i), choices=[c], created=i, model="gpt-4", object="chat.completion")
|
||||
for i, c in enumerate(choices)
|
||||
]
|
||||
|
||||
def test_make_client_kwargs_without_proxy(self, config):
|
||||
instance = OpenAILLM()
|
||||
instance.config = config
|
||||
def test_make_client_kwargs_without_proxy(self):
|
||||
instance = OpenAILLM(mock_llm_config)
|
||||
kwargs = instance._make_client_kwargs()
|
||||
assert kwargs == {"api_key": "test_key", "base_url": "test_url"}
|
||||
assert kwargs["api_key"] == "mock_api_key"
|
||||
assert kwargs["base_url"] == "mock_base_url"
|
||||
assert "http_client" not in kwargs
|
||||
|
||||
def test_make_client_kwargs_without_proxy_azure(self, config_azure):
|
||||
instance = OpenAILLM()
|
||||
instance.config = config_azure
|
||||
kwargs = instance._make_client_kwargs()
|
||||
assert kwargs == {"api_key": "test_key", "base_url": "test_url"}
|
||||
assert "http_client" not in kwargs
|
||||
|
||||
def test_make_client_kwargs_with_proxy(self, config_proxy):
|
||||
instance = OpenAILLM()
|
||||
instance.config = config_proxy
|
||||
kwargs = instance._make_client_kwargs()
|
||||
assert "http_client" in kwargs
|
||||
|
||||
def test_make_client_kwargs_with_proxy_azure(self, config_azure_proxy):
|
||||
instance = OpenAILLM()
|
||||
instance.config = config_azure_proxy
|
||||
def test_make_client_kwargs_with_proxy(self):
|
||||
instance = OpenAILLM(mock_llm_config_proxy)
|
||||
kwargs = instance._make_client_kwargs()
|
||||
assert "http_client" in kwargs
|
||||
|
||||
def test_get_choice_function_arguments_for_aask_code(self, tool_calls_rsp):
|
||||
instance = OpenAILLM()
|
||||
instance = OpenAILLM(mock_llm_config_proxy)
|
||||
for i, rsp in enumerate(tool_calls_rsp):
|
||||
code = instance.get_choice_function_arguments(rsp)
|
||||
logger.info(f"\ntest get function call arguments {i}: {code}")
|
||||
|
|
|
|||
|
|
@ -4,14 +4,9 @@
|
|||
|
||||
import pytest
|
||||
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.config2 import Config
|
||||
from metagpt.provider.spark_api import GetMessageFromWeb, SparkLLM
|
||||
|
||||
CONFIG.spark_appid = "xxx"
|
||||
CONFIG.spark_api_secret = "xxx"
|
||||
CONFIG.spark_api_key = "xxx"
|
||||
CONFIG.domain = "xxxxxx"
|
||||
CONFIG.spark_url = "xxxx"
|
||||
from tests.metagpt.provider.mock_llm_config import mock_llm_config
|
||||
|
||||
prompt_msg = "who are you"
|
||||
resp_content = "I'm Spark"
|
||||
|
|
@ -28,8 +23,8 @@ class MockWebSocketApp(object):
|
|||
def test_get_msg_from_web(mocker):
|
||||
mocker.patch("websocket.WebSocketApp", MockWebSocketApp)
|
||||
|
||||
get_msg_from_web = GetMessageFromWeb(text=prompt_msg)
|
||||
assert get_msg_from_web.gen_params()["parameter"]["chat"]["domain"] == "xxxxxx"
|
||||
get_msg_from_web = GetMessageFromWeb(prompt_msg, mock_llm_config)
|
||||
assert get_msg_from_web.gen_params()["parameter"]["chat"]["domain"] == "mock_domain"
|
||||
|
||||
ret = get_msg_from_web.run()
|
||||
assert ret == ""
|
||||
|
|
@ -39,11 +34,19 @@ def mock_spark_get_msg_from_web_run(self) -> str:
|
|||
return resp_content
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_spark_aask():
|
||||
llm = SparkLLM(Config.from_home("spark.yaml").llm)
|
||||
|
||||
resp = await llm.aask("Hello!")
|
||||
print(resp)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_spark_acompletion(mocker):
|
||||
mocker.patch("metagpt.provider.spark_api.GetMessageFromWeb.run", mock_spark_get_msg_from_web_run)
|
||||
|
||||
spark_gpt = SparkLLM()
|
||||
spark_gpt = SparkLLM(mock_llm_config)
|
||||
|
||||
resp = await spark_gpt.acompletion([])
|
||||
assert resp == resp_content
|
||||
|
|
|
|||
|
|
@ -3,47 +3,25 @@
|
|||
# @Desc : the unittest of ZhiPuAILLM
|
||||
|
||||
import pytest
|
||||
from zhipuai.utils.sse_client import Event
|
||||
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.provider.zhipuai_api import ZhiPuAILLM
|
||||
|
||||
CONFIG.zhipuai_api_key = "xxx.xxx"
|
||||
from tests.metagpt.provider.mock_llm_config import mock_llm_config_zhipu
|
||||
|
||||
prompt_msg = "who are you"
|
||||
messages = [{"role": "user", "content": prompt_msg}]
|
||||
|
||||
resp_content = "I'm chatglm-turbo"
|
||||
default_resp = {
|
||||
"code": 200,
|
||||
"data": {
|
||||
"choices": [{"role": "assistant", "content": resp_content}],
|
||||
"usage": {"prompt_tokens": 20, "completion_tokens": 20},
|
||||
},
|
||||
"choices": [{"finish_reason": "stop", "index": 0, "message": {"content": resp_content, "role": "assistant"}}],
|
||||
"usage": {"completion_tokens": 22, "prompt_tokens": 19, "total_tokens": 41},
|
||||
}
|
||||
|
||||
|
||||
def mock_zhipuai_invoke(**kwargs) -> dict:
|
||||
return default_resp
|
||||
|
||||
|
||||
async def mock_zhipuai_ainvoke(**kwargs) -> dict:
|
||||
return default_resp
|
||||
|
||||
|
||||
async def mock_zhipuai_asse_invoke(**kwargs):
|
||||
async def mock_zhipuai_acreate_stream(**kwargs):
|
||||
class MockResponse(object):
|
||||
async def _aread(self):
|
||||
class Iterator(object):
|
||||
events = [
|
||||
Event(id="xxx", event="add", data=resp_content, retry=0),
|
||||
Event(
|
||||
id="xxx",
|
||||
event="finish",
|
||||
data="",
|
||||
meta='{"usage": {"completion_tokens": 20,"prompt_tokens": 20}}',
|
||||
),
|
||||
]
|
||||
events = [{"choices": [{"index": 0, "delta": {"content": resp_content, "role": "assistant"}}]}]
|
||||
|
||||
async def __aiter__(self):
|
||||
for event in self.events:
|
||||
|
|
@ -52,23 +30,26 @@ async def mock_zhipuai_asse_invoke(**kwargs):
|
|||
async for chunk in Iterator():
|
||||
yield chunk
|
||||
|
||||
async def async_events(self):
|
||||
async def stream(self):
|
||||
async for chunk in self._aread():
|
||||
yield chunk
|
||||
|
||||
return MockResponse()
|
||||
|
||||
|
||||
async def mock_zhipuai_acreate(**kwargs) -> dict:
|
||||
return default_resp
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_zhipuai_acompletion(mocker):
|
||||
mocker.patch("metagpt.provider.zhipuai.zhipu_model_api.ZhiPuModelAPI.invoke", mock_zhipuai_invoke)
|
||||
mocker.patch("metagpt.provider.zhipuai.zhipu_model_api.ZhiPuModelAPI.ainvoke", mock_zhipuai_ainvoke)
|
||||
mocker.patch("metagpt.provider.zhipuai.zhipu_model_api.ZhiPuModelAPI.asse_invoke", mock_zhipuai_asse_invoke)
|
||||
mocker.patch("metagpt.provider.zhipuai.zhipu_model_api.ZhiPuModelAPI.acreate", mock_zhipuai_acreate)
|
||||
mocker.patch("metagpt.provider.zhipuai.zhipu_model_api.ZhiPuModelAPI.acreate_stream", mock_zhipuai_acreate_stream)
|
||||
|
||||
zhipu_gpt = ZhiPuAILLM()
|
||||
zhipu_gpt = ZhiPuAILLM(mock_llm_config_zhipu)
|
||||
|
||||
resp = await zhipu_gpt.acompletion(messages)
|
||||
assert resp["data"]["choices"][0]["content"] == resp_content
|
||||
assert resp["choices"][0]["message"]["content"] == resp_content
|
||||
|
||||
resp = await zhipu_gpt.aask(prompt_msg, stream=False)
|
||||
assert resp == resp_content
|
||||
|
|
@ -84,6 +65,7 @@ async def test_zhipuai_acompletion(mocker):
|
|||
|
||||
|
||||
def test_zhipuai_proxy():
|
||||
# CONFIG.openai_proxy = "http://127.0.0.1:8080"
|
||||
_ = ZhiPuAILLM()
|
||||
# assert openai.proxy == CONFIG.openai_proxy
|
||||
# it seems like zhipuai would be inflected by the proxy of openai, maybe it's a bug
|
||||
# but someone may want to use openai.proxy, so we keep this test case
|
||||
# assert openai.proxy == config.llm.proxy
|
||||
_ = ZhiPuAILLM(mock_llm_config_zhipu)
|
||||
|
|
|
|||
|
|
@ -11,16 +11,16 @@ from metagpt.provider.zhipuai.async_sse_client import AsyncSSEClient
|
|||
async def test_async_sse_client():
|
||||
class Iterator(object):
|
||||
async def __aiter__(self):
|
||||
yield b"data: test_value"
|
||||
yield b'data: {"test_key": "test_value"}'
|
||||
|
||||
async_sse_client = AsyncSSEClient(event_source=Iterator())
|
||||
async for event in async_sse_client.async_events():
|
||||
assert event.data, "test_value"
|
||||
async for chunk in async_sse_client.stream():
|
||||
assert "test_value" in chunk.values()
|
||||
|
||||
class InvalidIterator(object):
|
||||
async def __aiter__(self):
|
||||
yield b"invalid: test_value"
|
||||
|
||||
async_sse_client = AsyncSSEClient(event_source=InvalidIterator())
|
||||
async for event in async_sse_client.async_events():
|
||||
assert not event
|
||||
async for chunk in async_sse_client.stream():
|
||||
assert not chunk
|
||||
|
|
|
|||
|
|
@ -6,15 +6,13 @@ from typing import Any, Tuple
|
|||
|
||||
import pytest
|
||||
import zhipuai
|
||||
from zhipuai.model_api.api import InvokeType
|
||||
from zhipuai.utils.http_client import headers as zhipuai_default_headers
|
||||
|
||||
from metagpt.provider.zhipuai.zhipu_model_api import ZhiPuModelAPI
|
||||
|
||||
api_key = "xxx.xxx"
|
||||
zhipuai.api_key = api_key
|
||||
|
||||
default_resp = b'{"result": "test response"}'
|
||||
default_resp = b'{"choices": [{"finish_reason": "stop", "index": 0, "message": {"content": "test response", "role": "assistant"}}]}'
|
||||
|
||||
|
||||
async def mock_requestor_arequest(self, **kwargs) -> Tuple[Any, Any, str]:
|
||||
|
|
@ -23,22 +21,15 @@ async def mock_requestor_arequest(self, **kwargs) -> Tuple[Any, Any, str]:
|
|||
|
||||
@pytest.mark.asyncio
|
||||
async def test_zhipu_model_api(mocker):
|
||||
header = ZhiPuModelAPI.get_header()
|
||||
zhipuai_default_headers.update({"Authorization": api_key})
|
||||
assert header == zhipuai_default_headers
|
||||
|
||||
sse_header = ZhiPuModelAPI.get_sse_header()
|
||||
assert len(sse_header["Authorization"]) == 191
|
||||
|
||||
url_prefix, url_suffix = ZhiPuModelAPI.split_zhipu_api_url(InvokeType.SYNC, kwargs={"model": "chatglm_turbo"})
|
||||
url_prefix, url_suffix = ZhiPuModelAPI(api_key=api_key).split_zhipu_api_url()
|
||||
assert url_prefix == "https://open.bigmodel.cn/api"
|
||||
assert url_suffix == "/paas/v3/model-api/chatglm_turbo/invoke"
|
||||
assert url_suffix == "/paas/v4/chat/completions"
|
||||
|
||||
mocker.patch("metagpt.provider.general_api_requestor.GeneralAPIRequestor.arequest", mock_requestor_arequest)
|
||||
result = await ZhiPuModelAPI.arequest(
|
||||
InvokeType.SYNC, stream=False, method="get", headers={}, kwargs={"model": "chatglm_turbo"}
|
||||
result = await ZhiPuModelAPI(api_key=api_key).arequest(
|
||||
stream=False, method="get", headers={}, kwargs={"model": "glm-3-turbo"}
|
||||
)
|
||||
assert result == default_resp
|
||||
|
||||
result = await ZhiPuModelAPI.ainvoke()
|
||||
assert result["result"] == "test response"
|
||||
result = await ZhiPuModelAPI(api_key=api_key).acreate()
|
||||
assert result["choices"][0]["message"]["content"] == "test response"
|
||||
|
|
|
|||
|
|
@ -9,9 +9,7 @@ from metagpt.schema import Plan
|
|||
from metagpt.utils.recovery_util import load_history, save_history
|
||||
|
||||
|
||||
async def run_code_interpreter(
|
||||
role_class, requirement, auto_run, use_tools, use_code_steps, make_udfs, use_udfs, save_dir, tools
|
||||
):
|
||||
async def run_code_interpreter(role_class, requirement, auto_run, use_tools, save_dir, tools):
|
||||
"""
|
||||
The main function to run the MLEngineer with optional history loading.
|
||||
|
||||
|
|
@ -25,16 +23,11 @@ async def run_code_interpreter(
|
|||
"""
|
||||
|
||||
if role_class == "ci":
|
||||
role = CodeInterpreter(
|
||||
goal=requirement, auto_run=auto_run, use_tools=use_tools, make_udfs=make_udfs, tools=tools
|
||||
)
|
||||
role = CodeInterpreter(auto_run=auto_run, use_tools=use_tools, tools=tools)
|
||||
else:
|
||||
role = MLEngineer(
|
||||
goal=requirement,
|
||||
auto_run=auto_run,
|
||||
use_tools=use_tools,
|
||||
use_code_steps=use_code_steps,
|
||||
make_udfs=make_udfs,
|
||||
tools=tools,
|
||||
)
|
||||
|
||||
|
|
@ -50,10 +43,10 @@ async def run_code_interpreter(
|
|||
try:
|
||||
await role.run(requirement)
|
||||
except Exception as e:
|
||||
save_path = save_history(role, save_dir)
|
||||
|
||||
logger.exception(f"An error occurred: {e}, save trajectory here: {save_path}")
|
||||
|
||||
save_history(role, save_dir)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# requirement = "Run data analysis on sklearn Iris dataset, include a plot"
|
||||
|
|
@ -73,8 +66,6 @@ if __name__ == "__main__":
|
|||
role_class = "mle"
|
||||
auto_run = True
|
||||
use_tools = True
|
||||
make_udfs = False
|
||||
use_udfs = False
|
||||
tools = []
|
||||
# tools = ["FillMissingValue", "CatCross", "non_existing_test"]
|
||||
|
||||
|
|
@ -83,14 +74,9 @@ if __name__ == "__main__":
|
|||
requirement: str = requirement,
|
||||
auto_run: bool = auto_run,
|
||||
use_tools: bool = use_tools,
|
||||
use_code_steps: bool = False,
|
||||
make_udfs: bool = make_udfs,
|
||||
use_udfs: bool = use_udfs,
|
||||
save_dir: str = save_dir,
|
||||
tools=tools,
|
||||
):
|
||||
await run_code_interpreter(
|
||||
role_class, requirement, auto_run, use_tools, use_code_steps, make_udfs, use_udfs, save_dir, tools
|
||||
)
|
||||
await run_code_interpreter(role_class, requirement, auto_run, use_tools, save_dir, tools)
|
||||
|
||||
fire.Fire(main)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import uuid
|
|||
import pytest
|
||||
|
||||
from metagpt.actions import WriteDesign, WritePRD
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.const import PRDS_FILE_REPO
|
||||
from metagpt.logs import logger
|
||||
from metagpt.roles import Architect
|
||||
|
|
@ -22,12 +21,12 @@ from tests.metagpt.roles.mock import MockMessages
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_architect():
|
||||
async def test_architect(context):
|
||||
# Prerequisites
|
||||
filename = uuid.uuid4().hex + ".json"
|
||||
await awrite(CONFIG.git_repo.workdir / PRDS_FILE_REPO / filename, data=MockMessages.prd.content)
|
||||
await awrite(context.repo.workdir / PRDS_FILE_REPO / filename, data=MockMessages.prd.content)
|
||||
|
||||
role = Architect()
|
||||
role = Architect(context=context)
|
||||
rsp = await role.run(with_message=Message(content="", cause_by=WritePRD))
|
||||
logger.info(rsp)
|
||||
assert len(rsp.content) > 0
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ from pydantic import BaseModel
|
|||
|
||||
from metagpt.actions.skill_action import SkillAction
|
||||
from metagpt.actions.talk_action import TalkAction
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.memory.brain_memory import BrainMemory
|
||||
from metagpt.roles.assistant import Assistant
|
||||
from metagpt.schema import Message
|
||||
|
|
@ -20,8 +19,11 @@ from metagpt.utils.common import any_to_str
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_run():
|
||||
CONFIG.language = "Chinese"
|
||||
async def test_run(mocker, context):
|
||||
# mock
|
||||
mocker.patch("metagpt.learn.text_to_image", return_value="http://mock.com/1.png")
|
||||
|
||||
context.kwargs.language = "Chinese"
|
||||
|
||||
class Input(BaseModel):
|
||||
memory: BrainMemory
|
||||
|
|
@ -65,7 +67,7 @@ async def test_run():
|
|||
"cause_by": any_to_str(SkillAction),
|
||||
},
|
||||
]
|
||||
CONFIG.agent_skills = [
|
||||
agent_skills = [
|
||||
{"id": 1, "name": "text_to_speech", "type": "builtin", "config": {}, "enabled": True},
|
||||
{"id": 2, "name": "text_to_image", "type": "builtin", "config": {}, "enabled": True},
|
||||
{"id": 3, "name": "ai_call", "type": "builtin", "config": {}, "enabled": True},
|
||||
|
|
@ -77,9 +79,11 @@ async def test_run():
|
|||
|
||||
for i in inputs:
|
||||
seed = Input(**i)
|
||||
CONFIG.language = seed.language
|
||||
CONFIG.agent_description = seed.agent_description
|
||||
role = Assistant(language="Chinese")
|
||||
role = Assistant(language="Chinese", context=context)
|
||||
role.context.kwargs.language = seed.language
|
||||
role.context.kwargs.agent_description = seed.agent_description
|
||||
role.context.kwargs.agent_skills = agent_skills
|
||||
|
||||
role.memory = seed.memory # Restore historical conversation content.
|
||||
while True:
|
||||
has_action = await role.think()
|
||||
|
|
@ -110,21 +114,16 @@ async def test_run():
|
|||
],
|
||||
)
|
||||
@pytest.mark.asyncio
|
||||
async def test_memory(memory):
|
||||
role = Assistant()
|
||||
async def test_memory(memory, context):
|
||||
role = Assistant(context=context)
|
||||
role.context.kwargs.agent_skills = []
|
||||
role.load_memory(memory)
|
||||
|
||||
val = role.get_memory()
|
||||
assert val
|
||||
|
||||
await role.talk("draw apple")
|
||||
|
||||
agent_skills = CONFIG.agent_skills
|
||||
CONFIG.agent_skills = []
|
||||
try:
|
||||
await role.think()
|
||||
finally:
|
||||
CONFIG.agent_skills = agent_skills
|
||||
await role.think()
|
||||
assert isinstance(role.rc.todo, TalkAction)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ from metagpt.roles.code_interpreter import CodeInterpreter
|
|||
@pytest.mark.asyncio
|
||||
async def test_code_interpreter():
|
||||
requirement = "Run data analysis on sklearn Iris dataset, include a plot"
|
||||
ci = CodeInterpreter(goal=requirement, auto_run=True, use_tools=False)
|
||||
tools = []
|
||||
|
||||
ci = CodeInterpreter(auto_run=True, use_tools=True, tools=tools)
|
||||
rsp = await ci.run(requirement)
|
||||
logger.info(rsp)
|
||||
assert len(rsp.content) > 0
|
||||
|
|
|
|||
|
|
@ -1,50 +0,0 @@
|
|||
import pytest
|
||||
from tqdm import tqdm
|
||||
|
||||
from metagpt.logs import logger
|
||||
from metagpt.roles.ml_engineer import ExecutePyCode, MLEngineer
|
||||
from metagpt.schema import Plan
|
||||
|
||||
|
||||
def reset(role):
|
||||
"""Restart role with the same goal."""
|
||||
role.working_memory.clear()
|
||||
role.planner.plan = Plan(goal=role.planner.plan.goal)
|
||||
role.execute_code = ExecutePyCode()
|
||||
|
||||
|
||||
async def make_use_tools(requirement: str, auto_run: bool = True):
|
||||
"""make and use tools for requirement."""
|
||||
role = MLEngineer(goal=requirement, auto_run=auto_run)
|
||||
# make udfs
|
||||
role.use_tools = False
|
||||
role.use_code_steps = False
|
||||
role.make_udfs = True
|
||||
role.use_udfs = False
|
||||
await role.run(requirement)
|
||||
# use udfs
|
||||
reset(role)
|
||||
role.make_udfs = False
|
||||
role.use_udfs = True
|
||||
role.use_code_steps = False
|
||||
role.use_tools = False
|
||||
await role.run(requirement)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_make_use_tools():
|
||||
requirements = [
|
||||
"Run data analysis on sklearn Iris dataset, include a plot",
|
||||
"Run data analysis on sklearn Diabetes dataset, include a plot",
|
||||
"Run data analysis on sklearn Wine recognition dataset, include a plot, and train a model to predict wine class (20% as validation), and show validation accuracy",
|
||||
"Run data analysis on sklearn Wisconsin Breast Cancer dataset, include a plot, train a model to predict targets (20% as validation), and show validation accuracy",
|
||||
"Run EDA and visualization on this dataset, train a model to predict survival, report metrics on validation set (20%), dataset: tests/data/titanic.csv",
|
||||
]
|
||||
success = 0
|
||||
for requirement in tqdm(requirements, total=len(requirements)):
|
||||
try:
|
||||
await make_use_tools(requirement)
|
||||
success += 1
|
||||
except Exception as e:
|
||||
logger.error(f"Found Error in {requirement}, {e}")
|
||||
logger.info(f"success: {round(success/len(requirements), 1)*100}%")
|
||||
|
|
@ -13,40 +13,30 @@ from pathlib import Path
|
|||
import pytest
|
||||
|
||||
from metagpt.actions import WriteCode, WriteTasks
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.const import (
|
||||
PRDS_FILE_REPO,
|
||||
REQUIREMENT_FILENAME,
|
||||
SYSTEM_DESIGN_FILE_REPO,
|
||||
TASK_FILE_REPO,
|
||||
)
|
||||
from metagpt.const import REQUIREMENT_FILENAME, SYSTEM_DESIGN_FILE_REPO, TASK_FILE_REPO
|
||||
from metagpt.logs import logger
|
||||
from metagpt.roles.engineer import Engineer
|
||||
from metagpt.schema import CodingContext, Message
|
||||
from metagpt.utils.common import CodeParser, any_to_name, any_to_str, aread, awrite
|
||||
from metagpt.utils.file_repository import FileRepository
|
||||
from metagpt.utils.git_repository import ChangeType
|
||||
from tests.metagpt.roles.mock import STRS_FOR_PARSING, TASKS, MockMessages
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_engineer():
|
||||
async def test_engineer(context):
|
||||
# Prerequisites
|
||||
rqno = "20231221155954.json"
|
||||
await FileRepository.save_file(REQUIREMENT_FILENAME, content=MockMessages.req.content)
|
||||
await FileRepository.save_file(rqno, relative_path=PRDS_FILE_REPO, content=MockMessages.prd.content)
|
||||
await FileRepository.save_file(
|
||||
rqno, relative_path=SYSTEM_DESIGN_FILE_REPO, content=MockMessages.system_design.content
|
||||
)
|
||||
await FileRepository.save_file(rqno, relative_path=TASK_FILE_REPO, content=MockMessages.json_tasks.content)
|
||||
await context.repo.save(REQUIREMENT_FILENAME, content=MockMessages.req.content)
|
||||
await context.repo.docs.prd.save(rqno, content=MockMessages.prd.content)
|
||||
await context.repo.docs.system_design.save(rqno, content=MockMessages.system_design.content)
|
||||
await context.repo.docs.task.save(rqno, content=MockMessages.json_tasks.content)
|
||||
|
||||
engineer = Engineer()
|
||||
engineer = Engineer(context=context)
|
||||
rsp = await engineer.run(Message(content="", cause_by=WriteTasks))
|
||||
|
||||
logger.info(rsp)
|
||||
assert rsp.cause_by == any_to_str(WriteCode)
|
||||
src_file_repo = CONFIG.git_repo.new_file_repository(CONFIG.src_workspace)
|
||||
assert src_file_repo.changed_files
|
||||
assert context.repo.with_src_path(context.src_workspace).srcs.changed_files
|
||||
|
||||
|
||||
def test_parse_str():
|
||||
|
|
@ -109,54 +99,52 @@ def test_parse_code():
|
|||
|
||||
def test_todo():
|
||||
role = Engineer()
|
||||
assert role.todo == any_to_name(WriteCode)
|
||||
assert role.action_description == any_to_name(WriteCode)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_new_coding_context():
|
||||
async def test_new_coding_context(context):
|
||||
# Prerequisites
|
||||
demo_path = Path(__file__).parent / "../../data/demo_project"
|
||||
deps = json.loads(await aread(demo_path / "dependencies.json"))
|
||||
dependency = await CONFIG.git_repo.get_dependency()
|
||||
dependency = await context.git_repo.get_dependency()
|
||||
for k, v in deps.items():
|
||||
await dependency.update(k, set(v))
|
||||
data = await aread(demo_path / "system_design.json")
|
||||
rqno = "20231221155954.json"
|
||||
await awrite(CONFIG.git_repo.workdir / SYSTEM_DESIGN_FILE_REPO / rqno, data)
|
||||
await awrite(context.repo.workdir / SYSTEM_DESIGN_FILE_REPO / rqno, data)
|
||||
data = await aread(demo_path / "tasks.json")
|
||||
await awrite(CONFIG.git_repo.workdir / TASK_FILE_REPO / rqno, data)
|
||||
await awrite(context.repo.workdir / TASK_FILE_REPO / rqno, data)
|
||||
|
||||
CONFIG.src_workspace = Path(CONFIG.git_repo.workdir) / "game_2048"
|
||||
src_file_repo = CONFIG.git_repo.new_file_repository(relative_path=CONFIG.src_workspace)
|
||||
task_file_repo = CONFIG.git_repo.new_file_repository(relative_path=TASK_FILE_REPO)
|
||||
design_file_repo = CONFIG.git_repo.new_file_repository(relative_path=SYSTEM_DESIGN_FILE_REPO)
|
||||
context.src_workspace = Path(context.repo.workdir) / "game_2048"
|
||||
|
||||
filename = "game.py"
|
||||
ctx_doc = await Engineer._new_coding_doc(
|
||||
filename=filename,
|
||||
src_file_repo=src_file_repo,
|
||||
task_file_repo=task_file_repo,
|
||||
design_file_repo=design_file_repo,
|
||||
dependency=dependency,
|
||||
)
|
||||
assert ctx_doc
|
||||
assert ctx_doc.filename == filename
|
||||
assert ctx_doc.content
|
||||
ctx = CodingContext.model_validate_json(ctx_doc.content)
|
||||
assert ctx.filename == filename
|
||||
assert ctx.design_doc
|
||||
assert ctx.design_doc.content
|
||||
assert ctx.task_doc
|
||||
assert ctx.task_doc.content
|
||||
assert ctx.code_doc
|
||||
try:
|
||||
filename = "game.py"
|
||||
engineer = Engineer(context=context)
|
||||
ctx_doc = await engineer._new_coding_doc(
|
||||
filename=filename,
|
||||
dependency=dependency,
|
||||
)
|
||||
assert ctx_doc
|
||||
assert ctx_doc.filename == filename
|
||||
assert ctx_doc.content
|
||||
ctx = CodingContext.model_validate_json(ctx_doc.content)
|
||||
assert ctx.filename == filename
|
||||
assert ctx.design_doc
|
||||
assert ctx.design_doc.content
|
||||
assert ctx.task_doc
|
||||
assert ctx.task_doc.content
|
||||
assert ctx.code_doc
|
||||
|
||||
CONFIG.git_repo.add_change({f"{TASK_FILE_REPO}/{rqno}": ChangeType.UNTRACTED})
|
||||
CONFIG.git_repo.commit("mock env")
|
||||
await src_file_repo.save(filename=filename, content="content")
|
||||
role = Engineer()
|
||||
assert not role.code_todos
|
||||
await role._new_code_actions()
|
||||
assert role.code_todos
|
||||
context.git_repo.add_change({f"{TASK_FILE_REPO}/{rqno}": ChangeType.UNTRACTED})
|
||||
context.git_repo.commit("mock env")
|
||||
await context.repo.with_src_path(context.src_workspace).srcs.save(filename=filename, content="content")
|
||||
role = Engineer(context=context)
|
||||
assert not role.code_todos
|
||||
await role._new_code_actions()
|
||||
assert role.code_todos
|
||||
finally:
|
||||
context.git_repo.delete_repository()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
|||
|
|
@ -41,9 +41,11 @@ from metagpt.schema import Message
|
|||
),
|
||||
],
|
||||
)
|
||||
async def test_invoice_ocr_assistant(query: str, invoice_path: Path, invoice_table_path: Path, expected_result: dict):
|
||||
async def test_invoice_ocr_assistant(
|
||||
query: str, invoice_path: Path, invoice_table_path: Path, expected_result: dict, context
|
||||
):
|
||||
invoice_path = TEST_DATA_PATH / invoice_path
|
||||
role = InvoiceOCRAssistant()
|
||||
role = InvoiceOCRAssistant(context=context)
|
||||
await role.run(Message(content=query, instruct_content=InvoicePath(file_path=invoice_path)))
|
||||
invoice_table_path = DATA_PATH / invoice_table_path
|
||||
df = pd.read_excel(invoice_table_path)
|
||||
|
|
|
|||
21
tests/metagpt/roles/test_ml_engineer.py
Normal file
21
tests/metagpt/roles/test_ml_engineer.py
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import pytest
|
||||
|
||||
from metagpt.logs import logger
|
||||
from metagpt.roles.ml_engineer import MLEngineer
|
||||
|
||||
|
||||
def test_mle_init():
|
||||
ci = MLEngineer(goal="test", auto_run=True, use_tools=True, tools=["tool1", "tool2"])
|
||||
assert ci.tools == []
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_ml_engineer():
|
||||
data_path = "tests/data/ml_datasets/titanic"
|
||||
requirement = f"This is a titanic passenger survival dataset, your goal is to predict passenger survival outcome. The target column is Survived. Perform data analysis, data preprocessing, feature engineering, and modeling to predict the target. Report accuracy on the eval data. Train data path: '{data_path}/split_train.csv', eval data path: '{data_path}/split_eval.csv'."
|
||||
tools = ["FillMissingValue", "CatCross", "dummy_tool"]
|
||||
|
||||
mle = MLEngineer(goal=requirement, auto_run=True, use_tools=True, tools=tools)
|
||||
rsp = await mle.run(requirement)
|
||||
logger.info(rsp)
|
||||
assert len(rsp.content) > 0
|
||||
|
|
@ -5,17 +5,51 @@
|
|||
@Author : alexanderwu
|
||||
@File : test_product_manager.py
|
||||
"""
|
||||
import json
|
||||
|
||||
import pytest
|
||||
|
||||
from metagpt.actions import WritePRD
|
||||
from metagpt.actions.prepare_documents import PrepareDocuments
|
||||
from metagpt.const import REQUIREMENT_FILENAME
|
||||
from metagpt.context import Context
|
||||
from metagpt.logs import logger
|
||||
from metagpt.roles import ProductManager
|
||||
from metagpt.utils.common import any_to_str
|
||||
from tests.metagpt.roles.mock import MockMessages
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_product_manager(new_filename):
|
||||
product_manager = ProductManager()
|
||||
rsp = await product_manager.run(MockMessages.req)
|
||||
logger.info(rsp)
|
||||
assert len(rsp.content) > 0
|
||||
assert rsp.content == MockMessages.req.content
|
||||
context = Context()
|
||||
try:
|
||||
assert context.git_repo is None
|
||||
assert context.repo is None
|
||||
product_manager = ProductManager(context=context)
|
||||
# prepare documents
|
||||
rsp = await product_manager.run(MockMessages.req)
|
||||
assert context.git_repo
|
||||
assert context.repo
|
||||
assert rsp.cause_by == any_to_str(PrepareDocuments)
|
||||
assert REQUIREMENT_FILENAME in context.repo.docs.changed_files
|
||||
|
||||
# write prd
|
||||
rsp = await product_manager.run(rsp)
|
||||
assert rsp.cause_by == any_to_str(WritePRD)
|
||||
logger.info(rsp)
|
||||
assert len(rsp.content) > 0
|
||||
doc = list(rsp.instruct_content.docs.values())[0]
|
||||
m = json.loads(doc.content)
|
||||
assert m["Original Requirements"] == MockMessages.req.content
|
||||
|
||||
# nothing to do
|
||||
rsp = await product_manager.run(rsp)
|
||||
assert rsp is None
|
||||
except Exception as e:
|
||||
assert not e
|
||||
finally:
|
||||
context.git_repo.delete_repository()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pytest.main([__file__, "-s"])
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ from tests.metagpt.roles.mock import MockMessages
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_project_manager():
|
||||
project_manager = ProjectManager()
|
||||
async def test_project_manager(context):
|
||||
project_manager = ProjectManager(context=context)
|
||||
rsp = await project_manager.run(MockMessages.system_design)
|
||||
logger.info(rsp)
|
||||
|
|
|
|||
|
|
@ -13,20 +13,19 @@ from pydantic import Field
|
|||
|
||||
from metagpt.actions import DebugError, RunCode, WriteTest
|
||||
from metagpt.actions.summarize_code import SummarizeCode
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.environment import Environment
|
||||
from metagpt.roles import QaEngineer
|
||||
from metagpt.schema import Message
|
||||
from metagpt.utils.common import any_to_str, aread, awrite
|
||||
|
||||
|
||||
async def test_qa():
|
||||
async def test_qa(context):
|
||||
# Prerequisites
|
||||
demo_path = Path(__file__).parent / "../../data/demo_project"
|
||||
CONFIG.src_workspace = Path(CONFIG.git_repo.workdir) / "qa/game_2048"
|
||||
context.src_workspace = Path(context.repo.workdir) / "qa/game_2048"
|
||||
data = await aread(filename=demo_path / "game.py", encoding="utf-8")
|
||||
await awrite(filename=CONFIG.src_workspace / "game.py", data=data, encoding="utf-8")
|
||||
await awrite(filename=Path(CONFIG.git_repo.workdir) / "requirements.txt", data="")
|
||||
await awrite(filename=context.src_workspace / "game.py", data=data, encoding="utf-8")
|
||||
await awrite(filename=Path(context.repo.workdir) / "requirements.txt", data="")
|
||||
|
||||
class MockEnv(Environment):
|
||||
msgs: List[Message] = Field(default_factory=list)
|
||||
|
|
@ -37,7 +36,7 @@ async def test_qa():
|
|||
|
||||
env = MockEnv()
|
||||
|
||||
role = QaEngineer()
|
||||
role = QaEngineer(context=context)
|
||||
role.set_env(env)
|
||||
await role.run(with_message=Message(content="", cause_by=SummarizeCode))
|
||||
assert env.msgs
|
||||
|
|
|
|||
|
|
@ -4,7 +4,10 @@ from tempfile import TemporaryDirectory
|
|||
|
||||
import pytest
|
||||
|
||||
from metagpt.actions.research import CollectLinks
|
||||
from metagpt.roles import researcher
|
||||
from metagpt.tools import SearchEngineType
|
||||
from metagpt.tools.search_engine import SearchEngine
|
||||
|
||||
|
||||
async def mock_llm_ask(self, prompt: str, system_msgs):
|
||||
|
|
@ -25,16 +28,20 @@ async def mock_llm_ask(self, prompt: str, system_msgs):
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_researcher(mocker):
|
||||
async def test_researcher(mocker, search_engine_mocker, context):
|
||||
with TemporaryDirectory() as dirname:
|
||||
topic = "dataiku vs. datarobot"
|
||||
mocker.patch("metagpt.provider.base_llm.BaseLLM.aask", mock_llm_ask)
|
||||
researcher.RESEARCH_PATH = Path(dirname)
|
||||
await researcher.Researcher().run(topic)
|
||||
role = researcher.Researcher(context=context)
|
||||
for i in role.actions:
|
||||
if isinstance(i, CollectLinks):
|
||||
i.search_engine = SearchEngine(SearchEngineType.DUCK_DUCK_GO)
|
||||
await role.run(topic)
|
||||
assert (researcher.RESEARCH_PATH / f"{topic}.md").read_text().startswith("# Research Report")
|
||||
|
||||
|
||||
def test_write_report(mocker):
|
||||
def test_write_report(mocker, context):
|
||||
with TemporaryDirectory() as dirname:
|
||||
for i, topic in enumerate(
|
||||
[
|
||||
|
|
@ -46,7 +53,7 @@ def test_write_report(mocker):
|
|||
):
|
||||
researcher.RESEARCH_PATH = Path(dirname)
|
||||
content = "# Research Report"
|
||||
researcher.Researcher().write_report(topic, content)
|
||||
researcher.Researcher(context=context).write_report(topic, content)
|
||||
assert (researcher.RESEARCH_PATH / f"{i+1}. metagpt.md").read_text().startswith("# Research Report")
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# @Desc : unittest of Role
|
||||
import pytest
|
||||
|
||||
from metagpt.llm import HumanProvider
|
||||
from metagpt.provider.human_provider import HumanProvider
|
||||
from metagpt.roles.role import Role
|
||||
|
||||
|
||||
|
|
@ -13,8 +13,8 @@ def test_role_desc():
|
|||
assert role.desc == "Best Seller"
|
||||
|
||||
|
||||
def test_role_human():
|
||||
role = Role(is_human=True)
|
||||
def test_role_human(context):
|
||||
role = Role(is_human=True, context=context)
|
||||
assert isinstance(role.llm, HumanProvider)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5,19 +5,17 @@
|
|||
@Author : mashenquan
|
||||
@File : test_teacher.py
|
||||
"""
|
||||
import os
|
||||
from typing import Dict, Optional
|
||||
|
||||
import pytest
|
||||
from pydantic import BaseModel
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from metagpt.config import CONFIG, Config
|
||||
from metagpt.context import Context
|
||||
from metagpt.roles.teacher import Teacher
|
||||
from metagpt.schema import Message
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.skip
|
||||
async def test_init():
|
||||
class Inputs(BaseModel):
|
||||
name: str
|
||||
|
|
@ -31,6 +29,7 @@ async def test_init():
|
|||
expect_goal: str
|
||||
expect_constraints: str
|
||||
expect_desc: str
|
||||
exclude: list = Field(default_factory=list)
|
||||
|
||||
inputs = [
|
||||
{
|
||||
|
|
@ -45,6 +44,7 @@ async def test_init():
|
|||
"kwargs": {},
|
||||
"desc": "aaa{language}",
|
||||
"expect_desc": "aaa{language}",
|
||||
"exclude": ["language", "key1", "something_big", "teaching_language"],
|
||||
},
|
||||
{
|
||||
"name": "Lily{language}",
|
||||
|
|
@ -58,20 +58,21 @@ async def test_init():
|
|||
"kwargs": {"language": "CN", "key1": "HaHa", "something_big": "sleep", "teaching_language": "EN"},
|
||||
"desc": "aaa{language}",
|
||||
"expect_desc": "aaaCN",
|
||||
"language": "CN",
|
||||
"teaching_language": "EN",
|
||||
},
|
||||
]
|
||||
|
||||
env = os.environ.copy()
|
||||
for i in inputs:
|
||||
seed = Inputs(**i)
|
||||
os.environ.clear()
|
||||
os.environ.update(env)
|
||||
CONFIG = Config()
|
||||
CONFIG.set_context(seed.kwargs)
|
||||
print(CONFIG.options)
|
||||
assert bool("language" in seed.kwargs) == bool("language" in CONFIG.options)
|
||||
context = Context()
|
||||
for k in seed.exclude:
|
||||
context.kwargs.set(k, None)
|
||||
for k, v in seed.kwargs.items():
|
||||
context.kwargs.set(k, v)
|
||||
|
||||
teacher = Teacher(
|
||||
context=context,
|
||||
name=seed.name,
|
||||
profile=seed.profile,
|
||||
goal=seed.goal,
|
||||
|
|
@ -105,7 +106,6 @@ async def test_new_file_name():
|
|||
|
||||
@pytest.mark.asyncio
|
||||
async def test_run():
|
||||
CONFIG.set_context({"language": "Chinese", "teaching_language": "English"})
|
||||
lesson = """
|
||||
UNIT 1 Making New Friends
|
||||
TOPIC 1 Welcome to China!
|
||||
|
|
@ -149,7 +149,10 @@ async def test_run():
|
|||
|
||||
3c Match the big letters with the small ones. Then write them on the lines.
|
||||
"""
|
||||
teacher = Teacher()
|
||||
context = Context()
|
||||
context.kwargs.language = "Chinese"
|
||||
context.kwargs.teaching_language = "English"
|
||||
teacher = Teacher(context=context)
|
||||
rsp = await teacher.run(Message(content=lesson))
|
||||
assert rsp
|
||||
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ from metagpt.roles.tutorial_assistant import TutorialAssistant
|
|||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize(("language", "topic"), [("Chinese", "Write a tutorial about pip")])
|
||||
async def test_tutorial_assistant(language: str, topic: str):
|
||||
role = TutorialAssistant(language=language)
|
||||
async def test_tutorial_assistant(language: str, topic: str, context):
|
||||
role = TutorialAssistant(language=language, context=context)
|
||||
msg = await role.run(topic)
|
||||
assert TUTORIAL_PATH.exists()
|
||||
filename = msg.content
|
||||
|
|
|
|||
|
|
@ -5,28 +5,22 @@
|
|||
import pytest
|
||||
|
||||
from metagpt.actions import Action
|
||||
from metagpt.llm import LLM
|
||||
|
||||
|
||||
def test_action_serialize():
|
||||
action = Action()
|
||||
ser_action_dict = action.model_dump()
|
||||
assert "name" in ser_action_dict
|
||||
assert "llm" not in ser_action_dict # not export
|
||||
assert "__module_class_name" not in ser_action_dict
|
||||
|
||||
action = Action(name="test")
|
||||
ser_action_dict = action.model_dump()
|
||||
assert "test" in ser_action_dict["name"]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_action_deserialize():
|
||||
action = Action()
|
||||
serialized_data = action.model_dump()
|
||||
async def test_action_serdeser(context):
|
||||
action = Action(context=context)
|
||||
ser_action_dict = action.model_dump()
|
||||
assert "name" in ser_action_dict
|
||||
assert "llm" not in ser_action_dict # not export
|
||||
assert "__module_class_name" in ser_action_dict
|
||||
|
||||
new_action = Action(**serialized_data)
|
||||
action = Action(name="test", context=context)
|
||||
ser_action_dict = action.model_dump()
|
||||
assert "test" in ser_action_dict["name"]
|
||||
|
||||
assert new_action.name == "Action"
|
||||
assert isinstance(new_action.llm, type(LLM()))
|
||||
new_action = Action(**ser_action_dict, context=context)
|
||||
|
||||
assert new_action.name == "test"
|
||||
assert isinstance(new_action.llm, type(context.llm()))
|
||||
assert len(await new_action._aask("who are you")) > 0
|
||||
|
|
|
|||
|
|
@ -8,21 +8,21 @@ from metagpt.actions.action import Action
|
|||
from metagpt.roles.architect import Architect
|
||||
|
||||
|
||||
def test_architect_serialize():
|
||||
role = Architect()
|
||||
@pytest.mark.asyncio
|
||||
async def test_architect_serdeser(context):
|
||||
role = Architect(context=context)
|
||||
ser_role_dict = role.model_dump(by_alias=True)
|
||||
assert "name" in ser_role_dict
|
||||
assert "states" in ser_role_dict
|
||||
assert "actions" in ser_role_dict
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_architect_deserialize():
|
||||
role = Architect()
|
||||
ser_role_dict = role.model_dump(by_alias=True)
|
||||
new_role = Architect(**ser_role_dict)
|
||||
# new_role = Architect.deserialize(ser_role_dict)
|
||||
new_role = Architect(**ser_role_dict, context=context)
|
||||
assert new_role.name == "Bob"
|
||||
assert len(new_role.actions) == 1
|
||||
assert len(new_role.rc.watch) == 1
|
||||
assert isinstance(new_role.actions[0], Action)
|
||||
await new_role.actions[0].run(with_messages="write a cli snake game")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pytest.main([__file__, "-s"])
|
||||
|
|
@ -2,7 +2,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# @Desc :
|
||||
|
||||
import shutil
|
||||
|
||||
from metagpt.actions.action_node import ActionNode
|
||||
from metagpt.actions.add_requirement import UserRequirement
|
||||
|
|
@ -10,7 +9,7 @@ from metagpt.actions.project_management import WriteTasks
|
|||
from metagpt.environment import Environment
|
||||
from metagpt.roles.project_manager import ProjectManager
|
||||
from metagpt.schema import Message
|
||||
from metagpt.utils.common import any_to_str
|
||||
from metagpt.utils.common import any_to_str, read_json_file, write_json_file
|
||||
from tests.metagpt.serialize_deserialize.test_serdeser_base import (
|
||||
ActionOK,
|
||||
ActionRaise,
|
||||
|
|
@ -19,23 +18,20 @@ from tests.metagpt.serialize_deserialize.test_serdeser_base import (
|
|||
)
|
||||
|
||||
|
||||
def test_env_serialize():
|
||||
env = Environment()
|
||||
def test_env_serdeser(context):
|
||||
env = Environment(context=context)
|
||||
env.publish_message(message=Message(content="test env serialize"))
|
||||
|
||||
ser_env_dict = env.model_dump()
|
||||
assert "roles" in ser_env_dict
|
||||
assert len(ser_env_dict["roles"]) == 0
|
||||
|
||||
|
||||
def test_env_deserialize():
|
||||
env = Environment()
|
||||
env.publish_message(message=Message(content="test env serialize"))
|
||||
ser_env_dict = env.model_dump()
|
||||
new_env = Environment(**ser_env_dict)
|
||||
new_env = Environment(**ser_env_dict, context=context)
|
||||
assert len(new_env.roles) == 0
|
||||
assert len(new_env.history) == 25
|
||||
|
||||
|
||||
def test_environment_serdeser():
|
||||
def test_environment_serdeser(context):
|
||||
out_mapping = {"field1": (list[str], ...)}
|
||||
out_data = {"field1": ["field1 value1", "field1 value2"]}
|
||||
ic_obj = ActionNode.create_model_class("prd", out_mapping)
|
||||
|
|
@ -44,7 +40,7 @@ def test_environment_serdeser():
|
|||
content="prd", instruct_content=ic_obj(**out_data), role="product manager", cause_by=any_to_str(UserRequirement)
|
||||
)
|
||||
|
||||
environment = Environment()
|
||||
environment = Environment(context=context)
|
||||
role_c = RoleC()
|
||||
environment.add_role(role_c)
|
||||
environment.publish_message(message)
|
||||
|
|
@ -52,7 +48,7 @@ def test_environment_serdeser():
|
|||
ser_data = environment.model_dump()
|
||||
assert ser_data["roles"]["Role C"]["name"] == "RoleC"
|
||||
|
||||
new_env: Environment = Environment(**ser_data)
|
||||
new_env: Environment = Environment(**ser_data, context=context)
|
||||
assert len(new_env.roles) == 1
|
||||
|
||||
assert list(new_env.roles.values())[0].states == list(environment.roles.values())[0].states
|
||||
|
|
@ -61,30 +57,31 @@ def test_environment_serdeser():
|
|||
assert type(list(new_env.roles.values())[0].actions[1]) == ActionRaise
|
||||
|
||||
|
||||
def test_environment_serdeser_v2():
|
||||
environment = Environment()
|
||||
def test_environment_serdeser_v2(context):
|
||||
environment = Environment(context=context)
|
||||
pm = ProjectManager()
|
||||
environment.add_role(pm)
|
||||
|
||||
ser_data = environment.model_dump()
|
||||
|
||||
new_env: Environment = Environment(**ser_data)
|
||||
new_env: Environment = Environment(**ser_data, context=context)
|
||||
role = new_env.get_role(pm.profile)
|
||||
assert isinstance(role, ProjectManager)
|
||||
assert isinstance(role.actions[0], WriteTasks)
|
||||
assert isinstance(list(new_env.roles.values())[0].actions[0], WriteTasks)
|
||||
|
||||
|
||||
def test_environment_serdeser_save():
|
||||
environment = Environment()
|
||||
def test_environment_serdeser_save(context):
|
||||
environment = Environment(context=context)
|
||||
role_c = RoleC()
|
||||
|
||||
shutil.rmtree(serdeser_path.joinpath("team"), ignore_errors=True)
|
||||
|
||||
stg_path = serdeser_path.joinpath("team", "environment")
|
||||
env_path = stg_path.joinpath("env.json")
|
||||
environment.add_role(role_c)
|
||||
environment.serialize(stg_path)
|
||||
|
||||
new_env: Environment = Environment.deserialize(stg_path)
|
||||
write_json_file(env_path, environment.model_dump())
|
||||
|
||||
env_dict = read_json_file(env_path)
|
||||
new_env: Environment = Environment(**env_dict, context=context)
|
||||
assert len(new_env.roles) == 1
|
||||
assert type(list(new_env.roles.values())[0].actions[0]) == ActionOK
|
||||
|
|
|
|||
|
|
@ -9,11 +9,11 @@ from metagpt.actions.add_requirement import UserRequirement
|
|||
from metagpt.actions.design_api import WriteDesign
|
||||
from metagpt.memory.memory import Memory
|
||||
from metagpt.schema import Message
|
||||
from metagpt.utils.common import any_to_str
|
||||
from metagpt.utils.common import any_to_str, read_json_file, write_json_file
|
||||
from tests.metagpt.serialize_deserialize.test_serdeser_base import serdeser_path
|
||||
|
||||
|
||||
def test_memory_serdeser():
|
||||
def test_memory_serdeser(context):
|
||||
msg1 = Message(role="Boss", content="write a snake game", cause_by=UserRequirement)
|
||||
|
||||
out_mapping = {"field2": (list[str], ...)}
|
||||
|
|
@ -39,7 +39,7 @@ def test_memory_serdeser():
|
|||
assert memory.count() == 2
|
||||
|
||||
|
||||
def test_memory_serdeser_save():
|
||||
def test_memory_serdeser_save(context):
|
||||
msg1 = Message(role="User", content="write a 2048 game", cause_by=UserRequirement)
|
||||
|
||||
out_mapping = {"field1": (list[str], ...)}
|
||||
|
|
@ -53,14 +53,14 @@ def test_memory_serdeser_save():
|
|||
memory.add_batch([msg1, msg2])
|
||||
|
||||
stg_path = serdeser_path.joinpath("team", "environment")
|
||||
memory.serialize(stg_path)
|
||||
assert stg_path.joinpath("memory.json").exists()
|
||||
memory_path = stg_path.joinpath("memory.json")
|
||||
write_json_file(memory_path, memory.model_dump())
|
||||
assert memory_path.exists()
|
||||
|
||||
new_memory = Memory.deserialize(stg_path)
|
||||
memory_dict = read_json_file(memory_path)
|
||||
new_memory = Memory(**memory_dict)
|
||||
assert new_memory.count() == 2
|
||||
new_msg2 = new_memory.get(1)[0]
|
||||
assert new_msg2.instruct_content.field1 == ["field1 value1", "field1 value2"]
|
||||
assert new_msg2.cause_by == any_to_str(WriteDesign)
|
||||
assert len(new_memory.index) == 2
|
||||
|
||||
stg_path.joinpath("memory.json").unlink()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# @Desc : unittest of polymorphic conditions
|
||||
import copy
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, SerializeAsAny
|
||||
|
||||
|
|
@ -12,6 +13,8 @@ from tests.metagpt.serialize_deserialize.test_serdeser_base import (
|
|||
|
||||
|
||||
class ActionSubClasses(BaseModel):
|
||||
model_config = ConfigDict(arbitrary_types_allowed=True)
|
||||
|
||||
actions: list[SerializeAsAny[Action]] = []
|
||||
|
||||
|
||||
|
|
@ -40,19 +43,21 @@ def test_no_serialize_as_any():
|
|||
|
||||
|
||||
def test_polymorphic():
|
||||
_ = ActionOKV2(
|
||||
ok_v2 = ActionOKV2(
|
||||
**{"name": "ActionOKV2", "context": "", "prefix": "", "desc": "", "extra_field": "ActionOKV2 Extra Info"}
|
||||
)
|
||||
|
||||
action_subcls = ActionSubClasses(actions=[ActionOKV2(), ActionPass()])
|
||||
action_subcls_dict = action_subcls.model_dump()
|
||||
action_subcls_dict2 = copy.deepcopy(action_subcls_dict)
|
||||
|
||||
assert "__module_class_name" in action_subcls_dict["actions"][0]
|
||||
|
||||
new_action_subcls = ActionSubClasses(**action_subcls_dict)
|
||||
assert isinstance(new_action_subcls.actions[0], ActionOKV2)
|
||||
assert new_action_subcls.actions[0].extra_field == ok_v2.extra_field
|
||||
assert isinstance(new_action_subcls.actions[1], ActionPass)
|
||||
|
||||
new_action_subcls = ActionSubClasses.model_validate(action_subcls_dict)
|
||||
new_action_subcls = ActionSubClasses.model_validate(action_subcls_dict2)
|
||||
assert isinstance(new_action_subcls.actions[0], ActionOKV2)
|
||||
assert isinstance(new_action_subcls.actions[1], ActionPass)
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@ from metagpt.actions.prepare_interview import PrepareInterview
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_action_deserialize():
|
||||
action = PrepareInterview()
|
||||
async def test_action_serdeser(context):
|
||||
action = PrepareInterview(context=context)
|
||||
serialized_data = action.model_dump()
|
||||
assert serialized_data["name"] == "PrepareInterview"
|
||||
|
||||
new_action = PrepareInterview(**serialized_data)
|
||||
new_action = PrepareInterview(**serialized_data, context=context)
|
||||
|
||||
assert new_action.name == "PrepareInterview"
|
||||
assert type(await new_action.run("python developer")) == ActionNode
|
||||
|
|
|
|||
|
|
@ -10,10 +10,10 @@ from metagpt.schema import Message
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_product_manager_deserialize(new_filename):
|
||||
role = ProductManager()
|
||||
async def test_product_manager_serdeser(new_filename, context):
|
||||
role = ProductManager(context=context)
|
||||
ser_role_dict = role.model_dump(by_alias=True)
|
||||
new_role = ProductManager(**ser_role_dict)
|
||||
new_role = ProductManager(**ser_role_dict, context=context)
|
||||
|
||||
assert new_role.name == "Alice"
|
||||
assert len(new_role.actions) == 2
|
||||
|
|
|
|||
|
|
@ -9,20 +9,15 @@ from metagpt.actions.project_management import WriteTasks
|
|||
from metagpt.roles.project_manager import ProjectManager
|
||||
|
||||
|
||||
def test_project_manager_serialize():
|
||||
role = ProjectManager()
|
||||
@pytest.mark.asyncio
|
||||
async def test_project_manager_serdeser(context):
|
||||
role = ProjectManager(context=context)
|
||||
ser_role_dict = role.model_dump(by_alias=True)
|
||||
assert "name" in ser_role_dict
|
||||
assert "states" in ser_role_dict
|
||||
assert "actions" in ser_role_dict
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_project_manager_deserialize():
|
||||
role = ProjectManager()
|
||||
ser_role_dict = role.model_dump(by_alias=True)
|
||||
|
||||
new_role = ProjectManager(**ser_role_dict)
|
||||
new_role = ProjectManager(**ser_role_dict, context=context)
|
||||
assert new_role.name == "Eve"
|
||||
assert len(new_role.actions) == 1
|
||||
assert isinstance(new_role.actions[0], Action)
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue