Skip to content

Commit 7d87029

Browse files
committed
chore: resolve merge conflicts
2 parents 1d2ef76 + 2160b79 commit 7d87029

File tree

7 files changed

+83
-36
lines changed

7 files changed

+83
-36
lines changed

neurons/validators/genie_validator.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import bittensor as bt
33
import numpy as np
44
import random
5+
import requests
56
import threading
67
import time
78

@@ -46,11 +47,10 @@
4647
from webgenie.tasks.image_task_generator import ImageTaskGenerator
4748
from webgenie.utils.uids import get_all_available_uids
4849

49-
5050
class GenieValidator:
5151
def __init__(self, neuron: BaseNeuron):
5252
self.neuron = neuron
53-
self.lock = neuron.lock
53+
self.lock = threading.Lock()
5454
self.config = neuron.config
5555
self.miner_results = []
5656
self.synthetic_tasks = []
@@ -93,10 +93,9 @@ async def query_miners(self):
9393

9494
available_challenges_classes = [
9595
AccuracyChallenge,
96-
#QualityChallenge,
96+
SeoChallenge,
9797
AccuracyChallenge,
9898
SeoChallenge,
99-
BalancedChallenge,
10099
]
101100

102101
with self.lock:
@@ -281,7 +280,6 @@ async def synthensize_task(self, session:int, task_number:int):
281280
self.synthetic_tasks.append((task, synapse))
282281

283282
bt.logging.success(f"Successfully generated task for {task.src}")
284-
285283
except Exception as e:
286284
bt.logging.error(f"Error in synthensize_task: {e}")
287285
raise e

neurons/validators/score_manager.py

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,28 @@
11
import bittensor as bt
22
import copy
33
import numpy as np
4-
4+
import threading
55
from io import StringIO
66
from rich.console import Console
77
from rich.table import Table
88
from typing import List
99

1010
from webgenie.base.neuron import BaseNeuron
11-
from webgenie.challenges.challenge import Challenge
11+
12+
from webgenie.challenges.challenge import Challenge, RESERVED_WEIGHTS
1213
from webgenie.constants import (
1314
CONSIDERING_SESSION_COUNTS,
1415
__STATE_VERSION__,
1516
WORK_DIR,
16-
MAX_UNANSWERED_TASKS,
17+
MAX_UNANSWERED_TASKS
1718
)
1819
from webgenie.helpers.weights import save_file_to_wandb
1920

2021
class ScoreManager:
2122
def __init__(self, neuron: BaseNeuron):
2223
self.neuron = neuron
2324
self.state_path = self.neuron.config.neuron.full_path + "/state.npz"
24-
self.lock = neuron.lock
25+
self.lock = threading.Lock()
2526

2627
self.hotkeys = copy.deepcopy(self.neuron.metagraph.hotkeys)
2728
self.current_session = -1
@@ -120,8 +121,7 @@ def set_new_hotkeys(self, new_hotkeys: List[str]):
120121

121122
# Update the hotkeys.
122123
self.hotkeys = copy.deepcopy(new_hotkeys)
123-
with self.lock:
124-
self.save_scores()
124+
self.save_scores()
125125

126126
def update_scores(self, rewards: np.ndarray, uids: List[int], challenge: Challenge):
127127
bt.logging.info("Updating scores")
@@ -158,8 +158,7 @@ def update_scores(self, rewards: np.ndarray, uids: List[int], challenge: Challen
158158
if session_number < session - CONSIDERING_SESSION_COUNTS * 2:
159159
self.session_results.pop(session_number)
160160

161-
with self.lock:
162-
self.save_scores()
161+
self.save_scores()
163162

164163
console = Console()
165164
self.print_session_result(session, console)
@@ -174,14 +173,32 @@ def get_winner(self, total_scores: np.ndarray, solved_tasks: np.ndarray, number_
174173
if self.is_blacklisted(uid):
175174
continue
176175

177-
if solved_tasks[uid] >= max(1, number_of_tasks - MAX_UNANSWERED_TASKS):
178-
avg_scores[uid] = total_scores[uid] / solved_tasks[uid]
179-
else:
180-
avg_scores[uid] = 0
176+
avg_scores[uid] = total_scores[uid] / number_of_tasks
177+
178+
# if solved_tasks[uid] >= max(1, number_of_tasks - MAX_UNANSWERED_TASKS):
179+
# avg_scores[uid] = total_scores[uid] / solved_tasks[uid]
180+
# else:
181+
# avg_scores[uid] = 0
181182
winner = np.argmax(avg_scores) if max(avg_scores) > 0 else -1
182183
return winner
183184

184185
def get_scores(self, session_upto: int):
186+
# scores = np.zeros(self.neuron.metagraph.n, dtype=np.float32)
187+
# for session_number in self.session_results:
188+
# if (session_number <= session_upto - CONSIDERING_SESSION_COUNTS or
189+
# session_number > session_upto):
190+
# continue
191+
192+
# try:
193+
# winner = self.session_results[session_number]["winner"]
194+
# competition_type = self.session_results[session_number]["competition_type"]
195+
# if winner == -1:
196+
# continue
197+
# scores[winner] += RESERVED_WEIGHTS[competition_type]
198+
# except Exception as e:
199+
# bt.logging.warning(f"Error getting scores: {e}")
200+
201+
# return scores
185202
scores = np.zeros(self.neuron.metagraph.n, dtype=np.float32)
186203
tiny_weight = 1 / 128
187204
big_weight = 1.0
@@ -190,22 +207,13 @@ def get_scores(self, session_upto: int):
190207
session_number > session_upto):
191208
continue
192209

193-
winner = self.get_winner(
194-
self.session_results[session_number]["scores"],
195-
self.session_results[session_number]["solved_tasks"],
196-
self.session_results[session_number]["number_of_tasks"],
197-
)
210+
winner = self.session_results[session_number]["winner"]
198211
if winner == -1:
199212
continue
200213
if session_number == session_upto:
201214
scores[winner] += big_weight
202215
else:
203216
scores[winner] += tiny_weight
204-
205-
for uid in range(self.neuron.metagraph.n):
206-
if self.is_blacklisted(uid):
207-
scores[uid] = 0
208-
209217
return scores
210218

211219
# if session_upto in self.session_results:

neurons/validators/validator.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def __init__(self, config=None):
6969
self.query_miners_thread: Union[threading.Thread, None] = None
7070
self.score_thread: Union[threading.Thread, None] = None
7171
self.sync_thread: Union[threading.Thread, None] = None
72-
self.lock = threading.RLock()
72+
self.lock = threading.Lock()
7373

7474
self.genie_validator = GenieValidator(neuron=self)
7575
self.score_manager = ScoreManager(neuron=self)
@@ -346,7 +346,7 @@ def sync_loop(self):
346346
try:
347347
with self.lock:
348348
self.sync()
349-
self.set_weights()
349+
self.set_weights()
350350
except Exception as e:
351351
bt.logging.error(f"Error during sync: {str(e)}")
352352
if self.should_exit:

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "web-genie-ai"
3-
version = "1.1.26"
3+
version = "1.1.20"
44
description = "The first bittensor subnet for web generation"
55
readme = "README.md"
66
requires-python = ">=3.12.4"

tests/test_llms.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import sys
22
import os
3+
import random
34

45
parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
56
sys.path.append(parent_dir)
@@ -10,7 +11,7 @@
1011
import asyncio
1112
from pydantic import BaseModel
1213

13-
from webgenie.helpers.llms import openai_call
14+
from webgenie.helpers.llms import openai_call, set_seed
1415

1516

1617
class HTML(BaseModel):
@@ -20,15 +21,16 @@ class HTML(BaseModel):
2021
async def test_openai_call():
2122
result = await openai_call(
2223
messages = [
23-
{"role": "system", "content": "You are an expert web developer who specializes in HTML and CSS. A user will provide you with the webpage requirements. You need to return a single html file that uses HTML and CSS to satisfy the requirements. Include all CSS code in the HTML file itself. If it involves any images, use 'rick.jpg' as the placeholder. Do not hallucinate any dependencies to external files. You do not need to include JavaScript scripts for dynamic interactions. Pay attention to things like size, text, position, and color of all the elements, as well as the overall layout. Respond with the content of the HTML+CSS file:"},
24-
{"role": "user", "content": "Create a webpage with a red background and a blue rectangle in the center."},
24+
{"role": "system", "content": "Could you make the following webpage more complex? It should be more complex and have more elements."},
25+
{"role": "user", "content": """<!DOCTYPE html>\n<html lang="en">\n<head>\n <meta charset="UTF-8">\n <meta name="viewport" content="width=device-width, initial-scale=1.0">\n <title>Red Background with Blue Rectangle</title>\n <style>\n body {\n margin: 0;\n height: 100vh;\n display: flex;\n justify-content: center;\n align-items: center;\n background-color: red;\n }\n .blue-rectangle {\n width: 300px;\n height: 200px;\n background-color: blue;\n }\n </style>\n</head>\n<body>\n <div class="blue-rectangle"></div>\n</body>\n</html>"""},
2526
],
2627
response_format = HTML,
2728
)
2829
print(result)
2930

3031

3132
if __name__ == "__main__":
33+
set_seed(5)
3234
asyncio.run(test_openai_call())
3335

3436

webgenie/challenges/challenge.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ async def calculate_scores(self) -> dict[str, np.ndarray]:
5757
aggregated_scores = np.where(accuracy_scores > 0.9, quality_scores, 0)
5858
return aggregated_scores, scores
5959

60+
6061
class BalancedChallenge(Challenge):
6162
competition_type: str = Field(default=BALANCED_COMPETITION_TYPE, description="The type of competition")
6263

@@ -65,13 +66,13 @@ async def calculate_scores(self) -> dict[str, np.ndarray]:
6566
accuracy_scores = scores[ACCURACY_METRIC_NAME]
6667
quality_scores = scores[QUALITY_METRIC_NAME]
6768
seo_scores = scores[SEO_METRIC_NAME]
68-
aggregated_scores = accuracy_scores * 0.4 + quality_scores * 0.3 + seo_scores * 0.3
69+
aggregated_scores = accuracy_scores * 0.6 + quality_scores * 0.2 + seo_scores * 0.2
6970
return aggregated_scores, scores
7071

7172

7273
RESERVED_WEIGHTS = {
73-
ACCURACY_COMPETITION_TYPE: 50,
74-
BALANCED_COMPETITION_TYPE: 30,
74+
ACCURACY_COMPETITION_TYPE: 70,
75+
BALANCED_COMPETITION_TYPE: 10,
7576
SEO_COMPETITION_TYPE: 10,
7677
QUALITY_COMPETITION_TYPE: 10,
7778
}

webgenie/tasks/image_task_generator.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,41 @@ async def generate_task(self, **kwargs) -> Tuple[Task, bt.Synapse]:
8686
image_task,
8787
WebgenieImageSynapse(base64_image=base64_image, task_id=image_task.task_id),
8888
)
89+
90+
async def generate_task(self, session:int, task_number:int)->Tuple[Task, bt.Synapse]:
91+
bt.logging.info("Generating Image task")
92+
93+
dataset, _ = random.choices(self.datasets, weights=[weight for _, weight in self.datasets])[0]
94+
dataset_entry = await dataset.generate_context(session, task_number)
95+
bt.logging.debug(f"Generated dataset entry: {dataset_entry.url}")
96+
97+
ground_truth_html = preprocess_html(dataset_entry.ground_truth_html)
98+
bt.logging.info(f"Preprocessed ground truth html")
99+
if not ground_truth_html :
100+
raise ValueError("Invalid ground truth html")
101+
102+
if is_empty_html(ground_truth_html):
103+
raise ValueError("Empty ground truth html")
104+
105+
base64_image = await html_to_screenshot(ground_truth_html, page_load_time=GROUND_TRUTH_HTML_LOAD_TIME)
106+
# Check image dimensions ratio
107+
image = base64_to_image(base64_image)
108+
width, height = image.size
109+
aspect_ratio = height / width
110+
if aspect_ratio > 7: # If height is more than 7x the width
111+
raise ValueError(f"Image aspect ratio too extreme: {aspect_ratio:.2f}. Height should not exceed 7x width.")
112+
113+
bt.logging.debug(f"Screenshot generated for {dataset_entry.url}")
114+
image_task = ImageTask(
115+
base64_image=base64_image,
116+
ground_truth_html=ground_truth_html,
117+
generator=self,
118+
src=dataset_entry.src,
119+
task_id=hashlib.sha256(dataset_entry.url.encode()).hexdigest(),
120+
timeout=IMAGE_TASK_TIMEOUT,
121+
)
122+
123+
return (
124+
image_task,
125+
WebgenieImageSynapse(base64_image=base64_image, task_id=image_task.task_id),
126+
)

0 commit comments

Comments
 (0)