planning

package
v0.14.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 1, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Overview

Package planning provides goal-directed state planning as an Agent execution strategy. Goal, Condition, WorldState, Action, and Plan belong exclusively to this package; the Agent kernel sees only opaque Execution state and Effects.

Planning separates predicted Action semantics from external execution. A Planner is a pure, deterministic search over a Problem. A managed Planning Execution observes the real world and executes selected Actions outside its Step through a Deployment-bound dispatcher or a child Process, then observes again before accepting that the prediction became true.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ErrInvalidCondition        = errors.New("planning: invalid condition")
	ErrInvalidWorldState       = errors.New("planning: invalid world state")
	ErrInvalidGoal             = errors.New("planning: invalid goal")
	ErrInvalidAction           = errors.New("planning: invalid action")
	ErrInvalidActionCost       = errors.New("planning: invalid action cost")
	ErrInvalidPlan             = errors.New("planning: invalid plan")
	ErrInvalidProblem          = errors.New("planning: invalid problem")
	ErrInvalidDefinitionConfig = errors.New("planning: invalid definition configuration")
	ErrInvalidDispatcherConfig = errors.New("planning: invalid dispatcher configuration")
	ErrInvalidExecutionState   = errors.New("planning: invalid execution state")
	ErrInvalidProtocol         = errors.New("planning: invalid protocol payload")
)

Functions

func NewActionSettlement

func NewActionSettlement(effectID agent.EffectID, result ActionResult) (agent.Settlement, error)

NewActionSettlement converts an executor result into the kernel settlement that closes the effect. Going through this constructor is what keeps an executor from encoding planning vocabulary into a payload the kernel would then have to understand.

Types

type Action

type Action struct {
	// contains filtered or unexported fields
}

Action is an immutable predictive operation used only by Planners. It does not execute I/O and is not a model Tool.

func NewAction

func NewAction(config ActionConfig) (Action, error)

NewAction builds the predictive half of an action — preconditions, effects, and cost — with no executable body. Keeping execution out means the planner can search over actions without the risk of running one, and the same action can be bound to different executors.

func (Action) Applicable

func (a Action) Applicable(state WorldState) bool

Applicable reports whether state establishes every Action precondition.

func (Action) Apply

func (a Action) Apply(source WorldState) (WorldState, error)

Apply returns the Action's predicted successor state. It does not assert that external execution actually produced the prediction.

func (Action) Cost

func (a Action) Cost(source WorldState) (cost float64, err error)

Cost evaluates the Action's predicted edge cost against source. Panics, errors, negative values, and non-finite values are returned as ErrInvalidActionCost.

func (Action) Description

func (a Action) Description() string

Description returns the human-readable predicted behavior.

func (Action) Effects

func (a Action) Effects() []Condition

Effects returns an independently owned, key-sorted prediction set.

func (Action) Name

func (a Action) Name() string

Name returns the stable Action identity.

func (Action) Preconditions

func (a Action) Preconditions() []Condition

Preconditions returns an independently owned, key-sorted requirement set.

func (Action) Valid

func (a Action) Valid() bool

type ActionBinding

type ActionBinding struct {
	// contains filtered or unexported fields
}

ActionBinding is an immutable association between predictive Action semantics and exactly one external execution mechanism.

func NewChildBinding

func NewChildBinding(config ChildBindingConfig) (ActionBinding, error)

NewChildBinding attaches an action to a child Deployment, so a plan step becomes a real Process with its own identity, budget, and recovery instead of an opaque call inside the parent.

func NewDispatcherBinding

func NewDispatcherBinding(config DispatcherBindingConfig) (ActionBinding, error)

NewDispatcherBinding attaches an action to an external executor. Binding is separate from the action itself so the same predictive model can be planned against in tests without an executor present.

func (ActionBinding) Action

func (a ActionBinding) Action() Action

Action returns the immutable predictive Action owned by the binding.

func (ActionBinding) Valid

func (a ActionBinding) Valid() bool

type ActionConfig

type ActionConfig struct {
	// Name is the stable lower-case qualified Action identity.
	Name string

	// Description explains what the Action is expected to accomplish.
	Description string

	// Preconditions are truths required in the source WorldState.
	Preconditions []Condition

	// Effects are truths predicted in the successor WorldState after success.
	Effects []Condition

	// Cost computes the non-negative search edge cost. Nil defaults to 1.
	Cost CostFunc
}

ActionConfig contains one Action's complete predictive planning semantics. External execution is deliberately absent and is bound separately by a managed Planning Definition.

type ActionExecutor

type ActionExecutor interface {
	// Execute attempts one selected Action against the observed WorldState. A
	// valid ActionResult is definite; a non-nil error means the external outcome
	// is unknown and must not be translated into an ordinary failed Action or
	// implicitly retried under a new identity.
	Execute(ctx context.Context, request ActionRequest) (ActionResult, error)
}

ActionExecutor performs one dispatcher-bound Action. A valid ActionResult is a definite success or failure. A non-nil error means the external outcome is unknown, so Dispatcher returns an unknown Effect settlement and never retries it implicitly.

type ActionExecutorFunc

type ActionExecutorFunc func(ctx context.Context, request ActionRequest) (ActionResult, error)

ActionExecutorFunc adapts a plain function to the executor interface, so a single action does not require a named type to be made runnable.

func (ActionExecutorFunc) Execute

func (a ActionExecutorFunc) Execute(
	ctx context.Context,
	request ActionRequest,
) (ActionResult, error)

type ActionRequest

type ActionRequest struct {
	// EffectID is the stable identity of the prepared Action attempt.
	EffectID agent.EffectID
	// Input is the original immutable Planning Process input.
	Input agent.Input
	// ActionName is the exact frozen Action identity.
	ActionName string
	// ActionDescription is the exact frozen model-facing Action description.
	ActionDescription string
	// WorldState is the complete observation against which the Action was selected.
	WorldState WorldState
}

ActionRequest is one external dispatcher Action invocation selected against an observed WorldState. Input and WorldState are immutable values.

type ActionResult

type ActionResult struct {
	// contains filtered or unexported fields
}

ActionResult is the definite external result reported by an ActionExecutor. Its zero value is invalid.

func ActionFailed

func ActionFailed(diagnostic string) (ActionResult, error)

ActionFailed constructs a definite failed Action result with a bounded diagnostic suitable for a portable Planning attempt record.

func ActionSucceeded

func ActionSucceeded() ActionResult

ActionSucceeded returns a definite successful Action result.

func (ActionResult) Diagnostic

func (a ActionResult) Diagnostic() string

Diagnostic returns the definite failure explanation, or an empty string on success.

func (ActionResult) Succeeded

func (a ActionResult) Succeeded() bool

Succeeded reports whether the definite Action result succeeded.

func (ActionResult) Valid

func (a ActionResult) Valid() bool

type Attempt

type Attempt struct {
	// ActionName is the exact Action identity selected for this attempt.
	ActionName string `json:"action_name" jsonschema:"pattern=^[a-z][a-z0-9._-]{0\\,127}$"`
	// Status is the observed semantic outcome of this attempt.
	Status AttemptStatus `json:"status" jsonschema:"enum=succeeded,enum=failed,enum=unconfirmed"`
	// Diagnostic explains failed or unconfirmed attempts and is empty on success.
	Diagnostic string `json:"diagnostic,omitempty" jsonschema:"minLength=1,maxLength=4096"`
}

Attempt is one final, portable Action-attempt fact. Diagnostic is empty only for a succeeded attempt.

func (Attempt) Validate

func (a Attempt) Validate() error

type AttemptStatus

type AttemptStatus string

AttemptStatus records the observed result of one selected Action attempt.

const (
	// AttemptSucceeded means execution succeeded and reobservation established
	// every predicted effect.
	AttemptSucceeded AttemptStatus = "succeeded"
	// AttemptFailed means the dispatcher or child Process definitely failed.
	AttemptFailed AttemptStatus = "failed"
	// AttemptUnconfirmed means execution reported success but reobservation did
	// not establish every predicted effect.
	AttemptUnconfirmed AttemptStatus = "unconfirmed"
)

func (AttemptStatus) Valid

func (a AttemptStatus) Valid() bool

type ChildBindingConfig

type ChildBindingConfig struct {
	// Action is the immutable predictive behavior delegated to a child Process.
	Action Action
	// DeploymentRef identifies the exact child behavior binding.
	DeploymentRef agent.DeploymentRef
	// Input deterministically derives child input; nil reuses Process input.
	Input ChildInputFunc
	// Budget is permanently allocated to each child attempt.
	Budget agent.Budget
	// Capabilities is the attenuated authority granted to each child attempt.
	Capabilities agent.CapabilitySet
}

ChildBindingConfig binds a predictive Action to one exact child Deployment. Every attempt starts a new child Process with a stable Engine-derived identity, explicit budget, and attenuated capabilities.

type ChildInputFunc

type ChildInputFunc func(processInput agent.Input, worldState WorldState) (agent.Input, error)

ChildInputFunc derives a child Process input from the parent input and the current world state, so a plan step can be parameterized by facts discovered during execution rather than only by what the plan was started with.

type Condition

type Condition struct {
	// contains filtered or unexported fields
}

Condition is one immutable known truth requirement or prediction. Unknown is represented by absence from a WorldState and therefore cannot be stored in a Condition.

func NewCondition

func NewCondition(key string, truth Truth) (Condition, error)

NewCondition names one fact the planner reasons over. Conditions are keys with a truth value rather than arbitrary predicates, because the planner has to compare and combine them without executing anything.

func (Condition) JSONSchemaModel

func (Condition) JSONSchemaModel() any

JSONSchemaModel returns the typed JSON wire model owned by Condition.

func (Condition) Key

func (c Condition) Key() string

Key returns the stable condition identity.

func (Condition) MarshalJSON

func (c Condition) MarshalJSON() ([]byte, error)

func (Condition) Truth

func (c Condition) Truth() Truth

Truth returns the known truth asserted by the condition.

func (*Condition) UnmarshalJSON

func (c *Condition) UnmarshalJSON(data []byte) error

func (Condition) Valid

func (c Condition) Valid() bool

type CostFunc

type CostFunc func(source WorldState) (float64, error)

CostFunc lets an action's cost depend on the world state it would run in, which is what allows a planner to prefer a cheap path under current facts rather than a fixed ordering. Returning an error keeps an uncomputable cost from being silently treated as zero, which would make that action always win.

func FixedCost

func FixedCost(value float64) CostFunc

FixedCost returns a CostFunc that always returns value. Validation occurs when an Action evaluates the cost so the same error contract covers fixed and dynamic costs.

type Definition

type Definition struct {
	// contains filtered or unexported fields
}

Definition is an immutable Planning Strategy definition. It contains no Observer or ActionExecutor; those I/O capabilities belong to its Deployment-bound Dispatcher.

func NewDefinition

func NewDefinition(config DefinitionConfig) (*Definition, error)

NewDefinition freezes the goal, actions, and planner into one immutable behavior. The planner is chosen here rather than at run time so that a restored Execution searches with the same algorithm that produced the plan it is resuming.

func (*Definition) Descriptor

func (d *Definition) Descriptor() agent.Descriptor

Descriptor returns the immutable managed Planning contract.

func (*Definition) Restore

func (d *Definition) Restore(state agent.ExecutionState) (agent.Execution, error)

Restore recreates a Planning Execution solely from its opaque state and this exact Definition.

func (*Definition) Start

func (d *Definition) Start(input agent.Input) (agent.Execution, error)

Start creates a fresh Planning Execution from validated opaque task input.

type DefinitionConfig

type DefinitionConfig struct {
	// Name is the stable qualified Definition name.
	Name string

	// Description states the managed goal-directed behavior for discovery.
	Description string

	// InputSchema is the authoritative schema for opaque task input passed to
	// Observer, ActionExecutor, and child input functions.
	InputSchema agent.Schema

	// Goal is the immutable target state.
	Goal Goal

	// Actions binds every predictive Action to exactly one execution mechanism.
	Actions []ActionBinding

	// Planner selects Actions from each newly observed WorldState.
	Planner Planner

	// MaxActionAttempts bounds external Action attempts. It must be positive.
	MaxActionAttempts uint32
}

DefinitionConfig contains one immutable managed Planning behavior. Goal, Planner, and Action bindings are fixed for the exact Deployment; only Input varies per Process.

type Dispatcher

type Dispatcher struct {
	// contains filtered or unexported fields
}

Dispatcher executes observation and dispatcher Action Effects emitted by one Planning Definition. It is immutable after construction and may serve Processes concurrently when Observer and ActionExecutors are concurrent-safe.

func NewDispatcher

func NewDispatcher(definition *Definition, config DispatcherConfig) (*Dispatcher, error)

NewDispatcher binds a definition to the executors that carry out its effects. It is constructed against an exact definition so an effect cannot be routed to an executor the planner never planned against.

func (*Dispatcher) Dispatch

func (d *Dispatcher) Dispatch(
	ctx context.Context,
	request agent.EffectRequest,
	_ agent.DeltaEmitter,
) (agent.Settlement, error)

Dispatch executes one validated Planning protocol operation. Observer errors and valid ActionResult failures are definite failed settlements; an ActionExecutor error leaves the Effect outcome unknown.

func (*Dispatcher) ReplayPolicy

func (*Dispatcher) ReplayPolicy(effect agent.Effect) agent.ReplayPolicy

ReplayPolicy permits same-identity replay only for side-effect-free observation. Action Effects may have irreversible external consequences and always require explicit resolution after an unknown attempt.

type DispatcherBindingConfig

type DispatcherBindingConfig struct {
	// Action is the immutable predictive behavior bound to a dispatcher target.
	Action Action
	// RequiredCapabilities is the authority required before dispatch.
	RequiredCapabilities []agent.Capability
}

DispatcherBindingConfig binds a predictive Action to the Planning Dispatcher. RequiredCapabilities are enforced by Engine before dispatch.

type DispatcherConfig

type DispatcherConfig struct {
	// Observer supplies each complete WorldState observation.
	Observer Observer
	// ActionExecutors maps dispatcher-bound Action names to exact executors.
	ActionExecutors map[string]ActionExecutor
}

DispatcherConfig binds side-effect-free observation and the exact set of dispatcher-targeted Action executors required by a Definition. Child-bound Actions must not appear in ActionExecutors.

type Goal

type Goal struct {
	// contains filtered or unexported fields
}

Goal is an immutable set of desired condition truths.

func NewGoal

func NewGoal(config GoalConfig) (Goal, error)

NewGoal states the target as conditions rather than as a procedure, which is what lets the planner decide the route and re-plan when observed facts change.

func (Goal) Conditions

func (g Goal) Conditions() []Condition

Conditions returns an independently owned, key-sorted requirement set.

func (Goal) Description

func (g Goal) Description() string

Description returns the human-readable desired state.

func (Goal) Name

func (g Goal) Name() string

Name returns the stable goal identity.

func (Goal) SatisfiedBy

func (g Goal) SatisfiedBy(state WorldState) bool

SatisfiedBy reports whether state establishes every goal condition.

func (Goal) Valid

func (g Goal) Valid() bool

type GoalConfig

type GoalConfig struct {
	// Name is the stable lower-case qualified goal identity.
	Name string

	// Description explains the desired state to a human consumer.
	Description string

	// Conditions are the known truths the final WorldState must establish.
	Conditions []Condition
}

GoalConfig contains the complete immutable description of a Planning goal.

type ObservationRequest

type ObservationRequest struct {
	// EffectID is the stable identity of the prepared observation attempt.
	EffectID agent.EffectID
	// Input is the original immutable Planning Process input.
	Input agent.Input
}

ObservationRequest is one side-effect-free request for the current complete WorldState. Input is the original Planning Process input; EffectID is stable for the prepared attempt.

type Observer

type Observer interface {
	// Observe obtains one complete immutable WorldState for the original Process
	// input. It must honor ctx and must not cause externally visible side effects,
	// because the same EffectID may be replayed after an unknown observation.
	Observe(ctx context.Context, request ObservationRequest) (WorldState, error)
}

Observer produces one complete WorldState without externally visible side effects. A returned error is a definite observation failure and terminates Planning; an Observer must not use error to report an unknown side effect.

type ObserverFunc

type ObserverFunc func(ctx context.Context, request ObservationRequest) (WorldState, error)

ObserverFunc adapts a plain function to the observer interface. Observation is an Effect rather than part of a Step, because reading the world is external I/O and its result must arrive as a settlement the Execution can be resumed from.

func (ObserverFunc) Observe

func (o ObserverFunc) Observe(
	ctx context.Context,
	request ObservationRequest,
) (WorldState, error)

type Outcome

type Outcome string

Outcome is the Planning-owned semantic reason a Goal-directed execution completed. It does not add states to the common Process lifecycle.

const (
	// OutcomeAchieved means the latest observed WorldState satisfies the Goal.
	OutcomeAchieved Outcome = "achieved"
	// OutcomeUnreachable means the initial complete planning search found no plan.
	OutcomeUnreachable Outcome = "unreachable"
	// OutcomeStuck means attempts or the Action limit were exhausted without
	// reaching the Goal.
	OutcomeStuck Outcome = "stuck"
)

func (Outcome) Valid

func (o Outcome) Valid() bool

type Output

type Output struct {
	// Outcome is the Planning-owned semantic completion reason.
	Outcome Outcome `json:"outcome" jsonschema:"enum=achieved,enum=unreachable,enum=stuck"`
	// WorldState is the final complete observation.
	WorldState WorldState `json:"world_state"`
	// Attempts preserves Action-attempt order.
	Attempts []Attempt `json:"attempts"`
	// PlanningPasses counts calls to Planner.
	PlanningPasses uint32 `json:"planning_passes" jsonschema:"maximum=4294967295"`
}

Output is the final semantic Planning result. WorldState is the last complete observation, Attempts preserve selection order, and PlanningPasses counts calls to Planner. No field is derived from Event or Delta history.

func (Output) Validate

func (o Output) Validate() error

type Plan

type Plan struct {
	// contains filtered or unexported fields
}

Plan is an immutable ordered Action sequence and its predicted total cost. An empty Plan with zero cost is valid and represents an already-satisfied Goal; Planner's separate found result distinguishes it from no solution.

func NewPlan

func NewPlan(actions []PlannedAction, totalCost float64) (Plan, error)

NewPlan carries the total cost alongside the steps so an operator can compare two plans without re-running the search that produced them.

func (Plan) Actions

func (p Plan) Actions() []PlannedAction

Actions returns independently owned Action references in execution order.

func (Plan) MarshalJSON

func (p Plan) MarshalJSON() ([]byte, error)

func (Plan) TotalCost

func (p Plan) TotalCost() float64

TotalCost returns the predicted sum of Action edge costs.

func (*Plan) UnmarshalJSON

func (p *Plan) UnmarshalJSON(data []byte) error

func (Plan) Valid

func (p Plan) Valid() bool

type PlannedAction

type PlannedAction struct {
	// contains filtered or unexported fields
}

PlannedAction is one immutable Action reference in Planner-selected order. It contains no executable capability or copied Action metadata.

func NewPlannedAction

func NewPlannedAction(name string) (PlannedAction, error)

NewPlannedAction names a step by action name only. A plan holds names rather than action values so it stays serializable in the Execution snapshot, and so resuming resolves the action from the Definition instead of trusting a stored copy.

func (PlannedAction) MarshalJSON

func (p PlannedAction) MarshalJSON() ([]byte, error)

func (PlannedAction) Name

func (p PlannedAction) Name() string

Name returns the referenced Action identity.

func (*PlannedAction) UnmarshalJSON

func (p *PlannedAction) UnmarshalJSON(data []byte) error

func (PlannedAction) Valid

func (p PlannedAction) Valid() bool

type Planner

type Planner interface {
	// Plan searches one immutable Problem without mutating it or performing I/O.
	// found=false with nil error is reserved for an exhausted complete search;
	// cancellation, resource limits, invalid costs, and internal failure return
	// errors. Equivalent Problems must produce an equivalent ordered Plan.
	Plan(ctx context.Context, problem Problem) (plan Plan, found bool, err error)
}

Planner finds an ordered Action sequence for one immutable Problem. It must be deterministic and side-effect-free for the same Problem, safe for concurrent calls, and honor context cancellation. found=false with nil error means the search proved no plan within its algorithm's complete search space; resource exhaustion must be returned as an error instead.

type PlannerFunc

type PlannerFunc func(ctx context.Context, problem Problem) (plan Plan, found bool, err error)

PlannerFunc adapts a plain function to the planner interface. The separate found result distinguishes a completed search that proved no path exists from a search that failed, because the first is a legitimate planning answer and the second is an error.

func (PlannerFunc) Plan

func (p PlannerFunc) Plan(
	ctx context.Context,
	problem Problem,
) (Plan, bool, error)

type Problem

type Problem struct {
	// contains filtered or unexported fields
}

Problem is one immutable Planner input: a current observation, one Goal, and the available predictive Actions. It contains no dispatcher, Process, or application dependency.

func NewProblem

func NewProblem(initial WorldState, goal Goal, actions ...Action) (Problem, error)

NewProblem binds the initial state, the goal, and the actions available to reach it into one value, so a planner cannot be handed a goal without the vocabulary it is expected to search over.

func (Problem) Action

func (p Problem) Action(name string) (Action, bool)

Action returns the named Action and true, or the zero Action and false.

func (Problem) Actions

func (p Problem) Actions() []Action

Actions returns an independently owned slice in declaration order.

func (Problem) Goal

func (p Problem) Goal() Goal

Goal returns the immutable desired state.

func (Problem) InitialState

func (p Problem) InitialState() WorldState

InitialState returns the immutable starting observation.

func (Problem) Valid

func (p Problem) Valid() bool

func (Problem) ValidatePlan

func (p Problem) ValidatePlan(plan Plan) error

ValidatePlan verifies that every referenced Action exists and is applicable in sequence, the reported cost equals the evaluated path cost, and the predicted final state satisfies the Goal.

type Truth

type Truth string

Truth is the three-valued truth of one observed condition. Unknown is not a synonym for False: it means the current WorldState does not establish either known value. The zero value is invalid; callers must choose explicitly.

const (
	// Unknown means the current observation does not establish the condition.
	Unknown Truth = "unknown"
	// False means the current observation establishes that the condition is false.
	False Truth = "false"
	// True means the current observation establishes that the condition is true.
	True Truth = "true"
)

func (Truth) MarshalJSON

func (t Truth) MarshalJSON() ([]byte, error)

func (Truth) String

func (t Truth) String() string

func (*Truth) UnmarshalJSON

func (t *Truth) UnmarshalJSON(data []byte) error

func (Truth) Valid

func (t Truth) Valid() bool

type WorldState

type WorldState struct {
	// contains filtered or unexported fields
}

WorldState is an immutable, canonical observation of known condition truths. Missing conditions read as Unknown. Its zero value is the valid empty state.

func NewWorldState

func NewWorldState(conditions ...Condition) (WorldState, error)

NewWorldState collects the facts a plan is evaluated against. It is a validated set rather than a free-form map because the planner compares states for equality while searching, and duplicate or conflicting conditions would make that comparison meaningless.

Example
package main

import (
	"fmt"

	"github.com/Tangerg/scope/agent/planning"
)

func main() {
	ready, err := planning.NewCondition("service.ready", planning.True)
	if err != nil {
		panic(err)
	}
	state, err := planning.NewWorldState(ready)
	if err != nil {
		panic(err)
	}

	fmt.Println(state.Truth("service.ready"), state.Truth("service.cached"), state.Satisfies(ready))
}
Output:
true unknown true

func (WorldState) Apply

func (w WorldState) Apply(effects ...Condition) (WorldState, error)

Apply returns a new state with predicted effects layered over this state. The receiver is never mutated.

func (WorldState) Conditions

func (w WorldState) Conditions() []Condition

Conditions returns an independently owned, key-sorted snapshot.

func (WorldState) JSONSchemaModel

func (WorldState) JSONSchemaModel() any

JSONSchemaModel returns the typed JSON wire model owned by WorldState.

func (WorldState) Key

func (w WorldState) Key() string

Key returns a stable identity derived only from canonical known truths.

func (WorldState) MarshalJSON

func (w WorldState) MarshalJSON() ([]byte, error)

func (WorldState) Satisfies

func (w WorldState) Satisfies(requirements ...Condition) bool

Satisfies reports whether w establishes every required condition.

func (WorldState) Truth

func (w WorldState) Truth(key string) Truth

Truth returns the observed truth for key, or Unknown when key is absent.

func (*WorldState) UnmarshalJSON

func (w *WorldState) UnmarshalJSON(data []byte) error

func (WorldState) Valid

func (w WorldState) Valid() bool

Directories

Path Synopsis
Package goap provides deterministic goal-oriented action planning over immutable planning.WorldState values.
Package goap provides deterministic goal-oriented action planning over immutable planning.WorldState values.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL