Feature: Actor configuration uncovered lines coverage As a developer maintaining actor configuration parsing I want robust coverage for actor config edge cases So that failures and overrides are validated Background: Given an isolated actor config workspace # --- load_blob_from_file: lines 39-55 --- Scenario: Missing config file surfaces helpful error When I load the actor config blob from "missing.json" Then a ValueError should be raised containing "Config file not found" Scenario: JSON null config becomes empty mapping Given an actor config file "null.json" with content: """ null """ When I load the actor config blob from "null.json" Then the loaded actor config blob should equal {} Scenario: JSON list config raises validation error Given an actor config file "list.json" with content: """ [1, 2, 3] """ When I load the actor config blob from "list.json" Then a ValueError should be raised containing "Config must be a JSON or YAML object" Scenario: Valid JSON config is loaded correctly Given an actor config file "valid.json" with content: """ {"provider": "openai", "model": "gpt-4"} """ When I load the actor config blob from "valid.json" Then the loaded actor config blob should equal {"provider": "openai", "model": "gpt-4"} # --- _load_v2_yaml_content: lines 59-60 (yaml unavailable) --- Scenario: YAML dependency absence surfaces requirement Given PyYAML parsing is unavailable for actor config And an actor config file "needs_yaml.yaml" with content: """ provider: openai """ When I load the actor config blob from "needs_yaml.yaml" Then a ValueError should be raised containing "PyYAML is required for YAML actor configs" # --- _load_v2_yaml_content: lines 63-106 (YAML parsing paths) --- Scenario: Empty YAML returns empty object Given an actor config file "empty.yaml" with content: """ """ When I load the actor config blob from "empty.yaml" Then the loaded actor config blob should equal {} Scenario: Non-object YAML raises validation error Given an actor config file "list.yaml" with content: """ - provider: openai """ When I load the actor config blob from "list.yaml" Then a ValueError should be raised containing "Config must be a JSON or YAML object" Scenario: Plain YAML config is loaded via safe_load path Given an actor config file "plain.yaml" with content: """ provider: openai model: gpt-4 """ When I load the actor config blob from "plain.yaml" Then the loaded actor config blob should equal {"provider": "openai", "model": "gpt-4"} # --- _load_v2_yaml_content: lines 64-92 (templated YAML branch) --- Scenario: Templated YAML preserves double-brace placeholders in system_prompt Given an actor config file "templated.yaml" with content: """ provider: openai model: gpt-4 system_prompt: "Use {{ context.paper_details.topic }} to write." """ When I load the actor config blob from "templated.yaml" Then the loaded actor config value at "system_prompt" should equal "Use {{ context.paper_details.topic }} to write." Scenario: Templated YAML preserves block-tag placeholders in system_prompt Given an actor config file "block_template.yaml" with content: """ provider: openai model: gpt-4 system_prompt: "{% if context.brainstorming_summary %}summary{% endif %}" """ When I load the actor config blob from "block_template.yaml" Then the loaded actor config value at "system_prompt" should contain "summary" # --- _restore_template_syntax: lines 110-130 (dict and list recursion) --- Scenario: Restore template syntax recurses into nested dicts Given an actor config file "nested_template.yaml" with content: """ provider: openai model: gpt-4 outer: system_prompt: "Hello {{ context.paper_details.topic }}" """ When I load the actor config blob from "nested_template.yaml" Then the loaded actor config nested value at "outer.system_prompt" should equal "Hello {{ context.paper_details.topic }}" Scenario: Restore template syntax recurses into lists Given an actor config file "list_template.yaml" with content: """ provider: openai model: gpt-4 messages: - role: system system_prompt: "Topic is {{ context.paper_details.topic }}" - role: user content: "plain text" """ When I load the actor config blob from "list_template.yaml" Then the loaded actor config nested value at "messages.0.system_prompt" should equal "Topic is {{ context.paper_details.topic }}" # --- _interpolate_env_vars: lines 134-174 (env var substitution and type coercion) --- Scenario: Environment variable interpolation uses default boolean value Given an actor config file "env_bool.yaml" with content: """ provider: openai model: gpt-4 options: flag: "${MISSING_BOOL_VAR:true}" """ And the actor config environment variable "MISSING_BOOL_VAR" is unset When I load the actor config blob from "env_bool.yaml" Then the loaded actor config value at "options.flag" should equal True Scenario: Environment variable interpolation uses default false boolean value Given an actor config file "env_false.yaml" with content: """ provider: openai model: gpt-4 options: flag: "${MISSING_BOOL_FALSE:false}" """ And the actor config environment variable "MISSING_BOOL_FALSE" is unset When I load the actor config blob from "env_false.yaml" Then the loaded actor config value at "options.flag" should equal False Scenario: Environment variable interpolation uses default integer value Given an actor config file "env_int.yaml" with content: """ provider: openai model: gpt-4 options: count: "${MISSING_INT_VAR:42}" """ And the actor config environment variable "MISSING_INT_VAR" is unset When I load the actor config blob from "env_int.yaml" Then the loaded actor config value at "options.count" should equal 42 Scenario: Environment variable interpolation uses default string value Given an actor config file "env_str.yaml" with content: """ provider: openai model: gpt-4 options: greeting: "${MISSING_STR_VAR:hello}" """ And the actor config environment variable "MISSING_STR_VAR" is unset When I load the actor config blob from "env_str.yaml" Then the loaded actor config value at "options.greeting" should equal "hello" Scenario: Environment variable interpolation uses default float value Given an actor config file "env_float.yaml" with content: """ provider: openai model: gpt-4 options: ratio: "${MISSING_FLOAT_VAR:2.5}" """ And the actor config environment variable "MISSING_FLOAT_VAR" is unset When I load the actor config blob from "env_float.yaml" Then the loaded actor config value at "options.ratio" should equal 2.5 Scenario: Environment variable interpolation reads set env var Given an actor config file "env_set.yaml" with content: """ provider: openai model: gpt-4 options: api_key: "${TEST_ACTOR_API_KEY}" """ And the actor config environment variable "TEST_ACTOR_API_KEY" is set to "secret123" When I load the actor config blob from "env_set.yaml" Then the loaded actor config value at "options.api_key" should equal "secret123" Scenario: Missing required environment variable raises an error Given an actor config file "required_env.yaml" with content: """ provider: openai model: gpt-4 secret: "${REQUIRED_SECRET}" """ And the actor config environment variable "REQUIRED_SECRET" is unset When I load the actor config blob from "required_env.yaml" Then a ValueError should be raised containing "Environment variable 'REQUIRED_SECRET' is not set" Scenario: Environment variable coerces top-level string true to boolean Given an actor config file "env_top_bool.yaml" with content: """ provider: openai model: gpt-4 enabled: true """ When I load the actor config blob from "env_top_bool.yaml" Then the loaded actor config value at "enabled" should equal True Scenario: Environment variable coerces string integer to int Given an actor config file "env_top_int.yaml" with content: """ provider: openai model: gpt-4 retries: 3 """ When I load the actor config blob from "env_top_int.yaml" Then the loaded actor config value at "retries" should equal 3 Scenario: Interpolation coerces negative integer default Given an actor config file "env_neg_int.yaml" with content: """ provider: openai model: gpt-4 options: offset: "${MISSING_NEG_INT:-5}" """ And the actor config environment variable "MISSING_NEG_INT" is unset When I load the actor config blob from "env_neg_int.yaml" Then the loaded actor config value at "options.offset" should equal -5 Scenario: Interpolation recurses into nested dicts and lists Given an actor config file "env_nested.yaml" with content: """ provider: openai model: gpt-4 options: items: - "${MISSING_ITEM_VAR:default_item}" """ And the actor config environment variable "MISSING_ITEM_VAR" is unset When I load the actor config blob from "env_nested.yaml" Then the loaded actor config nested value at "options.items.0" should equal "default_item" # --- from_file: lines 189-190 --- Scenario: from_file applies overrides and unsafe flag Given an actor config file "valid_ff.json" with content: """ {"provider": "file-provider", "model": "file-model", "options": {"k": "v"}, "graph_descriptor": {"node": true}} """ When I parse the actor configuration from file "valid_ff.json" with overrides: """ {"name": "cli-name", "graph_descriptor": {"node": "override"}, "unsafe": true} """ Then the actor configuration should have provider "file-provider" and model "file-model" And the actor configuration name should be "cli-name" And the actor configuration graph descriptor should equal {"node": "override"} And the actor configuration options should equal {"k": "v"} And the actor configuration unsafe flag should be true # --- from_blob: lines 236 (default_options), 238 (v2_options), 250 (missing model) --- Scenario: from_blob rejects missing provider When I build an actor configuration from blob {"model": "only-model"} Then a ValueError should be raised containing "provider is required" Scenario: from_blob rejects missing model When I build an actor configuration from blob {"provider": "only-provider"} Then a ValueError should be raised containing "model is required" Scenario: from_blob with None blob defaults to empty data When I build actor config from None blob with provider and model overrides Then the actor configuration should have provider "override-provider" and model "override-model" Scenario: from_blob reads provider_type and model_id aliases When I build an actor configuration from blob {"provider_type": "aliased-provider", "model_id": "aliased-model"} Then the actor configuration should have provider "aliased-provider" and model "aliased-model" Scenario: from_blob resolves graph from graph key alias When I build actor config from blob using graph key alias Then the actor configuration graph descriptor should equal {"step": "one"} Scenario: from_blob sets unsafe from blob data When I build an actor configuration from blob {"provider": "p", "model": "m", "unsafe": True} Then the actor configuration should have provider "p" and model "m" And the actor configuration unsafe flag should be true Scenario: from_blob with non-dict graph coerces to None When I build an actor configuration from blob {"provider": "p", "model": "m", "graph_descriptor": "not-a-dict"} Then the actor configuration should have provider "p" and model "m" And the actor configuration graph descriptor should be None