Skip to content

Send message to the ADK API and display in the chat/session #3722

Closed

Description

@zdenulo

In my workflow, an agent is taking input from a user and, in the tool, submits a long-running job to the outside API. API returns "id" of the job, which the user can then use to query information about the job, i.e., if it is completed and similar.

I'm wondering if there is a way to send an API request to the ADK server from the outside, i.e., in my context, I would like to send a message from the outside system to a user that the job has been completed, and (ideally) it displays in real time in the chat window.

I've tried this code snippet

import requests

url = "http://127.0.0.1:8000/run_sse"
url = "http://127.0.0.1:8000/run"

session_id = 'b8adac74-e070-4c28-b899-a375b07c9258'

data = {
    'app_name': 'chat_agent',
    'user_id': 'user',
    'session_id': session_id,
    'new_message': {
        'parts': [
            {'text': 'Job xx is completed'}
        ],
        'role': 'model'
    }
}

r = requests.post(url, json=data)
print(r.text)

When sending data like this, I only see the message when I reload the Web UI (session), and it appears as if it were from a user (not a model) to which the model then responds.
So my questions are:

  1. Can a message be posted as it is from a model (not a user)
  2. Can the update be done in real-time (without reloading the session)

Activity

  1. juszzz commented on Nov 26, 2025

    @juszzz

    We prototyped something using the long-running function tool pattern, and found the official docs to be a bit confusing/unhelpful. What worked for us:

    We would send a message (with user role -- not sure if this is critical or not) to the ADK agent from our outside API once the job was completed:

    updated_function_response_part = types.Part(
                function_response=types.FunctionResponse(
                    id=tool_call_id,     # This is generated by ADK during the initial LongRunningFunctionTool call
                    name=tool,
                    response={
                        "status": "completed",
                        "message": "Job '123' successful",
                        "job_id": "123",
                    },
                )
            )
    
  2. juszzz commented on Nov 26, 2025

    @juszzz

    My hunch is that using the user role is important to prod the agent to initiate another conversational turn, and using the types.FunctionResponse message Part instead of text might allow ADK to recognize this is a long-running tool response, and not actually a message from the user that needs to be rendered. This is just based on my recollection from a few months ago though, so I could be off-base here.

  3. added
    services[Component] This issue is related to runtime services, e.g. sessions, memory, artifacts, etc
    on Nov 27, 2025
  4. zdenulo commented on Nov 27, 2025

    @zdenulo
    Author

    @juszzz thanks for the response and your tips, it helped a lot. I managed to send the data back to ADK API, and it handled it correctly. When data is posted to the ADK API, ADK makes a request to the LLM and sends the LLM's response to the chat.

    One thing, though, that I haven't managed yet is how to do an update for chat real-time (but maybe that's an issue of ADK Web UI, I didn't check that yet), chat update is displayed only upon session reload.

    This is the code snippet I was using for prototyping. I'm leaving it here for future reference.

    Within the data that is being sent to the API, there is "adk_data" that would be sent back from the API

    async def my_tool(user_query: str, tool_context: ToolContext) -> dict:
        """A tool that answer user questions
        :param user_query: user query for which job will be submitted
    
        :return: submitted job id and status
        """
    
        # adk data are needed for the request back to the ADK API
        adk_data = {
            'app_name': tool_context.agent_name,
            'user_id': tool_context.user_id,
            'session_id': tool_context.session.id,
            'function_call_id': tool_context.function_call_id,
            'name': 'my_tool',  # this needs to correspond to the tool (function) name
        }
    
        api_data = {
            'adk_data': adk_data,
            'api_input_data': {
            # data for API itself for example
            }
        }
        # request to the API that submits input as well as ADK data
        resp = requests.post(url=os.environ['API_URL'], json=api_data)
        if resp.ok:
            job_response = resp.json()
            response_data = {
                'job_id': job_response['job_id'],
                'status': job_response['status'],
            }
            return response_data
        else:
            return {
                'status': 'error',
                'message': resp.text
            }

    and this is part from API how data should be send back:

    adk_url = "http://127.0.0.1:8000/run"
    
    adk_data = {'app_name': 'chat_agent', 'user_id': 'user', 'session_id': 'd44a9855-d4e3-4d1a-9722-5ec20a1b6a25',
                'function_call_id': 'adk-b8ff9c21-f56a-445c-afe2-edc546417894', 'name': 'my_tool'}
    
    data = {
        'app_name': adk_data['app_name'],
        'user_id': adk_data['user_id'],
        'session_id': adk_data['session_id'],
        'new_message': {
            'parts': [
                {
                    'function_response': {
                        'id': adk_data['function_call_id'],
                        'name': adk_data['name'],
                        'response': {'status': 'completed', 'job_id': '12'}
                    }
                }
            ],
            'role': 'user'
        }
    }
    
    r = requests.post(adk_url, json=data)
  5. juszzz commented on Nov 27, 2025

    @juszzz

    @zdenulo glad to help. Did you wrap my_tool in a LongRunningFunctionTool wrapper before providing it to your agent?

  6. zdenulo commented on Nov 27, 2025

    @zdenulo
    Author

    @juszzz yes I did

  7. locked and limited conversation to collaborators on Dec 2, 2025
  8. converted this issue into a discussion #3774 on Dec 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    services[Component] This issue is related to runtime services, e.g. sessions, memory, artifacts, etc

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions