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.
- fg_env/__init__.py +113 -0
- fg_env/__main__.py +36 -0
- fg_env/_snapshot_copy.py +44 -0
- fg_env/action.py +249 -0
- fg_env/board_module.py +1051 -0
- fg_env/checkpoint.py +215 -0
- fg_env/cognition.py +424 -0
- fg_env/compile.py +3 -0
- fg_env/composition.py +346 -0
- fg_env/connectors.py +439 -0
- fg_env/continuous_time.py +416 -0
- fg_env/contract.py +3 -0
- fg_env/crafting.py +242 -0
- fg_env/deck_module.py +231 -0
- fg_env/derived_rules.py +220 -0
- fg_env/domain/__init__.py +41 -0
- fg_env/domain/base.py +368 -0
- fg_env/domain/markets.py +807 -0
- fg_env/domain/stubs.py +112 -0
- fg_env/domain_module.py +19 -0
- fg_env/effect_context.py +76 -0
- fg_env/effect_values.py +301 -0
- fg_env/effects.py +936 -0
- fg_env/engine.py +14 -0
- fg_env/entity.py +77 -0
- fg_env/event.py +201 -0
- fg_env/factions.py +152 -0
- fg_env/goals.py +222 -0
- fg_env/hand_module.py +271 -0
- fg_env/hidden_state_module.py +169 -0
- fg_env/invariants.py +127 -0
- fg_env/inventory.py +222 -0
- fg_env/kernel.py +362 -0
- fg_env/kernel_module.py +152 -0
- fg_env/legacy/__init__.py +198 -0
- fg_env/legacy/cli.py +389 -0
- fg_env/lint.py +3 -0
- fg_env/location_properties.py +206 -0
- fg_env/messaging.py +113 -0
- fg_env/negotiation.py +691 -0
- fg_env/observability.py +332 -0
- fg_env/pathfinding.py +125 -0
- fg_env/phase_handlers.py +680 -0
- fg_env/phase_state_machine.py +467 -0
- fg_env/physics.py +566 -0
- fg_env/pipeline/__init__.py +98 -0
- fg_env/pipeline/authoring_shapes.py +53 -0
- fg_env/pipeline/compile.py +309 -0
- fg_env/pipeline/contract.py +129 -0
- fg_env/pipeline/env_package.py +390 -0
- fg_env/pipeline/initial_values.py +29 -0
- fg_env/pipeline/lint.py +831 -0
- fg_env/pipeline/loader.py +1225 -0
- fg_env/pipeline/replay.py +247 -0
- fg_env/pipeline/smoke.py +284 -0
- fg_env/pipeline/versioning.py +158 -0
- fg_env/planning.py +481 -0
- fg_env/policies.py +126 -0
- fg_env/polls.py +246 -0
- fg_env/predicates.py +946 -0
- fg_env/primitives_loader.py +285 -0
- fg_env/property_dynamics.py +493 -0
- fg_env/py.typed +0 -0
- fg_env/registry.py +287 -0
- fg_env/relations.py +227 -0
- fg_env/resolution.py +739 -0
- fg_env/resource.py +130 -0
- fg_env/roles.py +136 -0
- fg_env/runtime/__init__.py +41 -0
- fg_env/runtime/actions.py +449 -0
- fg_env/runtime/conditions.py +256 -0
- fg_env/runtime/effect_dispatch.py +1050 -0
- fg_env/runtime/engine.py +1358 -0
- fg_env/runtime/perception.py +312 -0
- fg_env/runtime/sequence.py +87 -0
- fg_env/runtime/termination.py +767 -0
- fg_env/runtime/triggers.py +190 -0
- fg_env/runtime/turn.py +537 -0
- fg_env/sdk/__init__.py +4 -0
- fg_env/sdk/action_params.py +55 -0
- fg_env/sdk/action_schemas.py +255 -0
- fg_env/sdk/action_validation.py +266 -0
- fg_env/sdk/actions.py +373 -0
- fg_env/sdk/analysis/__init__.py +44 -0
- fg_env/sdk/analysis/accuracy.py +120 -0
- fg_env/sdk/analysis/assessment.py +78 -0
- fg_env/sdk/analysis/backtest.py +307 -0
- fg_env/sdk/analysis/calibrate.py +459 -0
- fg_env/sdk/analysis/checks.py +337 -0
- fg_env/sdk/analysis/cli.py +396 -0
- fg_env/sdk/analysis/compare.py +268 -0
- fg_env/sdk/analysis/constraints.py +254 -0
- fg_env/sdk/analysis/decisions.py +502 -0
- fg_env/sdk/analysis/draws.py +120 -0
- fg_env/sdk/analysis/drivers.py +230 -0
- fg_env/sdk/analysis/facts.py +133 -0
- fg_env/sdk/analysis/goals.py +209 -0
- fg_env/sdk/analysis/highlights.py +385 -0
- fg_env/sdk/analysis/holdout.py +76 -0
- fg_env/sdk/analysis/optimise.py +489 -0
- fg_env/sdk/analysis/optimise_guide.py +65 -0
- fg_env/sdk/analysis/optimise_result.py +193 -0
- fg_env/sdk/analysis/optimize.py +177 -0
- fg_env/sdk/analysis/output_scope.py +74 -0
- fg_env/sdk/analysis/runner.py +177 -0
- fg_env/sdk/analysis/scoring.py +289 -0
- fg_env/sdk/analysis/search.py +183 -0
- fg_env/sdk/analysis/sensitivity.py +247 -0
- fg_env/sdk/analysis/stats.py +345 -0
- fg_env/sdk/analysis/sweep.py +307 -0
- fg_env/sdk/analysis/targets.py +243 -0
- fg_env/sdk/analysis/validate.py +244 -0
- fg_env/sdk/api.py +379 -0
- fg_env/sdk/arm_inputs.py +38 -0
- fg_env/sdk/assets/__init__.py +15 -0
- fg_env/sdk/assets/blobs.py +111 -0
- fg_env/sdk/assets/catalog.py +183 -0
- fg_env/sdk/assets/checks.py +90 -0
- fg_env/sdk/assets/delivery.py +130 -0
- fg_env/sdk/assets/describe.py +70 -0
- fg_env/sdk/assets/functions.py +38 -0
- fg_env/sdk/assets/guide.py +69 -0
- fg_env/sdk/assets/intake.py +200 -0
- fg_env/sdk/assets/kinds.py +91 -0
- fg_env/sdk/assets/multimodal.py +130 -0
- fg_env/sdk/assets/spec.py +25 -0
- fg_env/sdk/assets/store.py +199 -0
- fg_env/sdk/bench.py +160 -0
- fg_env/sdk/binomial.py +48 -0
- fg_env/sdk/branch.py +348 -0
- fg_env/sdk/budget.py +159 -0
- fg_env/sdk/build.py +533 -0
- fg_env/sdk/captures.py +76 -0
- fg_env/sdk/chance.py +229 -0
- fg_env/sdk/check.py +383 -0
- fg_env/sdk/check_actions.py +254 -0
- fg_env/sdk/check_effects.py +321 -0
- fg_env/sdk/check_inventory.py +64 -0
- fg_env/sdk/check_params.py +76 -0
- fg_env/sdk/check_roots.py +24 -0
- fg_env/sdk/check_rules.py +194 -0
- fg_env/sdk/check_scans.py +196 -0
- fg_env/sdk/check_space.py +126 -0
- fg_env/sdk/check_state.py +201 -0
- fg_env/sdk/check_turns.py +67 -0
- fg_env/sdk/check_world.py +306 -0
- fg_env/sdk/cli.py +439 -0
- fg_env/sdk/cli_games.py +86 -0
- fg_env/sdk/cli_new.py +37 -0
- fg_env/sdk/cli_runs.py +137 -0
- fg_env/sdk/clock_math.py +25 -0
- fg_env/sdk/clock_words.py +115 -0
- fg_env/sdk/contract.py +261 -0
- fg_env/sdk/contract_base.py +81 -0
- fg_env/sdk/contract_measure.py +107 -0
- fg_env/sdk/contract_rules.py +240 -0
- fg_env/sdk/contract_world.py +336 -0
- fg_env/sdk/copying.py +36 -0
- fg_env/sdk/coupled_physics.py +195 -0
- fg_env/sdk/delivery.py +73 -0
- fg_env/sdk/describe/__init__.py +91 -0
- fg_env/sdk/describe/claims.py +61 -0
- fg_env/sdk/describe/metadata.py +393 -0
- fg_env/sdk/describe/odd.py +335 -0
- fg_env/sdk/describe/walk.py +143 -0
- fg_env/sdk/diagnostics.py +230 -0
- fg_env/sdk/driving.py +458 -0
- fg_env/sdk/effects.py +829 -0
- fg_env/sdk/entity_physics.py +182 -0
- fg_env/sdk/errors.py +62 -0
- fg_env/sdk/evaluate/__init__.py +11 -0
- fg_env/sdk/evaluate/play.py +124 -0
- fg_env/sdk/evaluate/result.py +126 -0
- fg_env/sdk/evaluate/suite.py +198 -0
- fg_env/sdk/experiment.py +501 -0
- fg_env/sdk/exposure.py +278 -0
- fg_env/sdk/expr.py +92 -0
- fg_env/sdk/expr_base.py +173 -0
- fg_env/sdk/expr_calls.py +183 -0
- fg_env/sdk/expr_codegen.py +604 -0
- fg_env/sdk/expr_compile.py +195 -0
- fg_env/sdk/expr_scope.py +103 -0
- fg_env/sdk/expr_values.py +205 -0
- fg_env/sdk/feeds.py +152 -0
- fg_env/sdk/fork.py +405 -0
- fg_env/sdk/functions.py +663 -0
- fg_env/sdk/game/__init__.py +17 -0
- fg_env/sdk/game/algorithms/__init__.py +15 -0
- fg_env/sdk/game/algorithms/best_response.py +123 -0
- fg_env/sdk/game/algorithms/cfr.py +87 -0
- fg_env/sdk/game/algorithms/mcts.py +315 -0
- fg_env/sdk/game/algorithms/minimax.py +133 -0
- fg_env/sdk/game/algorithms/participants.py +216 -0
- fg_env/sdk/game/algorithms/policy.py +68 -0
- fg_env/sdk/game/algorithms/tree.py +142 -0
- fg_env/sdk/game/bench.py +116 -0
- fg_env/sdk/game/conformance.py +373 -0
- fg_env/sdk/game/game.py +254 -0
- fg_env/sdk/game/leaks.py +148 -0
- fg_env/sdk/game/observe.py +144 -0
- fg_env/sdk/game/pettingzoo.py +284 -0
- fg_env/sdk/game/playthrough.py +117 -0
- fg_env/sdk/game/runs.py +114 -0
- fg_env/sdk/game/space.py +344 -0
- fg_env/sdk/game/state.py +467 -0
- fg_env/sdk/game/steps.py +90 -0
- fg_env/sdk/game/transforms.py +192 -0
- fg_env/sdk/game_spec.py +35 -0
- fg_env/sdk/geometry.py +259 -0
- fg_env/sdk/guide.py +270 -0
- fg_env/sdk/guide_pages.py +320 -0
- fg_env/sdk/guide_text.py +502 -0
- fg_env/sdk/gym.py +208 -0
- fg_env/sdk/happenings.py +191 -0
- fg_env/sdk/host/__init__.py +30 -0
- fg_env/sdk/host/adapters.py +273 -0
- fg_env/sdk/host/allowlist.py +411 -0
- fg_env/sdk/host/api.py +77 -0
- fg_env/sdk/host/common.py +70 -0
- fg_env/sdk/host/hosts.py +101 -0
- fg_env/sdk/host/personas.py +125 -0
- fg_env/sdk/host/protocols.py +108 -0
- fg_env/sdk/host/stubs.py +156 -0
- fg_env/sdk/host/tape.py +180 -0
- fg_env/sdk/host/tools.py +165 -0
- fg_env/sdk/host/turn_tools.py +245 -0
- fg_env/sdk/inputs.py +221 -0
- fg_env/sdk/integration.py +61 -0
- fg_env/sdk/layer_effect.py +101 -0
- fg_env/sdk/layers.py +90 -0
- fg_env/sdk/links.py +262 -0
- fg_env/sdk/load_calibration.py +67 -0
- fg_env/sdk/macros.py +298 -0
- fg_env/sdk/measure.py +241 -0
- fg_env/sdk/mechanisms/__init__.py +419 -0
- fg_env/sdk/mechanisms/_common.py +315 -0
- fg_env/sdk/mechanisms/_game.py +27 -0
- fg_env/sdk/mechanisms/_social.py +168 -0
- fg_env/sdk/mechanisms/abilities.py +510 -0
- fg_env/sdk/mechanisms/amm.py +551 -0
- fg_env/sdk/mechanisms/auction_reads.py +103 -0
- fg_env/sdk/mechanisms/auctions.py +731 -0
- fg_env/sdk/mechanisms/beliefs.py +297 -0
- fg_env/sdk/mechanisms/board_engine.py +538 -0
- fg_env/sdk/mechanisms/board_geometry.py +213 -0
- fg_env/sdk/mechanisms/board_rules.py +610 -0
- fg_env/sdk/mechanisms/boards.py +677 -0
- fg_env/sdk/mechanisms/book_functions.py +127 -0
- fg_env/sdk/mechanisms/book_mechanism.py +254 -0
- fg_env/sdk/mechanisms/book_rules.py +148 -0
- fg_env/sdk/mechanisms/book_session.py +126 -0
- fg_env/sdk/mechanisms/card_scoring.py +348 -0
- fg_env/sdk/mechanisms/cards.py +736 -0
- fg_env/sdk/mechanisms/cards_mechanism.py +201 -0
- fg_env/sdk/mechanisms/channels.py +641 -0
- fg_env/sdk/mechanisms/common.py +57 -0
- fg_env/sdk/mechanisms/contract_cache.py +55 -0
- fg_env/sdk/mechanisms/deliberation.py +605 -0
- fg_env/sdk/mechanisms/diffusion.py +377 -0
- fg_env/sdk/mechanisms/econ_asset_actions.py +254 -0
- fg_env/sdk/mechanisms/econ_assets.py +620 -0
- fg_env/sdk/mechanisms/econ_base.py +299 -0
- fg_env/sdk/mechanisms/econ_bookings.py +397 -0
- fg_env/sdk/mechanisms/econ_demand.py +355 -0
- fg_env/sdk/mechanisms/econ_demand_trade.py +517 -0
- fg_env/sdk/mechanisms/econ_inventory.py +298 -0
- fg_env/sdk/mechanisms/econ_labor.py +380 -0
- fg_env/sdk/mechanisms/econ_ledger.py +371 -0
- fg_env/sdk/mechanisms/econ_negotiation.py +632 -0
- fg_env/sdk/mechanisms/econ_production.py +398 -0
- fg_env/sdk/mechanisms/econ_replenishment.py +233 -0
- fg_env/sdk/mechanisms/econ_replenishment_rules.py +378 -0
- fg_env/sdk/mechanisms/econ_subscriptions.py +301 -0
- fg_env/sdk/mechanisms/econ_supply_chain.py +272 -0
- fg_env/sdk/mechanisms/economy.py +28 -0
- fg_env/sdk/mechanisms/families.py +59 -0
- fg_env/sdk/mechanisms/feed.py +644 -0
- fg_env/sdk/mechanisms/judging.py +507 -0
- fg_env/sdk/mechanisms/ledger.py +86 -0
- fg_env/sdk/mechanisms/locations.py +322 -0
- fg_env/sdk/mechanisms/market_stats.py +231 -0
- fg_env/sdk/mechanisms/markets.py +32 -0
- fg_env/sdk/mechanisms/memory.py +467 -0
- fg_env/sdk/mechanisms/ops_engine.py +356 -0
- fg_env/sdk/mechanisms/ops_queue.py +394 -0
- fg_env/sdk/mechanisms/ops_stats.py +138 -0
- fg_env/sdk/mechanisms/order_book.py +653 -0
- fg_env/sdk/mechanisms/package_auction.py +187 -0
- fg_env/sdk/mechanisms/posted.py +560 -0
- fg_env/sdk/mechanisms/pot.py +617 -0
- fg_env/sdk/mechanisms/procedure.py +440 -0
- fg_env/sdk/mechanisms/procedure_stack.py +456 -0
- fg_env/sdk/mechanisms/relationships.py +499 -0
- fg_env/sdk/mechanisms/roles.py +272 -0
- fg_env/sdk/mechanisms/slots.py +208 -0
- fg_env/sdk/mechanisms/social.py +19 -0
- fg_env/sdk/mechanisms/status.py +463 -0
- fg_env/sdk/mechanisms/traders.py +328 -0
- fg_env/sdk/mechanisms/turn_order.py +233 -0
- fg_env/sdk/mechanisms/victory.py +249 -0
- fg_env/sdk/mechanisms/voting.py +366 -0
- fg_env/sdk/networks.py +132 -0
- fg_env/sdk/parse_errors.py +119 -0
- fg_env/sdk/participants.py +592 -0
- fg_env/sdk/patterns/__init__.py +7 -0
- fg_env/sdk/patterns/base.py +163 -0
- fg_env/sdk/patterns/catalogue.py +6 -0
- fg_env/sdk/patterns/check.py +285 -0
- fg_env/sdk/patterns/compose.py +118 -0
- fg_env/sdk/patterns/count_math.py +167 -0
- fg_env/sdk/patterns/decompose.py +145 -0
- fg_env/sdk/patterns/describe.py +40 -0
- fg_env/sdk/patterns/draws.py +222 -0
- fg_env/sdk/patterns/estimators.py +482 -0
- fg_env/sdk/patterns/expand.py +115 -0
- fg_env/sdk/patterns/fit.py +410 -0
- fg_env/sdk/patterns/guide.py +151 -0
- fg_env/sdk/patterns/joint.py +404 -0
- fg_env/sdk/patterns/memory.py +239 -0
- fg_env/sdk/patterns/numeric.py +438 -0
- fg_env/sdk/patterns/observe.py +130 -0
- fg_env/sdk/patterns/processes.py +380 -0
- fg_env/sdk/patterns/product_math.py +44 -0
- fg_env/sdk/patterns/responses.py +231 -0
- fg_env/sdk/patterns/runtime.py +457 -0
- fg_env/sdk/patterns/schema.py +34 -0
- fg_env/sdk/patterns/signals.py +479 -0
- fg_env/sdk/patterns/timebase.py +181 -0
- fg_env/sdk/perception.py +344 -0
- fg_env/sdk/pilot.py +301 -0
- fg_env/sdk/poisson.py +73 -0
- fg_env/sdk/positions.py +173 -0
- fg_env/sdk/previews.py +117 -0
- fg_env/sdk/probability.py +18 -0
- fg_env/sdk/props.py +48 -0
- fg_env/sdk/reads.py +225 -0
- fg_env/sdk/record_events.py +52 -0
- fg_env/sdk/record_index.py +104 -0
- fg_env/sdk/registry.py +317 -0
- fg_env/sdk/replay.py +185 -0
- fg_env/sdk/report/__init__.py +221 -0
- fg_env/sdk/report/cli.py +88 -0
- fg_env/sdk/report/confidence.py +117 -0
- fg_env/sdk/report/demand.py +157 -0
- fg_env/sdk/report/evidence.py +231 -0
- fg_env/sdk/report/noise.py +80 -0
- fg_env/sdk/report/optimisation.py +146 -0
- fg_env/sdk/report/pattern_effects.py +176 -0
- fg_env/sdk/report/queue.py +288 -0
- fg_env/sdk/report/sections.py +376 -0
- fg_env/sdk/report/words.py +138 -0
- fg_env/sdk/result_file.py +161 -0
- fg_env/sdk/returns.py +169 -0
- fg_env/sdk/run_checks.py +76 -0
- fg_env/sdk/run_copy.py +297 -0
- fg_env/sdk/run_diagnosis.py +281 -0
- fg_env/sdk/run_rounds.py +221 -0
- fg_env/sdk/run_stages.py +362 -0
- fg_env/sdk/runtime.py +359 -0
- fg_env/sdk/scaffold.py +152 -0
- fg_env/sdk/seeds.py +42 -0
- fg_env/sdk/session.py +254 -0
- fg_env/sdk/snapshot.py +319 -0
- fg_env/sdk/space.py +135 -0
- fg_env/sdk/space_functions.py +132 -0
- fg_env/sdk/stdlib/__init__.py +6 -0
- fg_env/sdk/stdlib/_args.py +145 -0
- fg_env/sdk/stdlib/dates.py +145 -0
- fg_env/sdk/stdlib/dists.py +264 -0
- fg_env/sdk/stdlib/linalg.py +274 -0
- fg_env/sdk/stdlib/lists.py +186 -0
- fg_env/sdk/stdlib/mathx.py +216 -0
- fg_env/sdk/stdlib/puzzles.py +330 -0
- fg_env/sdk/stdlib/regex.py +324 -0
- fg_env/sdk/stdlib/scoring.py +191 -0
- fg_env/sdk/stdlib/sets.py +80 -0
- fg_env/sdk/stdlib/stats.py +254 -0
- fg_env/sdk/stdlib/strings.py +192 -0
- fg_env/sdk/stdlib/tables.py +96 -0
- fg_env/sdk/stdlib/words.py +75 -0
- fg_env/sdk/stepping.py +421 -0
- fg_env/sdk/stochastic.py +72 -0
- fg_env/sdk/stochastic_integration.py +97 -0
- fg_env/sdk/sync_events.py +101 -0
- fg_env/sdk/syntax_hints.py +64 -0
- fg_env/sdk/template.py +212 -0
- fg_env/sdk/tool_text.py +184 -0
- fg_env/sdk/tournament/__init__.py +14 -0
- fg_env/sdk/tournament/evaluation.py +188 -0
- fg_env/sdk/tournament/play.py +176 -0
- fg_env/sdk/tournament/ratings.py +210 -0
- fg_env/sdk/tournament/result.py +110 -0
- fg_env/sdk/tournament/scoring.py +138 -0
- fg_env/sdk/tournament/seating.py +56 -0
- fg_env/sdk/tournament/standings.py +129 -0
- fg_env/sdk/trace/__init__.py +16 -0
- fg_env/sdk/trace/reader.py +262 -0
- fg_env/sdk/trace/render.py +120 -0
- fg_env/sdk/trace/rerun.py +486 -0
- fg_env/sdk/turn.py +560 -0
- fg_env/sdk/type_index.py +84 -0
- fg_env/sdk/workers.py +228 -0
- fg_env/sdk/world.py +819 -0
- fg_env/sdk/world_defaults.py +55 -0
- fg_env/sdk/world_parts.py +147 -0
- fg_env/sdk/world_physics.py +129 -0
- fg_env/sequences.py +106 -0
- fg_env/sim_controller.py +476 -0
- fg_env/skills.py +145 -0
- fg_env/slots_module.py +193 -0
- fg_env/smoke.py +3 -0
- fg_env/snapshot.py +217 -0
- fg_env/social.py +587 -0
- fg_env/spatial.py +183 -0
- fg_env/state.py +912 -0
- fg_env/status_effects.py +213 -0
- fg_env/temporal.py +260 -0
- fg_env/termination.py +684 -0
- fg_env/trade_module.py +389 -0
- fg_env/transfers.py +141 -0
- fg_env/triggers.py +136 -0
- fg_env/turn_manager.py +339 -0
- fg_env/types.py +99 -0
- fg_env/visibility.py +319 -0
- fg_env/world_events.py +296 -0
- fg_env/world_loader.py +22 -0
- fg_env/world_model.py +407 -0
- fg_env-0.3.0.dist-info/METADATA +239 -0
- fg_env-0.3.0.dist-info/RECORD +432 -0
- fg_env-0.3.0.dist-info/WHEEL +4 -0
- fg_env-0.3.0.dist-info/entry_points.txt +2 -0
- 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())
|
fg_env/_snapshot_copy.py
ADDED
|
@@ -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 = ""
|