Commit 0bfec88
authored
docs: update GEMINI setup (#968)
# Description
Updated gemini setup. It is applicable to other models as well.
Example of `ai_learnings.md` entries:
```
## 2026-04-13 — Using extend() on a str return value
**Mistake**: Used `response_parts.extend(get_message_text(...))` and
`response_parts.extend(get_artifact_text(...))` where both functions
return `str`. `list.extend()` on a string iterates its characters,
producing `['H', 'e', 'l', 'l', 'o']` instead of `['Hello']`.
**Root cause**: Assumed the utility functions returned an iterable of
strings rather than a single string, and did not check their signatures
or run the tests before presenting the code.
**Rule**: Before calling `extend()`, verify the return type of the
expression. If it returns `str`, use `append()`. Run the tests after
any change to aggregation logic.
---
## 2026-04-13 — Assuming streaming event order without verifying across transports
**Mistake**: Added a strict check that the first streaming event must be
a `Task` or `Message`, raising a `RuntimeError` otherwise. Also used
`event.WhichOneof("event")` which fails because `StreamResponse` has no
oneof named "event" — its fields are independent message fields.
The REST transport sends a `status_update` as its first event, not a
`Task`, so the guard rejected valid responses.
**Root cause**: Assumed spec wording ("first event should be a Task")
held across all transport implementations without testing it. Did not
check the `StreamResponse` proto definition before calling `WhichOneof`.
**Rule**: Before adding ordering assumptions about streaming events,
verify the behaviour against every transport (JSONRPC, HTTP+JSON, GRPC).
Before calling `WhichOneof`, confirm the oneof name exists in the proto.
---
## 2026-04-13 — Assuming extras without checking dev dependencies
**Mistake**: Told the user that `http-server` and `grpc` extras needed
to be specified explicitly in the samples README prerequisites.
**Root cause**: Looked at the SDK's optional extras list and reasoned
from imports in the sample files, without checking whether the dev
dependency group already covered them. The dev group includes
`a2a-sdk[all]`, so a plain `uv sync` installs everything. Checking the
actual installed environment with one command would have revealed this
immediately.
**Rule**: Before writing installation instructions, verify what is
already provided by the project's dev dependencies (`uv sync` with no
flags). Do not recommend extra flags unless confirmed they are absent
from the dev group.
---
## 2026-04-13 — Proposing unverified code
**Mistake**: Proposed `_GRPC_ERROR = None` as a way to make `grpc`
optional in an `except` clause. `None` is not a valid exception type
in Python; the code would have crashed at runtime.
**Root cause**: The fix was reasoned about at a high level ("set it to
None when grpc is absent") without tracing through whether Python
actually accepts `None` in an `except` tuple. No verification step was
performed before presenting it to the user.
**Rule**: Before presenting any code change, trace through its
execution explicitly. For `except` clauses specifically: every element
in the tuple must be an exception class, never `None` or any other
non-exception value.
---
## 2026-04-14 — Race condition when reading state from DB in stream
**Mistake**: Used `active_task.get_task()` in `on_message_send_stream` to fetch the task state for the initial response. This caused a race condition where `get_task()` returned a task state that was ahead of the stream events, leading to test failures.
**Root cause**: Assumed `get_task()` would return the state corresponding to the event being processed, overlooking that the consumer loop runs independently and may have already processed subsequent events and updated the DB.
**Rule**: When processing a stream of events, do not rely on reading the current state from a shared store (like DB) to represent the state at the time of a specific event. Use state snapshots passed with the event if available.
```1 parent 57a6624 commit 0bfec88
3 files changed
Lines changed: 37 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
| 15 | + | |
15 | 16 | | |
16 | 17 | | |
17 | 18 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
0 commit comments