synth-ai 0.2.9.dev4__py3-none-any.whl → 0.2.9.dev5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of synth-ai might be problematic. Click here for more details.
- synth_ai/cli/task_apps.py +28 -2
- {synth_ai-0.2.9.dev4.dist-info → synth_ai-0.2.9.dev5.dist-info}/METADATA +1 -1
- {synth_ai-0.2.9.dev4.dist-info → synth_ai-0.2.9.dev5.dist-info}/RECORD +7 -9
- examples/warming_up_to_rl/task_app/synth_envs_hosted/test_stepwise_rewards.py +0 -58
- synth_ai/environments/examples/sokoban/units/astar_common.py +0 -95
- {synth_ai-0.2.9.dev4.dist-info → synth_ai-0.2.9.dev5.dist-info}/WHEEL +0 -0
- {synth_ai-0.2.9.dev4.dist-info → synth_ai-0.2.9.dev5.dist-info}/entry_points.txt +0 -0
- {synth_ai-0.2.9.dev4.dist-info → synth_ai-0.2.9.dev5.dist-info}/licenses/LICENSE +0 -0
- {synth_ai-0.2.9.dev4.dist-info → synth_ai-0.2.9.dev5.dist-info}/top_level.txt +0 -0
synth_ai/cli/task_apps.py
CHANGED
|
@@ -1220,12 +1220,23 @@ def _write_modal_entrypoint(
|
|
|
1220
1220
|
except Exception:
|
|
1221
1221
|
remote_file_str = None
|
|
1222
1222
|
module_name = entry.config_factory.__module__
|
|
1223
|
+
|
|
1224
|
+
# Prefer a guaranteed mount for the discovered file to avoid package import issues
|
|
1225
|
+
guaranteed_file_str: str | None = None
|
|
1226
|
+
if original_path:
|
|
1227
|
+
guaranteed_file_str = str((Path("/opt/synth_ai_repo/__local_task_app__") / Path(original_path).stem).with_suffix('.py'))
|
|
1223
1228
|
|
|
1224
1229
|
dotenv_paths = [str(Path(path)) for path in (dotenv_paths or [])]
|
|
1225
1230
|
|
|
1226
1231
|
pip_packages = list(modal_cfg.pip_packages)
|
|
1227
1232
|
|
|
1228
1233
|
local_dirs = [(str(Path(src)), dst) for src, dst in modal_cfg.extra_local_dirs]
|
|
1234
|
+
# Ensure the discovered app directory is mounted, regardless of modal_cfg
|
|
1235
|
+
if original_path:
|
|
1236
|
+
discovered_dir = str(Path(original_path).resolve().parent)
|
|
1237
|
+
mount_dst = "/opt/synth_ai_repo/__local_task_app__"
|
|
1238
|
+
if (discovered_dir, mount_dst) not in local_dirs:
|
|
1239
|
+
local_dirs.append((discovered_dir, mount_dst))
|
|
1229
1240
|
secret_names = list(modal_cfg.secret_names)
|
|
1230
1241
|
volume_mounts = [(name, mount) for name, mount in modal_cfg.volume_mounts]
|
|
1231
1242
|
|
|
@@ -1244,7 +1255,7 @@ from synth_ai.task.server import create_task_app
|
|
|
1244
1255
|
ENTRY_ID = {entry.app_id!r}
|
|
1245
1256
|
MODAL_APP_NAME = {modal_name!r}
|
|
1246
1257
|
MODULE_NAME = {module_name!r}
|
|
1247
|
-
MODULE_FILE = {remote_file_str!r}
|
|
1258
|
+
MODULE_FILE = {guaranteed_file_str or remote_file_str!r}
|
|
1248
1259
|
DOTENV_PATHS = {dotenv_paths!r}
|
|
1249
1260
|
|
|
1250
1261
|
image = Image.debian_slim(python_version={modal_cfg.python_version!r})
|
|
@@ -1278,7 +1289,22 @@ if MODULE_FILE:
|
|
|
1278
1289
|
else:
|
|
1279
1290
|
raise RuntimeError("Failed to import task app from file: " + str(MODULE_FILE))
|
|
1280
1291
|
else:
|
|
1281
|
-
|
|
1292
|
+
# Try module import; if that fails, attempt to load from the guaranteed mount
|
|
1293
|
+
try:
|
|
1294
|
+
importlib.import_module(MODULE_NAME)
|
|
1295
|
+
except Exception:
|
|
1296
|
+
import os
|
|
1297
|
+
fallback_file = '/opt/synth_ai_repo/__local_task_app__/' + (MODULE_NAME.split('.')[-1] if MODULE_NAME else 'task_app') + '.py'
|
|
1298
|
+
if os.path.exists(fallback_file):
|
|
1299
|
+
spec = importlib.util.spec_from_file_location(MODULE_NAME or 'task_app_module', fallback_file)
|
|
1300
|
+
if spec and spec.loader:
|
|
1301
|
+
mod = importlib.util.module_from_spec(spec)
|
|
1302
|
+
sys.modules[MODULE_NAME or 'task_app_module'] = mod
|
|
1303
|
+
spec.loader.exec_module(mod)
|
|
1304
|
+
else:
|
|
1305
|
+
raise
|
|
1306
|
+
else:
|
|
1307
|
+
raise
|
|
1282
1308
|
|
|
1283
1309
|
# Get the entry from registry (now that it's registered)
|
|
1284
1310
|
entry = registry.get(ENTRY_ID)
|
|
@@ -81,7 +81,6 @@ examples/warming_up_to_rl/task_app/synth_envs_hosted/registry.py,sha256=pMVwiutZ
|
|
|
81
81
|
examples/warming_up_to_rl/task_app/synth_envs_hosted/rollout.py,sha256=506KV0x0oOajTuNVVWLUxeIXG2YaZjWwfgbVg2EorcA,71477
|
|
82
82
|
examples/warming_up_to_rl/task_app/synth_envs_hosted/test_agents.py,sha256=PRkQlVKGfn2-w4EOTTHc8T-tqFW6m21mS7BII6TUUd4,5599
|
|
83
83
|
examples/warming_up_to_rl/task_app/synth_envs_hosted/test_service.py,sha256=PAYPP0tWU0cQUUxJuAYbDwvWeGjAcPFRHsW2vG3vOpg,5228
|
|
84
|
-
examples/warming_up_to_rl/task_app/synth_envs_hosted/test_stepwise_rewards.py,sha256=OfzZ18_bykLll6-4-2-OZI4a2wFx68hnTxufZeFE5t4,1836
|
|
85
84
|
examples/warming_up_to_rl/task_app/synth_envs_hosted/utils.py,sha256=Qcxfa_WASxbUCbAKejiZB6QIl8eJeeIrFPt5GU-Zb6E,2013
|
|
86
85
|
examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/__init__.py,sha256=5e-BmaXi_5EGcqF2hEGsnbtkHsNvPNMTX9wJ3yiz3XQ,34
|
|
87
86
|
examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/__init__.py,sha256=nTmSVzOfRUnjxEN1-IHjxuvPHij-AdRu_NZoH6Ozv2M,197
|
|
@@ -120,7 +119,7 @@ synth_ai/cli/recent.py,sha256=mHhM-QrR_MfjfKSzBvvPUEC-lkXTWUZrQwqYTmb2x0Y,4173
|
|
|
120
119
|
synth_ai/cli/rl_demo.py,sha256=P09_atVrSTfGUhAs0Obe63erniJ3EDHtm51yL2xBouM,8796
|
|
121
120
|
synth_ai/cli/root.py,sha256=0fuWNO5NeWTSCANzPBfoQsZKe3iUxnJ9hsSWS-SK2UM,11370
|
|
122
121
|
synth_ai/cli/status.py,sha256=M_bt7U58Ubi-q-ZlrIpgCASKq9_k6uMjpx926f6kLLA,4591
|
|
123
|
-
synth_ai/cli/task_apps.py,sha256=
|
|
122
|
+
synth_ai/cli/task_apps.py,sha256=AQmZtnvNDHMRhvUF0KOvnIF1tRbg0J-nwnJe1T49ajg,52077
|
|
124
123
|
synth_ai/cli/traces.py,sha256=_QBdCR92u0Gv51U4DH0Ws1d5yCrbJRpaYKe7pmcHrHs,6484
|
|
125
124
|
synth_ai/cli/watch.py,sha256=HBKbAcpUkkPhGvsPRofckbu8oILiVqp35NXHkIEpTTc,17808
|
|
126
125
|
synth_ai/compound/cais.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -334,7 +333,6 @@ synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/sokoban_env_
|
|
|
334
333
|
synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/sokoban_env_pull.py,sha256=ZCEr6LoSxKvVQzbRGwRBN62RAQPP5jiLoNqI8c4Ij2Q,3808
|
|
335
334
|
synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/sokoban_env_two_player.py,sha256=99yZCBsbx3i5Wiuf786TiHQjq2tMEY0OKsOEa-obhXY,3763
|
|
336
335
|
synth_ai/environments/examples/sokoban/engine_helpers/vendored/envs/sokoban_env_variations.py,sha256=VKMXRVmVdIxfa0q_T5Dfll5HHadc5QHpktRQztEIxGs,15455
|
|
337
|
-
synth_ai/environments/examples/sokoban/units/astar_common.py,sha256=4vG-_JrGI-yX8HY22CTY9P3DXPqCV_AHMPwH-flr0Z4,3006
|
|
338
336
|
synth_ai/environments/examples/tictactoe/__init__.py,sha256=XGoOP8GEGXjG-TI_E_-3b1jOhpGNtl_LmR9G3K59Gig,31
|
|
339
337
|
synth_ai/environments/examples/tictactoe/engine.py,sha256=B2OYQ3TVi_c75BRy_zHIEWjcTSaO4vnZZQJTo6wFe7k,12430
|
|
340
338
|
synth_ai/environments/examples/tictactoe/environment.py,sha256=p_ZN5-AyYKUnIJ5Df46fXMlJZ6yRerkvXC9GA1W0Ht8,9336
|
|
@@ -535,9 +533,9 @@ synth_ai/v0/tracing_v1/events/manage.py,sha256=ZDXXP-ZwLH9LCsmw7Ru9o55d7bl_diPtJ
|
|
|
535
533
|
synth_ai/v0/tracing_v1/events/scope.py,sha256=BuBkhSpVHUJt8iGT9HJZF82rbb88mQcd2vM2shg-w2I,2550
|
|
536
534
|
synth_ai/v0/tracing_v1/events/store.py,sha256=0342lvAcalyJbVEIzQFaPuMQGgwiFm7M5rE6gr-G0E8,9041
|
|
537
535
|
synth_ai/zyk/__init__.py,sha256=htVLnzTYQ5rxzYpzSYBm7_o6uNKZ3pB_PrqkBrgTRS4,771
|
|
538
|
-
synth_ai-0.2.9.
|
|
539
|
-
synth_ai-0.2.9.
|
|
540
|
-
synth_ai-0.2.9.
|
|
541
|
-
synth_ai-0.2.9.
|
|
542
|
-
synth_ai-0.2.9.
|
|
543
|
-
synth_ai-0.2.9.
|
|
536
|
+
synth_ai-0.2.9.dev5.dist-info/licenses/LICENSE,sha256=ynhjRQUfqA_RdGRATApfFA_fBAy9cno04sLtLUqxVFM,1069
|
|
537
|
+
synth_ai-0.2.9.dev5.dist-info/METADATA,sha256=-GRGwjAZPLUJpTxbLEiu-B_fZtBPodHuem1ySlmqiXk,5200
|
|
538
|
+
synth_ai-0.2.9.dev5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
539
|
+
synth_ai-0.2.9.dev5.dist-info/entry_points.txt,sha256=Neq-3bT7TAijjgOIR77pKL-WYg6TWBDeO8pp_nL4vGY,91
|
|
540
|
+
synth_ai-0.2.9.dev5.dist-info/top_level.txt,sha256=1moNHgctEUJ3F3eH3V-7FSMb2iTTze1V13dj1R04oUY,18
|
|
541
|
+
synth_ai-0.2.9.dev5.dist-info/RECORD,,
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import math
|
|
2
|
-
|
|
3
|
-
from backend.app.routes.clustered_training.dev.synth_envs_hosted.rollout import (
|
|
4
|
-
compute_stepwise_reward,
|
|
5
|
-
)
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def test_compute_stepwise_reward_detects_unlock() -> None:
|
|
9
|
-
prev = {"build_workbench": False, "pet_cow": False}
|
|
10
|
-
new = {"build_workbench": True, "pet_cow": False}
|
|
11
|
-
actions = [{"tool": "interact", "args": {"action": "build_workbench"}}]
|
|
12
|
-
|
|
13
|
-
info, decision, stats = compute_stepwise_reward(
|
|
14
|
-
prev,
|
|
15
|
-
new,
|
|
16
|
-
decision_index=2,
|
|
17
|
-
actions_summary=actions,
|
|
18
|
-
indicator_lambda=0.75,
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
assert info["decision_index"] == 2
|
|
22
|
-
assert info["new_achievements"] == ["build_workbench"]
|
|
23
|
-
assert info["indicator"] == 1
|
|
24
|
-
assert math.isclose(info["reward"], 0.75)
|
|
25
|
-
|
|
26
|
-
assert decision["actions"] == actions
|
|
27
|
-
assert decision["indicator"] == 1
|
|
28
|
-
assert math.isclose(decision["r_i"], 0.75)
|
|
29
|
-
|
|
30
|
-
assert math.isclose(stats["indicator"], 1.0)
|
|
31
|
-
assert math.isclose(stats["reward"], 0.75)
|
|
32
|
-
assert math.isclose(stats["new_achievements_count"], 1.0)
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
def test_compute_stepwise_reward_handles_no_unlock() -> None:
|
|
36
|
-
prev = {"collect_wheat": True, "milk_cow": False}
|
|
37
|
-
new = {"collect_wheat": True, "milk_cow": False}
|
|
38
|
-
actions = [{"tool": "interact", "args": {"action": "sleep"}}]
|
|
39
|
-
|
|
40
|
-
info, decision, stats = compute_stepwise_reward(
|
|
41
|
-
prev,
|
|
42
|
-
new,
|
|
43
|
-
decision_index=5,
|
|
44
|
-
actions_summary=actions,
|
|
45
|
-
indicator_lambda=1.2,
|
|
46
|
-
)
|
|
47
|
-
|
|
48
|
-
assert info["new_achievements"] == []
|
|
49
|
-
assert info["indicator"] == 0
|
|
50
|
-
assert math.isclose(info["reward"], 0.0)
|
|
51
|
-
|
|
52
|
-
assert decision["actions"] == actions
|
|
53
|
-
assert decision["indicator"] == 0
|
|
54
|
-
assert math.isclose(decision["r_i"], 0.0)
|
|
55
|
-
|
|
56
|
-
assert math.isclose(stats["indicator"], 0.0)
|
|
57
|
-
assert math.isclose(stats["reward"], 0.0)
|
|
58
|
-
assert math.isclose(stats["new_achievements_count"], 0.0)
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
astar_common.py – one A* routine usable by both engine-level and
|
|
3
|
-
environment-level unit tests.
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
import heapq
|
|
7
|
-
import itertools
|
|
8
|
-
import json
|
|
9
|
-
from typing import Any, Awaitable, Callable, List, Tuple
|
|
10
|
-
|
|
11
|
-
import numpy as np
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
# ---------- generic utilities ------------------------------------ #
|
|
15
|
-
def _boxes_left(env_pkg) -> int:
|
|
16
|
-
"""#targets – #boxes-on-targets (uses raw grids, never the counter)."""
|
|
17
|
-
return int(np.sum(env_pkg.room_fixed == 2) - np.sum(env_pkg.room_state == 3))
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def solved(obj: Any) -> bool:
|
|
21
|
-
"""Expects obj to have a .package_sokoban_env attribute."""
|
|
22
|
-
return _boxes_left(obj.package_sokoban_env) == 0
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def heuristic(obj: Any) -> int:
|
|
26
|
-
"""Expects obj to have a .package_sokoban_env attribute."""
|
|
27
|
-
return _boxes_left(obj.package_sokoban_env)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
# ---------- single reusable A* ----------------------------------- #
|
|
31
|
-
async def astar(
|
|
32
|
-
root_obj: Any,
|
|
33
|
-
step_fn: Callable[[Any, int], Awaitable[None]],
|
|
34
|
-
deserialize_fn: Callable[[Any], Awaitable[Any]],
|
|
35
|
-
max_nodes: int = 1000,
|
|
36
|
-
) -> List[int]:
|
|
37
|
-
"""
|
|
38
|
-
Generic A* over Sokoban snapshots.
|
|
39
|
-
|
|
40
|
-
• `root_obj` - current engine *or* environment
|
|
41
|
-
• `step_fn(obj, action)` - async: apply one move to *obj*
|
|
42
|
-
• `deserialize_fn(snapshot)` - async: new obj from snapshot
|
|
43
|
-
"""
|
|
44
|
-
start_snap = await root_obj._serialize_engine()
|
|
45
|
-
|
|
46
|
-
frontier: List[Tuple[int, int, Any, List[int]]] = []
|
|
47
|
-
counter = itertools.count()
|
|
48
|
-
frontier.append((heuristic(root_obj), next(counter), start_snap, []))
|
|
49
|
-
seen: set[str] = set()
|
|
50
|
-
|
|
51
|
-
nodes = 0
|
|
52
|
-
while frontier and nodes < max_nodes:
|
|
53
|
-
f, _, snap, path = heapq.heappop(frontier)
|
|
54
|
-
cur = await deserialize_fn(snap)
|
|
55
|
-
key = json.dumps(snap.engine_snapshot, sort_keys=True)
|
|
56
|
-
if key in seen:
|
|
57
|
-
continue
|
|
58
|
-
seen.add(key)
|
|
59
|
-
if solved(cur):
|
|
60
|
-
return path
|
|
61
|
-
|
|
62
|
-
nodes += 1
|
|
63
|
-
for action in range(cur.package_sokoban_env.action_space.n):
|
|
64
|
-
child = await deserialize_fn(snap) # fresh copy
|
|
65
|
-
try:
|
|
66
|
-
await step_fn(child, action)
|
|
67
|
-
except Exception: # illegal/off-board
|
|
68
|
-
continue
|
|
69
|
-
|
|
70
|
-
child_snap = await child._serialize_engine()
|
|
71
|
-
g = len(path) + 1
|
|
72
|
-
heapq.heappush(
|
|
73
|
-
frontier,
|
|
74
|
-
(g + heuristic(child), next(counter), child_snap, path + [action]),
|
|
75
|
-
)
|
|
76
|
-
return []
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
# convenience lambdas for the two concrete APIs
|
|
80
|
-
async def _engine_step(e, a): # `SokobanEngine`
|
|
81
|
-
await e._step_engine(a)
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
async def _env_step(env, a): # `SokobanEnvironment` (expects Move wrapper)
|
|
85
|
-
from synth_ai.environments.examples.sokoban.units.test_sokoban_environment import Move
|
|
86
|
-
|
|
87
|
-
await env.step([[Move(a)]])
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
ENGINE_ASTAR = lambda eng, **kw: astar(eng, _engine_step, eng.__class__._deserialize_engine, **kw)
|
|
91
|
-
ENV_ASTAR = lambda env, **kw: astar(
|
|
92
|
-
env.engine, _env_step, env.engine.__class__._deserialize_engine, **kw
|
|
93
|
-
)
|
|
94
|
-
|
|
95
|
-
# ----------------------------------------------------------------- #
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|