Free-model routers often answer with surrounding prose, so a strict whole-
response JSON parse failed and every triage run ended in error. Extract the
first JSON block before parsing, keeping the zod schema gate intact.
The provider tests asserted the default gpt-4o-mini model, which broke once
a local .env set AI_MODEL=openrouter/free. The test env now pins the model
before config/env is imported.
Also fix two bugs the tests surfaced in the merged AI implementation:
- agent-tool-call model made approval.summary/expiresAt conditionally required only when an approval subdocument is present, so blocked/error tool calls persist without a fake approval
- agent.repo.createRun coerced empty-string session/user ids to null so autonomous triage runs (no session/user) no longer fail ObjectId casting