feat(adk): replace forced tool call with response_format fallback for… - #1145
Open
N3kox wants to merge 125 commits into
Open
feat(adk): replace forced tool call with response_format fallback for…#1145N3kox wants to merge 125 commits into
N3kox wants to merge 125 commits into
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## alpha/10 #1145 +/- ##
===========================================
Coverage ? 82.05%
===========================================
Files ? 194
Lines ? 31343
Branches ? 0
===========================================
Hits ? 25719
Misses ? 3810
Partials ? 1814 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
shentongmartin
force-pushed
the
alpha/10
branch
2 times, most recently
from
July 21, 2026 04:03
af155cf to
a4afa59
Compare
Change-Id: I09b9754cf51f10fe662fb6cb33935ad92a4d1656
…mance
- Add HumanReadableSerializer that produces human-readable JSON output
- Add GobSerializer for comparison benchmarks
- Refactor serialization_test.go to use table-driven tests for both serializers
- Add comprehensive benchmarks comparing InternalSerializer, HumanReadableSerializer, and GobSerializer
Performance improvements over InternalSerializer:
- 30-68% faster marshal/unmarshal operations
- 17-49% less memory allocation
- 30-76% fewer allocations
- 33-59% smaller serialized output size
The HumanReadableSerializer uses standard JSON encoding with type annotations
only for interface{} fields, making the output both human-readable and
type-preserving for round-trip serialization.~
Change-Id: Ifeae12484fc73b74067a0ac3a496e73e0674b975
Change-Id: Iecbcfd8ab5905e61df9a5578e8d3c99387dace85
Change-Id: I5ac5d8b60be92a28d1e57929f03fa4201649fbd0
Change-Id: I318ff16a6bd81bb57b38791eeea17b3385b1fde4
Change-Id: Iefb047967d4cb4796edd363e7e6ba0a9c4f49148
Change-Id: I3de2ba37914fe779cd880b38ce067acf5fbde7c8
The runner previously wrote the interrupt checkpoint inline, before the session event persister had flushed. This risks a checkpoint that references events not yet durable in the SessionStore. Introduce deferredRunnerCheckpoint: on the interrupt/cancel path the checkpoint payload is captured but not written until finalize() confirms persister.closeAndWait succeeded. If event persistence failed, the checkpoint write is skipped entirely (fail-closed). Also adds regression tests for checkpoint ordering invariants and the InMemoryStore checkpoint round-trip. Change-Id: Ib29263add4a261513f1349a9173a913c74ee65ef
Resume previously assumed the agent_tool interrupt state was always the JSON envelope (agentToolInterruptState) introduced for SessionID-based event filtering. Pre-envelope checkpoints stored raw gob bridge bytes, so json.Unmarshal failed outright and resume errored. Try the JSON envelope first; on parse failure or empty BridgeCheckpoint, treat the raw bytes as the legacy bridge checkpoint and synthesize a fresh childSessionID. Pre-envelope checkpoints predate session persistence and have no parent-session filter to coordinate with, so the synthesized ID is harmless. Un-skip the v0.7.37, v0.8.2, v0.8.3, v0.8.4 compat fixtures so the resume path is now exercised for real on-disk legacy bytes. Change-Id: I5000424ba028e9fb9fe3843ea9673a3dd23a7860
Merge AfterCursor and PageToken into a single `After` field in LoadEventsOptions. Rename NextPageToken to `Next` in LoadEventsResult. Rename afterEventCursor to afterCursor in LoadLatestTurnEnd returns. One concept, one name: the caller seeds After from LoadLatestTurnEnd, then passes res.Next back as After on subsequent pages. Change-Id: Icd0960940b7f69938e2b4a5062d220c709bc0e66
The Options suffix implies a functional-options pattern; Request better reflects the struct-pointer parameter style and pairs with LoadEventsResult. Also removes dead variable in conformance test. Change-Id: Ia28d8a1f92f4307182508dfba56e2b3c454acfa4
…ializer Correct the tool-call middleware ordering in chatmodel.go doc comments (cancelMonitor wraps around user handlers, not inside). Add architectural doc comment to newTypedInvokableAgentToolRunner explaining why AgentTool lacks its own SessionStore. Remove the unused GobSerializer type alias from schema/serialization.go (already aliased internally). Update conformance test variable names to match LoadEventsRequest rename. Change-Id: I2251e190c9d343dbd1e57cbebfc236840be4a0fa
…igurable page size AppendEvents failures in the session persister now retry with exponential backoff (default 3 retries, 50ms initial delay, 2x multiplier, 25% jitter) before latching the error. This prevents transient store failures from causing irrecoverable session log corruption. Also extracts the hard-coded page-size=100 in reconstructFromEventLog and replayTailEvents into the configurable LoadPageSize field on SessionPersistenceConfig (default 100, preserving current behavior). New config fields on SessionPersistenceConfig: - MaxFlushRetries (default 3, set to -1 to disable) - FlushRetryInitialBackoff (default 50ms) - LoadPageSize (default 100) Change-Id: I407b6038fd61df74420a5ddd16ce8ec0f8860948
…preservation When a SessionStore is configured, the Runner now reuses the exact tool list from the previous turn's TurnEndState to feed the model, ensuring byte-exact prompt cache hits across turns. The ToolSearch middleware skips its initialization strip logic when it detects pre-seeded tool infos via the new ToolInfosPreSeededKey RunLocalValue. Users can opt out with WithRefreshToolInfos() when tools have genuinely changed between turns. Change-Id: I95585e105d41689f08116325478f21552482b79b
Change-Id: Id35944259eaee9254bc9ffa7288fe6bc43bc021b
…ion mode When sessions are enabled, TurnEndState.Messages carries the previous turn's system message. The Runner prepends this history to the new input, then defaultGenModelInput unconditionally prepends a fresh system message, causing duplication. Strip the leading system message from history before prepending the fresh instruction so that dynamic SessionValues are always re-evaluated without duplicating the system prompt. Change-Id: Id14acc6aa5f2941ea64c4de82393a36bcea2fb36
…to single file Merge three scattered test files (human_readable_test.go, human_readable_edge_test.go, schema/toolinfo_humanreadable_test.go) into one unified file in internal/serialization. Replace schema.ToolInfo usage with a local mock type to eliminate the circular dependency, and remove duplicate test cases that exercised identical code paths. Change-Id: I0b1fa9d001201382917abb8bf4b3bd220ffdf13d
Reduce SessionStore from 4 methods to 2 (AppendEvents + LoadEvents) by merging TurnEndState into the event log as a SessionEvent variant. This eliminates duplicate message storage and unifies reconstruction into a single reverse-scan algorithm. - Rewrite session/in_memory_store.go with forward/reverse pagination - Remove SaveTurnEnd/LoadLatestTurnEnd from all test mocks - Replace encodeTurnEndState/decodeTurnEndState with encodeSessionEvent - Replace reconstructFromEventLog with reconstructSessionState Change-Id: I979e88727dd33bfaa6983241b7e90b7bbbe040e0
Replace the opaque integer-index cursor with the per-event UUIDv4 event_id, giving SSE consumers a stable identity for Last-Event-ID resume and de-duplication. AppendEvents becomes idempotent (first-write-wins on duplicate event_id) so persister retries no longer double-write. Introduce ErrInvalidEventID and ErrEventIDOutOfRange sentinels with isProtocolError classification, so the persister fail-fasts protocol violations while still retrying infrastructure errors. Stores treat event_id as an opaque non-empty string; UUIDv4 is the Runner allocation convention, not a store-enforced format. Change-Id: I70c277af5505d57c7354e8056372c1021d6009eb
Allocate EventID once at the AgentEvent emission boundary (execCtx.send) so user-land stream consumers and persisted SessionStore records share the same identity. SSE adapters can now use AgentEvent.EventID as the SSE id: line, and clients reconnecting with Last-Event-ID can pass that value directly to SessionStore.LoadEvents(After: ...) without going through the store. toSessionEvent reuses event.EventID instead of minting a new UUID, with a defensive fallback for test fixtures that construct events directly. makeInputSessionEvent is unchanged (no upstream AgentEvent). Change-Id: I525675f948aef55d6afc0dcdc46bd7e255a68311
Persist lifecycle, model span, retry/failover, and tool observation events through the managed session log while preserving the EventID identity contract between live AgentEvents and stored SessionEvents. Add focused coverage for replay boundaries, timeline exposure, retry/failover observability, model usage metadata, gob compatibility, and persistence guards. Change-Id: Id78c137b40265324d315237067a82e8ea1ffc8ef
Change-Id: I84f8155f66807d6e229741b9f5b3f6345f58f1d5
Change-Id: Id53b725579b6e7ceaeb9f4edd3c65a11e092f8e1
Delay loaded checkpoint abandonment until fresh-turn agent preparation succeeds, and fail before execution if checkpoint deletion fails. Fold durable attack coverage into normal ADK test suites and remove the standalone attack test file. Change-Id: I43fa3cd8d25dbd4ea3d1ca4c845191fa5a9c503d
…nt model (#1106) * refactor(adk): introduce SessionEventVariant and simplify session event model - Replace SessionEvent pointer in TypedAgentEvent with SessionEventVariant sum type - SessionEventVariant carries either materialized SessionEvent or MessageStreamRef for streaming - Move SessionID from durable SessionEvent to live SessionEventVariant metadata - Remove EventID and Timestamp from TypedAgentEvent (already in SessionEvent/MessageStreamRef) - Simplify store interface: pass sessionID as first-class arg, remove AppendEventsRequest - Rename UserObservation/UserInterrupt/AgentInterrupt to Cancel/Interrupt - Remove SessionRunStateRescheduled (only running and idle remain) Change-Id: Iab036b8ac7c445fde8cb54215aefab12f51eef1c * fix(adk): resolve dead code in toSessionEventChecked and add doc comments - Remove unused SessionEvent construction in fallback path of toSessionEventChecked - Add doc comments for MessageStreamRef, CancelEvent, and SessionEventVariant methods Change-Id: I4ba1ff5faf2abfa13ddc59fafb065a73a17d0345 * fix(adk): snapshot leading system message before genModelInput - deep copy leading system message before calling GenModelInput to detect in-place mutations (Extra map, Content, etc.) that would otherwise be missed by sameSystemMessage comparison - remove dead code in streaming-complete persistence branch (persistMV / persistOutput were constructed and immediately discarded) - add regression tests for in-place Extra and Content mutation in GenModelInput - document SessionEventVariant invariant and turn_end legacy compatibility Change-Id: Id8d6d3f91e013642a7573502ae4ad562239cbc07 * refactor(adk): replace turn_end bypass with generic unknown-kind tolerance replace hardcoded "turn_end" compatibility shim with a general mechanism that tolerates any unrecognized event kind carrying no payload: - add knownSessionEventKinds set and isKnownSessionEventKind helper - add countActiveSessionEventPayloads helper for structural check - tolerate unknown kinds with zero recognized payloads (forward/backward compat) - known kinds with missing/wrong payloads still error as before Change-Id: I48a74dc546a3c3b5a1f21a6a9a23ccae32aaf7fe * chore(adk): remove unreachable gob registrations for SessionEventVariant and MessageStreamRef checkpoint sanitizers strip SessionEventVariant before gob encoding, and the store serializer only encodes *SessionEvent[M]. add a comment explaining why these types are not registered. Change-Id: I55e2726a95ed3e31abc28719b8ed4c2f8106114e * test(adk): align variant serialization test with durable payload Change-Id: I0b9607028aebc61976529082b67f2d9751196563
…ng (#1107) * feat(adk): background-task manager with subagent/filesystem/deep wiring Introduce a shared, domain-agnostic background-task engine and wire it into the subagent and filesystem middlewares and the deep prebuilt agent. adk/backgroundtask (engine): - Manager tracks foreground/background/auto-background runs under one task-ID space; Run blocks with an optional foreground budget, then either completes, auto-backgrounds (Config.ShouldAutoBackground), or times out. - RunStream + StreamWorkFunc forward a run's output to the caller in real time during the foreground phase, then on auto-background inject a generic notice and drain the rest into the task result. - Cancellation records a reason on Task.Error and the foreground caller reports StatusCanceled (not a StatusFailed ctx error). - Task ids are TaskType_base62(int64), where the int64 packs a ms timestamp, a per-ms sequence (spinning to the next ms on overflow), and random low bits — unique within a process and self-describing by type. - Optional OutputStore persists completed results (filesystem.Backend satisfies it directly); WaitForTask/WaitAllDone for lifecycle waits. adk/middlewares/backgroundtask (control tools): - Injects task_output/task_stop once, bound to a Config{Manager}. task_output supports CC-aligned block/timeout inputs. adk/middlewares/subagent + filesystem: - subagent agent tool and filesystem execute tool route through a shared Manager when configured, gaining run_in_background; the streaming execute tool streams its foreground output via RunStream. filesystem.Shell now documents the ctx-cancellation contract. adk/prebuilt/deep: - deep.New accepts a Manager, wiring it into the top-level subagent + filesystem middlewares and injecting the control tools once; sub-agents stay foreground-only. Replaces the old task_tool with the subagent middleware. Co-Authored-By: Claude Opus 4 <noreply@anthropic.com> * feat: adjust background.Manager * refactor(adk): clarify background task events * feat: simplify done check * feat: reduce one goroutine for direct run_in_background * refactor: enchance background task with direct run_in_background * refactor(adk): make background task output file worker-owned The background-task Manager previously declared an output file globally and wrote it once at completion, which broke its "interim output" promise and made the file redundant with Task.Result. Move output-file ownership to the launching adapters (execute / agent tools): the Manager only records RunInput.OutputFile, while the worker writes — shell runs tee interim output as it streams, sub-agent runs append their final result. - backgroundtask: drop Config.OutputStore/OutputDir and persistOutput; add RunInput.OutputFile (path only, Manager never writes) - filesystem: add Appender optional interface + AppendRequest (InMemoryBackend implements it); output files require an Appender, no rewrite fallback - bundle Manager + output config into a nested BackgroundConfig across the filesystem, subagent, and deep configs - name output files after the launching tool-call id (matching Task.ToolUseID), with a uuid fallback when absent - task_output's formatTask points at the file when present instead of inlining the result Co-Authored-By: Claude Opus 4 <noreply@anthropic.com> * feat: support mark output file * fix: golangci-lint * refactor(adk): hand WorkFunc a TaskInfo and key output-file failures by id The launcher needs the Manager-assigned task id at write time to report an output-file write failure, but the id is generated inside createTask, after the work closure is already built. Pass a TaskInfo (read-only snapshot of creation-time identity) as an explicit WorkFunc/StreamWorkFunc parameter so the work receives the id directly; MarkOutputFileUnreliable then keys by id (O(1) map lookup) instead of scanning all tasks by output-file path. Also make the failed-write reporting honest: when a write fails, neither the partial file nor the in-memory Result is the authoritative complete output (Result may be empty while the task runs, or a partial projection of the file for sub-agent runs). formatTask and the OutputFileErr doc no longer claim Result is always the full copy. Co-Authored-By: Claude Opus 4 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4 <noreply@anthropic.com>
…rated leading system messages (#1121) * fix(schema): remove gob registration for map[string]any and []any Registering map[string]any / []any with custom _eino_ prefixed names in init() causes gob to panic when other libraries (e.g. go-openapi/spec) register the same types with their default names, since gob enforces one name per concrete type globally. These registrations were added preemptively in commit 318c253 (model timeout feature) so that GobSerializer could round-trip nested maps/ slices inside Extra/MetaData fields. However: - No eino-internal code puts nested map[string]any / []any into Extra - All existing tests pass without them - The conflict with third-party libraries is a real init-time failure GobSerializer will still fail at runtime if users store nested map[string]any / []any in Extra, but that is a runtime error surface rather than an unconditional init-time panic. Change-Id: Id4594751cb0a7ffb4666e07749ee2104f04a0267 * refactor(adk): remove session turn ids Use committed idle event IDs as rollback boundaries and remove runner-side turn ID generation, checkpointing, and session event stamping. Change-Id: Ica138789eae5cc901a9af23572d5f6aee801b416 * fix(adk): stop persisting runtime generated leading system messages in session events Generated leading system messages from GenModelInput are runtime model input scaffolding, not durable conversation history. They should be recalculated on each run via applyBeforeAgent -> GenModelInput rather than reconstructed from SessionEventStore. - Add runtime provenance marker (_eino_adk_runtime_generated_system_message) to distinguish generated vs caller-supplied leading system messages - Remove syncLeadingSystemMessageSessionEvent from all 3 run paths (no-tools, message ReAct, agentic ReAct) - Summarization Middleware strips marked messages from MessagesReplaced event payload while preserving them in runtime state - Caller-supplied leading system messages (unmarked) remain durable Change-Id: I4a9ddd895b1d5fd32ad15345e3f7d43417342f4d * chore: format code Change-Id: I4d8b7e4d78f688255142a1823462ca8864d8468d * refactor(adk): remove TurnLoop managed resume mode Remove the redundant managed interrupt resume mode where business interrupts kept the TurnLoop alive and waited for explicit Resume(). Business interrupts now always exit with *InterruptError and persist a checkpoint when Store + CheckpointID are configured, consistent with the normal interrupt-exit path. Restored checkpoint resume via GenResume remains intact. Deleted: - TurnLoopInterruptMode type and constants - InterruptMode and ResumeWaitTimeout from TurnLoopConfig - TurnLoop.Resume() method and sentinel errors - turnLoopPendingResumeSource enum and managed-only fields/helpers - Managed parking loop in takePendingResume - Managed-mode branch in run() and proxy iterator - Resume-wait watcher and timeout logic - InterruptContexts from turnLoopCheckpoint - ~2000 lines of managed-mode tests and helpers Change-Id: I4cc772012939ed8d0c768d00b9472ea8887f937f * fix(adk): use json canonical comparison for model context tool equality reflect.DeepEqual incorrectly reports tool change when persisted ToolInfo numbers decoded as float64 differ from runtime int values, causing redundant model context events every model call. Fall back to comparing canonical JSON form to keep semantic equivalence across persist/reload. Change-Id: I3baffe7decdf0d30217ccf45db354dc01a7779f5 * refactor(adk): skip persisting ModelContext session event Change-Id: I7ebc6ceb603b4d236c1978a5db2e64e6d5afb413
…#1091) * chore: ensure that tool calls match tool results and correct comments * chore: adjust condition
Change-Id: Iabc283f15ab65dc8100ace045344a4a24574eea9
Allow the summarization middleware to reuse the main conversation's cached prompt instead of rebuilding a fresh input, avoiding a full prompt-cache invalidation on every summarize call.
… turn (#1128) * fix(adk): stop forwarding backgrounded sub-agent events to the parent turn A managed sub-agent run that is backgrounded (explicit run_in_background or auto-moved at the foreground deadline) runs detached and outlives the turn that launched it. It kept forwarding the inner agent's events to the parent turn's event generator, which the turn closes on end — injecting events into a stream the user has stopped watching, and racing a send against that close. Introduce a lifecycle signal (backgroundtask TaskInfo.Backgrounded) that closes when a task moves to the background, and an AgentTool option (WithAgentToolParentForwardUntil) that bounds parent forwarding by it. The subagent middleware wires the two together, so forwarding stops the moment a run detaches; foreground runs are unaffected. The gated path uses a non-panicking send by definition (it may outlive its consumer); the plain foreground path keeps a panicking send so an unexpected closed-generator send still surfaces. Co-Authored-By: Claude Opus 4 <noreply@anthropic.com> * refactor(adk): rename AgentTool event-forward options for self-documentation Make the two halves of AgentTool event forwarding read as a pair: the target (where inner events go) and the bound (how long they go there). - withAgentToolEventGenerator -> withAgentToolEventForwardTarget - withTypedAgentToolEventGenerator -> withTypedAgentToolEventForwardTarget - WithAgentToolParentForwardUntil -> WithAgentToolEventForwardUntil - agentToolOptions.gatedForward/forwardParentUntil -> eventForwardGated/eventForwardUntil Behavior is unchanged; this is a naming-only refactor. Co-Authored-By: Claude Opus 4 <noreply@anthropic.com> * refactor(adk): consolidate event-forward gate into internal/agenttool.ForwardGate Move the event-forwarding gate option to a self-documenting ForwardGate struct in internal/agenttool, replacing the split across agentToolOptions and the exported WithAgentToolEventForwardUntil. Also remove the AgentEvent type-specialization wrapper (withAgentToolEventForwardTarget) in favor of the generic withTypedAgentToolEventForwardTarget. Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4 <noreply@anthropic.com>
#1140) fix(adk): preserve ToolInfos and DeferredToolInfos in BeforeModelRewriteState
* feat: change appender to sreamable
* refactor(adk): expose append sessions as writers
* feat(adk): stream subagent events to task output
* refactor(adk): tighten event receiver contract
* refactor(adk): persist materialized agent events as jsonl
* refactor(adk): strip only root message extra
* feat(adk): preview streaming shell startup output
* test(adk): support go 1.18 atomic APIs
* perf(adk): make in-memory append linear
* docs(adk): clarify background preview completion
* refactor(adk): unify pumped stream forwarding
* refactor(adk): clarify foreground timeout naming
* refactor(adk): enforce append-writer Close contract in in-memory backend
Make the InMemoryBackend append handle strictly honor the AppendOpener
contract: Close is now idempotent and records a closed state, and a Write
or WriteString after Close is rejected with io.ErrClosedPipe without
mutating the file. Document the write-after-close behavior on the
AppendOpener interface so other backends follow suit, and add a regression
test covering idempotent Close and post-close writes.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* docs(adk): clarify streaming foreground-timeout and preview timing
Document that RunStream's foreground timeout and BackgroundStartupPreviewMs
windows are measured from when the StreamWorkFunc returns its reader, not
from the RunStream call, since RunStream invokes the work synchronously and
starts the timers only afterward. Blocking initialization done before the
reader is returned is therefore not bounded by either window, so streaming
work must return its reader promptly and push blocking init into the
producer goroutine. Note the Run vs RunStream difference on ForegroundTimeoutMs.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* feat(adk): make sub-agent background output encoder pluggable
Replace the hardcoded JSONL envelope for managed sub-agent output files
with a pluggable subagent.AgentEventFormat[M] encoder on the sub-agent
BackgroundConfig. It encodes one AgentEvent into a single line (framework
appends the newline); returning an empty line skips the event, so a caller
can filter down to a final-result-only file. When nil, a built-in default
encoder writes {agent_name, message} per line with the message's root Extra
stripped — the event kind is read from the message's own role/tool_calls,
so no invented type taxonomy is introduced.
Keep the format concern inside the subagent middleware: the format hint is
surfaced only through the tool's own background-run message, so the
backgroundtask manager and task_output stay format-agnostic (drop the shared
metadata key and formatTask rendering). deep.BackgroundConfig exposes only
shared knobs (Manager, OutputDir) and no longer needs to be generic; a custom
encoder is available by composing the subagent middleware directly.
Also report elapsed duration instead of an absolute (zone-ambiguous)
completion timestamp in task_output.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* fix(adk): treat short writes to the sub-agent output file as errors
io.WriteString falls back to Write([]byte) for a non-StringWriter, and a
misbehaving writer can report n < len with a nil error. Convert that short
write into io.ErrShortWrite so a truncated line marks the output file
unreliable instead of being trusted by task_output as authoritative.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* fix(adk): preserve session envelope when copying agent events
copyTypedAgentEvent dropped SessionEventVariant, so the per-receiver copies
that AgentTool forwards lost the child-session stamp applied by
stampAgentToolSessionEvent — leaving the parent unable to filter child/tool
events out of its own session. Copy the variant (and its Event /
MessageStreamRef, which are value/one-level structs) so each forwarded copy
carries the stamp. Nested Message payloads remain shared, matching the
existing copy convention. Add a test asserting a receiver sees the stamped
envelope.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* refactor(adk): expose subagent BackgroundConfig as a typed alias
Rename the generic subagent background config to TypedBackgroundConfig[M] and
add BackgroundConfig = TypedBackgroundConfig[*schema.Message], mirroring the
existing Config = TypedConfig[*schema.Message] pattern so the common case
writes BackgroundConfig{} instead of BackgroundConfig[*schema.Message]{};
generic callers (deep) use TypedBackgroundConfig[M].
Also reframe the output-file contract: the file is line-oriented (one line
per event, format defined by EventFormat). JSONL {agent_name, message} is
documented as the default encoder's output specifically, not a property of
the file — a custom EventFormat may emit any per-line text. No type field.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* docs(adk): align foreground-timeout terminology and RunStream timing wording
Rename lingering "foreground budget" comments to "foreground timeout" in the
filesystem execute tool to match the manager, and tighten the RunStream doc
to say the forwarding goroutine starts the timers after work returns its
reader. Comment-only.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…#1147) * perf(schema): assemble streamed string fields with pre-sized builders ConcatAgenticMessages and its downstream concat helpers assembled streamed string fields (reasoning text/signature, assistant text, media Base64 data, function/MCP tool arguments, tool-result text, OpenAI refusal reason and indexed reasoning content) with in-loop `+=` concatenation. That produced a fresh full-history intermediate string per chunk, making a single concat pass O(n^2) in the number of chunks and generating heavy allocation and GC churn — observed as the dominant CPU cost in production profiles. Replace every such path with a single pre-sized allocation: sum the fragment lengths, then Grow a strings.Builder once and WriteString each fragment (no reflection, no unsafe), mirroring the existing ConcatMessages implementation. The FunctionToolResult content merge is restructured to flatten all chunks once and collapse adjacent text runs in a single pass instead of repeatedly copying the accumulated slice. The OpenAI refusal path now builds a fresh OutputRefusal, which also fixes an input-chunk mutation. Public APIs, output content, ordering, error behavior, and extension/Extra merge semantics are unchanged. Benchmarks (16/64/256/1024 chunks x 8/128 byte payloads, ReportAllocs) show constant ~2 allocs/op regardless of chunk count and up to -99.8% time and bytes at large chunk counts (geomean -95.9% time, -98.1% bytes). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * perf(schema): drop per-index length map in reasoning extension concat Compute each index's total length in the final build loop instead of maintaining a separate indexToLen map, removing one map allocation and N hashed map writes per stream. Behavior is unchanged: the builder is still pre-sized to the exact byte total. Also re-split a tool-result test fragment ("hel" -> "he"/"llo ") to avoid a false-positive typos check while preserving the merge-across- chunks assertion. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Change-Id: I3a51986eb27032bc0f96bbc9e83ed627519768ea
mrh997
approved these changes
Aug 6, 2026
shentongmartin
force-pushed
the
alpha/10
branch
from
August 19, 2026 01:52
3210008 to
49cb90b
Compare
shentongmartin
force-pushed
the
alpha/10
branch
2 times, most recently
from
August 28, 2026 07:30
5738375 to
d94e4dc
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
… topic selection
What type of PR is this?
Check the PR title.
(Optional) Translate the PR title into Chinese.
(Optional) More detailed description for this PR(en: English/zh: Chinese).
en:
zh(optional):
(Optional) Which issue(s) this PR fixes:
(optional) The PR that updates user documentation: