-
Notifications
You must be signed in to change notification settings - Fork 411
Open
Description
I have some custom functiontools and the LLM is calling it in batch via message parts. In those functiontools, I update the state, which is what the docs say to do: https://google.github.io/adk-docs/sessions/state/#a-warning-about-direct-state-modification
It looks like only the last tool call's state is being applied to the delta. I have confirmed the tools is called many times in one turn
Example state modifying functiontool
const CacheRemoveTool = "cache_remove"
const CacheRemoveDesc = `
adds or overwrites an entry in your working key/value cache and context
`
type CacheRemoveArgs struct {
Key string `json:"key"` // path to a directory
}
type CacheRemoveResult struct {
Key string `json:"key"` // path to a directory
Status string `json:"status"` // "ok" or "error"
Error string `json:"error,omitempty"`
}
func NewCacheRemove() (tool.Tool, error) {
handler := func(ctx tool.Context, input CacheRemoveArgs) (CacheRemoveResult, error) {
k := fmt.Sprintf("cache:%s:%s", ctx.AgentName(), input.Key)
fmt.Println("CACHE.REMOVE!", k)
err := ctx.State().Set(k, nil)
if err != nil {
return CacheRemoveResult{Status: "error", Key: input.Key, Error: err.Error()}, err
}
return CacheRemoveResult{Status: "ok", Key: input.Key}, nil
}
return functiontool.New(functiontool.Config{
Name: CacheRemoveTool,
Description: strings.TrimSpace(CacheRemoveDesc),
}, handler)
}Event with bulk functionCall
{
"Content": {
"parts": [
{
"text": "That is an insightful observation. Keeping the key with a marker like \"no relevant\" is a good way to maintain a memory of explored files without cluttering the context with content.\n\nI will now attempt to update a batch of keys using `cache_write` to see if it suffers from the same \"only the last command commits\" bug. I will use the marker value `\"no relevant\"` for the keys that currently show `<no value>` but have been examined.\n\nI will use the following keys for the test:\n1. `package.json`\n2. `src/main.tsx`\n3. `src/App.tsx`\n4. `src/vscodeApi.ts` (This will be the final command to see if it's the only one that persists)\n\n"
},
{
"functionCall": {
"id": "adk-3caaaeab-b818-4967-8a06-cf57908d0a72",
"args": {
"key": "package.json",
"value": "no relevant"
},
"name": "cache_write"
}
},
{
"functionCall": {
"id": "adk-7b44dc4e-205d-4882-b8c3-63dcec005eeb",
"args": {
"key": "src/main.tsx",
"value": "no relevant"
},
"name": "cache_write"
}
},
{
"functionCall": {
"id": "adk-60a05b82-cbfd-441f-a565-fd966db0d92f",
"args": {
"key": "src/App.tsx",
"value": "no relevant"
},
"name": "cache_write"
}
},
{
"functionCall": {
"id": "adk-dd68d7e9-08ee-4ba1-96d1-06784bdd4e89",
"args": {
"key": "src/vscodeApi.ts",
"value": "no relevant"
},
"name": "cache_write"
}
}
],
"role": "model"
},
"CitationMetadata": null,
"GroundingMetadata": null,
"UsageMetadata": {
"cacheTokensDetails": [
{
"modality": "TEXT",
"tokenCount": 6772
}
],
"cachedContentTokenCount": 6772,
"candidatesTokenCount": 284,
"promptTokenCount": 7262,
"promptTokensDetails": [
{
"modality": "TEXT",
"tokenCount": 7262
}
],
"totalTokenCount": 7546
},
"CustomMetadata": null,
"LogprobsResult": null,
"Partial": false,
"TurnComplete": false,
"Interrupted": false,
"ErrorCode": "",
"ErrorMessage": "",
"FinishReason": "",
"AvgLogprobs": 0,
"ID": "2bf8cec9-5805-4209-832e-0eb085ef133a",
"Timestamp": "2025-11-24T21:00:10.756461-08:00",
"InvocationID": "e-f9ed648d-d584-49f5-9c5d-ebaa54c5ef07",
"Branch": "",
"Author": "hack",
"Actions": {
"StateDelta": {},
"ArtifactDelta": null,
"SkipSummarization": false,
"TransferToAgent": "",
"Escalate": false
},
"LongRunningToolIDs": null
}Event with bulk functionResponse
{
"Content": {
"parts": [
{
"functionResponse": {
"id": "adk-3caaaeab-b818-4967-8a06-cf57908d0a72",
"name": "cache_write",
"response": {
"key": "package.json",
"status": "ok"
}
}
},
{
"functionResponse": {
"id": "adk-7b44dc4e-205d-4882-b8c3-63dcec005eeb",
"name": "cache_write",
"response": {
"key": "src/main.tsx",
"status": "ok"
}
}
},
{
"functionResponse": {
"id": "adk-60a05b82-cbfd-441f-a565-fd966db0d92f",
"name": "cache_write",
"response": {
"key": "src/App.tsx",
"status": "ok"
}
}
},
{
"functionResponse": {
"id": "adk-dd68d7e9-08ee-4ba1-96d1-06784bdd4e89",
"name": "cache_write",
"response": {
"key": "src/vscodeApi.ts",
"status": "ok"
}
}
}
],
"role": "user"
},
"CitationMetadata": null,
"GroundingMetadata": null,
"UsageMetadata": null,
"CustomMetadata": null,
"LogprobsResult": null,
"Partial": false,
"TurnComplete": false,
"Interrupted": false,
"ErrorCode": "",
"ErrorMessage": "",
"FinishReason": "",
"AvgLogprobs": 0,
"ID": "d635feb2-4f3a-4353-9cb5-80b713e567b8",
"Timestamp": "2025-11-24T21:00:10.76217-08:00",
"InvocationID": "e-f9ed648d-d584-49f5-9c5d-ebaa54c5ef07",
"Branch": "",
"Author": "hack",
"Actions": {
"StateDelta": {
"cache:hack:src/vscodeApi.ts": "no relevant"
},
"ArtifactDelta": null,
"SkipSummarization": false,
"TransferToAgent": "",
"Escalate": false
},
"LongRunningToolIDs": null
}Multiple tool calls in the logs
Chatting payload: handlers.ChatPayload{Text:"ok, we can see the right logs now. Try a bulk operation to write \"not relevant\" to all the cache keys", Sid:"065471a3-969a-4dc1-bc49-a3a4bcf9bcc3", Agent:"hack", Model:"gemini-2.5-flash"}
userMsg &{[0x140004ea230] user} map[env:map[clipboard:WRITE machineId:cf912dbf5f56042166332d2be6fdf1e21f8155680986088029fbcbf130665dda sid:065471a3-969a-4dc1-bc49-a3a4bcf9bcc3 user:verdverm vscodeSid:0ac5806d-099c-44ea-aa35-ea7c7005b2fc1764048527260 workspaceDir:/Users/tony/hof/hof/extensions/vscode/webviews/chat]]
BAC.hack
renderInstructions.Agent hack
BMC.hack
AMC.hack
model.LLMResponse{Content:(*genai.Content)(0x14000b5cde0), CitationMetadata:(*genai.CitationMetadata)(nil), GroundingMetadata:(*genai.GroundingMetadata)(nil), UsageMetadata:(*genai.GenerateContentResponseUsageMetadata)(0x14000858750), CustomMetadata:map[string]interface {}(nil), LogprobsResult:(*genai.LogprobsResult)(nil), Partial:false, TurnComplete:false, Interrupted:false, ErrorCode:"", ErrorMessage:"", FinishReason:"STOP", AvgLogprobs:0}
chat.event: &{{0x14000b5cde0 <nil> <nil> 0x14000858750 map[] <nil> false false false STOP 0} d340e2dd-ed3b-4e8c-8376-5c89c45f46e0 2025-11-24 21:30:43.717199 -0800 PST m=+123.955414043 e-32938734-d387-4cfb-afe2-3de23b201181 hack {map[] map[] false false} []}
BTC.hack.cache_write map[key:. value:not relevant]
CACHE.WRITE: cache:hack:.
ATC.hack.cache_write map[key:. value:not relevant] map[key:. status:ok]
BTC.hack.cache_write map[key:package.json value:not relevant]
CACHE.WRITE: cache:hack:package.json
ATC.hack.cache_write map[key:package.json value:not relevant] map[key:package.json status:ok]
BTC.hack.cache_write map[key:src value:not relevant]
CACHE.WRITE: cache:hack:src
ATC.hack.cache_write map[key:src value:not relevant] map[key:src status:ok]
BTC.hack.cache_write map[key:src/App.tsx value:not relevant]
CACHE.WRITE: cache:hack:src/App.tsx
ATC.hack.cache_write map[key:src/App.tsx value:not relevant] map[key:src/App.tsx status:ok]
BTC.hack.cache_write map[key:src/components value:not relevant]
CACHE.WRITE: cache:hack:src/components
ATC.hack.cache_write map[key:src/components value:not relevant] map[key:src/components status:ok]
BTC.hack.cache_write map[key:src/components/Header.tsx value:not relevant]
CACHE.WRITE: cache:hack:src/components/Header.tsx
ATC.hack.cache_write map[key:src/components/Header.tsx value:not relevant] map[key:src/components/Header.tsx status:ok]
BTC.hack.cache_write map[key:src/components/Messages.tsx value:not relevant]
CACHE.WRITE: cache:hack:src/components/Messages.tsx
ATC.hack.cache_write map[key:src/components/Messages.tsx value:not relevant] map[key:src/components/Messages.tsx status:ok]
BTC.hack.cache_write map[key:src/main.tsx value:not relevant]
CACHE.WRITE: cache:hack:src/main.tsx
ATC.hack.cache_write map[key:src/main.tsx value:not relevant] map[key:src/main.tsx status:ok]
BTC.hack.cache_write map[key:src/vscodeApi.ts value:not relevant]
CACHE.WRITE: cache:hack:src/vscodeApi.ts
ATC.hack.cache_write map[key:src/vscodeApi.ts value:not relevant] map[key:src/vscodeApi.ts status:ok]
chat.event: &{{0x14000a919e0 <nil> <nil> <nil> map[] <nil> false false false 0} 504e260a-8bc1-4b5a-91ae-4790f149eacf 2025-11-24 21:30:43.722247 -0800 PST m=+123.960462543 e-32938734-d387-4cfb-afe2-3de23b201181 hack {map[cache:hack:src/vscodeApi.ts:not relevant] map[] false false} []}
renderInstructions.Agent hack
BMC.hack
AMC.hack
model.LLMResponse{Content:(*genai.Content)(0x14000c19470), CitationMetadata:(*genai.CitationMetadata)(nil), GroundingMetadata:(*genai.GroundingMetadata)(nil), UsageMetadata:(*genai.GenerateContentResponseUsageMetadata)(0x14000b0c240), CustomMetadata:map[string]interface {}(nil), LogprobsResult:(*genai.LogprobsResult)(nil), Partial:false, TurnComplete:false, Interrupted:false, ErrorCode:"", ErrorMessage:"", FinishReason:"STOP", AvgLogprobs:0}
chat.event: &{{0x14000c19470 <nil> <nil> 0x14000b0c240 map[] <nil> false false false STOP 0} b8b6d228-20c2-4732-bd97-f2db9822ced8 2025-11-24 21:30:44.467564 -0800 PST m=+124.705775334 e-32938734-d387-4cfb-afe2-3de23b201181 hack {map[] map[] false false} []}
AAC.hack
Legend:
BAC: BeforeAgentCallback
BMC: BeforeModelCallback
BTC: BeforeToolCallback
ATC: AfterToolCallback
AMC: AfterModelCallback
AAC: AfterAgentCallback
sowmiyan-s
Metadata
Metadata
Assignees
Labels
No labels