Restore `CodeMode` discovery announcements after compaction or history loss
With dynamic_catalog=True, _announced_tools was a run-lifetime in-memory set: after a CompactionPart (or a history processor dropping the announcement SystemPromptParts), the model lost the announcement but the set still remembered it — so a rediscovered tool's catalog entry was never re-announced. Found while verifying CodeMode against pydantic-ai's tool-reveal endgame (pydantic/pydantic-ai#7104) and compaction follow-up (pydantic/pydantic-ai#7225), but the history-processor variant reproduces against pinned main today.
Announced-state is now derived from visible history — announcements parsed from our own authored format, scanning in reverse and stopping at the latest CompactionPart, mirroring core's parse_discovered_tools — plus a small in-flight set (cleared each step) for same-step dedup before the enqueued part lands. Re-announcing when compaction or a processor removed the original is deliberate and tested; same-run dedup without compaction is unchanged.
Also makes the deferred-capability assertion in test_code_mode.py compatible with the upcoming pydantic-ai declared/visibility split (pydantic/pydantic-ai#7104), where a hidden tool stays in function_tools with non-'visible' visibility instead of being absent.
Full suite: 4507 passed. The boundary behavior is mutation-verified (ignoring the compaction boundary in the scan fails the re-announce test).