simulation

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Aug 21, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package simulation implements the flyedge-go client for the platform's agent simulation / attack-injection layer. When the config poller reports an active simulation (the `simulation` block of GET /v1/flyedge/config), the Controller streams RuntimeEvents to the run's telemetry WebSocket so the CompFly Simulation Lab can observe — and, in attack mode, red-team — the agent.

It is a subpackage on purpose: the WebSocket dependency lives here only, so the core flyedge package stays stdlib-only. flyedge imports simulation (one-way); simulation never imports flyedge.

Behavioral reference: the Python SDK's simulation layer. The wire shapes below match it exactly.

Index

Constants

View Source
const SystemPromptID = "__system__"

SystemPromptID is the sentinel prompt_id for system-level events (heartbeat).

Variables

This section is empty.

Functions

func CapList

func CapList(items []map[string]any) []map[string]any

CapList caps a slice of maps to maxListItems (llm_messages / tool_calls).

func Flags

func Flags(in BehaviorInput) []string

Flags runs all detectors and returns the behavioral flags for an operation. Observe-only — it never blocks. The controller attaches these to the RuntimeEvent.

func Truncate

func Truncate(s string) string

Truncate caps a string field to maxFieldChars (matches the Python telemetry cap).

Types

type AttackChain

type AttackChain struct {
	Name  string
	Steps []AttackStep
	// contains filtered or unexported fields
}

AttackChain fires its steps sequentially — each waits for a matching component call.

type AttackStep

type AttackStep struct {
	Strategy       string
	TargetType     string // llm | tool | retriever | checkpoint
	TargetName     string // "*" (or "") matches any component of that type
	Sophistication int
	Payload        any // explicit override; nil → resolve from the payload tables
	Variant        int
}

AttackStep targets one component type/name with a strategy + sophistication.

type BehaviorInput

type BehaviorInput struct {
	ComponentType string // "tool" | "llm" | "retriever" | ...
	ComponentName string
	ArgsText      string
	ResultText    string
	ErrorText     string
}

BehaviorInput is what the monitor scans for a single intercepted operation. ArgsText is the stringified tool args / LLM kwargs; Result/Error are the outcome.

type Config

type Config struct {
	Active             bool            `json:"active"`
	RunID              string          `json:"run_id"`
	Middlewares        []string        `json:"middlewares"`
	TelemetryJWT       string          `json:"telemetry_jwt"`
	TelemetryURL       string          `json:"telemetry_url"`
	ProtectionDisabled bool            `json:"protection_disabled"`
	Extra              json.RawMessage `json:"extra,omitempty"`
}

Config is the `simulation` block from GET /v1/flyedge/config (frozen wire — matches prism SimulationConfig / the Python SimulationConfig). flyedge converts its own SimulationConfig into this when handing off to the Controller.

func (*Config) HasMiddleware

func (c *Config) HasMiddleware(name string) bool

HasMiddleware reports whether name is in the server-selected middleware list.

func (*Config) Valid

func (c *Config) Valid() bool

Valid reports whether the config has everything required to activate a run.

type Controller

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

Controller manages the simulation lifecycle for a Guard. The config poller calls OnConfigChange whenever the `simulation` block changes; the Controller starts/stops the telemetry WebSocket, drives the heartbeat, tracks protection_disabled, and streams RuntimeEvents the Guard hands it via Record. Mirrors the Python SimulationConfigHandler, adapted to Go's explicit interception model (no middleware orchestrator — the Guard's own seams call Record).

func New

func New(framework string) *Controller

New builds a Controller. framework labels emitted events (e.g. "flyedge-go/anthropic").

func (*Controller) Active

func (c *Controller) Active() bool

Active reports whether a simulation run is currently active.

func (*Controller) InjectLLMSystemMessage

func (c *Controller) InjectLLMSystemMessage(component string) (string, bool)

InjectLLMSystemMessage returns an adversarial system message to insert into an LLM request when the active run is in attack mode (config_inject), emitting the injection telemetry. Returns ("", false) otherwise.

func (*Controller) InjectToolResult

func (c *Controller) InjectToolResult(toolName, result string) (string, bool)

InjectToolResult applies a tool_poison/error_inject step to a tool result when the active run is in attack mode, emits the injection telemetry, and returns the (possibly mutated) result. No-op (and returns the original result) otherwise — so the Guard can call it unconditionally.

func (*Controller) OnConfigChange

func (c *Controller) OnConfigChange(sim *Config)

OnConfigChange reacts to the simulation block from the config poll. nil ⇒ no simulation (deactivate if running). A changed run_id restarts; the same run_id hot-swaps config (tier transitions).

func (*Controller) ProtectionDisabled

func (c *Controller) ProtectionDisabled() bool

ProtectionDisabled reports whether the active run requested protection be disabled (baseline eval) — the Guard then short-circuits /check to allow.

func (*Controller) Record

func (c *Controller) Record(ev RuntimeEvent, bi BehaviorInput)

Record finalizes and streams a RuntimeEvent if a run is active and telemetry is enabled. It stamps event_id/run_id/timestamp and, when behavior_monitor is on and the caller hasn't set flags, attaches behavior flags from bi. No-op otherwise, so the Guard can call it unconditionally on every intercepted operation.

func (*Controller) RunID

func (c *Controller) RunID() string

RunID returns the active run id ("" if inactive).

func (*Controller) SetManifest

func (c *Controller) SetManifest(tools, models []string)

SetManifest gives the profiler the agent's declared tools/models (from Connect) so the agent_profile emitted in observe mode reflects the declared surface plus runtime observations. Safe to call before or after a run activates.

func (*Controller) Stop

func (c *Controller) Stop()

Stop force-deactivates on Guard shutdown.

type RuntimeEvent

type RuntimeEvent struct {
	EventID       string  `json:"event_id"`
	RunID         string  `json:"run_id"`
	PromptID      string  `json:"prompt_id"`
	Timestamp     float64 `json:"timestamp"` // unix epoch seconds (float), matching Python time.time()
	ComponentType string  `json:"component_type"`
	ComponentName string  `json:"component_name"`
	Framework     string  `json:"framework,omitempty"`

	// LLM-specific
	LLMMessages  []map[string]any `json:"llm_messages,omitempty"`
	LLMModel     string           `json:"llm_model,omitempty"`
	LLMResponse  string           `json:"llm_response,omitempty"`
	LLMToolCalls []map[string]any `json:"llm_tool_calls,omitempty"`

	// Tool-specific
	ToolName   string `json:"tool_name,omitempty"`
	ToolArgs   any    `json:"tool_args,omitempty"` // dict (map) or the heartbeat payload
	ToolResult string `json:"tool_result,omitempty"`
	ToolError  string `json:"tool_error,omitempty"`

	// Retriever-specific
	RetrieverQuery   string           `json:"retriever_query,omitempty"`
	RetrieverResults []map[string]any `json:"retriever_results,omitempty"`

	// Behavioral flags (set by the behavior monitor)
	Flags []string `json:"flags,omitempty"`

	// Injection tracking (set by the attack injector)
	InjectionID             string `json:"injection_id,omitempty"`
	InjectionStrategy       string `json:"injection_strategy,omitempty"`
	InjectionTarget         string `json:"injection_target,omitempty"`
	InjectionSophistication int    `json:"injection_sophistication,omitempty"`
	InjectionChain          string `json:"injection_chain,omitempty"`
	InjectionTier           int    `json:"injection_tier,omitempty"`

	// Agent profiling (set by the attack injector in observe mode)
	AgentProfile map[string]any `json:"agent_profile,omitempty"`
}

RuntimeEvent is a single runtime event streamed over the telemetry WebSocket. prism republishes it to the platform for the Simulation Lab. JSON matches the Python RuntimeEvent.to_dict (optional fields omitted when empty).

type State

type State string

State is the lifecycle state of the simulation controller.

const (
	StateInactive State = "inactive"
	StateStarting State = "starting"
	StateActive   State = "active"
	StateStopping State = "stopping"
)

Jump to

Keyboard shortcuts

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