Skip to content

fix(agents): date an inline task's tool call with its result - #6981

Open
u9g wants to merge 1 commit into
mainfrom
jason/inline-task-call-order
Open

fix(agents): date an inline task's tool call with its result#6981
u9g wants to merge 1 commit into
mainfrom
jason/inline-task-call-order

Conversation

@u9g

@u9g u9g commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

What

After a tool awaits an AgentTask and the task completes, the parent's next LLM turn sometimes calls the same tool again instead of using the result. A second task starts, the caller hangs up, and the tool fails with AgentTask ... is cancelled. Seen in the data-capture-sim CI job (examples/data_capture_sim) on main since at least Aug 20, in the phone and date-of-birth scenarios.

Cause

The parent's FunctionCall item is created before the task's sub-conversation exists. When that conversation is merged into the parent's chat_ctx (sorted by created_at), the call sorts ahead of it, and group_tool_calls places its output beside the call. The parent model reads:

call collect_phone_number -> "Phone number captured: … Read it back."
assistant: Please tell me your phone number
… whole capture dialogue …
user: Yes, that's correct.
call confirm_phone_number -> (empty)

and treats the capture as still in progress.

Fix

Date the call at task completion. The call then sorts after the sub-conversation it produced, next to its output:

… capture dialogue …
user: Yes, that's correct.
call confirm_phone_number -> (empty)
call collect_phone_number -> "Phone number captured: … Read it back."
assistant: Your phone number +1 415 555 0199 has been recorded. …

Parallel tool calls sharing a group_id are grouped at the first call's position, so this is a no-op for them.

Measured

Real DataCaptureAgent on gpt-4.1-mini, 5-turn phone scenario, text modality: 3/10 re-calls before, 0/20 after. Unit suite: 2133 passed.

agents-js has the same merge + insert-by-createdAt shape in agents/src/voice/agent.ts and needs the same change.

The call that awaited an AgentTask was created before the task's whole
sub-conversation, so once that conversation is merged into the parent the
call sorts ahead of it and the result follows the call. The parent model
then reads result -> dialogue and, with the dialogue ending on a bare
confirmation, starts the capture over. Dating the call at completion
puts dialogue -> call -> result in front of the parent's reply.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Open in Devin Review

@longcw

longcw commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

can you share the full chat context before and after the fix?

call collect_phone_number -> "Phone number captured: … Read it back."
assistant: Please tell me your phone number
… whole capture dialogue …
user: Yes, that's correct.
call confirm_phone_number -> (empty)

by default the function tool inside the AgentTask won't be merged back to the parent agent, so something like call confirm_phone_number should be exist in the parent's chat context.

@u9g

u9g commented Aug 26, 2026

Copy link
Copy Markdown
Contributor Author

can you share the full chat context before and after the fix?

call collect_phone_number -> "Phone number captured: … Read it back."
assistant: Please tell me your phone number
… whole capture dialogue …
user: Yes, that's correct.
call confirm_phone_number -> (empty)

by default the function tool inside the AgentTask won't be merged back to the parent agent, so something like call confirm_phone_number should be exist in the parent's chat context.

You're right,confirm_phone_number and update_phone_number are not in the parent's chat context; merge(exclude_function_call=True) drops them. The listing in the description was dumped from session.history, which records every agent's tool calls, not from the parent agent's chat_ctx.

Here is the actual chat_ctx passed to the parent's LLM on the request right after the task completed (captured by wrapping llm.chat, gpt-4.1-mini, 5-turn phone scenario from examples/data_capture_sim):

main

user: Let me give you my phone number.
assistant: Hello! What detail would you like to provide today? …
assistant: TOOL_CALL collect_phone_number
tool: Phone number captured: +14155550199. Read it back to the user.
assistant: Please provide your phone number.
user: 555 12
assistant: The number you provided seems too short…
user: +1 415 555 0142
assistant: I have recorded the number as +1 415 555 0142. Is this correct?
user: hmm, actually use my new number, +1 415 555 0199 - that's the right one.
assistant: I have updated your number to +1 415 555 0199. Is this correct?
user: Yes, that's correct.

this branch

user: Let me give you my phone number.
assistant: Hello! Please let me know which detail you would like to provide today…
assistant: Please provide your phone number.
user: 555 12
assistant: The number you provided seems too short…
user: +1 415 555 0142
assistant: I have recorded the number as +1 (415) 555-0142. Is that correct?
user: hmm, actually use my new number, +1 415 555 0199 - that's the right one.
assistant: I have updated your number to +1 (415) 555-0199. Is this correct?
user: Yes, that's correct.
assistant: TOOL_CALL collect_phone_number
tool: Phone number captured: +14155550199. Read it back to the user.

The problem is the same without the inner calls: on main, the collect_phone_number call and its output sort above the sub-conversation (the FunctionCall was created before the task ran, and group_tool_calls keeps the output beside the call), so the context ends on the user's confirmation with nothing after it, and the model calls the tool again. Dating the call at task completion puts the call/output pair after the dialogue it produced.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants