fix: silence AI SDK "system message in messages" warning in act/extract/observe
What & why
#2305 silenced the AI SDK v5 "system message in messages" warning, but only for agent.execute()'s outer loop (v3AgentHandler.ts). act(), extract(), and observe() build their system prompt the same way — a { role: "system", ... } message inside the messages array — and route through a separate call path that was never patched: AISdkClient.createChatCompletion() in packages/core/lib/v3/llm/aisdk.ts (the default client for any "provider/model" string), plus the identical pattern in the public BYOC client packages/core/lib/v3/external_clients/aisdk.ts.
Since the hybrid/DOM agent's own act/extract/observe tools call these primitives internally on every step, an agent.execute() run that clicks/types repeatedly still spammed the warning even after upgrading past the first fix — a customer reported exactly this.
Fix
Add allowSystemInMessages: true to the 4 remaining generateObject/generateText call sites (2 in llm/aisdk.ts, 2 in external_clients/aisdk.ts), same pattern as the original fix.
E2E Test Matrix
| Command / flow | Observed output | Confidence / sufficiency |
|---|---|---|
BEFORE — published @browserbasehq/stagehand@alpha (already includes #2305's fix), act() → extract() → observe() chain on a real Browserbase session | AI SDK system-in-messages warnings emitted: YES (4) | Reproduces the customer's exact symptom on the current alpha — confirms #2305 left this path unpatched. |
AFTER — local patched build (this branch), identical act() → extract() → observe() chain, same model, real Browserbase session | AI SDK system-in-messages warnings emitted: NO (0) | Proves the fix removes the warning from all three primitives. |
AFTER — local patched build, full chain: act() + extract() + observe() + hybrid agent.execute() (multi-step form fill, real Browserbase session) | AI SDK system-in-messages warnings emitted: NO (0 total) | Confirms no regression on the already-fixed agent.execute() outer loop, and that the agent's internal act/extract/observe tool calls are also silenced end-to-end. |
pnpm turbo run build --filter @browserbasehq/stagehand | Tasks: 3 successful, 3 total | Typecheck + emit green. |
eslint + prettier --check on changed files | Both clean | Style/lint gates pass. |
A/B model: anthropic/claude-haiku-4-5-20251001, experimental: true, hybrid agent mode — same harness shape as #2305's own E2E matrix.
Closes STG-2573.
Summary by cubic
Silences the noisy "system message in messages" warning in act(), extract(), and observe(), including internal tool calls. Sets allowSystemInMessages: true at 4 generateObject/generateText sites and adds unit tests for both AISDK clients; closes STG-2573.