CopilotKit

Manually emitting messages


While most agent interactions happen automatically through shared state updates as the agent runs, you can also manually send messages from within your agent code to provide immediate feedback to users.

This video shows the result of npx copilotkit@latest init with the implementation section applied to it!

What is this?#

In CrewAI, messages are only emitted when a function is completed. CopilotKit allows you to manually emit messages in the middle of a function's execution to provide immediate feedback to the user.

When should I use this?#

Manually emitted messages are great for when you don't want to wait for the function to complete and you:

  • Have a long running task that you want to provide feedback on
  • Want to provide a status update to the user
  • Want to provide a warning or error message

Implementation#

Run and Connect Your Agent to CopilotKit#

You'll need to run your agent and connect it to CopilotKit before proceeding. If you haven't done so already, you can follow the instructions in the Getting Started guide.

If you don't already have an agent, you can use the coagent starter as a starting point as this guide uses it as a starting point.

Install the CopilotKit SDK#

Any LangGraph agent can be used with CopilotKit. However, creating deep agentic experiences with CopilotKit requires our LangGraph SDK.

uv add copilotkit
poetry add copilotkit
pip install copilotkit --extra-index-url https://copilotkit.gateway.scarf.sh/simple/
conda install copilotkit -c copilotkit-channel

npm npm install @copilotkit/sdk-js

Manually emit a message#

The copilotkit_emit_message method allows you to emit messages early in a functions's execution to communicate status updates to the user. This is particularly useful for long running tasks.

from litellm import completion
from crewai.flow.flow import start
from copilotkit.crewai import copilotkit_emit_message 
# ...

@start()
async def start(self):
    intermediate_message = "Thinking really hard..."
    await copilotkit_emit_message(intermediate_message)

    # simulate a long running task
    await asyncio.sleep(2)

    response = copilotkit_stream(
        completion(
            model="openai/gpt-5.4",
            messages=[
                {"role": "system", "content": "You are a helpful assistant."},
                *self.state["messages"]
            ],
            stream=True
        )
    )
     message = response.choices[0]["message"]

    self.state["messages"].append(message)

Give it a try!#

Now when you talk to your agent you'll notice that it immediately responds with the message "Thinking really hard..." before giving you a response 2 seconds later.