{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Stateless Runs\n",
    "\n",
    "Most of the time, you provide a `thread_id` to your client when you run your graph in order to keep track of prior runs through the persistent state implemented in LangGraph Cloud. However, if you have your own database to save runs and don't need to use the built in persistent state, you can create stateless runs.\n",
    "\n",
    "## Setup\n",
    "\n",
    "First, let's setup our client"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 106,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langgraph_sdk import get_client\n",
    "\n",
    "client = get_client()\n",
    "assistants = await client.assistants.search()\n",
    "assistants = [a for a in assistants if not a[\"config\"]]\n",
    "assistant = assistants[0]\n",
    "thread = await client.threads.create()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Stateless streaming\n",
    "\n",
    "We can stream the results of a stateless run in an almost identical fashion to how we stream from a run with the state attribute, but instead of passing a value to the `thread_id` parameter, we pass `None`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 107,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'agent': {'messages': [{'content': \"Hello Bagatur! It's nice to meet you. Thank you for introducing yourself and sharing your age. Is there anything specific you'd like to know or discuss? I'm here to help with any questions or topics you're interested in.\", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-489ec573-1645-4ce2-a3b8-91b391d50a71', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}]}}\n"
     ]
    }
   ],
   "source": [
    "input = {\n",
    "    \"messages\": [\n",
    "        {\"role\": \"user\", \"content\": \"Hello! My name is Bagatur and I am 26 years old.\"}\n",
    "    ]\n",
    "}\n",
    "\n",
    "\n",
    "async for chunk in client.runs.stream(\n",
    "    # Don't pass in a thread_id and the stream will be stateless\n",
    "    None,\n",
    "    assistant[\"assistant_id\"],  # graph_id\n",
    "    input=input,\n",
    "    stream_mode=\"updates\",\n",
    "):\n",
    "    if chunk.data and \"run_id\" not in chunk.data:\n",
    "        print(chunk.data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Waiting for stateless results\n",
    "\n",
    "In addition to streaming, you can also wait for a stateless result by using the `.wait` function like follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 108,
   "metadata": {},
   "outputs": [],
   "source": [
    "stateless_run_result = await client.runs.wait(\n",
    "    None,\n",
    "    assistant[\"assistant_id\"],  # graph_id\n",
    "    input=input,\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 109,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'messages': [{'content': 'Hello! My name is Bagatur and I am 26 years old.',\n",
       "   'additional_kwargs': {},\n",
       "   'response_metadata': {},\n",
       "   'type': 'human',\n",
       "   'name': None,\n",
       "   'id': '5e088543-62c2-43de-9d95-6086ad7f8b48',\n",
       "   'example': False},\n",
       "  {'content': \"Hello Bagatur! It's nice to meet you. Thank you for introducing yourself and sharing your age. Is there anything specific you'd like to know or discuss? I'm here to help with any questions or topics you'd like to explore.\",\n",
       "   'additional_kwargs': {},\n",
       "   'response_metadata': {},\n",
       "   'type': 'ai',\n",
       "   'name': None,\n",
       "   'id': 'run-d6361e8d-4d4c-45bd-ba47-39520257f773',\n",
       "   'example': False,\n",
       "   'tool_calls': [],\n",
       "   'invalid_tool_calls': [],\n",
       "   'usage_metadata': None}]}"
      ]
     },
     "execution_count": 109,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "stateless_run_result"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
