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
- func CapList(items []map[string]any) []map[string]any
- func Flags(in BehaviorInput) []string
- func Truncate(s string) string
- type AttackChain
- type AttackStep
- type BehaviorInput
- type Config
- type Controller
- func (c *Controller) Active() bool
- func (c *Controller) InjectLLMSystemMessage(component string) (string, bool)
- func (c *Controller) InjectToolResult(toolName, result string) (string, bool)
- func (c *Controller) OnConfigChange(sim *Config)
- func (c *Controller) ProtectionDisabled() bool
- func (c *Controller) Record(ev RuntimeEvent, bi BehaviorInput)
- func (c *Controller) RunID() string
- func (c *Controller) SetManifest(tools, models []string)
- func (c *Controller) Stop()
- type RuntimeEvent
- type State
Constants ¶
const SystemPromptID = "__system__"
SystemPromptID is the sentinel prompt_id for system-level events (heartbeat).
Variables ¶
This section is empty.
Functions ¶
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.
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 ¶
HasMiddleware reports whether name is in the server-selected middleware list.
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.
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).