fix: preserve unrelated function events - #767
Conversation
There was a problem hiding this comment.
Code Review
This pull request updates the function response processing logic in contents_processor.go to ensure that unrelated tool events, such as function calls and responses occurring between a specific call and its final response, are preserved rather than lost or incorrectly merged. A new test case has been added to contents_processor_test.go to verify that these unrelated events are correctly maintained during rearrangement. I have no feedback to provide as there were no review comments.
|
@mazas-google tagging you here |
|
Hi @radhus Could you update the PR? |
8434be0 to
7cc60f9
Compare
Done, rebasing all our PRs now |
kdroste-google
left a comment
There was a problem hiding this comment.
Hi, @gustafvh
Thank you for your contribution!
Looking at the code, I'm thinking of HITL (Human In The Loop)
Could you please generate such a scenario, meaning:
Agent has a functiontool X
- User writes a prompt
- LLM wants to execute tool X
- Plugin takes over and requires human confirmation
- Human confirms
- The tool is actually called (another processor)
Variant B:
4a) Human denies
5) The tool is not called
Please see example in ./examples/toolconfirmation/main.go
you can easily generate more than one request and get different sequences of approvals
Adding such an test would be useful!
7ffa271 to
90e3a80
Compare
|
@kdroste-google Thanks for the input! I added some extended tests per your suggestion. Let me know if its what you had in mind I see some failures in the test suite but not sure if its connected to my PR as its not in internal/llminternal (If I'm wrong here do let me know and I'll fix) |
Yes, they seem unrelated. I have re-run the test. This time all are passing. |
kdroste-google
left a comment
There was a problem hiding this comment.
Looks good, thank you!
Keep unrelated function-call and function-response events when rearranging the latest function response so valid tool history is not dropped.
90e3a80 to
a5914ce
Compare
* fix: preserve unrelated function events Keep unrelated function-call and function-response events when rearranging the latest function response so valid tool history is not dropped. * test: Add extended tool confirmation tests
* Conformance fixes for change to yaml format and progressive sse (google#672) Co-authored-by: Mikalai Senkevich <hanorik@google.com> * fix: preserve error details and finish reason in streaming response aggregator and update test expectations (google#678) * feat: Implement and test recursive agent lookup by name. (google#626) * feat: Implement and test recursive agent lookup by name. * refactor: convert `TestFindAgent` to a table-driven test and enable parallel execution. * feat: Introduce a `FindAgent` method on `llmAgent` to locate sub-agents by name, replacing the `runner` package's internal `findAgent` helper. * feat: add GetArtifactVersion method to artifact service (google#575) * feat: add GetArtifactVersion method to artifact service * chore: remove adk-go main executable. * Update artifact/service.go Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * Extract resolveVersion helper in gcsartifact. --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * feat: custom runner provider for adka2a executor (google#680) * custom runner provider for adka2a executor * remove the mandatory dependency on runnerConfig * Add session service test suite (google#675) * Add session service test suite * lint fix * lint fix --------- Co-authored-by: Dmitry Pasiukevich <20398573+dpasiukevich@users.noreply.github.com> * fix: fix data part conversions (google#689) * fix data part conversions * fix: correct json envelope for datapart (google#695) * chore: update a2a-go and fix double cleanup (google#698) * update a2a-go and fix double cleanup * tidy * feat: Introduce skill package, define frontmatter and helper functions. (google#693) Define frontmatter per https://agentskills.io/specification#frontmatter. Implement helper functions for: - parsing frontmatter and instructions out from SKILL.md file content, - validating frontmatter struct, - building SKILL.md file content from frontmatter and instructions. * feat: setup subrouter for pub/sub trigger (google#704) Create a new subrouter that will handle the pubsub trigger endpoint and add the implementation for this trigger. * feat: update cloudrun deployment script to include pubsub (google#712) update cloudrun deployment script to include pubsub trigger * feat: add telemetry attributes for cache read input tokens and reason… (google#714) * feat: add telemetry attributes for cache read input tokens and reasoning tokens * fix: align indentation in telemetry test usage metadata struct fields * refactor: align attribute key variable definitions for better readability --------- Co-authored-by: Dmitry Pasiukevich <20398573+dpasiukevich@users.noreply.github.com> * feat: Define skill.Source interface and implement file system skill source. (google#711) Source interface defines a contract via which skills framework is going to access skills. * feat(telemetry): add configurable LRU cache in debug telemetry to avoid memory leaks (google#687) * feat(telemetry): add configurable LRU cache in debug telemetry to avoid memory leaks * improve error handling and mention cache size default in the docs * refactor the logic touching the trace ids for event spans --------- Co-authored-by: Dmitry Pasiukevich <20398573+dpasiukevich@users.noreply.github.com> * feat: add the implementation of Eventarc subrouter (google#713) Implementation of Cloud Events trigger processing * feat: Add agent engine deployment to ADK GO CLI (google#715) Co-authored-by: Karol Droste <kdroste@google.com> * Update content processor to exclude toolconfirmation.FunctionCallName (google#717) * Update content processor exclude * remove mds --------- Co-authored-by: Dmitry Pasiukevich <20398573+dpasiukevich@users.noreply.github.com> * feat: update cloudrun deployment script to include eventarc subrouter (google#716) Adds the eventarc trigger configuration to the cloudrun deployment docker container * feat: Allow toolsets implement toolinternal.RequestProcessor. (google#730) While for tools it's a requirement, for toolsets it's optional. The ability of toolsets to implement RequestProcessor is required to implement Agent Skills feature as a toolset. * feat: Implement SkillToolset. (google#733) SkillToolset encapsulates the Agent Skills feature. This toolset ensures agent is equipped with all the tools needed to use skills and is provided with proper instructions. What skill toolset enable agent to do: - List available skills. - Read instructions of the skills (by skill name). - Read specific resources of the skills (by resource path). Current implementation is very basic, e.g.: - There is no script execution support yet. - Skill activation is history-based: skill instructions and resources are provided to the llm as function call results in conversation history. - Every resource should be specifically mentioned in the SKILL.md file: the agent is unable to list resources available for the skills. * fix: adk-web sse error format (google#734) fix adk-web sse error format so it corresponds with SSE specifications * fix: add traceCapacity to the api config (google#731) * feat: Add skill Source proxy for preloading skills. (google#745) WithCompletePreloadSource proxy allows to load the skills to memory on initialization. It offers the fastest possible data access speed upon initialization, at the expense of higher memory usage and longer initialization. * feat: Add preload frontmatters skill source proxy. (google#748) Given instructions and resource files can be large, it might turn out to be expensive to load them all to RAM. Fortunately, at this stage of skill toolset implementation, instructions and resources are most likely going to be read just once - and then they'll stay in the conversation history. Frontmatters, on the other hand, are going to be listed frequently, and frontmatters are relatively lightweight, thus a proxy caching only the frontmatters (as opposed to the full preload) can help reach maximum benefit. * feat: Add merged skill source proxy. (google#747) This proxy allows combining multiple skill sources into a single source. * Agent Engine support (google#749) * Agent Engine support * Test fix * Fixes * Fixes * Error handling fix * Fixes * Fixes in encode * Fixed encode * sseTimeout fix * reflection fix * sseWriteTime fix * fix * encode fixes * linter fixes * various fixes * encode tests * linter fixes * fix * linter fixes * Fixes in encode * refactor: remove manual session ID input and enable auto-creation in runner (google#754) * refactor: remove manual session ID input and enable auto-creation in runner * refactor: remove unused output field from DeleteSessionResponse serialization * feat: add support for updating existing Agent Engine instances (google#755) * feat: add update functionality for Agent Engine instances via gcloud command flags * feat: add --update and --instance_name flags to support updating existing Agent Engine instances * feat: include and upload class methods in reasoning engine update request * refactor: replace update and instance_name flags with agent_engine_id for streamlined resource identification * refactor: replace update and instance_name flags with agent_engine_id for streamlined resource identification * Add support for simple text instead of full genai.Content for stream_query (google#773) * Add support for simple text instead of full genai.Content for stream_query * Small non-functional fixes * Small non-functional fixes (~/go/bin/golangci-lint run --fix) * feat: make adk work with a2a-go/v2 (google#701) * Copied the code to ./agent/remoteagent and ./server/adka2a to v2 directories. * Migrated the code in v2 directories to use a2a-go v2 types. * Changed the code in the original directories to delegate to the new code and serve as a type translation layer. * Deprecated original packages with a reference to v2 directories. What this gives is that ADK can be used with a2a-go/v2 which implements A2A protocol v1 (as well as v0). * refactor: rename experimental reasoning tokens attribute to gen_ai.us… (google#779) * refactor: rename experimental reasoning tokens attribute to gen_ai.usage.reasoning.output_tokens * fix: include thoughts token count in total output token calculation for telemetry spans * refactor: fix formatting of telemetry attribute key and token count calculation * refactor: add comment explaining gen_ai.usage.reasoning.output_tokens and gen_ai.usage.output_tokens relation * fix: propagate thought signature to first function call in mixed responses (google#788) * fix: propagate thought signature to first function call in mixed responses Propagates the thought signature of a candidate response to its first subsequent function call if it lacks one. This ensures Vertex AI validates the turn history when echoing it back on the next turn. * remove gitignore changes * Added VertexAI MemoryBank support (google#801) * Added support for Memory Bank * Fixed comments and names in util/vertexai * Fixed names * Fixed aiplatform package comment * Removed debug * Small fixes * Context fix * fix the old adka2a public api depending on the new a2a-go/v2 (google#813) * ADK GO version update for LLM Request tagging (google#816) * Add parallel HITL function test (google#817) * Added parallel hitl function test * fix: use tagged switch on origCall.ID * bump a2a-go version to have nil part fix (google#827) * Changed model for gemini API to gemini-3.1-flash-lite (in examples) (google#839) * feat(live): Add core bidirectional streaming support (google#833) * feat(live): Add core bidirectional streaming support Brings over the core files for live agent execution, including RunLive implementation, base flow updates, and session management. * Change live run config type * lint fixes * lint fix * Add logging to runtime controller * Replace fmt prints with log * chore: add Dependabot config for automated genai dependency updates (google#843) Add file-based Dependabot configuration to enable weekly scheduled dependency updates for google.golang.org/genai. The config uses an allow-list approach so only the genai SDK is updated automatically, with the list easily extensible to more dependencies in the future. Configuration: - Ecosystem: gomod - Schedule: weekly on Mondays at 02:00 UTC - Scope: google.golang.org/genai only (via allow-list) - Reviewer: wolo-lab - Commit prefix: chore(deps) - Labels: dependencies * feat(live): Add sequential agent live run (google#835) * feat(live): Add sequential agent live run * Change sample static folder to dynamic path * Add log to session close * feat(live): Add live example (google#834) * feat(live): Add live example * Add README, fix null element on querySelector * fix: Stop ignoring request Decode error in runtime. (google#851) When d.Decode returned an error, we were overriding it (with nil in most cases). This was not intended. The documentation for http.Request.Body mentions: > The Server will close the request body. > The ServeHTTP Handler does not need to. Given there is no need to Close the Body in the first place, we just remove this defer. * fix: Propagate StateDelta for non-streaming agent. (google#854) While StateDelta from agent request is propagated to runner in SSE Handler, it's silently ignored in non-SSE Handler. Make it propagate StateDelta in both handlers. * fix: Prevent nil deref when a tool doesn't implement tool.Tool interface. (google#855) If a tool doesn't implement tool.Tool interface, runOneStep yields an error. If that error is ignored (yield returns true), we need to skip this tool. What we were doing so far, however, is we added nil to the map of tools. If that ever happen in runtime, the code will later crash with nil deref. I don't know if that could actually happen in context of where runOneStep is used, but anyway, let's handle it properly: added continue, which will skip adding nil to the map and will go to the next tool. * feat(live): Add session resumption (google#837) * feat(live): Add core bidirectional streaming support Brings over the core files for live agent execution, including RunLive implementation, base flow updates, and session management. * lint fixes * feat(live): Add session resumption * lint fix * Change prints to log * Add invocation_context comments and simplify base flow context type cast. * feat(live): Add streaming tools (google#836) * feat(live): Add streaming tools * Change sample static folder to dynamic path * lint fix * lint fix * Clean examples uiMode if * feat(live): Add audio cache for save artifact (google#838) * feat(live): Add core bidirectional streaming support Brings over the core files for live agent execution, including RunLive implementation, base flow updates, and session management. * lint fixes * feat(live): Add audio cache for save artifact * lint fix * Fix audio cache manager different mimetypes for output and input * Change audio_cache_manager_test to table driven testing * chore: fix folder name (google#859) * fix: user auth propagation not working in adka2a compat (google#861) * fix user auth propagation in adka2a compat * fix import * fix: add validation for transfer agent (google#824) * fix replay_plugin: empty llmresponses and normalize function formatting before comparing. (google#869) * fix replay_plugin: empty llmresponses found in recording and normalize function formatting before comparing. * refactor(replay): Simplify YAML AST node copying and add description tests Use direct pointer struct copying for original YAML nodes in type mismatch correction, preserving all AST metadata (comments, line/column positions) automatically without manual property assignments. Add a comprehensive table-driven test suite for the package-private normalizeDescription utility, covering boundary spaces, edge newlines, middle empty lines, and complex whitespaces. * fix: copy ThoughtSignature onto adk_request_confirmation parts (google#763) Gemini thinking models require replayed model-role function-call parts to carry their thought signature. The synthetic adk_request_confirmation parts created by generateRequestConfirmationEvent did not preserve the original part's ThoughtSignature, causing replay to fail with 400 INVALID_ARGUMENT. Fixes google#656 * fix: yield tool responses before confirmations (google#765) A consumer that pauses on receiving an adk_request_confirmation event (typically to await human approval) would never see the merged function-response event for tools that already executed in the same step. Yield completed responses first so they are persisted before the human-confirmation pause. Fixes google#759 * fix: preserve Vertex AI function call IDs (google#762) Keep function call and response IDs when deserializing Vertex AI session events so tool history can be matched across invocations. * feat: update examples and cli launcher to use a2a-go/v2 sdk (google#780) update examples and cli launcher to use a2a-go/v2 sdk * feat: adka2a structured error propagation (google#874) * implement adka2a structured error propagation * lint * status preservation test * fix wrong parts passed * add state guard for extracting errmessage * fix test --------- Co-authored-by: João Westerberg <westerberg@google.com> * fix: a2a execution cleanup callback not triggered (google#903) * fix A2AExecutionCleanupCallback trigger * default client factory * Context unification agent/context + internal/contenxt/callback_context (google#868) * Create unified callbackContext * Fixed Actions * Introduced optional NewCallbackContextWithArtifactTracking * fix: preserve unrelated function events (google#767) * fix: preserve unrelated function events Keep unrelated function-call and function-response events when rearranging the latest function response so valid tool history is not dropped. * test: Add extended tool confirmation tests * Context unification: merged tool context to callbackContext (google#871) * Merged internal.toolinternal.toolContext into agent.CallbackContext * Renaming * Moved to agent * Updated model for examples/vertexai/imagegenerator * Renamed tool.ToolContext to tool.Context * Added explicit make(map[]) for actions passed to NewCallbackContext/NewCallbackContextWithArtifactTracking * Minor fixes * Switched from tool.NewToolContext to agent.NewToolContext * feat: Add conformance test recording plugin (google#890) * Add conformance test recording plugin. * lint fix * lint fix * lint fix * fix: accept metadata-only SSE chunks instead of aborting stream in StreamingResponseAggregator (google#918) * fix: skip metadata-only SSE chunks instead of aborting stream in StreamingResponseAggregator ## Link to Issue or Description of Change Signed-off-by: anish k <ak8686@princeton.edu> * Fix for SSE chunks with no candidates * Linter fix --------- Signed-off-by: anish k <ak8686@princeton.edu> Co-authored-by: anish k <ak8686@princeton.edu> * Add v2 checks (google#937) * Context unification: switch all to not deprecated (google#935) * Replaced tool.Context with agent.ToolContext * fixed runnableTool * fix: bump x/net and otel OTLP exporters to patch govulncheck advisories (google#994) Resolves the nightly govulncheck failures (exit 3) by updating the modules flagged in the call graph to their fixed versions: - golang.org/x/net v0.54.0 -> v0.55.0 (GO-2026-5026) - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.16.0 -> v0.19.0 (GO-2026-4985) - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 -> v1.43.0 (GO-2026-4985) Core go.opentelemetry.io/otel stays at v1.43.0; companion indirect deps (otel/log, otel/sdk/log, otlptrace, proto/otlp, grpc-gateway, x/sys) move forward via go mod tidy. Verified locally: go build ./... and go test -race -mod=readonly -count=1 -shuffle=on ./... both pass, and govulncheck no longer reports GO-2026-5026 or GO-2026-4985. * chore: complete Node 24 migration for GitHub Actions (google#996) Bump the remaining actions still on the deprecated Node 20 runtime: - actions/setup-go v5.5.0 -> v6.4.0 (shared setup composite) - actions/cache v4.2.3 -> v5.0.5 (shared setup composite) - golang/govulncheck-action v1.0.4 -> master HEAD setup-go only moved to Node 24 in v6.2.0, so v5.5.0 was still Node 20. The govulncheck-action latest release (v1.0.4) internally pins actions/checkout@v4.1.1 and actions/setup-go@v5.0.0 (Node 20); its master branch already uses Node 24 actions but has not been tagged, so it is pinned to master HEAD with a TODO to re-pin once a release past v1.0.4 is cut. A previous pass only bumped actions/checkout, leaving these behind. * feat: add platform clock and UUID provider seams for deterministic event creation (google#964) Introduce a platform package whose current time and UUID generation can be overridden per-context, mirroring the ContextVar-based seams in ADK-Python: - platform.Now(ctx) / platform.WithTimeProvider(ctx, fn) - platform.NewUUID(ctx) / platform.WithUUIDProvider(ctx, fn) Both fall back to time.Now and uuid.NewString when no provider is installed, so default behavior is unchanged. To honor the API stability policy (no breaking changes in a minor release), the existing session.NewEvent(invocationID) signature is preserved and marked deprecated; it delegates to the new session.NewEventWithContext(ctx, invocationID), which sources the event ID and timestamp from the platform seams. All in-repo event/session creation call sites are threaded with context and use NewEventWithContext, so a host runtime can make event creation deterministic and replay-safe (e.g. a workflow engine that must reproduce an execution exactly on replay). * feat(agent): add StrictContextMock test double (google#1019) StrictContextMock implements the full ToolContext / CallbackContext / ReadonlyContext surface so it can be embedded in a test fake; embedders keep compiling as the interfaces grow, instead of breaking on every added method. Un-overridden methods panic with "not implemented" (a loud failure on unexpected calls), while the context.Context methods (Deadline/Done/Err/Value) delegate to the wrapped Ctx. * fix: Allow manual setting of session IDs (google#721) * fix/allow manual setting of session IDs * fixing missing return + session case issues for inevitable test replay * Changes in tests * Updated replays * check rpc status code instead of string match --------- Co-authored-by: Karol Droste <kdroste@google.com> * docs: add AGENTS.md for AI coding agents (google#1045) Add an AGENTS.md with project context, exact build/test/lint commands, repository layout, idioms, a minimal example, framework-extension and testing guidance, and contribution boundaries for AI coding agents. GEMINI.md and CLAUDE.md are thin pointers to AGENTS.md so Gemini CLI and Claude Code pick up the same single source of truth. * fix(agentengine): support Gemini Enterprise AgentSpace streams (google#777) * fix(agentengine): support Gemini Enterprise AgentSpace streams * refactor(agentengine): split streaming_agent_run_with_events handler * fix(agentengine): add MemoryService to streamingAgentRunWithEventsHandler runner configuration. * fix(adkrest): make debug telemetry span tests order-insensitive - The Go test check was failing in TestDebugTelemetryGetSpansBySessionID because the test asserted a fixed ordering for returned spans. In practice, the debug telemetry store can return the same set of spans in a different order depending on span/export timing, especially when spans are created and ended very close together. - This change keeps the production behavior unchanged and updates the tests to compare spans as a stable sorted set before diffing. The comparison still checks the span names, relevant attributes, and logs, but no longer treats incidental retrieval order as part of the contract. * chore(agentengine): clarify streaming agent run metadata Document the request_json payload for streaming_agent_run_with_events, mark the method as async_stream consistently, and replace realistic test fixture IDs with clearly fake values. * Get rid of context.Background (google#1062) * Got rid of context.Background * Linter fixes * fix: update built-in load_memory tool for compatibility with VertexAiSessionService (google#793) * fix: update load_memory tool with json marshaling of memory search response into map[string]any to avoid downstream incompatibility with Go struct types * revert: undo initial changes to load_memory tool * fix: safely normalize all part.FunctionResponse.Response types via JSON round-trip before conversion to structpb. This prevents errors or panics in `structpb.NewStruct()` caused by raw Go types that are incompatible with Protocol Buffers. * feat: add utility to safely normalize Go types via JSON round-trip before conversion to structpb. This prevents errors or panics in structpb.NewStruct() caused by raw Go types that are incompatible with Protocol Buffers. * chore: rename and simplify toStructPB util function * chore: add broader vertexai sessions test coverage --------- Co-authored-by: nicholas@alisx.com <nicholas@alisx.com> Co-authored-by: Karol Droste <kdroste@google.com> * Main linter fixes (google#1068) * session test suite fix * Linter fixes * fix(conformance): Add "system_instruction" keyNode processing (google#1075) * test(session/vertexai): add table-driven tests for FunctionCall/Response mapping (google#739) Add TestAiplatformToGenaiContent_FunctionCallMapping, a table-driven test that verifies aiplatformToGenaiContent correctly preserves: - ID, Name, and Args for FunctionCall parts - ID, Name, and Response for FunctionResponse parts - empty-string IDs are passed through unchanged The table-driven format matches the style used elsewhere in this file and makes it easy to add further cases. * docs(model): document dual session-resumption carriers on LLMResponse Post-v1.5.0-merge, LLMResponse carries session resumption twice by design: upstream's SessionResumptionHandle string (populated by the googlellm connection, read by llminternal Flow.RunLive) and the fork's structured SessionResumptionUpdate (populated by model/gemini, consumed by the liveflow engine, which also honors Resumable=false handle invalidation). Document that on the fork field so neither carrier is removed as an apparent duplicate during future syncs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WQUNntrYi9Yn1ExuN9f5VR * docs(liveflow): document relationship to the upstream live engine The v1.5.0 merge brought in a second live engine: Runner.RunLive / agent.LiveSession / adkrest /run_live drive upstream Flow.RunLive plus the googlellm connection. Fence it off in the liveflow package doc by listing its verified v1.5.0 gaps (string-matched GoAway, no reconnect backoff or attempt budget, history re-sent on resume, dropped ToolCallCancellation, input transcriptions authored as the agent) and naming Runner.RunLiveQueue + liveflow as the hulilabs-supported path. Strengthen the RunLiveQueue doc comment to point at that comparison. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WQUNntrYi9Yn1ExuN9f5VR * fix(runner): extend sub-runner plugin-inheritance guard to upstream RunLive Fork fix #46 (2208905) made Run and the queue-based live entry point (now RunLiveQueue) skip installing the runner's own plugin manager into context when it has no plugins, so a plugin-less sub-runner inherits the parent's manager and model/tool/agent callbacks keep propagating. The upstream Runner.RunLive that arrived with v1.5.0 kept the unconditional upstream line, so a plugin-less sub-runner driven through it would clobber an inherited parent manager with its own empty one. Apply the same HasPlugins guard there and add a regression test that captures the context plugin manager via a fake live agent (the upstream live engine itself cannot run offline). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WQUNntrYi9Yn1ExuN9f5VR * docs(session): point LiveDiagnostics docs at RunLiveQueue after rename The v1.5.0 merge renamed the fork's queue-based Runner.RunLive to RunLiveQueue and rebound the RunLive name to upstream's new agent.LiveSession entry point, whose engine never sets LiveDiagnostics. The LiveDiagnostics struct doc and the session.Event field doc still said the field is populated "for events from RunLive", steering upstream-RunLive callers into expecting diagnostics they will never get. Reference RunLiveQueue and state explicitly that upstream-API RunLive events carry nil. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WQUNntrYi9Yn1ExuN9f5VR * docs(runner): warn pre-v1.5.0 fork callers on the rebound RunLive name The v1.5.0 merge renamed the fork's queue-based Runner.RunLive to RunLiveQueue while upstream introduced a different RunLive (agent.LiveSession API) under the surviving name. The compile break for out-of-repo fork consumers is loud, but the surviving name silently points at the weaker upstream engine, so a consumer adapting to the new signature could migrate onto it unknowingly. Document on RunLive itself that it is the upstream engine, that its events never carry LiveDiagnostics, and that pre-v1.5.0 callers belong on RunLiveQueue. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WQUNntrYi9Yn1ExuN9f5VR * test(runner): cover own-manager install on upstream RunLive plugin guard The three existing tests all prove the inheritance branch (plugin-less runner leaves the context-seeded parent manager). A guard regressed to never installing would still pass the suite. Add the positive counterpart: a runner that owns plugins must replace the seeded parent manager with its own. Verified the test fails with the guard mutated to never-install. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WQUNntrYi9Yn1ExuN9f5VR * refactor(context): realign invocation context with upstream order and docs The v1.5.0 merge union kept the fork's method ordering and dropped upstream's doc comments on the resumption-handle accessors, inflating the permanent diff against upstream in a file both sides edit. Restore upstream's declaration order and comments so the fork delta is exactly the LiveRequestQueue param and accessor. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WQUNntrYi9Yn1ExuN9f5VR * docs(liveflow): add upstream engine goroutine leak to known-gaps list Review feedback on PR #50 identified a per-reconnect goroutine leak in the upstream Flow.RunLive engine (unbuffered errChan abandoned on resumable errors). The engine is fenced as unsupported here; record the gap alongside the others and link the upstream report (google#1152). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WQUNntrYi9Yn1ExuN9f5VR --------- Signed-off-by: anish k <ak8686@princeton.edu> Co-authored-by: João Westerberg <westerberg@google.com> Co-authored-by: Mikalai Senkevich <hanorik@google.com> Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: Yaroslav <yarolegovich@gmail.com> Co-authored-by: Dmitry Pasiukevich <20398573+dpasiukevich@users.noreply.github.com> Co-authored-by: Serob Nahapetyan <serob@google.com> Co-authored-by: Artsiom Shut <63152812+foxfrikses@users.noreply.github.com> Co-authored-by: Anastasia <adudarenko@google.com> Co-authored-by: Piotr Górski <piotrgorski@google.com> Co-authored-by: Paweł Maciejczek <pawel-maciejczek@users.noreply.github.com> Co-authored-by: Karol Droste <kdroste@google.com> Co-authored-by: Karol Piotrowicz <karol.piotrowicz@gmail.com> Co-authored-by: Gustaf <32815781+gustafvh@users.noreply.github.com> Co-authored-by: Serob Nahapetyan <serobnahapetyan@gmail.com> Co-authored-by: anish k <ak8686@princeton.edu> Co-authored-by: David Hyde <DABH@users.noreply.github.com> Co-authored-by: wolo <wolo@google.com> Co-authored-by: Brett Dietsch <brett.dietsch@bayer.com> Co-authored-by: Jan Krynauw <jan@alisx.com> Co-authored-by: Nicholas Breckwoldt <52029793+nicholasbreckwoldt@users.noreply.github.com> Co-authored-by: nicholas@alisx.com <nicholas@alisx.com> Co-authored-by: nuthalapativarun <nuthalapativarun@gmail.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…ing history (#53) rearrangeEventsForFunctionResponsesInHistory re-attached every response immediately after its call, including the merged late response that rearrangeEventsForLatestFunctionResponse had just deliberately placed last — burying a long-running tool's completion mid-history and leaving a stale exchange as the final content models act on. Keep the adjacency invariant and add one rule: the call/response pair answered by the final event is emitted last. Pure no-op when the last event is not a function response. Preserves google#767's no-drop property (google#761); disjoint from the google#760 orphan path. (cherry picked from commit 5bb4691)
* fix: preserve unrelated function events Keep unrelated function-call and function-response events when rearranging the latest function response so valid tool history is not dropped. * test: Add extended tool confirmation tests
…1428) * fix(llminternal): keep a late tool completion as the final content buildContentsDefault runs two rearrangement passes. The first places a long running tool's final response last and preserves the unrelated tool exchanges that happened while it ran. The second then attaches every response to its matching call, which drags that completion back next to a call issued much earlier and leaves a stale exchange as the last content. Models act on the last content, so they answer the stale exchange and never see the completion. rearrangeEventsForFunctionResponsesInHistory keeps its adjacency rule and adds one: the call/response pair(s) answered by the last event are emitted last. The relocation is a no-op whenever the last event is not a function response, because only a response event's index can appear in the call-to-response index. Nothing is dropped, so the preservation property from #767 still holds; the unrelated exchange now sits before the completion instead of after it. Analysis and approach from #1182. Fixes #1181 Co-authored-by: David Mora <dla.mora@gmail.com> * docs(llminternal): state the pending-call behavior change in the code Review feedback on #1428. The reordering is unchanged; the source now says what only the PR body said, and the PR body does not travel with the code. - Qualify the doc claim that non-tool-call events keep their original order: they keep it relative to one another, but a pair routed to the tail moves past them. - Rewrite the unanswered-call test comment, which said the pending call keeps its place while the want below moves it ahead of the completed pair. It now gives the main-vs-now orders and the dropped "Continue processing..." turn. - Note that the nine-event row yields five contents because pass 1 drops three text turns, one of them a user turn, so the want is not read as proof that nothing is dropped. - Record why the multi-response merge branch is unreachable together with tail routing, instead of testing a history PopulateClientFunctionCallID cannot produce. - Preallocate the call/response pair to two elements. * docs(llminternal): correct the reachability comment on the merge branch The comment claimed the multi-response merge branch never coincides with the tail routing, and justified that with PopulateClientFunctionCallID assigning a fresh ID to every call. Both halves are wrong. Counters on the merge branch and on the tail-routing branch give defaultBranchHits=1 defaultAndTailHits=1 for the history CALL(c1,c2) | RESP(c2) | CALL(c3) | RESP(c1,c3), where every call precedes its response and every call ID is unique. The real precondition is one call event whose siblings are answered by two different response events, plus rearrangeEventsForLatestFunctionResponse returning early on adjacency so it merges nothing. PopulateClientFunctionCallID fills an ID only when it is empty, so it never guaranteed uniqueness across call events either. The comment now states that precondition and uses the four-event history as a worked example. --------- Co-authored-by: David Mora <dla.mora@gmail.com> Co-authored-by: wolo <wolo@google.com>
* fix: preserve unrelated function events Keep unrelated function-call and function-response events when rearranging the latest function response so valid tool history is not dropped. * test: Add extended tool confirmation tests
Link to Issue or Description of Change
Problem
rearrangeEventsForLatestFunctionResponserebuilds history when the latest event is a function response. After finding the matching function-call event, it collects related response events to merge, then returns only the history up to that matching call plus the merged response.That can drop unrelated function-call or function-response events that happened between the matching call and the latest response. For long-running tool flows, this loses valid tool history that should still be replayed.
Solution
When scanning intermediate events between the matching function-call event and the latest response:
This keeps unrelated tool history intact while still consolidating the response sequence that triggered rearrangement.
Testing Plan
Rearrangement preserves unrelated function eventscovering an interleaved long-running response sequence with an unrelated tool call/response before the final response.go test ./internal/llminternalAlignment with adk-python
This preserves the shared history invariant that function-response rearrangement should repair pairing for the target long-running response without dropping unrelated valid events from the conversation history.