fg-env 0.3.0__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.
Files changed (432) hide show
  1. fg_env/__init__.py +113 -0
  2. fg_env/__main__.py +36 -0
  3. fg_env/_snapshot_copy.py +44 -0
  4. fg_env/action.py +249 -0
  5. fg_env/board_module.py +1051 -0
  6. fg_env/checkpoint.py +215 -0
  7. fg_env/cognition.py +424 -0
  8. fg_env/compile.py +3 -0
  9. fg_env/composition.py +346 -0
  10. fg_env/connectors.py +439 -0
  11. fg_env/continuous_time.py +416 -0
  12. fg_env/contract.py +3 -0
  13. fg_env/crafting.py +242 -0
  14. fg_env/deck_module.py +231 -0
  15. fg_env/derived_rules.py +220 -0
  16. fg_env/domain/__init__.py +41 -0
  17. fg_env/domain/base.py +368 -0
  18. fg_env/domain/markets.py +807 -0
  19. fg_env/domain/stubs.py +112 -0
  20. fg_env/domain_module.py +19 -0
  21. fg_env/effect_context.py +76 -0
  22. fg_env/effect_values.py +301 -0
  23. fg_env/effects.py +936 -0
  24. fg_env/engine.py +14 -0
  25. fg_env/entity.py +77 -0
  26. fg_env/event.py +201 -0
  27. fg_env/factions.py +152 -0
  28. fg_env/goals.py +222 -0
  29. fg_env/hand_module.py +271 -0
  30. fg_env/hidden_state_module.py +169 -0
  31. fg_env/invariants.py +127 -0
  32. fg_env/inventory.py +222 -0
  33. fg_env/kernel.py +362 -0
  34. fg_env/kernel_module.py +152 -0
  35. fg_env/legacy/__init__.py +198 -0
  36. fg_env/legacy/cli.py +389 -0
  37. fg_env/lint.py +3 -0
  38. fg_env/location_properties.py +206 -0
  39. fg_env/messaging.py +113 -0
  40. fg_env/negotiation.py +691 -0
  41. fg_env/observability.py +332 -0
  42. fg_env/pathfinding.py +125 -0
  43. fg_env/phase_handlers.py +680 -0
  44. fg_env/phase_state_machine.py +467 -0
  45. fg_env/physics.py +566 -0
  46. fg_env/pipeline/__init__.py +98 -0
  47. fg_env/pipeline/authoring_shapes.py +53 -0
  48. fg_env/pipeline/compile.py +309 -0
  49. fg_env/pipeline/contract.py +129 -0
  50. fg_env/pipeline/env_package.py +390 -0
  51. fg_env/pipeline/initial_values.py +29 -0
  52. fg_env/pipeline/lint.py +831 -0
  53. fg_env/pipeline/loader.py +1225 -0
  54. fg_env/pipeline/replay.py +247 -0
  55. fg_env/pipeline/smoke.py +284 -0
  56. fg_env/pipeline/versioning.py +158 -0
  57. fg_env/planning.py +481 -0
  58. fg_env/policies.py +126 -0
  59. fg_env/polls.py +246 -0
  60. fg_env/predicates.py +946 -0
  61. fg_env/primitives_loader.py +285 -0
  62. fg_env/property_dynamics.py +493 -0
  63. fg_env/py.typed +0 -0
  64. fg_env/registry.py +287 -0
  65. fg_env/relations.py +227 -0
  66. fg_env/resolution.py +739 -0
  67. fg_env/resource.py +130 -0
  68. fg_env/roles.py +136 -0
  69. fg_env/runtime/__init__.py +41 -0
  70. fg_env/runtime/actions.py +449 -0
  71. fg_env/runtime/conditions.py +256 -0
  72. fg_env/runtime/effect_dispatch.py +1050 -0
  73. fg_env/runtime/engine.py +1358 -0
  74. fg_env/runtime/perception.py +312 -0
  75. fg_env/runtime/sequence.py +87 -0
  76. fg_env/runtime/termination.py +767 -0
  77. fg_env/runtime/triggers.py +190 -0
  78. fg_env/runtime/turn.py +537 -0
  79. fg_env/sdk/__init__.py +4 -0
  80. fg_env/sdk/action_params.py +55 -0
  81. fg_env/sdk/action_schemas.py +255 -0
  82. fg_env/sdk/action_validation.py +266 -0
  83. fg_env/sdk/actions.py +373 -0
  84. fg_env/sdk/analysis/__init__.py +44 -0
  85. fg_env/sdk/analysis/accuracy.py +120 -0
  86. fg_env/sdk/analysis/assessment.py +78 -0
  87. fg_env/sdk/analysis/backtest.py +307 -0
  88. fg_env/sdk/analysis/calibrate.py +459 -0
  89. fg_env/sdk/analysis/checks.py +337 -0
  90. fg_env/sdk/analysis/cli.py +396 -0
  91. fg_env/sdk/analysis/compare.py +268 -0
  92. fg_env/sdk/analysis/constraints.py +254 -0
  93. fg_env/sdk/analysis/decisions.py +502 -0
  94. fg_env/sdk/analysis/draws.py +120 -0
  95. fg_env/sdk/analysis/drivers.py +230 -0
  96. fg_env/sdk/analysis/facts.py +133 -0
  97. fg_env/sdk/analysis/goals.py +209 -0
  98. fg_env/sdk/analysis/highlights.py +385 -0
  99. fg_env/sdk/analysis/holdout.py +76 -0
  100. fg_env/sdk/analysis/optimise.py +489 -0
  101. fg_env/sdk/analysis/optimise_guide.py +65 -0
  102. fg_env/sdk/analysis/optimise_result.py +193 -0
  103. fg_env/sdk/analysis/optimize.py +177 -0
  104. fg_env/sdk/analysis/output_scope.py +74 -0
  105. fg_env/sdk/analysis/runner.py +177 -0
  106. fg_env/sdk/analysis/scoring.py +289 -0
  107. fg_env/sdk/analysis/search.py +183 -0
  108. fg_env/sdk/analysis/sensitivity.py +247 -0
  109. fg_env/sdk/analysis/stats.py +345 -0
  110. fg_env/sdk/analysis/sweep.py +307 -0
  111. fg_env/sdk/analysis/targets.py +243 -0
  112. fg_env/sdk/analysis/validate.py +244 -0
  113. fg_env/sdk/api.py +379 -0
  114. fg_env/sdk/arm_inputs.py +38 -0
  115. fg_env/sdk/assets/__init__.py +15 -0
  116. fg_env/sdk/assets/blobs.py +111 -0
  117. fg_env/sdk/assets/catalog.py +183 -0
  118. fg_env/sdk/assets/checks.py +90 -0
  119. fg_env/sdk/assets/delivery.py +130 -0
  120. fg_env/sdk/assets/describe.py +70 -0
  121. fg_env/sdk/assets/functions.py +38 -0
  122. fg_env/sdk/assets/guide.py +69 -0
  123. fg_env/sdk/assets/intake.py +200 -0
  124. fg_env/sdk/assets/kinds.py +91 -0
  125. fg_env/sdk/assets/multimodal.py +130 -0
  126. fg_env/sdk/assets/spec.py +25 -0
  127. fg_env/sdk/assets/store.py +199 -0
  128. fg_env/sdk/bench.py +160 -0
  129. fg_env/sdk/binomial.py +48 -0
  130. fg_env/sdk/branch.py +348 -0
  131. fg_env/sdk/budget.py +159 -0
  132. fg_env/sdk/build.py +533 -0
  133. fg_env/sdk/captures.py +76 -0
  134. fg_env/sdk/chance.py +229 -0
  135. fg_env/sdk/check.py +383 -0
  136. fg_env/sdk/check_actions.py +254 -0
  137. fg_env/sdk/check_effects.py +321 -0
  138. fg_env/sdk/check_inventory.py +64 -0
  139. fg_env/sdk/check_params.py +76 -0
  140. fg_env/sdk/check_roots.py +24 -0
  141. fg_env/sdk/check_rules.py +194 -0
  142. fg_env/sdk/check_scans.py +196 -0
  143. fg_env/sdk/check_space.py +126 -0
  144. fg_env/sdk/check_state.py +201 -0
  145. fg_env/sdk/check_turns.py +67 -0
  146. fg_env/sdk/check_world.py +306 -0
  147. fg_env/sdk/cli.py +439 -0
  148. fg_env/sdk/cli_games.py +86 -0
  149. fg_env/sdk/cli_new.py +37 -0
  150. fg_env/sdk/cli_runs.py +137 -0
  151. fg_env/sdk/clock_math.py +25 -0
  152. fg_env/sdk/clock_words.py +115 -0
  153. fg_env/sdk/contract.py +261 -0
  154. fg_env/sdk/contract_base.py +81 -0
  155. fg_env/sdk/contract_measure.py +107 -0
  156. fg_env/sdk/contract_rules.py +240 -0
  157. fg_env/sdk/contract_world.py +336 -0
  158. fg_env/sdk/copying.py +36 -0
  159. fg_env/sdk/coupled_physics.py +195 -0
  160. fg_env/sdk/delivery.py +73 -0
  161. fg_env/sdk/describe/__init__.py +91 -0
  162. fg_env/sdk/describe/claims.py +61 -0
  163. fg_env/sdk/describe/metadata.py +393 -0
  164. fg_env/sdk/describe/odd.py +335 -0
  165. fg_env/sdk/describe/walk.py +143 -0
  166. fg_env/sdk/diagnostics.py +230 -0
  167. fg_env/sdk/driving.py +458 -0
  168. fg_env/sdk/effects.py +829 -0
  169. fg_env/sdk/entity_physics.py +182 -0
  170. fg_env/sdk/errors.py +62 -0
  171. fg_env/sdk/evaluate/__init__.py +11 -0
  172. fg_env/sdk/evaluate/play.py +124 -0
  173. fg_env/sdk/evaluate/result.py +126 -0
  174. fg_env/sdk/evaluate/suite.py +198 -0
  175. fg_env/sdk/experiment.py +501 -0
  176. fg_env/sdk/exposure.py +278 -0
  177. fg_env/sdk/expr.py +92 -0
  178. fg_env/sdk/expr_base.py +173 -0
  179. fg_env/sdk/expr_calls.py +183 -0
  180. fg_env/sdk/expr_codegen.py +604 -0
  181. fg_env/sdk/expr_compile.py +195 -0
  182. fg_env/sdk/expr_scope.py +103 -0
  183. fg_env/sdk/expr_values.py +205 -0
  184. fg_env/sdk/feeds.py +152 -0
  185. fg_env/sdk/fork.py +405 -0
  186. fg_env/sdk/functions.py +663 -0
  187. fg_env/sdk/game/__init__.py +17 -0
  188. fg_env/sdk/game/algorithms/__init__.py +15 -0
  189. fg_env/sdk/game/algorithms/best_response.py +123 -0
  190. fg_env/sdk/game/algorithms/cfr.py +87 -0
  191. fg_env/sdk/game/algorithms/mcts.py +315 -0
  192. fg_env/sdk/game/algorithms/minimax.py +133 -0
  193. fg_env/sdk/game/algorithms/participants.py +216 -0
  194. fg_env/sdk/game/algorithms/policy.py +68 -0
  195. fg_env/sdk/game/algorithms/tree.py +142 -0
  196. fg_env/sdk/game/bench.py +116 -0
  197. fg_env/sdk/game/conformance.py +373 -0
  198. fg_env/sdk/game/game.py +254 -0
  199. fg_env/sdk/game/leaks.py +148 -0
  200. fg_env/sdk/game/observe.py +144 -0
  201. fg_env/sdk/game/pettingzoo.py +284 -0
  202. fg_env/sdk/game/playthrough.py +117 -0
  203. fg_env/sdk/game/runs.py +114 -0
  204. fg_env/sdk/game/space.py +344 -0
  205. fg_env/sdk/game/state.py +467 -0
  206. fg_env/sdk/game/steps.py +90 -0
  207. fg_env/sdk/game/transforms.py +192 -0
  208. fg_env/sdk/game_spec.py +35 -0
  209. fg_env/sdk/geometry.py +259 -0
  210. fg_env/sdk/guide.py +270 -0
  211. fg_env/sdk/guide_pages.py +320 -0
  212. fg_env/sdk/guide_text.py +502 -0
  213. fg_env/sdk/gym.py +208 -0
  214. fg_env/sdk/happenings.py +191 -0
  215. fg_env/sdk/host/__init__.py +30 -0
  216. fg_env/sdk/host/adapters.py +273 -0
  217. fg_env/sdk/host/allowlist.py +411 -0
  218. fg_env/sdk/host/api.py +77 -0
  219. fg_env/sdk/host/common.py +70 -0
  220. fg_env/sdk/host/hosts.py +101 -0
  221. fg_env/sdk/host/personas.py +125 -0
  222. fg_env/sdk/host/protocols.py +108 -0
  223. fg_env/sdk/host/stubs.py +156 -0
  224. fg_env/sdk/host/tape.py +180 -0
  225. fg_env/sdk/host/tools.py +165 -0
  226. fg_env/sdk/host/turn_tools.py +245 -0
  227. fg_env/sdk/inputs.py +221 -0
  228. fg_env/sdk/integration.py +61 -0
  229. fg_env/sdk/layer_effect.py +101 -0
  230. fg_env/sdk/layers.py +90 -0
  231. fg_env/sdk/links.py +262 -0
  232. fg_env/sdk/load_calibration.py +67 -0
  233. fg_env/sdk/macros.py +298 -0
  234. fg_env/sdk/measure.py +241 -0
  235. fg_env/sdk/mechanisms/__init__.py +419 -0
  236. fg_env/sdk/mechanisms/_common.py +315 -0
  237. fg_env/sdk/mechanisms/_game.py +27 -0
  238. fg_env/sdk/mechanisms/_social.py +168 -0
  239. fg_env/sdk/mechanisms/abilities.py +510 -0
  240. fg_env/sdk/mechanisms/amm.py +551 -0
  241. fg_env/sdk/mechanisms/auction_reads.py +103 -0
  242. fg_env/sdk/mechanisms/auctions.py +731 -0
  243. fg_env/sdk/mechanisms/beliefs.py +297 -0
  244. fg_env/sdk/mechanisms/board_engine.py +538 -0
  245. fg_env/sdk/mechanisms/board_geometry.py +213 -0
  246. fg_env/sdk/mechanisms/board_rules.py +610 -0
  247. fg_env/sdk/mechanisms/boards.py +677 -0
  248. fg_env/sdk/mechanisms/book_functions.py +127 -0
  249. fg_env/sdk/mechanisms/book_mechanism.py +254 -0
  250. fg_env/sdk/mechanisms/book_rules.py +148 -0
  251. fg_env/sdk/mechanisms/book_session.py +126 -0
  252. fg_env/sdk/mechanisms/card_scoring.py +348 -0
  253. fg_env/sdk/mechanisms/cards.py +736 -0
  254. fg_env/sdk/mechanisms/cards_mechanism.py +201 -0
  255. fg_env/sdk/mechanisms/channels.py +641 -0
  256. fg_env/sdk/mechanisms/common.py +57 -0
  257. fg_env/sdk/mechanisms/contract_cache.py +55 -0
  258. fg_env/sdk/mechanisms/deliberation.py +605 -0
  259. fg_env/sdk/mechanisms/diffusion.py +377 -0
  260. fg_env/sdk/mechanisms/econ_asset_actions.py +254 -0
  261. fg_env/sdk/mechanisms/econ_assets.py +620 -0
  262. fg_env/sdk/mechanisms/econ_base.py +299 -0
  263. fg_env/sdk/mechanisms/econ_bookings.py +397 -0
  264. fg_env/sdk/mechanisms/econ_demand.py +355 -0
  265. fg_env/sdk/mechanisms/econ_demand_trade.py +517 -0
  266. fg_env/sdk/mechanisms/econ_inventory.py +298 -0
  267. fg_env/sdk/mechanisms/econ_labor.py +380 -0
  268. fg_env/sdk/mechanisms/econ_ledger.py +371 -0
  269. fg_env/sdk/mechanisms/econ_negotiation.py +632 -0
  270. fg_env/sdk/mechanisms/econ_production.py +398 -0
  271. fg_env/sdk/mechanisms/econ_replenishment.py +233 -0
  272. fg_env/sdk/mechanisms/econ_replenishment_rules.py +378 -0
  273. fg_env/sdk/mechanisms/econ_subscriptions.py +301 -0
  274. fg_env/sdk/mechanisms/econ_supply_chain.py +272 -0
  275. fg_env/sdk/mechanisms/economy.py +28 -0
  276. fg_env/sdk/mechanisms/families.py +59 -0
  277. fg_env/sdk/mechanisms/feed.py +644 -0
  278. fg_env/sdk/mechanisms/judging.py +507 -0
  279. fg_env/sdk/mechanisms/ledger.py +86 -0
  280. fg_env/sdk/mechanisms/locations.py +322 -0
  281. fg_env/sdk/mechanisms/market_stats.py +231 -0
  282. fg_env/sdk/mechanisms/markets.py +32 -0
  283. fg_env/sdk/mechanisms/memory.py +467 -0
  284. fg_env/sdk/mechanisms/ops_engine.py +356 -0
  285. fg_env/sdk/mechanisms/ops_queue.py +394 -0
  286. fg_env/sdk/mechanisms/ops_stats.py +138 -0
  287. fg_env/sdk/mechanisms/order_book.py +653 -0
  288. fg_env/sdk/mechanisms/package_auction.py +187 -0
  289. fg_env/sdk/mechanisms/posted.py +560 -0
  290. fg_env/sdk/mechanisms/pot.py +617 -0
  291. fg_env/sdk/mechanisms/procedure.py +440 -0
  292. fg_env/sdk/mechanisms/procedure_stack.py +456 -0
  293. fg_env/sdk/mechanisms/relationships.py +499 -0
  294. fg_env/sdk/mechanisms/roles.py +272 -0
  295. fg_env/sdk/mechanisms/slots.py +208 -0
  296. fg_env/sdk/mechanisms/social.py +19 -0
  297. fg_env/sdk/mechanisms/status.py +463 -0
  298. fg_env/sdk/mechanisms/traders.py +328 -0
  299. fg_env/sdk/mechanisms/turn_order.py +233 -0
  300. fg_env/sdk/mechanisms/victory.py +249 -0
  301. fg_env/sdk/mechanisms/voting.py +366 -0
  302. fg_env/sdk/networks.py +132 -0
  303. fg_env/sdk/parse_errors.py +119 -0
  304. fg_env/sdk/participants.py +592 -0
  305. fg_env/sdk/patterns/__init__.py +7 -0
  306. fg_env/sdk/patterns/base.py +163 -0
  307. fg_env/sdk/patterns/catalogue.py +6 -0
  308. fg_env/sdk/patterns/check.py +285 -0
  309. fg_env/sdk/patterns/compose.py +118 -0
  310. fg_env/sdk/patterns/count_math.py +167 -0
  311. fg_env/sdk/patterns/decompose.py +145 -0
  312. fg_env/sdk/patterns/describe.py +40 -0
  313. fg_env/sdk/patterns/draws.py +222 -0
  314. fg_env/sdk/patterns/estimators.py +482 -0
  315. fg_env/sdk/patterns/expand.py +115 -0
  316. fg_env/sdk/patterns/fit.py +410 -0
  317. fg_env/sdk/patterns/guide.py +151 -0
  318. fg_env/sdk/patterns/joint.py +404 -0
  319. fg_env/sdk/patterns/memory.py +239 -0
  320. fg_env/sdk/patterns/numeric.py +438 -0
  321. fg_env/sdk/patterns/observe.py +130 -0
  322. fg_env/sdk/patterns/processes.py +380 -0
  323. fg_env/sdk/patterns/product_math.py +44 -0
  324. fg_env/sdk/patterns/responses.py +231 -0
  325. fg_env/sdk/patterns/runtime.py +457 -0
  326. fg_env/sdk/patterns/schema.py +34 -0
  327. fg_env/sdk/patterns/signals.py +479 -0
  328. fg_env/sdk/patterns/timebase.py +181 -0
  329. fg_env/sdk/perception.py +344 -0
  330. fg_env/sdk/pilot.py +301 -0
  331. fg_env/sdk/poisson.py +73 -0
  332. fg_env/sdk/positions.py +173 -0
  333. fg_env/sdk/previews.py +117 -0
  334. fg_env/sdk/probability.py +18 -0
  335. fg_env/sdk/props.py +48 -0
  336. fg_env/sdk/reads.py +225 -0
  337. fg_env/sdk/record_events.py +52 -0
  338. fg_env/sdk/record_index.py +104 -0
  339. fg_env/sdk/registry.py +317 -0
  340. fg_env/sdk/replay.py +185 -0
  341. fg_env/sdk/report/__init__.py +221 -0
  342. fg_env/sdk/report/cli.py +88 -0
  343. fg_env/sdk/report/confidence.py +117 -0
  344. fg_env/sdk/report/demand.py +157 -0
  345. fg_env/sdk/report/evidence.py +231 -0
  346. fg_env/sdk/report/noise.py +80 -0
  347. fg_env/sdk/report/optimisation.py +146 -0
  348. fg_env/sdk/report/pattern_effects.py +176 -0
  349. fg_env/sdk/report/queue.py +288 -0
  350. fg_env/sdk/report/sections.py +376 -0
  351. fg_env/sdk/report/words.py +138 -0
  352. fg_env/sdk/result_file.py +161 -0
  353. fg_env/sdk/returns.py +169 -0
  354. fg_env/sdk/run_checks.py +76 -0
  355. fg_env/sdk/run_copy.py +297 -0
  356. fg_env/sdk/run_diagnosis.py +281 -0
  357. fg_env/sdk/run_rounds.py +221 -0
  358. fg_env/sdk/run_stages.py +362 -0
  359. fg_env/sdk/runtime.py +359 -0
  360. fg_env/sdk/scaffold.py +152 -0
  361. fg_env/sdk/seeds.py +42 -0
  362. fg_env/sdk/session.py +254 -0
  363. fg_env/sdk/snapshot.py +319 -0
  364. fg_env/sdk/space.py +135 -0
  365. fg_env/sdk/space_functions.py +132 -0
  366. fg_env/sdk/stdlib/__init__.py +6 -0
  367. fg_env/sdk/stdlib/_args.py +145 -0
  368. fg_env/sdk/stdlib/dates.py +145 -0
  369. fg_env/sdk/stdlib/dists.py +264 -0
  370. fg_env/sdk/stdlib/linalg.py +274 -0
  371. fg_env/sdk/stdlib/lists.py +186 -0
  372. fg_env/sdk/stdlib/mathx.py +216 -0
  373. fg_env/sdk/stdlib/puzzles.py +330 -0
  374. fg_env/sdk/stdlib/regex.py +324 -0
  375. fg_env/sdk/stdlib/scoring.py +191 -0
  376. fg_env/sdk/stdlib/sets.py +80 -0
  377. fg_env/sdk/stdlib/stats.py +254 -0
  378. fg_env/sdk/stdlib/strings.py +192 -0
  379. fg_env/sdk/stdlib/tables.py +96 -0
  380. fg_env/sdk/stdlib/words.py +75 -0
  381. fg_env/sdk/stepping.py +421 -0
  382. fg_env/sdk/stochastic.py +72 -0
  383. fg_env/sdk/stochastic_integration.py +97 -0
  384. fg_env/sdk/sync_events.py +101 -0
  385. fg_env/sdk/syntax_hints.py +64 -0
  386. fg_env/sdk/template.py +212 -0
  387. fg_env/sdk/tool_text.py +184 -0
  388. fg_env/sdk/tournament/__init__.py +14 -0
  389. fg_env/sdk/tournament/evaluation.py +188 -0
  390. fg_env/sdk/tournament/play.py +176 -0
  391. fg_env/sdk/tournament/ratings.py +210 -0
  392. fg_env/sdk/tournament/result.py +110 -0
  393. fg_env/sdk/tournament/scoring.py +138 -0
  394. fg_env/sdk/tournament/seating.py +56 -0
  395. fg_env/sdk/tournament/standings.py +129 -0
  396. fg_env/sdk/trace/__init__.py +16 -0
  397. fg_env/sdk/trace/reader.py +262 -0
  398. fg_env/sdk/trace/render.py +120 -0
  399. fg_env/sdk/trace/rerun.py +486 -0
  400. fg_env/sdk/turn.py +560 -0
  401. fg_env/sdk/type_index.py +84 -0
  402. fg_env/sdk/workers.py +228 -0
  403. fg_env/sdk/world.py +819 -0
  404. fg_env/sdk/world_defaults.py +55 -0
  405. fg_env/sdk/world_parts.py +147 -0
  406. fg_env/sdk/world_physics.py +129 -0
  407. fg_env/sequences.py +106 -0
  408. fg_env/sim_controller.py +476 -0
  409. fg_env/skills.py +145 -0
  410. fg_env/slots_module.py +193 -0
  411. fg_env/smoke.py +3 -0
  412. fg_env/snapshot.py +217 -0
  413. fg_env/social.py +587 -0
  414. fg_env/spatial.py +183 -0
  415. fg_env/state.py +912 -0
  416. fg_env/status_effects.py +213 -0
  417. fg_env/temporal.py +260 -0
  418. fg_env/termination.py +684 -0
  419. fg_env/trade_module.py +389 -0
  420. fg_env/transfers.py +141 -0
  421. fg_env/triggers.py +136 -0
  422. fg_env/turn_manager.py +339 -0
  423. fg_env/types.py +99 -0
  424. fg_env/visibility.py +319 -0
  425. fg_env/world_events.py +296 -0
  426. fg_env/world_loader.py +22 -0
  427. fg_env/world_model.py +407 -0
  428. fg_env-0.3.0.dist-info/METADATA +239 -0
  429. fg_env-0.3.0.dist-info/RECORD +432 -0
  430. fg_env-0.3.0.dist-info/WHEEL +4 -0
  431. fg_env-0.3.0.dist-info/entry_points.txt +2 -0
  432. fg_env-0.3.0.dist-info/licenses/LICENSE +202 -0
fg_env/__init__.py ADDED
@@ -0,0 +1,113 @@
1
+ """fg-env: the Environment SDK for LLM agents. A JSON contract describes an environment; the engine runs it.
2
+
3
+ import fg_env
4
+
5
+ issues = fg_env.check("shop.json") # every problem with its path and a fix
6
+ result = fg_env.run("shop.json", {"shopper": "policy:thrifty"}, seed=1)
7
+ print(result.summary())
8
+
9
+ env = fg_env.load("shop.json", seed=7) # full control: preview, run, snapshot, fork
10
+ exp = fg_env.experiment("shop.json", runs=20, arms=["control", "promo"])
11
+
12
+ ``fg_env.guide()`` is the core authoring guide, mapping every other part (``fg_env.guide("all")`` is everything);
13
+ ``fg_env.new("game", "my_game.json")`` writes a ready-to-run contract to start from. The earlier template-based kernel API lives in
14
+ :mod:`fg_env.legacy`.
15
+ """
16
+ from importlib.metadata import PackageNotFoundError as _PackageNotFoundError
17
+ from importlib.metadata import version as _dist_version
18
+
19
+ try:
20
+ __version__ = _dist_version("fg-env")
21
+ except _PackageNotFoundError: # a source checkout on PYTHONPATH, not installed
22
+ __version__ = "0+unknown"
23
+
24
+ # Environment SDK public API. Everything a user needs is importable from ``fg_env``.
25
+ from .sdk.api import check, expand, load, parse, run
26
+ from .sdk.branch import Branch
27
+ from .sdk.fork import fork
28
+ from .sdk.game import Game, GameState, game
29
+ from .sdk.game.conformance import conformance
30
+ from .sdk.game.pettingzoo import pettingzoo_aec, pettingzoo_parallel
31
+ from .sdk.game.playthrough import playthrough
32
+ from .sdk.gym import GymEnv, gym
33
+ from .sdk.contract import Contract
34
+ from .sdk.errors import ContractError, InputError, InvariantViolation, Issue, RunError, SnapshotError
35
+ from .sdk.experiment import ExperimentResult, experiment
36
+ from .sdk.guide import guide, schema
37
+ from .sdk.scaffold import new
38
+ from .sdk.measure import RunResult
39
+ from .sdk.runtime import Env
40
+ from .sdk.session import ToolResult, Wake
41
+ from .sdk import participants
42
+ from .sdk import analysis
43
+ from .sdk.analysis import (backtest, behavior_checks, calibrate, chain, compare, drivers, highlights, narrative,
44
+ optimise, precision, score, sensitivity, sweep, validate)
45
+ from .sdk.tournament import tournament
46
+ from .sdk.describe import describe
47
+ from .sdk.patterns.fit import FitResult, fit_patterns
48
+ from .sdk.patterns.decompose import Decomposition, decompose
49
+ from .sdk.report import Report, report
50
+ from .sdk.trace import trace
51
+ from .sdk.evaluate import evaluate
52
+
53
+ __all__ = [
54
+ "__version__",
55
+ "load",
56
+ "run",
57
+ "check",
58
+ "parse",
59
+ "expand",
60
+ "experiment",
61
+ "fork",
62
+ "game",
63
+ "gym",
64
+ "Branch",
65
+ "Game",
66
+ "GameState",
67
+ "GymEnv",
68
+ "guide",
69
+ "schema",
70
+ "new",
71
+ "Env",
72
+ "Contract",
73
+ "RunResult",
74
+ "ExperimentResult",
75
+ "Wake",
76
+ "ToolResult",
77
+ "Issue",
78
+ "ContractError",
79
+ "InputError",
80
+ "RunError",
81
+ "InvariantViolation",
82
+ "SnapshotError",
83
+ "participants",
84
+ "analysis",
85
+ "sweep",
86
+ "sensitivity",
87
+ "calibrate",
88
+ "optimise",
89
+ "fit_patterns",
90
+ "FitResult",
91
+ "decompose",
92
+ "Decomposition",
93
+ "report",
94
+ "Report",
95
+ "score",
96
+ "backtest",
97
+ "validate",
98
+ "precision",
99
+ "behavior_checks",
100
+ "highlights",
101
+ "narrative",
102
+ "drivers",
103
+ "compare",
104
+ "chain",
105
+ "tournament",
106
+ "describe",
107
+ "trace",
108
+ "evaluate",
109
+ "conformance",
110
+ "playthrough",
111
+ "pettingzoo_aec",
112
+ "pettingzoo_parallel",
113
+ ]
fg_env/__main__.py ADDED
@@ -0,0 +1,36 @@
1
+ """The ``fg-env`` command line: ``fg-env <command> [args...]`` (or ``python -m fg_env <command>``).
2
+
3
+ ``fg-env --help`` lists the Environment SDK commands (check, run, preview, experiment, tournament, evaluate,
4
+ trace, guide, schema, ...); the earlier template API's commands are under ``fg-env legacy <command>``.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ import argparse
9
+ import sys
10
+ from typing import List, Optional
11
+
12
+
13
+ def main(argv: Optional[List[str]] = None) -> int:
14
+ parser = argparse.ArgumentParser(
15
+ prog="fg-env",
16
+ description="Fareground Environment SDK — check, run, preview and experiment with environment contracts",
17
+ )
18
+ from . import __version__
19
+ from .legacy.cli import add_legacy_command
20
+ from .sdk.analysis.cli import add_analysis_commands
21
+ from .sdk.cli import add_commands
22
+ from .sdk.report.cli import add_report_command
23
+
24
+ parser.add_argument("--version", action="version", version=f"fg-env {__version__}")
25
+ sub = parser.add_subparsers(dest="cmd", required=True)
26
+ add_commands(sub)
27
+ add_analysis_commands(sub)
28
+ add_report_command(sub)
29
+ add_legacy_command(sub)
30
+ args = parser.parse_args(argv)
31
+ code: int = args.func(args)
32
+ return code
33
+
34
+
35
+ if __name__ == "__main__":
36
+ sys.exit(main())
@@ -0,0 +1,44 @@
1
+ """Detach checkpoint trees without generic deepcopy dispatch for JSON leaves.
2
+
3
+ Only exact built-in types take the fast path. Subclasses and custom objects
4
+ retain their deepcopy protocol. One memo preserves aliases/cycles across both
5
+ paths; no mutable value is shared with the live world or another checkpoint.
6
+ """
7
+ import copy
8
+ from typing import Any
9
+
10
+ _ATOMIC = frozenset((type(None), bool, int, float, str, bytes))
11
+
12
+
13
+ def snapshot_copy(value: Any, memo: dict | None = None) -> Any:
14
+ kind = type(value)
15
+ if kind in _ATOMIC:
16
+ return value
17
+ if memo is None:
18
+ memo = {}
19
+ identity = id(value)
20
+ if identity in memo:
21
+ return memo[identity]
22
+ if kind is dict:
23
+ result: Any = {}
24
+ memo[identity] = result
25
+ for key, item in value.items():
26
+ result[snapshot_copy(key, memo)] = snapshot_copy(item, memo)
27
+ return result
28
+ if kind is list:
29
+ result = []
30
+ memo[identity] = result
31
+ result.extend(snapshot_copy(item, memo) for item in value)
32
+ return result
33
+ if kind is tuple:
34
+ # Same recursion rule as deepcopy's tuple handler: a nested mutable
35
+ # child may have completed this tuple while traversing a cycle.
36
+ items = [snapshot_copy(item, memo) for item in value]
37
+ if identity in memo:
38
+ return memo[identity]
39
+ if all(before is after for before, after in zip(value, items)):
40
+ return value # e.g. immutable RNG state; never live mutable state.
41
+ result = tuple(items)
42
+ memo[identity] = result
43
+ return result
44
+ return copy.deepcopy(value, memo)
fg_env/action.py ADDED
@@ -0,0 +1,249 @@
1
+ """Action definitions, preconditions, and effects."""
2
+ from dataclasses import dataclass, field
3
+ from enum import Enum
4
+ import math
5
+ from typing import Any, Dict, List, Optional
6
+
7
+
8
+ class Operator(Enum):
9
+ """Precondition operators."""
10
+ EQ = "eq"
11
+ NEQ = "neq"
12
+ GT = "gt"
13
+ GTE = "gte"
14
+ LT = "lt"
15
+ LTE = "lte"
16
+ IN = "in"
17
+ HAS_RESOURCE = "has_resource"
18
+ AT_LOCATION = "at_location"
19
+ IS_ADJACENT = "is_adjacent"
20
+ RELATION_GTE = "relation_gte"
21
+ IS_ALIVE = "is_alive"
22
+ SAME_FACTION = "same_faction"
23
+ DIFFERENT_FACTION = "different_faction"
24
+ HAS_ITEM = "has_item"
25
+ HAS_ITEM_TYPE = "has_item_type"
26
+ INVENTORY_NOT_FULL = "inventory_not_full"
27
+ SKILL_GTE = "skill_gte"
28
+ HAS_RECIPE = "has_recipe"
29
+
30
+
31
+ def validate_numeric_precondition(operator: str, value: Any, expr: Any = None) -> None:
32
+ if not expr and operator in {"gt", "gte", "lt", "lte", "has_resource", "skill_gte", "relation_gte"}:
33
+ if value is None and operator in {"has_resource", "skill_gte", "relation_gte"}:
34
+ return
35
+ if isinstance(value, bool) or not isinstance(value, (int, float)) or not math.isfinite(value):
36
+ raise ValueError(f"{operator} requires a finite numeric value; put dynamic comparisons in expr (for example, '$actor.price >= $actor.reservation_price').")
37
+
38
+
39
+ @dataclass
40
+ class Precondition:
41
+ """A single precondition check.
42
+
43
+ Two equivalent forms:
44
+ Legacy: Precondition(subject="actor", operator=Operator.GTE,
45
+ field="gold", value=100)
46
+ Modern: Precondition(expr="$actor.gold >= 100")
47
+
48
+ When ``expr`` is set it takes precedence and is evaluated through
49
+ the unified predicate engine (``fg_env.predicates``).
50
+ The modern form is preferred for new games — one grammar covers
51
+ every kind of guard.
52
+ """
53
+ subject: str = "actor" # "actor", "target", or entity property path
54
+ operator: Operator = Operator.EQ
55
+ value: Any = None # The value to compare against
56
+ field: Optional[str] = None # Property name (for property checks)
57
+ resource: Optional[str] = None # Resource name (for has_resource)
58
+ relation_type: Optional[str] = None # For relation checks
59
+ description: str = ""
60
+ # New: full expression form. String ("$actor.gold >= 100") or dict.
61
+ # Takes precedence when truthy.
62
+ expr: Any = None
63
+
64
+ def __post_init__(self):
65
+ validate_numeric_precondition(self.operator.value, self.value, self.expr)
66
+
67
+
68
+ class EffectOperation(Enum):
69
+ """Types of state changes an effect can apply.
70
+
71
+ NOTE: New ops should be added via the kernel registry
72
+ (``fg_env.registry.effect``), not by extending this enum.
73
+ The enum exists for backwards compatibility — built-in ops still
74
+ live here so the engine's legacy switch keeps working, but custom
75
+ games extend the verb set without editing kernel code."""
76
+ SET = "set"
77
+ ADD = "add"
78
+ SUBTRACT = "subtract"
79
+ MULTIPLY = "multiply"
80
+ TRANSFER_RESOURCE = "transfer_resource"
81
+ SET_RELATION = "set_relation"
82
+ MODIFY_RELATION = "modify_relation"
83
+ MOVE_TO = "move_to"
84
+ KILL = "kill"
85
+ EMIT_EVENT = "emit_event"
86
+ APPLY_STATUS = "apply_status"
87
+ REMOVE_STATUS = "remove_status"
88
+ SPAWN_ENTITY = "spawn_entity"
89
+ DESPAWN_ENTITY = "despawn_entity"
90
+ GIVE_ITEM = "give_item"
91
+ TAKE_ITEM = "take_item"
92
+ DROP_ITEM = "drop_item"
93
+ PICKUP_ITEM = "pickup_item"
94
+ AWARD_XP = "award_xp"
95
+ CRAFT_ITEM = "craft_item"
96
+ # Social actions
97
+ POST_CONTENT = "post_content"
98
+ SHARE_CONTENT = "share_content"
99
+ REACT_CONTENT = "react_content"
100
+ FOLLOW_ENTITY = "follow_entity"
101
+ UNFOLLOW_ENTITY = "unfollow_entity"
102
+ # Generic game tokens (Phase 1 EffectDSL — replaces per-env
103
+ # `jail_cards`-style counters with a declarative tokens dict).
104
+ GRANT_TOKEN = "grant_token"
105
+ CONSUME_TOKEN = "consume_token"
106
+ # Increment a numeric property by a value or expression. Same as
107
+ # ADD but exists explicitly for board-track advancement clarity.
108
+ ADVANCE_TRACK = "advance_track"
109
+ # Place a mark on a BoardModule cell (tic-tac-toe, connect-four).
110
+ # `field` = board_id; `value` = mark to place; condition.field == "cell"
111
+ # carries the cell index ($params expression).
112
+ PLACE_ON_BOARD = "place_on_board"
113
+ # Wipe all marks on a named BoardModule. Used for multi-game
114
+ # tic-tac-toe / connect-four / any "best-of-N" format where a game
115
+ # ends and the board resets for the next game.
116
+ # `field` = board_id.
117
+ RESET_BOARD = "reset_board"
118
+ # Draw a card from a named DeckModule and apply its `effect` list.
119
+ # `field` = deck_id. The drawn card's effects fire against this
120
+ # same actor/target/params context — so a Chance card can move the
121
+ # actor, pay the bank, or grant a token.
122
+ DRAW_FROM_DECK = "draw_from_deck"
123
+ # Conditional branching effect. `value` is a dict:
124
+ # { "if": { subject, field, operator, value }, OR
125
+ # "if_expr": "$actor.position == 30", (expression form)
126
+ # "then": [ effect_dict, ... ],
127
+ # "else": [ effect_dict, ... ] (optional) }
128
+ # Lets the schema express "pass-GO collects $200" or "promote pawn
129
+ # at back rank" without any code.
130
+ CONDITIONAL = "conditional"
131
+ # Per-player hand operations (Tier 5a — HandModule).
132
+ # `field` carries the hand_id (defaults to "hand"); `value` carries
133
+ # the number of cards (DRAW_TO_HAND) or the card_id string
134
+ # (DISCARD_FROM_HAND / PLAY_CARD / PASS_CARD).
135
+ DRAW_TO_HAND = "draw_to_hand"
136
+ DISCARD_FROM_HAND = "discard_from_hand"
137
+ PLAY_CARD = "play_card"
138
+ PASS_CARD = "pass_card"
139
+ # Worker placement (Tier 5b — SlotsModule).
140
+ # `field` = slots_id, `value` = slot_id to claim/release.
141
+ CLAIM_SLOT = "claim_slot"
142
+ RELEASE_SLOT = "release_slot"
143
+ # Use one of the entity's held (kept) cards — e.g. "get out of
144
+ # jail free". `field` = deck_id. Optional params['card_idx']
145
+ # selects which held card.
146
+ USE_HELD_CARD = "use_held_card"
147
+
148
+
149
+ @dataclass
150
+ class EffectCondition:
151
+ """A runtime condition that must be True for an effect to apply.
152
+
153
+ Two equivalent forms:
154
+ Legacy: EffectCondition(subject="actor", field="gold",
155
+ operator="gte", value=100)
156
+ Modern: EffectCondition(expr="$actor.gold >= 100")
157
+
158
+ When ``expr`` is set it takes precedence and is evaluated through
159
+ the unified predicate engine (``fg_env.predicates``).
160
+ """
161
+ subject: str = "actor" # "actor", "target"
162
+ field: Optional[str] = None # Property to check
163
+ operator: str = "gte" # "gte", "lte", "gt", "lt", "eq", "neq"
164
+ value: Any = None # Value to compare against
165
+ check_type: str = "property" # "property", "alive", "has_status"
166
+ # New: full expression form. Either a string ("$actor.gold >= 100")
167
+ # or a structured dict ({"op": "gte", ...}). Takes precedence when
168
+ # truthy.
169
+ expr: Any = None
170
+
171
+
172
+ @dataclass
173
+ class Effect:
174
+ """A single state change to apply after action resolution."""
175
+ target: str # "actor", "target", or entity_id
176
+ operation: EffectOperation
177
+ field: Optional[str] = None # Property to modify
178
+ value: Any = None # Value for the operation
179
+ resource: Optional[str] = None # Resource name
180
+ relation_type: Optional[str] = None
181
+ description: str = ""
182
+ condition: Optional[EffectCondition] = None # If set, effect only applies when True
183
+ scale_by_magnitude: bool = False # When True, numeric value is multiplied by success_degree
184
+ # JSON loaders distinguish an omitted operand from an explicit null.
185
+ # None retains compatibility with Effects constructed directly in Python.
186
+ value_supplied: Optional[bool] = None
187
+
188
+
189
+ @dataclass
190
+ class ActionDefinition:
191
+ """
192
+ Complete definition of an action that agents can take.
193
+
194
+ The LLM sees: name, description, parameters.
195
+ The engine evaluates: preconditions, resolution, effects.
196
+ """
197
+ name: str
198
+ description: str
199
+ actor_type: str # EntityType name that can perform this
200
+ target_type: Optional[str] = None # If the action requires a target
201
+ parameters: List[Dict[str, Any]] = field(default_factory=list)
202
+ # [{name: "amount", type: "int", required: True, min: 1, max: 100}]
203
+
204
+ preconditions: List[Precondition] = field(default_factory=list)
205
+
206
+ resolution_archetype: str = "deterministic"
207
+ resolution_params: Dict[str, Any] = field(default_factory=dict)
208
+
209
+ effects_on_success: List[Effect] = field(default_factory=list)
210
+ effects_on_failure: List[Effect] = field(default_factory=list)
211
+ effects_on_partial: List[Effect] = field(default_factory=list) # Applied on partial success
212
+
213
+ # Visibility: who can see this action was taken
214
+ broadcast: bool = True
215
+ range: Optional[float] = None
216
+
217
+ # Action chains
218
+ requires_action: Optional[str] = None # Must have completed this action first
219
+ requires_action_success: bool = True # Only if prior action succeeded
220
+ unlocks_actions: List[str] = field(default_factory=list) # Unlocked on success
221
+ locks_actions: List[str] = field(default_factory=list) # Locked on success
222
+ cooldown_rounds: int = 0 # Can't repeat for N rounds
223
+
224
+ # Multi-round sequences
225
+ sequence_rounds: int = 0 # 0 = instant, >0 = takes N rounds
226
+ interruptible: bool = True # Can be interrupted by choosing another action
227
+
228
+ # Communication
229
+ message_action: bool = False # If True, reasoning is posted as a message
230
+
231
+ # Continuous-time duration (only used in CONTINUOUS temporal mode)
232
+ duration: float = 0.0 # How long this action takes in continuous time
233
+ # Atomic, conserved numeric-property transfers on full success. Amounts
234
+ # resolve once against pre-transfer state; bounds reject rather than clamp.
235
+ transfers: List[Dict[str, Any]] = field(default_factory=list)
236
+
237
+
238
+ @dataclass
239
+ class ActionInstance:
240
+ """
241
+ A concrete action attempt by an agent during a turn.
242
+ Created when an agent decides to act; consumed by the engine.
243
+ """
244
+ action_name: str
245
+ actor_id: str
246
+ target_id: Optional[str] = None
247
+ parameters: Dict[str, Any] = field(default_factory=dict)
248
+ reasoning: str = ""
249
+ speech: str = ""