Summary
When an AgentKit run is resumed from persisted history inside an Inngest function, Gemini tool-call transcripts that were stored with a valid thought_signature still fail on the next agent.run() with error making inference request: unsuccessful status code: 400.
Separately, a clean non-Gemini control run on stock @inngest/agent-kit@0.13.2 with Anthropic (claude-haiku-4-5) fails with:
Duplicate step ID "routine-runner-seed-session-spike" detected across parallel chains
followed by the same step.ai 400.
Environment
@inngest/agent-kit@0.13.2
- Inngest dev server local
- Bun runtime for the app
- Inngest function owns the agent run and passes
step into agent.run(..., { step })
- History is persisted via
history.get / history.appendResults
Gemini repro
Goal: validate a long-running agent session that spans sleepUntil boundaries while preserving the same transcript.
High-level flow:
agent.run() executes inside an Inngest function.
- Agent calls a balance tool.
- Tool result is returned successfully.
- Agent emits
CHECK 1: ....
- Function sleeps with
step.sleepUntil(...).
- On wake, a second
agent.run() is invoked with the same AgentKit history thread.
- Second inference fails with
error making inference request: unsuccessful status code: 400.
The important part: the persisted history row does contain the original Gemini tool call with a real thought_signature.
Stored history excerpt:
{
"output": [
{
"role": "assistant",
"type": "tool_call",
"tools": [
{
"id": "get_account_balance",
"name": "get_account_balance",
"type": "tool",
"input": {
"reason": "Fetch account balance for CHECK 1"
},
"thought_signature": "<real signature present>"
}
],
"stop_reason": "tool"
}
],
"toolCalls": [
{
"role": "tool_result",
"tool": {
"id": "get_account_balance",
"name": "get_account_balance",
"type": "tool"
},
"type": "tool_result",
"content": {
"data": {
"cash": 50000.03,
"equity": 50000.03,
"buying_power": 200000.12
}
},
"stop_reason": "tool"
}
]
}
The same run also has the subsequent assistant text turn stored correctly:
{
"output": [
{
"role": "assistant",
"type": "text",
"content": "CHECK 1: equity 50000.03, cash 50000.03, buying_power 200000.12",
"stop_reason": "stop"
}
],
"toolCalls": []
}
So the signature is not absent in storage. The failure appears during AgentKit's history rehydration / replay-to-provider-request mapping for the next agent.run().
Anthropic control repro
To avoid Gemini signatures entirely, I ran the same spike against stock AgentKit with:
- provider: Anthropic
- model:
claude-haiku-4-5
- 3 iterations
- 1-minute sleeps owned by the executor, not a wait tool
That run fails on the first balance tool call with app-side output:
[tool:get_account_balance] fetched account snapshot.
Duplicate step ID "routine-runner-seed-session-spike" detected across parallel chains
and Inngest dev logs:
error handling generator response: error making inference request: unsuccessful status code: 400
This was on unpatched @inngest/agent-kit@0.13.2.
Why this seems upstream
- Gemini: the durable store contains the needed
thought_signature, but the resumed run still 400s.
- Anthropic: the same high-level executor-loop pattern hits duplicate AgentKit/Inngest step IDs on stock AgentKit before the session spike can complete.
That points to AgentKit replay/orchestration rather than application-level state loss.
Request
Could you take a look at:
- Gemini history rehydration for persisted tool-call transcripts containing
thought_signature.
- Whether
agent.run() inside resumed Inngest executions needs unique inference step IDs across turns / wakes, especially when the same agent name is reused.
If helpful I can provide a smaller standalone repro extracted from the app, but the diagnosis above is already from a minimal durable-session spike.
Summary
When an AgentKit run is resumed from persisted
historyinside an Inngest function, Gemini tool-call transcripts that were stored with a validthought_signaturestill fail on the nextagent.run()witherror making inference request: unsuccessful status code: 400.Separately, a clean non-Gemini control run on stock
@inngest/agent-kit@0.13.2with Anthropic (claude-haiku-4-5) fails with:followed by the same
step.ai400.Environment
@inngest/agent-kit@0.13.2stepintoagent.run(..., { step })history.get/history.appendResultsGemini repro
Goal: validate a long-running agent session that spans
sleepUntilboundaries while preserving the same transcript.High-level flow:
agent.run()executes inside an Inngest function.CHECK 1: ....step.sleepUntil(...).agent.run()is invoked with the same AgentKithistorythread.error making inference request: unsuccessful status code: 400.The important part: the persisted history row does contain the original Gemini tool call with a real
thought_signature.Stored history excerpt:
{ "output": [ { "role": "assistant", "type": "tool_call", "tools": [ { "id": "get_account_balance", "name": "get_account_balance", "type": "tool", "input": { "reason": "Fetch account balance for CHECK 1" }, "thought_signature": "<real signature present>" } ], "stop_reason": "tool" } ], "toolCalls": [ { "role": "tool_result", "tool": { "id": "get_account_balance", "name": "get_account_balance", "type": "tool" }, "type": "tool_result", "content": { "data": { "cash": 50000.03, "equity": 50000.03, "buying_power": 200000.12 } }, "stop_reason": "tool" } ] }The same run also has the subsequent assistant text turn stored correctly:
{ "output": [ { "role": "assistant", "type": "text", "content": "CHECK 1: equity 50000.03, cash 50000.03, buying_power 200000.12", "stop_reason": "stop" } ], "toolCalls": [] }So the signature is not absent in storage. The failure appears during AgentKit's history rehydration / replay-to-provider-request mapping for the next
agent.run().Anthropic control repro
To avoid Gemini signatures entirely, I ran the same spike against stock AgentKit with:
claude-haiku-4-5That run fails on the first balance tool call with app-side output:
and Inngest dev logs:
This was on unpatched
@inngest/agent-kit@0.13.2.Why this seems upstream
thought_signature, but the resumed run still 400s.That points to AgentKit replay/orchestration rather than application-level state loss.
Request
Could you take a look at:
thought_signature.agent.run()inside resumed Inngest executions needs unique inference step IDs across turns / wakes, especially when the same agent name is reused.If helpful I can provide a smaller standalone repro extracted from the app, but the diagnosis above is already from a minimal durable-session spike.