Editing function_call.arguments in Agents SDK Has No Effect — How to Reflect Updated Form State?

Hi everyone — I’m using the OpenAI Agents SDK (Python) and I’m trying to “rehydrate” a chat from my DB by feeding Runner.run() the previous run items from result.to_input_list().

I noticed something that feels like the model is still using the original tool-call arguments (or server-stored trace) even if I mutate the old history items locally.

What I’m trying to do

  1. Run an agent that calls a tool (the tool call includes a number in its arguments).

  2. Convert the run to result.to_input_list().

  3. Mutate the previous tool-call arguments (e.g., change {"number": 100}{"number": 58}) before saving/using it.

  4. Pass the mutated list back into a second Runner.run() call, then ask: “Give me the numbers you generated in the past messages.”

Full code

@function_tool
def generate_number(number: int) -> int:
    return "Generated"

async def main():
    prompt = (
        "With given tool genereate random number between 0 and 100 when user send any message"
        "But don't send it to the user with assistant's response."
        "If users ask you what you generate. Then say it."
    )
    agent = Agent(
        name="Test",
        instructions=prompt,
        tools=[generate_number],
        model="gpt-5-mini",
    )

    result = await Runner.run(
        agent,
        "Hello how are you?",
        run_config=RunConfig(
            tracing_disabled = True,
        )
    )

    output = result.to_input_list()
    print("Output:")
    print(json.dumps(output, indent=2))
    for item in output:
        if item.get("type") == "function_call":
            if item.get("name") == "generate_number":
                # Handle arguments as either string or dict
                if "arguments" in item:
                    if isinstance(item["arguments"], str):
                        args = json.loads(item["arguments"])
                    else:
                        args = item["arguments"]
                    
                    # Extract the number
                    number = args["number"]
                    print(f"Original number: {number}")
                    
                    # Update the number to 58
                    args["number"] = 58
                    
                    # Update the arguments back
                    if isinstance(item["arguments"], str):
                        item["arguments"] = json.dumps(args)
                    else:
                        item["arguments"] = args
                    
                    print(f"Updated number: {item['arguments']}")
    print("\nUpdated Output (Input for second run):")
    print(json.dumps(output, indent=2))
    output.append({
        "role": "user",
        "content": "Give me the numbers you generated in the past messages."
    })
    result = await Runner.run(
        agent,
        output,
        run_config=RunConfig(
            tracing_disabled = True,
        )
    )
    print("\nOutput (Second run):")
    print(json.dumps(result.to_input_list(), indent=2))
    print("\nFinal Output:", result.final_output)
if __name__ == "__main__":
    asyncio.run(main())


Prints
Output:
[
  {
    "content": "Hello how are you?",
    "role": "user"
  },
  {
    "id": "rs_0badf01a75adeca30069394a0841a481959dcb8286ab77a6a2",
    "summary": [],
    "type": "reasoning"
  },
  {
    "arguments": "{\"number\":100}",
    "call_id": "call_BQtEJEh3dBjMRlDpgAyjloqO",
    "name": "generate_number",
    "type": "function_call",
    "id": "fc_0badf01a75adeca30069394a0df2808195bc124f0c43d2a68a",
    "status": "completed"
  },
  {
    "call_id": "call_BQtEJEh3dBjMRlDpgAyjloqO",
    "output": "Generated",
    "type": "function_call_output"
  },
  {
    "id": "msg_0badf01a75adeca30069394a0f05d8819582a5548d1cf155a1",
    "content": [
      {
        "annotations": [],
        "text": "Hi \u2014 I\u2019m doing well, thanks! How can I help you today?",
        "type": "output_text",
        "logprobs": []
      }
    ],
    "role": "assistant",
    "status": "completed",
    "type": "message"
  }
]
Original number: 100
Updated number: {"number": 58}

Updated Output (Input for second run):
[
  {
    "content": "Hello how are you?",
    "role": "user"
  },
  {
    "id": "rs_0badf01a75adeca30069394a0841a481959dcb8286ab77a6a2",
    "summary": [],
    "type": "reasoning"
  },
  {
    "arguments": "{\"number\": 58}",
    "call_id": "call_BQtEJEh3dBjMRlDpgAyjloqO",
    "name": "generate_number",
    "type": "function_call",
    "id": "fc_0badf01a75adeca30069394a0df2808195bc124f0c43d2a68a",
    "status": "completed"
  },
  {
    "call_id": "call_BQtEJEh3dBjMRlDpgAyjloqO",
    "output": "Generated",
    "type": "function_call_output"
  },
  {
    "id": "msg_0badf01a75adeca30069394a0f05d8819582a5548d1cf155a1",
    "content": [
      {
        "annotations": [],
        "text": "Hi \u2014 I\u2019m doing well, thanks! How can I help you today?",
        "type": "output_text",
        "logprobs": []
      }
    ],
    "role": "assistant",
    "status": "completed",
    "type": "message"
  }
]

Output (Second run):
[
  {
    "content": "Hello how are you?",
    "role": "user"
  },
  {
    "id": "rs_0badf01a75adeca30069394a0841a481959dcb8286ab77a6a2",
    "summary": [],
    "type": "reasoning"
  },
  {
    "arguments": "{\"number\": 58}",
    "call_id": "call_BQtEJEh3dBjMRlDpgAyjloqO",
    "name": "generate_number",
    "type": "function_call",
    "id": "fc_0badf01a75adeca30069394a0df2808195bc124f0c43d2a68a",
    "status": "completed"
  },
  {
    "call_id": "call_BQtEJEh3dBjMRlDpgAyjloqO",
    "output": "Generated",
    "type": "function_call_output"
  },
  {
    "id": "msg_0badf01a75adeca30069394a0f05d8819582a5548d1cf155a1",
    "content": [
      {
        "annotations": [],
        "text": "Hi \u2014 I\u2019m doing well, thanks! How can I help you today?",
        "type": "output_text",
        "logprobs": []
      }
    ],
    "role": "assistant",
    "status": "completed",
    "type": "message"
  },
  {
    "role": "user",
    "content": "Give me the numbers you generated in the past messages."
  },
  {
    "id": "rs_0badf01a75adeca30069394a1102908195abf12d7b822a339c",
    "summary": [],
    "type": "reasoning"
  },
  {
    "id": "msg_0badf01a75adeca30069394a14276c8195958e335a89ad260f",
    "content": [
      {
        "annotations": [],
        "text": "I generated: 100.",
        "type": "output_text",
        "logprobs": []
      }
    ],
    "role": "assistant",
    "status": "completed",
    "type": "message"
  }
]

Final Output: I generated: 100.

What I actually want in my real app is a UI pattern: the LLM calls a tool like show_form(...) which triggers my frontend to render a form. After the user edits/submits the form, I want the LLM to “see” the updated form state in the conversation so it reasons with the latest values. What’s the correct way to represent this update? Do I need to append a new message/tool output describing the new form JSON, or is there a supported way to modify/overwrite the earlier tool-call content so the model treats it as changed?