refactor(agent): inject deps via context_schema, LLM-driven photo/confirm nodes
- graph.py: LangGraph-native DI - StateGraph(context_schema=GraphDeps),
nodes take (state, runtime: Runtime[GraphDeps]); build_graph() decoupled
from LLM; deleted scaffold _event_reply/_fake_llm_propose/stub nodes
- photo.py: model proposes stage+body via per-mode prompts (direct/addon);
validator enforces clientMode exits; deterministic event forcing removed
- confirm.py: single runtime for single/dual confirm, extraction call
isolated per person_index
- llm.py: workflow_fake_llm() (offline workflow-faithful responder,
history-aware) for smoke/tests
- backend: LangGraphBackend(graph, llm) passes context per call
- tests: invoke helpers inject GraphDeps; illegal-proposal test asserts
error + state untouched via second well-behaved fake
Verified: 143 passed; smoke turns 1/2/1 with original welcome text