generate: thread structured messages through the chat talent path (req_h5iyql3s)
Carry conversation history as list[{"role", "content"}] from the chat talent's
pre-hook through _execute_generate into each provider SDK's native turn array.
List-of-strings callers continue unchanged - no dual runtime, no feature flag.
Google gets a new types.Content/Part mapper (assistant -> "model"). chat.md
drops $chat_stream_tail; the tail is now a first-class structured list on the
pre-hook return.
Decisions (req_h5iyql3s):
- messages key on pre-hook return dict; plain list[dict[str, str]] with role
in {"user","assistant"}
- owner_message trigger: triggering owner turn already persisted in the chat
stream; for talent_finished / talent_errored synthesize a final user turn
"[talent <name> finished: <summary>]" / "[talent <name> errored: <reason>]"
- drop $chat_stream_tail from chat.md; tests/baselines/api/sol/preview.json
regenerated to match
- drop in-tail talent_* markers from the structured history (the system prompt
$active_talents block still carries in-flight exec context)
- per-provider mapping lives in its own module; no shared/abstract messages
type; system instruction stays in each provider's native field
Test plan:
- make test-only TEST=tests/test_chat_context.py (passed)
- make test-only TEST=tests/test_anthropic.py (passed, including structured+schema)
- make test-only TEST=tests/test_openai.py (passed)
- make test-only TEST=tests/test_ollama.py (passed)
- make test-only TEST=tests/test_google.py (passed, sync+async Content/Part mapping)
- make test-only TEST=tests/test_talent_fallback.py (passed, _execute_generate regression locks)
- PYTEST_ADDOPTS="--basetemp=$(mktemp -d /tmp/pytest-qufbiyo2.XXXXXX)" make ci
(passed - isolated tempdir to avoid a concurrent-worktree
/var/tmp/pytest-of-jer collision)
- make review: browser verify 19/19 pass; API verify hit one pre-existing
drift on sol/badge-count (expected {"count": 1}, got {"count": 0}) that
reproduces on a clean tree with this diff stashed - unrelated to structured
messages, filed as separate follow-up. Manual chat-tail sandbox spot-check
was skipped since the 19/19 browser verify exercises the chat UI path.
Co-Authored-By: OpenAI Codex <codex@openai.com>