From a649cf01c52060288ecb289b386d96f9c5bc775f Mon Sep 17 00:00:00 2001 From: shawnthapa Date: Fri, 29 May 2026 18:07:32 -0700 Subject: [PATCH] Add context compaction support --- examples/aio/compaction.py | 223 ++++++++++++++++++++++++++ examples/sync/compaction.py | 221 +++++++++++++++++++++++++ src/xai_sdk/aio/chat.py | 67 +++++++- src/xai_sdk/chat.py | 63 +++++++- src/xai_sdk/proto/v5/chat_pb2.py | 46 +++--- src/xai_sdk/proto/v5/chat_pb2.pyi | 28 +++- src/xai_sdk/proto/v5/chat_pb2_grpc.py | 47 ++++++ src/xai_sdk/proto/v6/chat_pb2.py | 46 +++--- src/xai_sdk/proto/v6/chat_pb2.pyi | 28 +++- src/xai_sdk/proto/v6/chat_pb2_grpc.py | 47 ++++++ src/xai_sdk/sync/chat.py | 67 +++++++- tests/aio/chat_test.py | 110 +++++++++++++ tests/chat_test.py | 129 ++++++++++++++- tests/server.py | 13 ++ tests/sync/chat_test.py | 103 ++++++++++++ 15 files changed, 1178 insertions(+), 60 deletions(-) create mode 100644 examples/aio/compaction.py create mode 100644 examples/sync/compaction.py diff --git a/examples/aio/compaction.py b/examples/aio/compaction.py new file mode 100644 index 0000000..dc98071 --- /dev/null +++ b/examples/aio/compaction.py @@ -0,0 +1,223 @@ +import asyncio + +from xai_sdk import AsyncClient +from xai_sdk.chat import assistant, system, user + +MODEL = "grok-4.3" + + +async def standalone_compaction(): + """Demonstrates client.chat.compact_context() on a pre-built message list.""" + client = AsyncClient() + + # Build a conversation: real content we care about, then thousands of tokens of filler + # to demonstrate compaction savings. + messages = [ + system("You are a concise and knowledgeable science tutor."), + # === Important context we want preserved through compaction === + user("What is the Higgs boson and why is it important?"), + assistant( + "The Higgs boson is an elementary particle in the Standard Model of particle physics. " + "It was predicted in 1964 by Peter Higgs and others, and confirmed experimentally in 2012 " + "at CERN's Large Hadron Collider. It's important because it's the quantum excitation of the " + "Higgs field, which gives mass to fundamental particles like quarks and leptons through the " + "Higgs mechanism. Without the Higgs field, particles would be massless and atoms couldn't form." + ), + user("How does the Higgs mechanism actually work?"), + assistant( + "The Higgs mechanism works through spontaneous symmetry breaking. The Higgs field permeates " + "all of space with a nonzero vacuum expectation value. As particles move through this field, " + "they interact with it -- the stronger the interaction, the more mass the particle acquires. " + "Think of it like moving through a crowd: a celebrity (strong interaction) gets slowed down " + "more than an unknown person (weak interaction). Photons don't interact with the Higgs field " + "at all, which is why they're massless and travel at the speed of light." + ), + # === Filler: many turns of trivia to bulk up the context === + user("Tell me about the history of the Roman Empire."), + assistant( + "The Roman Empire began in 27 BC when Octavian became Augustus, the first emperor. At its peak " + "under Trajan around 117 AD, it stretched from Britain to Mesopotamia, encompassing the entire " + "Mediterranean. The empire was characterized by its sophisticated legal system, engineering feats " + "like aqueducts and roads, and a professional military. The western half fell in 476 AD when " + "Romulus Augustulus was deposed by Odoacer. The eastern half, the Byzantine Empire, survived " + "until Constantinople fell to the Ottoman Turks in 1453. Key emperors include Augustus, Trajan, " + "Hadrian, Marcus Aurelius, Diocletian who split the empire, and Constantine who legalized " + "Christianity. The Pax Romana, roughly 27 BC to 180 AD, was a period of relative peace and " + "stability that allowed trade, culture, and infrastructure to flourish across the empire." + ), + user("What about the French Revolution?"), + assistant( + "The French Revolution began in 1789 with the storming of the Bastille and fundamentally " + "transformed French society. Key causes included financial crisis from wars and royal " + "extravagance, Enlightenment ideals challenging absolute monarchy, and widespread inequality " + "under the Estates system. Major phases include the National Assembly period with the " + "Declaration of the Rights of Man, the radical Jacobin phase under Robespierre and the Reign " + "of Terror (1793-94) which saw thousands guillotined, the Thermidorian Reaction, and the " + "Directory. It ended with Napoleon's coup in 1799. The revolution abolished feudalism, " + "established civil equality, secularized the state, and inspired democratic movements " + "worldwide. The metric system, the tricolor flag, and modern concepts of citizenship all " + "originated from this period. Its legacy includes both the ideals of liberty, equality, " + "and fraternity, and the cautionary tale of revolutionary violence." + ), + user("Explain photosynthesis in detail."), + assistant( + "Photosynthesis converts light energy into chemical energy in two main stages. The light-" + "dependent reactions occur in the thylakoid membranes of chloroplasts. Chlorophyll and other " + "pigments absorb photons, exciting electrons that pass through two photosystems (PSII and PSI) " + "and an electron transport chain. Water molecules are split (photolysis), releasing oxygen as " + "a byproduct. This process generates ATP via chemiosmosis and NADPH. The light-independent " + "reactions (Calvin cycle) occur in the stroma. CO2 is fixed by RuBisCO onto ribulose " + "bisphosphate (RuBP), forming 3-phosphoglycerate (3-PGA). ATP and NADPH from the light " + "reactions reduce 3-PGA to glyceraldehyde-3-phosphate (G3P). Most G3P is recycled to " + "regenerate RuBP, while some exits to form glucose and other organic molecules. The overall " + "equation is 6CO2 + 6H2O + light -> C6H12O6 + 6O2. C4 and CAM plants have evolved " + "modifications to reduce photorespiration in hot, dry environments." + ), + user("How do black holes form?"), + assistant( + "Black holes form primarily through stellar collapse. When a massive star (roughly 20+ solar " + "masses) exhausts its nuclear fuel, radiation pressure can no longer support the core against " + "gravity. The core collapses in milliseconds -- if the remnant exceeds the Tolman-Oppenheimer-" + "Volkoff limit (about 2-3 solar masses), neutron degeneracy pressure fails and the core " + "collapses into a singularity surrounded by an event horizon. This often produces a supernova " + "explosion of the outer layers. Supermassive black holes (millions to billions of solar masses) " + "at galactic centers likely formed through mergers and accretion over billions of years, though " + "their exact origin is debated. Intermediate-mass black holes may form in dense star clusters " + "through runaway collisions. The event horizon radius (Schwarzschild radius) equals 2GM/c^2. " + "Nothing, not even light, can escape from within the event horizon. Hawking radiation " + "theoretically causes black holes to slowly evaporate, though this is negligible for " + "stellar-mass and larger black holes." + ), + user("Describe the water cycle."), + assistant( + "The water cycle, or hydrological cycle, continuously moves water through Earth's systems. " + "Evaporation converts surface water from oceans, lakes, and rivers into vapor using solar " + "energy -- oceans contribute about 86% of atmospheric moisture. Transpiration releases water " + "vapor from plant leaves through stomata. Together these are called evapotranspiration. Warm, " + "moist air rises and cools adiabatically, reaching the dew point where condensation forms " + "clouds on condensation nuclei (dust, pollen, sea salt). Precipitation occurs when cloud " + "droplets coalesce (warm clouds) or ice crystals grow at the expense of supercooled droplets " + "(cold clouds, the Bergeron process). Water returns to the surface as rain, snow, sleet, or " + "hail. On land, some water infiltrates soil (percolation) recharging groundwater aquifers. " + "Surface runoff flows into streams and rivers, eventually returning to oceans. Groundwater " + "moves slowly through aquifers and can discharge into springs, rivers, or directly into the " + "ocean. The cycle is driven by solar energy and gravity. Human activities like deforestation, " + "urbanization, and groundwater pumping significantly alter local water cycles." + ), + user("Tell me about the periodic table."), + assistant( + "The periodic table organizes 118 known elements by atomic number (proton count). Dmitri " + "Mendeleev published the first widely recognized version in 1869, arranging elements by " + "atomic weight and predicting undiscovered elements. The modern table has 7 periods (rows) " + "and 18 groups (columns). Elements in the same group share similar chemical properties due " + "to identical valence electron configurations. Groups include alkali metals (1), alkaline " + "earth metals (2), halogens (17), and noble gases (18). The table is divided into s-block " + "(groups 1-2), p-block (13-18), d-block (3-12, transition metals), and f-block (lanthanides " + "and actinides). Trends across periods include increasing electronegativity, ionization " + "energy, and electron affinity from left to right, and decreasing atomic radius. Down groups, " + "atomic radius increases, ionization energy decreases, and metallic character increases. " + "Elements 1-94 occur naturally; 95-118 are synthetic, created in particle accelerators. " + "Oganesson (118) is the heaviest element synthesized to date." + ), + user("How does the immune system work?"), + assistant( + "The immune system has innate and adaptive components. The innate immune system provides " + "immediate, non-specific defense: physical barriers (skin, mucous membranes), chemical " + "barriers (stomach acid, lysozyme in tears), and cellular responses from neutrophils, " + "macrophages, dendritic cells, and natural killer cells. These recognize pathogen-associated " + "molecular patterns (PAMPs) via pattern recognition receptors (PRRs) like Toll-like receptors. " + "Inflammation recruits immune cells to infection sites through cytokine signaling. The " + "complement system, a cascade of plasma proteins, directly lyses pathogens and marks them for " + "phagocytosis (opsonization). The adaptive immune system is specific and develops memory. " + "T cells mature in the thymus: helper T cells (CD4+) coordinate responses, cytotoxic T cells " + "(CD8+) kill infected cells, and regulatory T cells suppress excessive responses. B cells " + "produce antibodies (immunoglobulins) that neutralize pathogens, activate complement, and " + "facilitate phagocytosis. After infection, memory B and T cells persist for years, enabling " + "faster responses to reinfection -- this is the basis of vaccination." + ), + user("Explain plate tectonics."), + assistant( + "Plate tectonics describes Earth's lithosphere as divided into about 15 major and several " + "minor plates that float on the semi-fluid asthenosphere. Convection currents in the mantle, " + "driven by radioactive decay heating, move plates at 1-15 cm/year. At divergent boundaries " + "(mid-ocean ridges), plates separate and new crust forms from upwelling magma -- the Mid-" + "Atlantic Ridge creates about 2.5 cm of new crust annually. At convergent boundaries, denser " + "oceanic crust subducts beneath continental or other oceanic crust, forming deep trenches " + "(Mariana Trench, 11 km deep), volcanic arcs (Ring of Fire), and mountain ranges (Himalayas " + "from India-Eurasia collision). Transform boundaries involve lateral sliding (San Andreas " + "Fault). Evidence for plate tectonics includes matching coastlines (South America and Africa), " + "fossil distributions, paleomagnetic striping on the ocean floor, and GPS measurements of " + "plate motion. Earthquakes concentrate at plate boundaries. Hotspot volcanism (Hawaii, " + "Yellowstone) occurs over mantle plumes independent of plate boundaries." + ), + ] + + print(f"Original conversation: {len(messages)} messages") + print("=" * 60) + + # Create a chat and load the conversation history. + chat = client.chat.create(model=MODEL, use_encrypted_content=True, messages=messages) + + # Compact the conversation in-place. The server will drop everything + # before the compaction blob on the next request. + compaction = await chat.compact() + + print(f"Compaction ID: {compaction.id}") + print(f"Dropped messages: {compaction.dropped_message_count}") + print(f"Usage: {compaction.usage}") + print("=" * 60) + + # Ask a question that requires the compacted context to answer. + chat.append(user("Based on our earlier conversation, what gives particles their mass?")) + response = await chat.sample() + + print("\n--- Follow-up using compacted context ---") + print(f"Grok: {response.content}") + print(f"\nFollow-up prompt tokens: {response.usage.prompt_tokens}") + print(f"Follow-up completion tokens: {response.usage.completion_tokens}") + print(f"Follow-up total tokens: {response.usage.total_tokens}") + + # Ask a second follow-up to verify multi-turn still works on top of compacted context. + chat.append(response) + chat.append(user("And who predicted that particle?")) + response2 = await chat.sample() + + print("\n--- Second follow-up ---") + print(f"Grok: {response2.content}") + + +async def in_place_compaction(): + """Demonstrates periodic chat.compact() inside a multi-turn conversation loop.""" + client = AsyncClient() + compact_every = 5 + + chat = client.chat.create(model=MODEL, use_encrypted_content=True) + chat.append(system("You are a helpful assistant. Keep answers brief.")) + + turns = 0 + while True: + prompt = input("You: ") + if prompt.lower() == "exit": + break + + chat.append(user(prompt)) + response = await chat.sample() + print(f"Grok: {response.content}") + chat.append(response) + turns += 1 + + if turns % compact_every == 0: + print("\nCompacting conversation...") + before = len(chat.messages) + compact = await chat.compact() + print( + f"\n [compacted {before} messages -> {len(chat.messages)} | " + f"dropped {compact.dropped_message_count} | " + f"tokens used: {compact.usage.total_tokens}]\n" + ) + + +if __name__ == "__main__": + # Uncomment the respective line to run the example. + asyncio.run(standalone_compaction()) + # asyncio.run(in_place_compaction()) diff --git a/examples/sync/compaction.py b/examples/sync/compaction.py new file mode 100644 index 0000000..f6262b0 --- /dev/null +++ b/examples/sync/compaction.py @@ -0,0 +1,221 @@ +from xai_sdk import Client +from xai_sdk.chat import assistant, system, user + +MODEL = "grok-4.3" + + +def standalone_compaction(): + """Demonstrates client.chat.compact_context() on a pre-built message list.""" + client = Client() + + # Build a conversation: real content we care about, then thousands of tokens of filler + # to demonstrate compaction savings. + messages = [ + system("You are a concise and knowledgeable science tutor."), + # === Important context we want preserved through compaction === + user("What is the Higgs boson and why is it important?"), + assistant( + "The Higgs boson is an elementary particle in the Standard Model of particle physics. " + "It was predicted in 1964 by Peter Higgs and others, and confirmed experimentally in 2012 " + "at CERN's Large Hadron Collider. It's important because it's the quantum excitation of the " + "Higgs field, which gives mass to fundamental particles like quarks and leptons through the " + "Higgs mechanism. Without the Higgs field, particles would be massless and atoms couldn't form." + ), + user("How does the Higgs mechanism actually work?"), + assistant( + "The Higgs mechanism works through spontaneous symmetry breaking. The Higgs field permeates " + "all of space with a nonzero vacuum expectation value. As particles move through this field, " + "they interact with it -- the stronger the interaction, the more mass the particle acquires. " + "Think of it like moving through a crowd: a celebrity (strong interaction) gets slowed down " + "more than an unknown person (weak interaction). Photons don't interact with the Higgs field " + "at all, which is why they're massless and travel at the speed of light." + ), + # === Filler: many turns of trivia to bulk up the context === + user("Tell me about the history of the Roman Empire."), + assistant( + "The Roman Empire began in 27 BC when Octavian became Augustus, the first emperor. At its peak " + "under Trajan around 117 AD, it stretched from Britain to Mesopotamia, encompassing the entire " + "Mediterranean. The empire was characterized by its sophisticated legal system, engineering feats " + "like aqueducts and roads, and a professional military. The western half fell in 476 AD when " + "Romulus Augustulus was deposed by Odoacer. The eastern half, the Byzantine Empire, survived " + "until Constantinople fell to the Ottoman Turks in 1453. Key emperors include Augustus, Trajan, " + "Hadrian, Marcus Aurelius, Diocletian who split the empire, and Constantine who legalized " + "Christianity. The Pax Romana, roughly 27 BC to 180 AD, was a period of relative peace and " + "stability that allowed trade, culture, and infrastructure to flourish across the empire." + ), + user("What about the French Revolution?"), + assistant( + "The French Revolution began in 1789 with the storming of the Bastille and fundamentally " + "transformed French society. Key causes included financial crisis from wars and royal " + "extravagance, Enlightenment ideals challenging absolute monarchy, and widespread inequality " + "under the Estates system. Major phases include the National Assembly period with the " + "Declaration of the Rights of Man, the radical Jacobin phase under Robespierre and the Reign " + "of Terror (1793-94) which saw thousands guillotined, the Thermidorian Reaction, and the " + "Directory. It ended with Napoleon's coup in 1799. The revolution abolished feudalism, " + "established civil equality, secularized the state, and inspired democratic movements " + "worldwide. The metric system, the tricolor flag, and modern concepts of citizenship all " + "originated from this period. Its legacy includes both the ideals of liberty, equality, " + "and fraternity, and the cautionary tale of revolutionary violence." + ), + user("Explain photosynthesis in detail."), + assistant( + "Photosynthesis converts light energy into chemical energy in two main stages. The light-" + "dependent reactions occur in the thylakoid membranes of chloroplasts. Chlorophyll and other " + "pigments absorb photons, exciting electrons that pass through two photosystems (PSII and PSI) " + "and an electron transport chain. Water molecules are split (photolysis), releasing oxygen as " + "a byproduct. This process generates ATP via chemiosmosis and NADPH. The light-independent " + "reactions (Calvin cycle) occur in the stroma. CO2 is fixed by RuBisCO onto ribulose " + "bisphosphate (RuBP), forming 3-phosphoglycerate (3-PGA). ATP and NADPH from the light " + "reactions reduce 3-PGA to glyceraldehyde-3-phosphate (G3P). Most G3P is recycled to " + "regenerate RuBP, while some exits to form glucose and other organic molecules. The overall " + "equation is 6CO2 + 6H2O + light -> C6H12O6 + 6O2. C4 and CAM plants have evolved " + "modifications to reduce photorespiration in hot, dry environments." + ), + user("How do black holes form?"), + assistant( + "Black holes form primarily through stellar collapse. When a massive star (roughly 20+ solar " + "masses) exhausts its nuclear fuel, radiation pressure can no longer support the core against " + "gravity. The core collapses in milliseconds -- if the remnant exceeds the Tolman-Oppenheimer-" + "Volkoff limit (about 2-3 solar masses), neutron degeneracy pressure fails and the core " + "collapses into a singularity surrounded by an event horizon. This often produces a supernova " + "explosion of the outer layers. Supermassive black holes (millions to billions of solar masses) " + "at galactic centers likely formed through mergers and accretion over billions of years, though " + "their exact origin is debated. Intermediate-mass black holes may form in dense star clusters " + "through runaway collisions. The event horizon radius (Schwarzschild radius) equals 2GM/c^2. " + "Nothing, not even light, can escape from within the event horizon. Hawking radiation " + "theoretically causes black holes to slowly evaporate, though this is negligible for " + "stellar-mass and larger black holes." + ), + user("Describe the water cycle."), + assistant( + "The water cycle, or hydrological cycle, continuously moves water through Earth's systems. " + "Evaporation converts surface water from oceans, lakes, and rivers into vapor using solar " + "energy -- oceans contribute about 86% of atmospheric moisture. Transpiration releases water " + "vapor from plant leaves through stomata. Together these are called evapotranspiration. Warm, " + "moist air rises and cools adiabatically, reaching the dew point where condensation forms " + "clouds on condensation nuclei (dust, pollen, sea salt). Precipitation occurs when cloud " + "droplets coalesce (warm clouds) or ice crystals grow at the expense of supercooled droplets " + "(cold clouds, the Bergeron process). Water returns to the surface as rain, snow, sleet, or " + "hail. On land, some water infiltrates soil (percolation) recharging groundwater aquifers. " + "Surface runoff flows into streams and rivers, eventually returning to oceans. Groundwater " + "moves slowly through aquifers and can discharge into springs, rivers, or directly into the " + "ocean. The cycle is driven by solar energy and gravity. Human activities like deforestation, " + "urbanization, and groundwater pumping significantly alter local water cycles." + ), + user("Tell me about the periodic table."), + assistant( + "The periodic table organizes 118 known elements by atomic number (proton count). Dmitri " + "Mendeleev published the first widely recognized version in 1869, arranging elements by " + "atomic weight and predicting undiscovered elements. The modern table has 7 periods (rows) " + "and 18 groups (columns). Elements in the same group share similar chemical properties due " + "to identical valence electron configurations. Groups include alkali metals (1), alkaline " + "earth metals (2), halogens (17), and noble gases (18). The table is divided into s-block " + "(groups 1-2), p-block (13-18), d-block (3-12, transition metals), and f-block (lanthanides " + "and actinides). Trends across periods include increasing electronegativity, ionization " + "energy, and electron affinity from left to right, and decreasing atomic radius. Down groups, " + "atomic radius increases, ionization energy decreases, and metallic character increases. " + "Elements 1-94 occur naturally; 95-118 are synthetic, created in particle accelerators. " + "Oganesson (118) is the heaviest element synthesized to date." + ), + user("How does the immune system work?"), + assistant( + "The immune system has innate and adaptive components. The innate immune system provides " + "immediate, non-specific defense: physical barriers (skin, mucous membranes), chemical " + "barriers (stomach acid, lysozyme in tears), and cellular responses from neutrophils, " + "macrophages, dendritic cells, and natural killer cells. These recognize pathogen-associated " + "molecular patterns (PAMPs) via pattern recognition receptors (PRRs) like Toll-like receptors. " + "Inflammation recruits immune cells to infection sites through cytokine signaling. The " + "complement system, a cascade of plasma proteins, directly lyses pathogens and marks them for " + "phagocytosis (opsonization). The adaptive immune system is specific and develops memory. " + "T cells mature in the thymus: helper T cells (CD4+) coordinate responses, cytotoxic T cells " + "(CD8+) kill infected cells, and regulatory T cells suppress excessive responses. B cells " + "produce antibodies (immunoglobulins) that neutralize pathogens, activate complement, and " + "facilitate phagocytosis. After infection, memory B and T cells persist for years, enabling " + "faster responses to reinfection -- this is the basis of vaccination." + ), + user("Explain plate tectonics."), + assistant( + "Plate tectonics describes Earth's lithosphere as divided into about 15 major and several " + "minor plates that float on the semi-fluid asthenosphere. Convection currents in the mantle, " + "driven by radioactive decay heating, move plates at 1-15 cm/year. At divergent boundaries " + "(mid-ocean ridges), plates separate and new crust forms from upwelling magma -- the Mid-" + "Atlantic Ridge creates about 2.5 cm of new crust annually. At convergent boundaries, denser " + "oceanic crust subducts beneath continental or other oceanic crust, forming deep trenches " + "(Mariana Trench, 11 km deep), volcanic arcs (Ring of Fire), and mountain ranges (Himalayas " + "from India-Eurasia collision). Transform boundaries involve lateral sliding (San Andreas " + "Fault). Evidence for plate tectonics includes matching coastlines (South America and Africa), " + "fossil distributions, paleomagnetic striping on the ocean floor, and GPS measurements of " + "plate motion. Earthquakes concentrate at plate boundaries. Hotspot volcanism (Hawaii, " + "Yellowstone) occurs over mantle plumes independent of plate boundaries." + ), + ] + + print(f"Original conversation: {len(messages)} messages") + print("=" * 60) + + # Create a chat and load the conversation history. + chat = client.chat.create(model=MODEL, use_encrypted_content=True, messages=messages) + + # Compact the conversation in-place. The server will drop everything + # before the compaction blob on the next request. + compaction = chat.compact() + + print(f"Compaction ID: {compaction.id}") + print(f"Dropped messages: {compaction.dropped_message_count}") + print(f"Usage: {compaction.usage}") + print("=" * 60) + + # Ask a question that requires the compacted context to answer. + chat.append(user("Based on our earlier conversation, what gives particles their mass?")) + response = chat.sample() + + print("\n--- Follow-up using compacted context ---") + print(f"Grok: {response.content}") + print(f"\nFollow-up prompt tokens: {response.usage.prompt_tokens}") + print(f"Follow-up completion tokens: {response.usage.completion_tokens}") + print(f"Follow-up total tokens: {response.usage.total_tokens}") + + # Ask a second follow-up to verify multi-turn still works on top of compacted context. + chat.append(response) + chat.append(user("And who predicted that particle?")) + response2 = chat.sample() + + print("\n--- Second follow-up ---") + print(f"Grok: {response2.content}") + + +def in_place_compaction(): + """Demonstrates periodic chat.compact() inside a multi-turn conversation loop.""" + client = Client() + compact_every = 5 + + chat = client.chat.create(model=MODEL, use_encrypted_content=True) + chat.append(system("You are a helpful assistant. Keep answers brief.")) + + turns = 0 + while True: + prompt = input("You: ") + if prompt.lower() == "exit": + break + + chat.append(user(prompt)) + response = chat.sample() + print(f"Grok: {response.content}") + chat.append(response) + turns += 1 + + if turns % compact_every == 0: + print("\nCompacting conversation...") + before = len(chat.messages) + compact = chat.compact() + print( + f"\n [compacted {before} messages -> {len(chat.messages)} | " + f"dropped {compact.dropped_message_count} | " + f"tokens used: {compact.usage.total_tokens}]\n" + ) + + +if __name__ == "__main__": + # Uncomment the respective line to run the example. + standalone_compaction() + # in_place_compaction() diff --git a/src/xai_sdk/aio/chat.py b/src/xai_sdk/aio/chat.py index 292fe3c..c4a7f78 100644 --- a/src/xai_sdk/aio/chat.py +++ b/src/xai_sdk/aio/chat.py @@ -2,15 +2,16 @@ import datetime import json import warnings -from typing import AsyncIterator, Optional, Sequence, TypeVar +from typing import AsyncIterator, Optional, Sequence, TypeVar, Union from opentelemetry.trace import SpanKind from pydantic import BaseModel -from ..chat import BaseChat, BaseClient, Chunk, Response +from ..chat import BaseChat, BaseClient, Chunk, CompactContextResponse, Response from ..poll_timer import PollTimer from ..proto import chat_pb2, deferred_pb2 from ..telemetry import get_tracer +from ..types import ChatModel tracer = get_tracer(__name__) @@ -52,6 +53,39 @@ async def get_stored_completion(self, response_id: str) -> Sequence[Response]: response = await self._stub.GetStoredCompletion(chat_pb2.GetStoredCompletionRequest(response_id=response_id)) return [Response(response, i) for i in range(len(response.outputs))] + async def compact_context( + self, + model: Union[ChatModel, str], + messages: Sequence[chat_pb2.Message], + ) -> CompactContextResponse: + """Compacts a conversation context into an opaque encrypted representation. + + Sends the current input messages to the server which returns a compacted + context. The resulting ``encrypted_content`` can be used in a follow-up + chat request via an assistant message with the ``encrypted_content`` field + set, allowing the model to hydrate the summarised context without sending + the full message history. + + Args: + model: Model to use for compaction, e.g. ``"grok-4.3"``. + messages: The conversation messages to compact. + + Returns: + CompactContextResponse: A response containing the ``encrypted_content`` + string, the number of dropped messages, and token usage. + + Example: + >>> from xai_sdk.chat import user, system + >>> compact = await client.chat.compact_context( + ... model="grok-4.3", + ... messages=[system("You are helpful."), user("Summarise our chat.")], + ... ) + >>> print(compact.encrypted_content) + """ + request = chat_pb2.CompactContextRequest(model=model, input=messages) + response = await self._stub.CompactContext(request) + return CompactContextResponse(response) + async def delete_stored_completion(self, response_id: str) -> str: """Deletes a stored chat completion response from the xAI backend. @@ -84,6 +118,35 @@ async def delete_stored_completion(self, response_id: str) -> str: class Chat(BaseChat): """Utility class for simplifying the interaction with Chat requests and responses.""" + async def compact(self) -> CompactContextResponse: + """Compacts the current conversation history. + + Sends all messages to the CompactContext RPC and appends the resulting + compaction message to the conversation. Prior messages are kept + client-side; the server will automatically drop everything before the + last compaction message when processing the next request. + + Returns: + CompactContextResponse: The compaction response with token usage + and dropped message count. + + Example: + >>> chat = client.chat.create(model="grok-4.3") + >>> chat.append(user("Hello!")) + >>> response = await chat.sample() + >>> chat.append(response) + >>> # ... many turns later ... + >>> compact = await chat.compact() + >>> print(f"Dropped {compact.dropped_message_count} messages") + >>> # Continue chatting on top of compacted context + >>> chat.append(user("What did we discuss?")) + >>> response = await chat.sample() + """ + response_pb = await self._stub.CompactContext(self._make_compact_request()) + result = CompactContextResponse(response_pb) + self._apply_compaction(result) + return result + async def sample(self) -> Response: """Asynchronously samples a single chat completion response from the model. diff --git a/src/xai_sdk/chat.py b/src/xai_sdk/chat.py index 0c33ee0..8f64edd 100644 --- a/src/xai_sdk/chat.py +++ b/src/xai_sdk/chat.py @@ -281,7 +281,7 @@ def __init__( self._conversation_id = conversation_id self._batch_request_id = batch_request_id - def append(self, message: Union[chat_pb2.Message, "Response"]) -> Self: + def append(self, message: Union[chat_pb2.Message, "Response", "CompactContextResponse"]) -> Self: """Adds a new message to the conversation history, enabling multi-turn interactions. This method appends a message to the chat's message sequence, which can be a user input, @@ -334,14 +334,25 @@ def append(self, message: Union[chat_pb2.Message, "Response"]) -> Self: ``` Args: - message: The message to append, either a `chat_pb2.Message` (e.g., created by `user`, - `system`, `assistant`, or `tool_result`) or a `Response` object from a previous - chat interaction. + message: The message to append. Can be a ``chat_pb2.Message`` (e.g., created by + ``user``, ``system``, ``assistant``, or ``tool_result``), a ``Response`` from a + previous chat interaction, or a ``CompactContextResponse`` from + ``client.chat.compact_context()``. **Note:** appending a + ``CompactContextResponse`` drops all previous messages and replaces + them with the compacted context. Returns: Self: The chat object, enabling method chaining. """ - if isinstance(message, chat_pb2.Message): + if isinstance(message, CompactContextResponse): + del self._proto.messages[:] + self._proto.messages.append( + chat_pb2.Message( + role=chat_pb2.MessageRole.ROLE_USER, + encrypted_content=message.encrypted_content, + ) + ) + elif isinstance(message, chat_pb2.Message): self._proto.messages.append(message) elif isinstance(message, Response): if message._index is None: @@ -602,6 +613,17 @@ def messages(self) -> Sequence[chat_pb2.Message]: """Returns the messages in the conversation.""" return self._proto.messages + def _make_compact_request(self) -> chat_pb2.CompactContextRequest: + """Creates a CompactContextRequest from the chat's current model and messages.""" + return chat_pb2.CompactContextRequest( + model=self._proto.model, + input=self._proto.messages, + ) + + def _apply_compaction(self, response: "CompactContextResponse") -> None: + """Replaces all messages with the compaction message to reduce payload size.""" + self.append(response) + def user(*args: Content) -> chat_pb2.Message: """Creates a new message of role "user".""" @@ -1324,3 +1346,34 @@ def request_settings(self) -> chat_pb2.RequestSettings: def debug_output(self) -> chat_pb2.DebugOutput: """Returns the debug output of this response. Only available to trusted testers.""" return self.proto.debug_output + + +class CompactContextResponse(ProtoDecorator[chat_pb2.CompactContextResponse]): + """Response from a context compaction request. + + Wraps a ``CompactContextResponse`` proto with convenience accessors. + The ``encrypted_content`` string is an opaque, compact representation + of the input messages produced by the model. It can be passed back + as an ``encrypted_content`` field on an assistant message in a + follow-up chat request to hydrate the compacted context. + """ + + @property + def id(self) -> str: + """Unique identifier for this compaction response.""" + return self._proto.id + + @property + def encrypted_content(self) -> str: + """Opaque compacted representation of the input messages.""" + return self._proto.encrypted_content + + @property + def dropped_message_count(self) -> int: + """Number of input messages that were dropped during compaction.""" + return self._proto.dropped_message_count + + @property + def usage(self) -> usage_pb2.SamplingUsage: + """Token usage for the compaction request.""" + return self._proto.usage diff --git a/src/xai_sdk/proto/v5/chat_pb2.py b/src/xai_sdk/proto/v5/chat_pb2.py index 80bb5d1..7960853 100644 --- a/src/xai_sdk/proto/v5/chat_pb2.py +++ b/src/xai_sdk/proto/v5/chat_pb2.py @@ -30,7 +30,7 @@ from . import usage_pb2 as xai_dot_api_dot_v1_dot_usage__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15xai/api/v1/chat.proto\x12\x07xai_api\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x19xai/api/v1/deferred.proto\x1a\x1axai/api/v1/documents.proto\x1a\x16xai/api/v1/image.proto\x1a\x17xai/api/v1/sample.proto\x1a\x16xai/api/v1/usage.proto\"\xb8\n\n\x15GetCompletionsRequest\x12,\n\x08messages\x18\x01 \x03(\x0b\x32\x10.xai_api.MessageR\x08messages\x12\x14\n\x05model\x18\x02 \x01(\tR\x05model\x12\x12\n\x04user\x18\x10 \x01(\tR\x04user\x12\x11\n\x01n\x18\x08 \x01(\x05H\x00R\x01n\x88\x01\x01\x12\"\n\nmax_tokens\x18\x07 \x01(\x05H\x01R\tmaxTokens\x88\x01\x01\x12\x17\n\x04seed\x18\x0b \x01(\x05H\x02R\x04seed\x88\x01\x01\x12\x12\n\x04stop\x18\x0c \x03(\tR\x04stop\x12%\n\x0btemperature\x18\x0e \x01(\x02H\x03R\x0btemperature\x88\x01\x01\x12\x18\n\x05top_p\x18\x0f \x01(\x02H\x04R\x04topP\x88\x01\x01\x12\x1a\n\x08logprobs\x18\x05 \x01(\x08R\x08logprobs\x12&\n\x0ctop_logprobs\x18\x06 \x01(\x05H\x05R\x0btopLogprobs\x88\x01\x01\x12#\n\x05tools\x18\x11 \x03(\x0b\x32\r.xai_api.ToolR\x05tools\x12\x34\n\x0btool_choice\x18\x12 \x01(\x0b\x32\x13.xai_api.ToolChoiceR\ntoolChoice\x12@\n\x0fresponse_format\x18\n \x01(\x0b\x32\x17.xai_api.ResponseFormatR\x0eresponseFormat\x12\x30\n\x11\x66requency_penalty\x18\x03 \x01(\x02H\x06R\x10\x66requencyPenalty\x88\x01\x01\x12.\n\x10presence_penalty\x18\t \x01(\x02H\x07R\x0fpresencePenalty\x88\x01\x01\x12H\n\x10reasoning_effort\x18\x13 \x01(\x0e\x32\x18.xai_api.ReasoningEffortH\x08R\x0freasoningEffort\x88\x01\x01\x12K\n\x11search_parameters\x18\x14 \x01(\x0b\x32\x19.xai_api.SearchParametersH\tR\x10searchParameters\x88\x01\x01\x12\x33\n\x13parallel_tool_calls\x18\x15 \x01(\x08H\nR\x11parallelToolCalls\x88\x01\x01\x12\x35\n\x14previous_response_id\x18\x16 \x01(\tH\x0bR\x12previousResponseId\x88\x01\x01\x12%\n\x0estore_messages\x18\x17 \x01(\x08R\rstoreMessages\x12\x32\n\x15use_encrypted_content\x18\x18 \x01(\x08R\x13useEncryptedContent\x12 \n\tmax_turns\x18\x19 \x01(\x05H\x0cR\x08maxTurns\x88\x01\x01\x12\x30\n\x07include\x18\x1a \x03(\x0e\x32\x16.xai_api.IncludeOptionR\x07include\x12\x39\n\x0b\x61gent_count\x18\x1d \x01(\x0e\x32\x13.xai_api.AgentCountH\rR\nagentCount\x88\x01\x01\x42\x04\n\x02_nB\r\n\x0b_max_tokensB\x07\n\x05_seedB\x0e\n\x0c_temperatureB\x08\n\x06_top_pB\x0f\n\r_top_logprobsB\x14\n\x12_frequency_penaltyB\x13\n\x11_presence_penaltyB\x13\n\x11_reasoning_effortB\x14\n\x12_search_parametersB\x16\n\x14_parallel_tool_callsB\x17\n\x15_previous_response_idB\x0c\n\n_max_turnsB\x0e\n\x0c_agent_countJ\x04\x08\x04\x10\x05\"\x96\x03\n\x19GetChatCompletionResponse\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12\x33\n\x07outputs\x18\x02 \x03(\x0b\x32\x19.xai_api.CompletionOutputR\x07outputs\x12\x34\n\x07\x63reated\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x07\x63reated\x12\x14\n\x05model\x18\x06 \x01(\tR\x05model\x12-\n\x12system_fingerprint\x18\x07 \x01(\tR\x11systemFingerprint\x12,\n\x05usage\x18\t \x01(\x0b\x32\x16.xai_api.SamplingUsageR\x05usage\x12\x1c\n\tcitations\x18\n \x03(\tR\tcitations\x12\x34\n\x08settings\x18\x0b \x01(\x0b\x32\x18.xai_api.RequestSettingsR\x08settings\x12\x37\n\x0c\x64\x65\x62ug_output\x18\x0c \x01(\x0b\x32\x14.xai_api.DebugOutputR\x0b\x64\x65\x62ugOutput\"\xe2\x02\n\x16GetChatCompletionChunk\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12\x38\n\x07outputs\x18\x02 \x03(\x0b\x32\x1e.xai_api.CompletionOutputChunkR\x07outputs\x12\x34\n\x07\x63reated\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x07\x63reated\x12\x14\n\x05model\x18\x04 \x01(\tR\x05model\x12-\n\x12system_fingerprint\x18\x05 \x01(\tR\x11systemFingerprint\x12,\n\x05usage\x18\x06 \x01(\x0b\x32\x16.xai_api.SamplingUsageR\x05usage\x12\x1c\n\tcitations\x18\x07 \x03(\tR\tcitations\x12\x37\n\x0c\x64\x65\x62ug_output\x18\n \x01(\x0b\x32\x14.xai_api.DebugOutputR\x0b\x64\x65\x62ugOutput\"\xa2\x01\n\x1dGetDeferredCompletionResponse\x12/\n\x06status\x18\x02 \x01(\x0e\x32\x17.xai_api.DeferredStatusR\x06status\x12\x43\n\x08response\x18\x01 \x01(\x0b\x32\".xai_api.GetChatCompletionResponseH\x00R\x08response\x88\x01\x01\x42\x0b\n\t_response\"\xc9\x01\n\x10\x43ompletionOutput\x12:\n\rfinish_reason\x18\x01 \x01(\x0e\x32\x15.xai_api.FinishReasonR\x0c\x66inishReason\x12\x14\n\x05index\x18\x02 \x01(\x05R\x05index\x12\x34\n\x07message\x18\x03 \x01(\x0b\x32\x1a.xai_api.CompletionMessageR\x07message\x12-\n\x08logprobs\x18\x04 \x01(\x0b\x32\x11.xai_api.LogProbsR\x08logprobs\"\x9a\x02\n\x11\x43ompletionMessage\x12\x18\n\x07\x63ontent\x18\x01 \x01(\tR\x07\x63ontent\x12+\n\x11reasoning_content\x18\x04 \x01(\tR\x10reasoningContent\x12(\n\x04role\x18\x02 \x01(\x0e\x32\x14.xai_api.MessageRoleR\x04role\x12\x30\n\ntool_calls\x18\x03 \x03(\x0b\x32\x11.xai_api.ToolCallR\ttoolCalls\x12+\n\x11\x65ncrypted_content\x18\x05 \x01(\tR\x10\x65ncryptedContent\x12\x35\n\tcitations\x18\x06 \x03(\x0b\x32\x17.xai_api.InlineCitationR\tcitations\"\xbe\x01\n\x15\x43ompletionOutputChunk\x12$\n\x05\x64\x65lta\x18\x01 \x01(\x0b\x32\x0e.xai_api.DeltaR\x05\x64\x65lta\x12-\n\x08logprobs\x18\x02 \x01(\x0b\x32\x11.xai_api.LogProbsR\x08logprobs\x12:\n\rfinish_reason\x18\x03 \x01(\x0e\x32\x15.xai_api.FinishReasonR\x0c\x66inishReason\x12\x14\n\x05index\x18\x04 \x01(\x05R\x05index\"\x8e\x02\n\x05\x44\x65lta\x12\x18\n\x07\x63ontent\x18\x01 \x01(\tR\x07\x63ontent\x12+\n\x11reasoning_content\x18\x04 \x01(\tR\x10reasoningContent\x12(\n\x04role\x18\x02 \x01(\x0e\x32\x14.xai_api.MessageRoleR\x04role\x12\x30\n\ntool_calls\x18\x03 \x03(\x0b\x32\x11.xai_api.ToolCallR\ttoolCalls\x12+\n\x11\x65ncrypted_content\x18\x05 \x01(\tR\x10\x65ncryptedContent\x12\x35\n\tcitations\x18\x06 \x03(\x0b\x32\x17.xai_api.InlineCitationR\tcitations\"\xad\x02\n\x0eInlineCitation\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12\x1f\n\x0bstart_index\x18\x02 \x01(\x05R\nstartIndex\x12\x1b\n\tend_index\x18\x06 \x01(\x05R\x08\x65ndIndex\x12\x39\n\x0cweb_citation\x18\x03 \x01(\x0b\x32\x14.xai_api.WebCitationH\x00R\x0bwebCitation\x12\x33\n\nx_citation\x18\x04 \x01(\x0b\x32\x12.xai_api.XCitationH\x00R\txCitation\x12Q\n\x14\x63ollections_citation\x18\x05 \x01(\x0b\x32\x1c.xai_api.CollectionsCitationH\x00R\x13\x63ollectionsCitationB\n\n\x08\x63itation\"\x1f\n\x0bWebCitation\x12\x10\n\x03url\x18\x01 \x01(\tR\x03url\"\x1d\n\tXCitation\x12\x10\n\x03url\x18\x01 \x01(\tR\x03url\"\xab\x01\n\x13\x43ollectionsCitation\x12\x17\n\x07\x66ile_id\x18\x01 \x01(\tR\x06\x66ileId\x12\x19\n\x08\x63hunk_id\x18\x02 \x01(\tR\x07\x63hunkId\x12#\n\rchunk_content\x18\x03 \x01(\tR\x0c\x63hunkContent\x12\x14\n\x05score\x18\x04 \x01(\x02R\x05score\x12%\n\x0e\x63ollection_ids\x18\x05 \x03(\tR\rcollectionIds\"6\n\x08LogProbs\x12*\n\x07\x63ontent\x18\x01 \x03(\x0b\x32\x10.xai_api.LogProbR\x07\x63ontent\"\x87\x01\n\x07LogProb\x12\x14\n\x05token\x18\x01 \x01(\tR\x05token\x12\x18\n\x07logprob\x18\x02 \x01(\x02R\x07logprob\x12\x14\n\x05\x62ytes\x18\x03 \x01(\x0cR\x05\x62ytes\x12\x36\n\x0ctop_logprobs\x18\x04 \x03(\x0b\x32\x13.xai_api.TopLogProbR\x0btopLogprobs\"R\n\nTopLogProb\x12\x14\n\x05token\x18\x01 \x01(\tR\x05token\x12\x18\n\x07logprob\x18\x02 \x01(\x02R\x07logprob\x12\x14\n\x05\x62ytes\x18\x03 \x01(\x0cR\x05\x62ytes\"\x8f\x01\n\x07\x43ontent\x12\x14\n\x04text\x18\x01 \x01(\tH\x00R\x04text\x12\x37\n\timage_url\x18\x02 \x01(\x0b\x32\x18.xai_api.ImageUrlContentH\x00R\x08imageUrl\x12*\n\x04\x66ile\x18\x03 \x01(\x0b\x32\x14.xai_api.FileContentH\x00R\x04\x66ileB\t\n\x07\x63ontent\"\x85\x01\n\x0b\x46ileContent\x12\x17\n\x07\x66ile_id\x18\x01 \x01(\tR\x06\x66ileId\x12\x12\n\x04\x64\x61ta\x18\x02 \x01(\x0cR\x04\x64\x61ta\x12\x1a\n\x08\x66ilename\x18\x03 \x01(\tR\x08\x66ilename\x12\x1b\n\tmime_type\x18\x04 \x01(\tR\x08mimeType\x12\x10\n\x03url\x18\x05 \x01(\tR\x03url\"\xd2\x02\n\x07Message\x12*\n\x07\x63ontent\x18\x01 \x03(\x0b\x32\x10.xai_api.ContentR\x07\x63ontent\x12\x30\n\x11reasoning_content\x18\x05 \x01(\tH\x00R\x10reasoningContent\x88\x01\x01\x12(\n\x04role\x18\x02 \x01(\x0e\x32\x14.xai_api.MessageRoleR\x04role\x12\x12\n\x04name\x18\x03 \x01(\tR\x04name\x12\x30\n\ntool_calls\x18\x04 \x03(\x0b\x32\x11.xai_api.ToolCallR\ttoolCalls\x12+\n\x11\x65ncrypted_content\x18\x06 \x01(\tR\x10\x65ncryptedContent\x12%\n\x0ctool_call_id\x18\x07 \x01(\tH\x01R\ntoolCallId\x88\x01\x01\x42\x14\n\x12_reasoning_contentB\x0f\n\r_tool_call_id\"k\n\nToolChoice\x12\'\n\x04mode\x18\x01 \x01(\x0e\x32\x11.xai_api.ToolModeH\x00R\x04mode\x12%\n\rfunction_name\x18\x02 \x01(\tH\x00R\x0c\x66unctionNameB\r\n\x0btool_choice\"\x9d\x03\n\x04Tool\x12/\n\x08\x66unction\x18\x01 \x01(\x0b\x32\x11.xai_api.FunctionH\x00R\x08\x66unction\x12\x33\n\nweb_search\x18\x03 \x01(\x0b\x32\x12.xai_api.WebSearchH\x00R\twebSearch\x12-\n\x08x_search\x18\x04 \x01(\x0b\x32\x10.xai_api.XSearchH\x00R\x07xSearch\x12?\n\x0e\x63ode_execution\x18\x05 \x01(\x0b\x32\x16.xai_api.CodeExecutionH\x00R\rcodeExecution\x12K\n\x12\x63ollections_search\x18\x06 \x01(\x0b\x32\x1a.xai_api.CollectionsSearchH\x00R\x11\x63ollectionsSearch\x12 \n\x03mcp\x18\x07 \x01(\x0b\x32\x0c.xai_api.MCPH\x00R\x03mcp\x12H\n\x11\x61ttachment_search\x18\x08 \x01(\x0b\x32\x19.xai_api.AttachmentSearchH\x00R\x10\x61ttachmentSearchB\x06\n\x04tool\"\xe7\x02\n\x03MCP\x12!\n\x0cserver_label\x18\x01 \x01(\tR\x0bserverLabel\x12-\n\x12server_description\x18\x02 \x01(\tR\x11serverDescription\x12\x1d\n\nserver_url\x18\x03 \x01(\tR\tserverUrl\x12,\n\x12\x61llowed_tool_names\x18\x04 \x03(\tR\x10\x61llowedToolNames\x12)\n\rauthorization\x18\x05 \x01(\tH\x00R\rauthorization\x88\x01\x01\x12\x43\n\rextra_headers\x18\x06 \x03(\x0b\x32\x1e.xai_api.MCP.ExtraHeadersEntryR\x0c\x65xtraHeaders\x1a?\n\x11\x45xtraHeadersEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value:\x02\x38\x01\x42\x10\n\x0e_authorization\"\xea\x02\n\tWebSearch\x12)\n\x10\x65xcluded_domains\x18\x01 \x03(\tR\x0f\x65xcludedDomains\x12\'\n\x0f\x61llowed_domains\x18\x02 \x03(\tR\x0e\x61llowedDomains\x12\x41\n\x1a\x65nable_image_understanding\x18\x03 \x01(\x08H\x00R\x18\x65nableImageUnderstanding\x88\x01\x01\x12\x33\n\x13\x65nable_image_search\x18\x05 \x01(\x08H\x01R\x11\x65nableImageSearch\x88\x01\x01\x12H\n\ruser_location\x18\x04 \x01(\x0b\x32\x1e.xai_api.WebSearchUserLocationH\x02R\x0cuserLocation\x88\x01\x01\x42\x1d\n\x1b_enable_image_understandingB\x16\n\x14_enable_image_searchB\x10\n\x0e_user_location\"\xba\x01\n\x15WebSearchUserLocation\x12\x1d\n\x07\x63ountry\x18\x01 \x01(\tH\x00R\x07\x63ountry\x88\x01\x01\x12\x17\n\x04\x63ity\x18\x02 \x01(\tH\x01R\x04\x63ity\x88\x01\x01\x12\x1b\n\x06region\x18\x03 \x01(\tH\x02R\x06region\x88\x01\x01\x12\x1f\n\x08timezone\x18\x04 \x01(\tH\x03R\x08timezone\x88\x01\x01\x42\n\n\x08_countryB\x07\n\x05_cityB\t\n\x07_regionB\x0b\n\t_timezone\"\xb9\x03\n\x07XSearch\x12<\n\tfrom_date\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x00R\x08\x66romDate\x88\x01\x01\x12\x38\n\x07to_date\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x01R\x06toDate\x88\x01\x01\x12*\n\x11\x61llowed_x_handles\x18\x03 \x03(\tR\x0f\x61llowedXHandles\x12,\n\x12\x65xcluded_x_handles\x18\x04 \x03(\tR\x10\x65xcludedXHandles\x12\x41\n\x1a\x65nable_image_understanding\x18\x05 \x01(\x08H\x02R\x18\x65nableImageUnderstanding\x88\x01\x01\x12\x41\n\x1a\x65nable_video_understanding\x18\x06 \x01(\x08H\x03R\x18\x65nableVideoUnderstanding\x88\x01\x01\x42\x0c\n\n_from_dateB\n\n\x08_to_dateB\x1d\n\x1b_enable_image_understandingB\x1d\n\x1b_enable_video_understanding\"\x0f\n\rCodeExecution\"\x89\x03\n\x11\x43ollectionsSearch\x12%\n\x0e\x63ollection_ids\x18\x01 \x03(\tR\rcollectionIds\x12\x19\n\x05limit\x18\x02 \x01(\x05H\x01R\x05limit\x88\x01\x01\x12\'\n\x0cinstructions\x18\x03 \x01(\tH\x02R\x0cinstructions\x88\x01\x01\x12\x45\n\x10hybrid_retrieval\x18\x04 \x01(\x0b\x32\x18.xai_api.HybridRetrievalH\x00R\x0fhybridRetrieval\x12K\n\x12semantic_retrieval\x18\x05 \x01(\x0b\x32\x1a.xai_api.SemanticRetrievalH\x00R\x11semanticRetrieval\x12H\n\x11keyword_retrieval\x18\x06 \x01(\x0b\x32\x19.xai_api.KeywordRetrievalH\x00R\x10keywordRetrievalB\x10\n\x0eretrieval_modeB\x08\n\x06_limitB\x0f\n\r_instructions\"7\n\x10\x41ttachmentSearch\x12\x19\n\x05limit\x18\x02 \x01(\x05H\x00R\x05limit\x88\x01\x01\x42\x08\n\x06_limit\"x\n\x08\x46unction\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12 \n\x0b\x64\x65scription\x18\x02 \x01(\tR\x0b\x64\x65scription\x12\x16\n\x06strict\x18\x03 \x01(\x08R\x06strict\x12\x1e\n\nparameters\x18\x04 \x01(\tR\nparameters\"\xef\x01\n\x08ToolCall\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12)\n\x04type\x18\x02 \x01(\x0e\x32\x15.xai_api.ToolCallTypeR\x04type\x12/\n\x06status\x18\x03 \x01(\x0e\x32\x17.xai_api.ToolCallStatusR\x06status\x12(\n\rerror_message\x18\x04 \x01(\tH\x01R\x0c\x65rrorMessage\x88\x01\x01\x12\x33\n\x08\x66unction\x18\n \x01(\x0b\x32\x15.xai_api.FunctionCallH\x00R\x08\x66unctionB\x06\n\x04toolB\x10\n\x0e_error_message\"@\n\x0c\x46unctionCall\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x1c\n\targuments\x18\x02 \x01(\tR\targuments\"n\n\x0eResponseFormat\x12\x34\n\x0b\x66ormat_type\x18\x01 \x01(\x0e\x32\x13.xai_api.FormatTypeR\nformatType\x12\x1b\n\x06schema\x18\x02 \x01(\tH\x00R\x06schema\x88\x01\x01\x42\t\n\x07_schema\"\xc9\x02\n\x10SearchParameters\x12\'\n\x04mode\x18\x01 \x01(\x0e\x32\x13.xai_api.SearchModeR\x04mode\x12)\n\x07sources\x18\t \x03(\x0b\x32\x0f.xai_api.SourceR\x07sources\x12\x37\n\tfrom_date\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x08\x66romDate\x12\x33\n\x07to_date\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x06toDate\x12)\n\x10return_citations\x18\x07 \x01(\x08R\x0freturnCitations\x12\x31\n\x12max_search_results\x18\x08 \x01(\x05H\x00R\x10maxSearchResults\x88\x01\x01\x42\x15\n\x13_max_search_results\"\xaf\x01\n\x06Source\x12&\n\x03web\x18\x01 \x01(\x0b\x32\x12.xai_api.WebSourceH\x00R\x03web\x12)\n\x04news\x18\x02 \x01(\x0b\x32\x13.xai_api.NewsSourceH\x00R\x04news\x12 \n\x01x\x18\x03 \x01(\x0b\x32\x10.xai_api.XSourceH\x00R\x01x\x12&\n\x03rss\x18\x04 \x01(\x0b\x32\x12.xai_api.RssSourceH\x00R\x03rssB\x08\n\x06source\"\xaf\x01\n\tWebSource\x12+\n\x11\x65xcluded_websites\x18\x02 \x03(\tR\x10\x65xcludedWebsites\x12)\n\x10\x61llowed_websites\x18\x05 \x03(\tR\x0f\x61llowedWebsites\x12\x1d\n\x07\x63ountry\x18\x03 \x01(\tH\x00R\x07\x63ountry\x88\x01\x01\x12\x1f\n\x0bsafe_search\x18\x04 \x01(\x08R\nsafeSearchB\n\n\x08_country\"\x85\x01\n\nNewsSource\x12+\n\x11\x65xcluded_websites\x18\x02 \x03(\tR\x10\x65xcludedWebsites\x12\x1d\n\x07\x63ountry\x18\x03 \x01(\tH\x00R\x07\x63ountry\x88\x01\x01\x12\x1f\n\x0bsafe_search\x18\x04 \x01(\x08R\nsafeSearchB\n\n\x08_country\"\xf9\x01\n\x07XSource\x12,\n\x12included_x_handles\x18\x07 \x03(\tR\x10includedXHandles\x12,\n\x12\x65xcluded_x_handles\x18\x08 \x03(\tR\x10\x65xcludedXHandles\x12\x33\n\x13post_favorite_count\x18\t \x01(\x05H\x00R\x11postFavoriteCount\x88\x01\x01\x12+\n\x0fpost_view_count\x18\n \x01(\x05H\x01R\rpostViewCount\x88\x01\x01\x42\x16\n\x14_post_favorite_countB\x12\n\x10_post_view_countJ\x04\x08\x06\x10\x07\"!\n\tRssSource\x12\x14\n\x05links\x18\x01 \x03(\tR\x05links\"\x9f\x06\n\x0fRequestSettings\x12\"\n\nmax_tokens\x18\x01 \x01(\x05H\x00R\tmaxTokens\x88\x01\x01\x12.\n\x13parallel_tool_calls\x18\x02 \x01(\x08R\x11parallelToolCalls\x12\x35\n\x14previous_response_id\x18\x03 \x01(\tH\x01R\x12previousResponseId\x88\x01\x01\x12H\n\x10reasoning_effort\x18\x04 \x01(\x0e\x32\x18.xai_api.ReasoningEffortH\x02R\x0freasoningEffort\x88\x01\x01\x12%\n\x0btemperature\x18\x05 \x01(\x02H\x03R\x0btemperature\x88\x01\x01\x12@\n\x0fresponse_format\x18\x06 \x01(\x0b\x32\x17.xai_api.ResponseFormatR\x0eresponseFormat\x12\x34\n\x0btool_choice\x18\x07 \x01(\x0b\x32\x13.xai_api.ToolChoiceR\ntoolChoice\x12#\n\x05tools\x18\x08 \x03(\x0b\x32\r.xai_api.ToolR\x05tools\x12\x18\n\x05top_p\x18\t \x01(\x02H\x04R\x04topP\x88\x01\x01\x12\x12\n\x04user\x18\n \x01(\tR\x04user\x12K\n\x11search_parameters\x18\x0b \x01(\x0b\x32\x19.xai_api.SearchParametersH\x05R\x10searchParameters\x88\x01\x01\x12%\n\x0estore_messages\x18\x0c \x01(\x08R\rstoreMessages\x12\x32\n\x15use_encrypted_content\x18\r \x01(\x08R\x13useEncryptedContent\x12\x30\n\x07include\x18\x0e \x03(\x0e\x32\x16.xai_api.IncludeOptionR\x07includeB\r\n\x0b_max_tokensB\x17\n\x15_previous_response_idB\x13\n\x11_reasoning_effortB\x0e\n\x0c_temperatureB\x08\n\x06_top_pB\x14\n\x12_search_parameters\"=\n\x1aGetStoredCompletionRequest\x12\x1f\n\x0bresponse_id\x18\x01 \x01(\tR\nresponseId\"@\n\x1d\x44\x65leteStoredCompletionRequest\x12\x1f\n\x0bresponse_id\x18\x01 \x01(\tR\nresponseId\"A\n\x1e\x44\x65leteStoredCompletionResponse\x12\x1f\n\x0bresponse_id\x18\x01 \x01(\tR\nresponseId\"\xba\x03\n\x0b\x44\x65\x62ugOutput\x12\x1a\n\x08\x61ttempts\x18\x01 \x01(\x05R\x08\x61ttempts\x12\x18\n\x07request\x18\x02 \x01(\tR\x07request\x12\x16\n\x06prompt\x18\x03 \x01(\tR\x06prompt\x12%\n\x0e\x65ngine_request\x18\t \x01(\tR\rengineRequest\x12\x1c\n\tresponses\x18\x04 \x03(\tR\tresponses\x12\x16\n\x06\x63hunks\x18\x0c \x03(\tR\x06\x63hunks\x12(\n\x10\x63\x61\x63he_read_count\x18\x05 \x01(\rR\x0e\x63\x61\x63heReadCount\x12\x33\n\x16\x63\x61\x63he_read_input_bytes\x18\x06 \x01(\x04R\x13\x63\x61\x63heReadInputBytes\x12*\n\x11\x63\x61\x63he_write_count\x18\x07 \x01(\rR\x0f\x63\x61\x63heWriteCount\x12\x35\n\x17\x63\x61\x63he_write_input_bytes\x18\x08 \x01(\x04R\x14\x63\x61\x63heWriteInputBytes\x12\x1d\n\nlb_address\x18\n \x01(\tR\tlbAddress\x12\x1f\n\x0bsampler_tag\x18\x0b \x01(\tR\nsamplerTag*\x82\x03\n\rIncludeOption\x12\x1a\n\x16INCLUDE_OPTION_INVALID\x10\x00\x12)\n%INCLUDE_OPTION_WEB_SEARCH_CALL_OUTPUT\x10\x01\x12\'\n#INCLUDE_OPTION_X_SEARCH_CALL_OUTPUT\x10\x02\x12-\n)INCLUDE_OPTION_CODE_EXECUTION_CALL_OUTPUT\x10\x03\x12\x31\n-INCLUDE_OPTION_COLLECTIONS_SEARCH_CALL_OUTPUT\x10\x04\x12\x30\n,INCLUDE_OPTION_ATTACHMENT_SEARCH_CALL_OUTPUT\x10\x05\x12\"\n\x1eINCLUDE_OPTION_MCP_CALL_OUTPUT\x10\x06\x12#\n\x1fINCLUDE_OPTION_INLINE_CITATIONS\x10\x07\x12$\n INCLUDE_OPTION_VERBOSE_STREAMING\x10\x08*\x8d\x01\n\x0bMessageRole\x12\x10\n\x0cINVALID_ROLE\x10\x00\x12\r\n\tROLE_USER\x10\x01\x12\x12\n\x0eROLE_ASSISTANT\x10\x02\x12\x0f\n\x0bROLE_SYSTEM\x10\x03\x12\x15\n\rROLE_FUNCTION\x10\x04\x1a\x02\x08\x01\x12\r\n\tROLE_TOOL\x10\x05\x12\x12\n\x0eROLE_DEVELOPER\x10\x06*j\n\x0fReasoningEffort\x12\x12\n\x0eINVALID_EFFORT\x10\x00\x12\x0e\n\nEFFORT_LOW\x10\x01\x12\x11\n\rEFFORT_MEDIUM\x10\x02\x12\x0f\n\x0b\x45\x46\x46ORT_HIGH\x10\x03\x12\x0f\n\x0b\x45\x46\x46ORT_NONE\x10\x04*P\n\nAgentCount\x12\x1b\n\x17\x41GENT_COUNT_UNSPECIFIED\x10\x00\x12\x11\n\rAGENT_COUNT_4\x10\x01\x12\x12\n\x0e\x41GENT_COUNT_16\x10\x02*a\n\x08ToolMode\x12\x15\n\x11TOOL_MODE_INVALID\x10\x00\x12\x12\n\x0eTOOL_MODE_AUTO\x10\x01\x12\x12\n\x0eTOOL_MODE_NONE\x10\x02\x12\x16\n\x12TOOL_MODE_REQUIRED\x10\x03*u\n\nFormatType\x12\x17\n\x13\x46ORMAT_TYPE_INVALID\x10\x00\x12\x14\n\x10\x46ORMAT_TYPE_TEXT\x10\x01\x12\x1b\n\x17\x46ORMAT_TYPE_JSON_OBJECT\x10\x02\x12\x1b\n\x17\x46ORMAT_TYPE_JSON_SCHEMA\x10\x03*\xb1\x02\n\x0cToolCallType\x12\x1a\n\x16TOOL_CALL_TYPE_INVALID\x10\x00\x12#\n\x1fTOOL_CALL_TYPE_CLIENT_SIDE_TOOL\x10\x01\x12\"\n\x1eTOOL_CALL_TYPE_WEB_SEARCH_TOOL\x10\x02\x12 \n\x1cTOOL_CALL_TYPE_X_SEARCH_TOOL\x10\x03\x12&\n\"TOOL_CALL_TYPE_CODE_EXECUTION_TOOL\x10\x04\x12*\n&TOOL_CALL_TYPE_COLLECTIONS_SEARCH_TOOL\x10\x05\x12\x1b\n\x17TOOL_CALL_TYPE_MCP_TOOL\x10\x06\x12)\n%TOOL_CALL_TYPE_ATTACHMENT_SEARCH_TOOL\x10\x07*\x90\x01\n\x0eToolCallStatus\x12 \n\x1cTOOL_CALL_STATUS_IN_PROGRESS\x10\x00\x12\x1e\n\x1aTOOL_CALL_STATUS_COMPLETED\x10\x01\x12\x1f\n\x1bTOOL_CALL_STATUS_INCOMPLETE\x10\x02\x12\x1b\n\x17TOOL_CALL_STATUS_FAILED\x10\x03*d\n\nSearchMode\x12\x17\n\x13INVALID_SEARCH_MODE\x10\x00\x12\x13\n\x0fOFF_SEARCH_MODE\x10\x01\x12\x12\n\x0eON_SEARCH_MODE\x10\x02\x12\x14\n\x10\x41UTO_SEARCH_MODE\x10\x03\x32\xc4\x04\n\x04\x43hat\x12U\n\rGetCompletion\x12\x1e.xai_api.GetCompletionsRequest\x1a\".xai_api.GetChatCompletionResponse\"\x00\x12Y\n\x12GetCompletionChunk\x12\x1e.xai_api.GetCompletionsRequest\x1a\x1f.xai_api.GetChatCompletionChunk\"\x00\x30\x01\x12[\n\x17StartDeferredCompletion\x12\x1e.xai_api.GetCompletionsRequest\x1a\x1e.xai_api.StartDeferredResponse\"\x00\x12^\n\x15GetDeferredCompletion\x12\x1b.xai_api.GetDeferredRequest\x1a&.xai_api.GetDeferredCompletionResponse\"\x00\x12`\n\x13GetStoredCompletion\x12#.xai_api.GetStoredCompletionRequest\x1a\".xai_api.GetChatCompletionResponse\"\x00\x12k\n\x16\x44\x65leteStoredCompletion\x12&.xai_api.DeleteStoredCompletionRequest\x1a\'.xai_api.DeleteStoredCompletionResponse\"\x00\x42P\n\x0b\x63om.xai_apiB\tChatProtoP\x01\xa2\x02\x03XXX\xaa\x02\x06XaiApi\xca\x02\x06XaiApi\xe2\x02\x12XaiApi\\GPBMetadata\xea\x02\x06XaiApib\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15xai/api/v1/chat.proto\x12\x07xai_api\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x19xai/api/v1/deferred.proto\x1a\x1axai/api/v1/documents.proto\x1a\x16xai/api/v1/image.proto\x1a\x17xai/api/v1/sample.proto\x1a\x16xai/api/v1/usage.proto\"\xb8\n\n\x15GetCompletionsRequest\x12,\n\x08messages\x18\x01 \x03(\x0b\x32\x10.xai_api.MessageR\x08messages\x12\x14\n\x05model\x18\x02 \x01(\tR\x05model\x12\x12\n\x04user\x18\x10 \x01(\tR\x04user\x12\x11\n\x01n\x18\x08 \x01(\x05H\x00R\x01n\x88\x01\x01\x12\"\n\nmax_tokens\x18\x07 \x01(\x05H\x01R\tmaxTokens\x88\x01\x01\x12\x17\n\x04seed\x18\x0b \x01(\x05H\x02R\x04seed\x88\x01\x01\x12\x12\n\x04stop\x18\x0c \x03(\tR\x04stop\x12%\n\x0btemperature\x18\x0e \x01(\x02H\x03R\x0btemperature\x88\x01\x01\x12\x18\n\x05top_p\x18\x0f \x01(\x02H\x04R\x04topP\x88\x01\x01\x12\x1a\n\x08logprobs\x18\x05 \x01(\x08R\x08logprobs\x12&\n\x0ctop_logprobs\x18\x06 \x01(\x05H\x05R\x0btopLogprobs\x88\x01\x01\x12#\n\x05tools\x18\x11 \x03(\x0b\x32\r.xai_api.ToolR\x05tools\x12\x34\n\x0btool_choice\x18\x12 \x01(\x0b\x32\x13.xai_api.ToolChoiceR\ntoolChoice\x12@\n\x0fresponse_format\x18\n \x01(\x0b\x32\x17.xai_api.ResponseFormatR\x0eresponseFormat\x12\x30\n\x11\x66requency_penalty\x18\x03 \x01(\x02H\x06R\x10\x66requencyPenalty\x88\x01\x01\x12.\n\x10presence_penalty\x18\t \x01(\x02H\x07R\x0fpresencePenalty\x88\x01\x01\x12H\n\x10reasoning_effort\x18\x13 \x01(\x0e\x32\x18.xai_api.ReasoningEffortH\x08R\x0freasoningEffort\x88\x01\x01\x12K\n\x11search_parameters\x18\x14 \x01(\x0b\x32\x19.xai_api.SearchParametersH\tR\x10searchParameters\x88\x01\x01\x12\x33\n\x13parallel_tool_calls\x18\x15 \x01(\x08H\nR\x11parallelToolCalls\x88\x01\x01\x12\x35\n\x14previous_response_id\x18\x16 \x01(\tH\x0bR\x12previousResponseId\x88\x01\x01\x12%\n\x0estore_messages\x18\x17 \x01(\x08R\rstoreMessages\x12\x32\n\x15use_encrypted_content\x18\x18 \x01(\x08R\x13useEncryptedContent\x12 \n\tmax_turns\x18\x19 \x01(\x05H\x0cR\x08maxTurns\x88\x01\x01\x12\x30\n\x07include\x18\x1a \x03(\x0e\x32\x16.xai_api.IncludeOptionR\x07include\x12\x39\n\x0b\x61gent_count\x18\x1d \x01(\x0e\x32\x13.xai_api.AgentCountH\rR\nagentCount\x88\x01\x01\x42\x04\n\x02_nB\r\n\x0b_max_tokensB\x07\n\x05_seedB\x0e\n\x0c_temperatureB\x08\n\x06_top_pB\x0f\n\r_top_logprobsB\x14\n\x12_frequency_penaltyB\x13\n\x11_presence_penaltyB\x13\n\x11_reasoning_effortB\x14\n\x12_search_parametersB\x16\n\x14_parallel_tool_callsB\x17\n\x15_previous_response_idB\x0c\n\n_max_turnsB\x0e\n\x0c_agent_countJ\x04\x08\x04\x10\x05\"\x96\x03\n\x19GetChatCompletionResponse\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12\x33\n\x07outputs\x18\x02 \x03(\x0b\x32\x19.xai_api.CompletionOutputR\x07outputs\x12\x34\n\x07\x63reated\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x07\x63reated\x12\x14\n\x05model\x18\x06 \x01(\tR\x05model\x12-\n\x12system_fingerprint\x18\x07 \x01(\tR\x11systemFingerprint\x12,\n\x05usage\x18\t \x01(\x0b\x32\x16.xai_api.SamplingUsageR\x05usage\x12\x1c\n\tcitations\x18\n \x03(\tR\tcitations\x12\x34\n\x08settings\x18\x0b \x01(\x0b\x32\x18.xai_api.RequestSettingsR\x08settings\x12\x37\n\x0c\x64\x65\x62ug_output\x18\x0c \x01(\x0b\x32\x14.xai_api.DebugOutputR\x0b\x64\x65\x62ugOutput\"\xe2\x02\n\x16GetChatCompletionChunk\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12\x38\n\x07outputs\x18\x02 \x03(\x0b\x32\x1e.xai_api.CompletionOutputChunkR\x07outputs\x12\x34\n\x07\x63reated\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x07\x63reated\x12\x14\n\x05model\x18\x04 \x01(\tR\x05model\x12-\n\x12system_fingerprint\x18\x05 \x01(\tR\x11systemFingerprint\x12,\n\x05usage\x18\x06 \x01(\x0b\x32\x16.xai_api.SamplingUsageR\x05usage\x12\x1c\n\tcitations\x18\x07 \x03(\tR\tcitations\x12\x37\n\x0c\x64\x65\x62ug_output\x18\n \x01(\x0b\x32\x14.xai_api.DebugOutputR\x0b\x64\x65\x62ugOutput\"\xa2\x01\n\x1dGetDeferredCompletionResponse\x12/\n\x06status\x18\x02 \x01(\x0e\x32\x17.xai_api.DeferredStatusR\x06status\x12\x43\n\x08response\x18\x01 \x01(\x0b\x32\".xai_api.GetChatCompletionResponseH\x00R\x08response\x88\x01\x01\x42\x0b\n\t_response\"\xc9\x01\n\x10\x43ompletionOutput\x12:\n\rfinish_reason\x18\x01 \x01(\x0e\x32\x15.xai_api.FinishReasonR\x0c\x66inishReason\x12\x14\n\x05index\x18\x02 \x01(\x05R\x05index\x12\x34\n\x07message\x18\x03 \x01(\x0b\x32\x1a.xai_api.CompletionMessageR\x07message\x12-\n\x08logprobs\x18\x04 \x01(\x0b\x32\x11.xai_api.LogProbsR\x08logprobs\"\x9a\x02\n\x11\x43ompletionMessage\x12\x18\n\x07\x63ontent\x18\x01 \x01(\tR\x07\x63ontent\x12+\n\x11reasoning_content\x18\x04 \x01(\tR\x10reasoningContent\x12(\n\x04role\x18\x02 \x01(\x0e\x32\x14.xai_api.MessageRoleR\x04role\x12\x30\n\ntool_calls\x18\x03 \x03(\x0b\x32\x11.xai_api.ToolCallR\ttoolCalls\x12+\n\x11\x65ncrypted_content\x18\x05 \x01(\tR\x10\x65ncryptedContent\x12\x35\n\tcitations\x18\x06 \x03(\x0b\x32\x17.xai_api.InlineCitationR\tcitations\"\xbe\x01\n\x15\x43ompletionOutputChunk\x12$\n\x05\x64\x65lta\x18\x01 \x01(\x0b\x32\x0e.xai_api.DeltaR\x05\x64\x65lta\x12-\n\x08logprobs\x18\x02 \x01(\x0b\x32\x11.xai_api.LogProbsR\x08logprobs\x12:\n\rfinish_reason\x18\x03 \x01(\x0e\x32\x15.xai_api.FinishReasonR\x0c\x66inishReason\x12\x14\n\x05index\x18\x04 \x01(\x05R\x05index\"\x8e\x02\n\x05\x44\x65lta\x12\x18\n\x07\x63ontent\x18\x01 \x01(\tR\x07\x63ontent\x12+\n\x11reasoning_content\x18\x04 \x01(\tR\x10reasoningContent\x12(\n\x04role\x18\x02 \x01(\x0e\x32\x14.xai_api.MessageRoleR\x04role\x12\x30\n\ntool_calls\x18\x03 \x03(\x0b\x32\x11.xai_api.ToolCallR\ttoolCalls\x12+\n\x11\x65ncrypted_content\x18\x05 \x01(\tR\x10\x65ncryptedContent\x12\x35\n\tcitations\x18\x06 \x03(\x0b\x32\x17.xai_api.InlineCitationR\tcitations\"\xad\x02\n\x0eInlineCitation\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12\x1f\n\x0bstart_index\x18\x02 \x01(\x05R\nstartIndex\x12\x1b\n\tend_index\x18\x06 \x01(\x05R\x08\x65ndIndex\x12\x39\n\x0cweb_citation\x18\x03 \x01(\x0b\x32\x14.xai_api.WebCitationH\x00R\x0bwebCitation\x12\x33\n\nx_citation\x18\x04 \x01(\x0b\x32\x12.xai_api.XCitationH\x00R\txCitation\x12Q\n\x14\x63ollections_citation\x18\x05 \x01(\x0b\x32\x1c.xai_api.CollectionsCitationH\x00R\x13\x63ollectionsCitationB\n\n\x08\x63itation\"\x1f\n\x0bWebCitation\x12\x10\n\x03url\x18\x01 \x01(\tR\x03url\"\x1d\n\tXCitation\x12\x10\n\x03url\x18\x01 \x01(\tR\x03url\"\xab\x01\n\x13\x43ollectionsCitation\x12\x17\n\x07\x66ile_id\x18\x01 \x01(\tR\x06\x66ileId\x12\x19\n\x08\x63hunk_id\x18\x02 \x01(\tR\x07\x63hunkId\x12#\n\rchunk_content\x18\x03 \x01(\tR\x0c\x63hunkContent\x12\x14\n\x05score\x18\x04 \x01(\x02R\x05score\x12%\n\x0e\x63ollection_ids\x18\x05 \x03(\tR\rcollectionIds\"6\n\x08LogProbs\x12*\n\x07\x63ontent\x18\x01 \x03(\x0b\x32\x10.xai_api.LogProbR\x07\x63ontent\"\x87\x01\n\x07LogProb\x12\x14\n\x05token\x18\x01 \x01(\tR\x05token\x12\x18\n\x07logprob\x18\x02 \x01(\x02R\x07logprob\x12\x14\n\x05\x62ytes\x18\x03 \x01(\x0cR\x05\x62ytes\x12\x36\n\x0ctop_logprobs\x18\x04 \x03(\x0b\x32\x13.xai_api.TopLogProbR\x0btopLogprobs\"R\n\nTopLogProb\x12\x14\n\x05token\x18\x01 \x01(\tR\x05token\x12\x18\n\x07logprob\x18\x02 \x01(\x02R\x07logprob\x12\x14\n\x05\x62ytes\x18\x03 \x01(\x0cR\x05\x62ytes\"\x8f\x01\n\x07\x43ontent\x12\x14\n\x04text\x18\x01 \x01(\tH\x00R\x04text\x12\x37\n\timage_url\x18\x02 \x01(\x0b\x32\x18.xai_api.ImageUrlContentH\x00R\x08imageUrl\x12*\n\x04\x66ile\x18\x03 \x01(\x0b\x32\x14.xai_api.FileContentH\x00R\x04\x66ileB\t\n\x07\x63ontent\"\x85\x01\n\x0b\x46ileContent\x12\x17\n\x07\x66ile_id\x18\x01 \x01(\tR\x06\x66ileId\x12\x12\n\x04\x64\x61ta\x18\x02 \x01(\x0cR\x04\x64\x61ta\x12\x1a\n\x08\x66ilename\x18\x03 \x01(\tR\x08\x66ilename\x12\x1b\n\tmime_type\x18\x04 \x01(\tR\x08mimeType\x12\x10\n\x03url\x18\x05 \x01(\tR\x03url\"\xd2\x02\n\x07Message\x12*\n\x07\x63ontent\x18\x01 \x03(\x0b\x32\x10.xai_api.ContentR\x07\x63ontent\x12\x30\n\x11reasoning_content\x18\x05 \x01(\tH\x00R\x10reasoningContent\x88\x01\x01\x12(\n\x04role\x18\x02 \x01(\x0e\x32\x14.xai_api.MessageRoleR\x04role\x12\x12\n\x04name\x18\x03 \x01(\tR\x04name\x12\x30\n\ntool_calls\x18\x04 \x03(\x0b\x32\x11.xai_api.ToolCallR\ttoolCalls\x12+\n\x11\x65ncrypted_content\x18\x06 \x01(\tR\x10\x65ncryptedContent\x12%\n\x0ctool_call_id\x18\x07 \x01(\tH\x01R\ntoolCallId\x88\x01\x01\x42\x14\n\x12_reasoning_contentB\x0f\n\r_tool_call_id\"k\n\nToolChoice\x12\'\n\x04mode\x18\x01 \x01(\x0e\x32\x11.xai_api.ToolModeH\x00R\x04mode\x12%\n\rfunction_name\x18\x02 \x01(\tH\x00R\x0c\x66unctionNameB\r\n\x0btool_choice\"\x9d\x03\n\x04Tool\x12/\n\x08\x66unction\x18\x01 \x01(\x0b\x32\x11.xai_api.FunctionH\x00R\x08\x66unction\x12\x33\n\nweb_search\x18\x03 \x01(\x0b\x32\x12.xai_api.WebSearchH\x00R\twebSearch\x12-\n\x08x_search\x18\x04 \x01(\x0b\x32\x10.xai_api.XSearchH\x00R\x07xSearch\x12?\n\x0e\x63ode_execution\x18\x05 \x01(\x0b\x32\x16.xai_api.CodeExecutionH\x00R\rcodeExecution\x12K\n\x12\x63ollections_search\x18\x06 \x01(\x0b\x32\x1a.xai_api.CollectionsSearchH\x00R\x11\x63ollectionsSearch\x12 \n\x03mcp\x18\x07 \x01(\x0b\x32\x0c.xai_api.MCPH\x00R\x03mcp\x12H\n\x11\x61ttachment_search\x18\x08 \x01(\x0b\x32\x19.xai_api.AttachmentSearchH\x00R\x10\x61ttachmentSearchB\x06\n\x04tool\"\xe7\x02\n\x03MCP\x12!\n\x0cserver_label\x18\x01 \x01(\tR\x0bserverLabel\x12-\n\x12server_description\x18\x02 \x01(\tR\x11serverDescription\x12\x1d\n\nserver_url\x18\x03 \x01(\tR\tserverUrl\x12,\n\x12\x61llowed_tool_names\x18\x04 \x03(\tR\x10\x61llowedToolNames\x12)\n\rauthorization\x18\x05 \x01(\tH\x00R\rauthorization\x88\x01\x01\x12\x43\n\rextra_headers\x18\x06 \x03(\x0b\x32\x1e.xai_api.MCP.ExtraHeadersEntryR\x0c\x65xtraHeaders\x1a?\n\x11\x45xtraHeadersEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value:\x02\x38\x01\x42\x10\n\x0e_authorization\"\xea\x02\n\tWebSearch\x12)\n\x10\x65xcluded_domains\x18\x01 \x03(\tR\x0f\x65xcludedDomains\x12\'\n\x0f\x61llowed_domains\x18\x02 \x03(\tR\x0e\x61llowedDomains\x12\x41\n\x1a\x65nable_image_understanding\x18\x03 \x01(\x08H\x00R\x18\x65nableImageUnderstanding\x88\x01\x01\x12H\n\ruser_location\x18\x04 \x01(\x0b\x32\x1e.xai_api.WebSearchUserLocationH\x01R\x0cuserLocation\x88\x01\x01\x12\x33\n\x13\x65nable_image_search\x18\x05 \x01(\x08H\x02R\x11\x65nableImageSearch\x88\x01\x01\x42\x1d\n\x1b_enable_image_understandingB\x10\n\x0e_user_locationB\x16\n\x14_enable_image_search\"\xba\x01\n\x15WebSearchUserLocation\x12\x1d\n\x07\x63ountry\x18\x01 \x01(\tH\x00R\x07\x63ountry\x88\x01\x01\x12\x17\n\x04\x63ity\x18\x02 \x01(\tH\x01R\x04\x63ity\x88\x01\x01\x12\x1b\n\x06region\x18\x03 \x01(\tH\x02R\x06region\x88\x01\x01\x12\x1f\n\x08timezone\x18\x04 \x01(\tH\x03R\x08timezone\x88\x01\x01\x42\n\n\x08_countryB\x07\n\x05_cityB\t\n\x07_regionB\x0b\n\t_timezone\"\xb9\x03\n\x07XSearch\x12<\n\tfrom_date\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x00R\x08\x66romDate\x88\x01\x01\x12\x38\n\x07to_date\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x01R\x06toDate\x88\x01\x01\x12*\n\x11\x61llowed_x_handles\x18\x03 \x03(\tR\x0f\x61llowedXHandles\x12,\n\x12\x65xcluded_x_handles\x18\x04 \x03(\tR\x10\x65xcludedXHandles\x12\x41\n\x1a\x65nable_image_understanding\x18\x05 \x01(\x08H\x02R\x18\x65nableImageUnderstanding\x88\x01\x01\x12\x41\n\x1a\x65nable_video_understanding\x18\x06 \x01(\x08H\x03R\x18\x65nableVideoUnderstanding\x88\x01\x01\x42\x0c\n\n_from_dateB\n\n\x08_to_dateB\x1d\n\x1b_enable_image_understandingB\x1d\n\x1b_enable_video_understanding\"\x0f\n\rCodeExecution\"\x89\x03\n\x11\x43ollectionsSearch\x12%\n\x0e\x63ollection_ids\x18\x01 \x03(\tR\rcollectionIds\x12\x19\n\x05limit\x18\x02 \x01(\x05H\x01R\x05limit\x88\x01\x01\x12\'\n\x0cinstructions\x18\x03 \x01(\tH\x02R\x0cinstructions\x88\x01\x01\x12\x45\n\x10hybrid_retrieval\x18\x04 \x01(\x0b\x32\x18.xai_api.HybridRetrievalH\x00R\x0fhybridRetrieval\x12K\n\x12semantic_retrieval\x18\x05 \x01(\x0b\x32\x1a.xai_api.SemanticRetrievalH\x00R\x11semanticRetrieval\x12H\n\x11keyword_retrieval\x18\x06 \x01(\x0b\x32\x19.xai_api.KeywordRetrievalH\x00R\x10keywordRetrievalB\x10\n\x0eretrieval_modeB\x08\n\x06_limitB\x0f\n\r_instructions\"7\n\x10\x41ttachmentSearch\x12\x19\n\x05limit\x18\x02 \x01(\x05H\x00R\x05limit\x88\x01\x01\x42\x08\n\x06_limit\"x\n\x08\x46unction\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12 \n\x0b\x64\x65scription\x18\x02 \x01(\tR\x0b\x64\x65scription\x12\x16\n\x06strict\x18\x03 \x01(\x08R\x06strict\x12\x1e\n\nparameters\x18\x04 \x01(\tR\nparameters\"\xef\x01\n\x08ToolCall\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12)\n\x04type\x18\x02 \x01(\x0e\x32\x15.xai_api.ToolCallTypeR\x04type\x12/\n\x06status\x18\x03 \x01(\x0e\x32\x17.xai_api.ToolCallStatusR\x06status\x12(\n\rerror_message\x18\x04 \x01(\tH\x01R\x0c\x65rrorMessage\x88\x01\x01\x12\x33\n\x08\x66unction\x18\n \x01(\x0b\x32\x15.xai_api.FunctionCallH\x00R\x08\x66unctionB\x06\n\x04toolB\x10\n\x0e_error_message\"@\n\x0c\x46unctionCall\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x1c\n\targuments\x18\x02 \x01(\tR\targuments\"n\n\x0eResponseFormat\x12\x34\n\x0b\x66ormat_type\x18\x01 \x01(\x0e\x32\x13.xai_api.FormatTypeR\nformatType\x12\x1b\n\x06schema\x18\x02 \x01(\tH\x00R\x06schema\x88\x01\x01\x42\t\n\x07_schema\"\xc9\x02\n\x10SearchParameters\x12\'\n\x04mode\x18\x01 \x01(\x0e\x32\x13.xai_api.SearchModeR\x04mode\x12)\n\x07sources\x18\t \x03(\x0b\x32\x0f.xai_api.SourceR\x07sources\x12\x37\n\tfrom_date\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x08\x66romDate\x12\x33\n\x07to_date\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x06toDate\x12)\n\x10return_citations\x18\x07 \x01(\x08R\x0freturnCitations\x12\x31\n\x12max_search_results\x18\x08 \x01(\x05H\x00R\x10maxSearchResults\x88\x01\x01\x42\x15\n\x13_max_search_results\"\xaf\x01\n\x06Source\x12&\n\x03web\x18\x01 \x01(\x0b\x32\x12.xai_api.WebSourceH\x00R\x03web\x12)\n\x04news\x18\x02 \x01(\x0b\x32\x13.xai_api.NewsSourceH\x00R\x04news\x12 \n\x01x\x18\x03 \x01(\x0b\x32\x10.xai_api.XSourceH\x00R\x01x\x12&\n\x03rss\x18\x04 \x01(\x0b\x32\x12.xai_api.RssSourceH\x00R\x03rssB\x08\n\x06source\"\xaf\x01\n\tWebSource\x12+\n\x11\x65xcluded_websites\x18\x02 \x03(\tR\x10\x65xcludedWebsites\x12)\n\x10\x61llowed_websites\x18\x05 \x03(\tR\x0f\x61llowedWebsites\x12\x1d\n\x07\x63ountry\x18\x03 \x01(\tH\x00R\x07\x63ountry\x88\x01\x01\x12\x1f\n\x0bsafe_search\x18\x04 \x01(\x08R\nsafeSearchB\n\n\x08_country\"\x85\x01\n\nNewsSource\x12+\n\x11\x65xcluded_websites\x18\x02 \x03(\tR\x10\x65xcludedWebsites\x12\x1d\n\x07\x63ountry\x18\x03 \x01(\tH\x00R\x07\x63ountry\x88\x01\x01\x12\x1f\n\x0bsafe_search\x18\x04 \x01(\x08R\nsafeSearchB\n\n\x08_country\"\xf9\x01\n\x07XSource\x12,\n\x12included_x_handles\x18\x07 \x03(\tR\x10includedXHandles\x12,\n\x12\x65xcluded_x_handles\x18\x08 \x03(\tR\x10\x65xcludedXHandles\x12\x33\n\x13post_favorite_count\x18\t \x01(\x05H\x00R\x11postFavoriteCount\x88\x01\x01\x12+\n\x0fpost_view_count\x18\n \x01(\x05H\x01R\rpostViewCount\x88\x01\x01\x42\x16\n\x14_post_favorite_countB\x12\n\x10_post_view_countJ\x04\x08\x06\x10\x07\"!\n\tRssSource\x12\x14\n\x05links\x18\x01 \x03(\tR\x05links\"\x9f\x06\n\x0fRequestSettings\x12\"\n\nmax_tokens\x18\x01 \x01(\x05H\x00R\tmaxTokens\x88\x01\x01\x12.\n\x13parallel_tool_calls\x18\x02 \x01(\x08R\x11parallelToolCalls\x12\x35\n\x14previous_response_id\x18\x03 \x01(\tH\x01R\x12previousResponseId\x88\x01\x01\x12H\n\x10reasoning_effort\x18\x04 \x01(\x0e\x32\x18.xai_api.ReasoningEffortH\x02R\x0freasoningEffort\x88\x01\x01\x12%\n\x0btemperature\x18\x05 \x01(\x02H\x03R\x0btemperature\x88\x01\x01\x12@\n\x0fresponse_format\x18\x06 \x01(\x0b\x32\x17.xai_api.ResponseFormatR\x0eresponseFormat\x12\x34\n\x0btool_choice\x18\x07 \x01(\x0b\x32\x13.xai_api.ToolChoiceR\ntoolChoice\x12#\n\x05tools\x18\x08 \x03(\x0b\x32\r.xai_api.ToolR\x05tools\x12\x18\n\x05top_p\x18\t \x01(\x02H\x04R\x04topP\x88\x01\x01\x12\x12\n\x04user\x18\n \x01(\tR\x04user\x12K\n\x11search_parameters\x18\x0b \x01(\x0b\x32\x19.xai_api.SearchParametersH\x05R\x10searchParameters\x88\x01\x01\x12%\n\x0estore_messages\x18\x0c \x01(\x08R\rstoreMessages\x12\x32\n\x15use_encrypted_content\x18\r \x01(\x08R\x13useEncryptedContent\x12\x30\n\x07include\x18\x0e \x03(\x0e\x32\x16.xai_api.IncludeOptionR\x07includeB\r\n\x0b_max_tokensB\x17\n\x15_previous_response_idB\x13\n\x11_reasoning_effortB\x0e\n\x0c_temperatureB\x08\n\x06_top_pB\x14\n\x12_search_parameters\"=\n\x1aGetStoredCompletionRequest\x12\x1f\n\x0bresponse_id\x18\x01 \x01(\tR\nresponseId\"@\n\x1d\x44\x65leteStoredCompletionRequest\x12\x1f\n\x0bresponse_id\x18\x01 \x01(\tR\nresponseId\"A\n\x1e\x44\x65leteStoredCompletionResponse\x12\x1f\n\x0bresponse_id\x18\x01 \x01(\tR\nresponseId\"\xba\x03\n\x0b\x44\x65\x62ugOutput\x12\x1a\n\x08\x61ttempts\x18\x01 \x01(\x05R\x08\x61ttempts\x12\x18\n\x07request\x18\x02 \x01(\tR\x07request\x12\x16\n\x06prompt\x18\x03 \x01(\tR\x06prompt\x12%\n\x0e\x65ngine_request\x18\t \x01(\tR\rengineRequest\x12\x1c\n\tresponses\x18\x04 \x03(\tR\tresponses\x12\x16\n\x06\x63hunks\x18\x0c \x03(\tR\x06\x63hunks\x12(\n\x10\x63\x61\x63he_read_count\x18\x05 \x01(\rR\x0e\x63\x61\x63heReadCount\x12\x33\n\x16\x63\x61\x63he_read_input_bytes\x18\x06 \x01(\x04R\x13\x63\x61\x63heReadInputBytes\x12*\n\x11\x63\x61\x63he_write_count\x18\x07 \x01(\rR\x0f\x63\x61\x63heWriteCount\x12\x35\n\x17\x63\x61\x63he_write_input_bytes\x18\x08 \x01(\x04R\x14\x63\x61\x63heWriteInputBytes\x12\x1d\n\nlb_address\x18\n \x01(\tR\tlbAddress\x12\x1f\n\x0bsampler_tag\x18\x0b \x01(\tR\nsamplerTag\"U\n\x15\x43ompactContextRequest\x12\x14\n\x05model\x18\x01 \x01(\tR\x05model\x12&\n\x05input\x18\x02 \x03(\x0b\x32\x10.xai_api.MessageR\x05input\"\xb7\x01\n\x16\x43ompactContextResponse\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12+\n\x11\x65ncrypted_content\x18\x02 \x01(\tR\x10\x65ncryptedContent\x12\x32\n\x15\x64ropped_message_count\x18\x03 \x01(\rR\x13\x64roppedMessageCount\x12,\n\x05usage\x18\x04 \x01(\x0b\x32\x16.xai_api.SamplingUsageR\x05usage*\x82\x03\n\rIncludeOption\x12\x1a\n\x16INCLUDE_OPTION_INVALID\x10\x00\x12)\n%INCLUDE_OPTION_WEB_SEARCH_CALL_OUTPUT\x10\x01\x12\'\n#INCLUDE_OPTION_X_SEARCH_CALL_OUTPUT\x10\x02\x12-\n)INCLUDE_OPTION_CODE_EXECUTION_CALL_OUTPUT\x10\x03\x12\x31\n-INCLUDE_OPTION_COLLECTIONS_SEARCH_CALL_OUTPUT\x10\x04\x12\x30\n,INCLUDE_OPTION_ATTACHMENT_SEARCH_CALL_OUTPUT\x10\x05\x12\"\n\x1eINCLUDE_OPTION_MCP_CALL_OUTPUT\x10\x06\x12#\n\x1fINCLUDE_OPTION_INLINE_CITATIONS\x10\x07\x12$\n INCLUDE_OPTION_VERBOSE_STREAMING\x10\x08*\x8d\x01\n\x0bMessageRole\x12\x10\n\x0cINVALID_ROLE\x10\x00\x12\r\n\tROLE_USER\x10\x01\x12\x12\n\x0eROLE_ASSISTANT\x10\x02\x12\x0f\n\x0bROLE_SYSTEM\x10\x03\x12\x15\n\rROLE_FUNCTION\x10\x04\x1a\x02\x08\x01\x12\r\n\tROLE_TOOL\x10\x05\x12\x12\n\x0eROLE_DEVELOPER\x10\x06*j\n\x0fReasoningEffort\x12\x12\n\x0eINVALID_EFFORT\x10\x00\x12\x0e\n\nEFFORT_LOW\x10\x01\x12\x11\n\rEFFORT_MEDIUM\x10\x02\x12\x0f\n\x0b\x45\x46\x46ORT_HIGH\x10\x03\x12\x0f\n\x0b\x45\x46\x46ORT_NONE\x10\x04*P\n\nAgentCount\x12\x1b\n\x17\x41GENT_COUNT_UNSPECIFIED\x10\x00\x12\x11\n\rAGENT_COUNT_4\x10\x01\x12\x12\n\x0e\x41GENT_COUNT_16\x10\x02*a\n\x08ToolMode\x12\x15\n\x11TOOL_MODE_INVALID\x10\x00\x12\x12\n\x0eTOOL_MODE_AUTO\x10\x01\x12\x12\n\x0eTOOL_MODE_NONE\x10\x02\x12\x16\n\x12TOOL_MODE_REQUIRED\x10\x03*u\n\nFormatType\x12\x17\n\x13\x46ORMAT_TYPE_INVALID\x10\x00\x12\x14\n\x10\x46ORMAT_TYPE_TEXT\x10\x01\x12\x1b\n\x17\x46ORMAT_TYPE_JSON_OBJECT\x10\x02\x12\x1b\n\x17\x46ORMAT_TYPE_JSON_SCHEMA\x10\x03*\xb1\x02\n\x0cToolCallType\x12\x1a\n\x16TOOL_CALL_TYPE_INVALID\x10\x00\x12#\n\x1fTOOL_CALL_TYPE_CLIENT_SIDE_TOOL\x10\x01\x12\"\n\x1eTOOL_CALL_TYPE_WEB_SEARCH_TOOL\x10\x02\x12 \n\x1cTOOL_CALL_TYPE_X_SEARCH_TOOL\x10\x03\x12&\n\"TOOL_CALL_TYPE_CODE_EXECUTION_TOOL\x10\x04\x12*\n&TOOL_CALL_TYPE_COLLECTIONS_SEARCH_TOOL\x10\x05\x12\x1b\n\x17TOOL_CALL_TYPE_MCP_TOOL\x10\x06\x12)\n%TOOL_CALL_TYPE_ATTACHMENT_SEARCH_TOOL\x10\x07*\x90\x01\n\x0eToolCallStatus\x12 \n\x1cTOOL_CALL_STATUS_IN_PROGRESS\x10\x00\x12\x1e\n\x1aTOOL_CALL_STATUS_COMPLETED\x10\x01\x12\x1f\n\x1bTOOL_CALL_STATUS_INCOMPLETE\x10\x02\x12\x1b\n\x17TOOL_CALL_STATUS_FAILED\x10\x03*d\n\nSearchMode\x12\x17\n\x13INVALID_SEARCH_MODE\x10\x00\x12\x13\n\x0fOFF_SEARCH_MODE\x10\x01\x12\x12\n\x0eON_SEARCH_MODE\x10\x02\x12\x14\n\x10\x41UTO_SEARCH_MODE\x10\x03\x32\x99\x05\n\x04\x43hat\x12U\n\rGetCompletion\x12\x1e.xai_api.GetCompletionsRequest\x1a\".xai_api.GetChatCompletionResponse\"\x00\x12Y\n\x12GetCompletionChunk\x12\x1e.xai_api.GetCompletionsRequest\x1a\x1f.xai_api.GetChatCompletionChunk\"\x00\x30\x01\x12[\n\x17StartDeferredCompletion\x12\x1e.xai_api.GetCompletionsRequest\x1a\x1e.xai_api.StartDeferredResponse\"\x00\x12^\n\x15GetDeferredCompletion\x12\x1b.xai_api.GetDeferredRequest\x1a&.xai_api.GetDeferredCompletionResponse\"\x00\x12`\n\x13GetStoredCompletion\x12#.xai_api.GetStoredCompletionRequest\x1a\".xai_api.GetChatCompletionResponse\"\x00\x12k\n\x16\x44\x65leteStoredCompletion\x12&.xai_api.DeleteStoredCompletionRequest\x1a\'.xai_api.DeleteStoredCompletionResponse\"\x00\x12S\n\x0e\x43ompactContext\x12\x1e.xai_api.CompactContextRequest\x1a\x1f.xai_api.CompactContextResponse\"\x00\x42P\n\x0b\x63om.xai_apiB\tChatProtoP\x01\xa2\x02\x03XXX\xaa\x02\x06XaiApi\xca\x02\x06XaiApi\xe2\x02\x12XaiApi\\GPBMetadata\xea\x02\x06XaiApib\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -42,24 +42,24 @@ _globals['_MESSAGEROLE'].values_by_name["ROLE_FUNCTION"]._serialized_options = b'\010\001' _globals['_MCP_EXTRAHEADERSENTRY']._loaded_options = None _globals['_MCP_EXTRAHEADERSENTRY']._serialized_options = b'8\001' - _globals['_INCLUDEOPTION']._serialized_start=10315 - _globals['_INCLUDEOPTION']._serialized_end=10701 - _globals['_MESSAGEROLE']._serialized_start=10704 - _globals['_MESSAGEROLE']._serialized_end=10845 - _globals['_REASONINGEFFORT']._serialized_start=10847 - _globals['_REASONINGEFFORT']._serialized_end=10953 - _globals['_AGENTCOUNT']._serialized_start=10955 - _globals['_AGENTCOUNT']._serialized_end=11035 - _globals['_TOOLMODE']._serialized_start=11037 - _globals['_TOOLMODE']._serialized_end=11134 - _globals['_FORMATTYPE']._serialized_start=11136 - _globals['_FORMATTYPE']._serialized_end=11253 - _globals['_TOOLCALLTYPE']._serialized_start=11256 - _globals['_TOOLCALLTYPE']._serialized_end=11561 - _globals['_TOOLCALLSTATUS']._serialized_start=11564 - _globals['_TOOLCALLSTATUS']._serialized_end=11708 - _globals['_SEARCHMODE']._serialized_start=11710 - _globals['_SEARCHMODE']._serialized_end=11810 + _globals['_INCLUDEOPTION']._serialized_start=10588 + _globals['_INCLUDEOPTION']._serialized_end=10974 + _globals['_MESSAGEROLE']._serialized_start=10977 + _globals['_MESSAGEROLE']._serialized_end=11118 + _globals['_REASONINGEFFORT']._serialized_start=11120 + _globals['_REASONINGEFFORT']._serialized_end=11226 + _globals['_AGENTCOUNT']._serialized_start=11228 + _globals['_AGENTCOUNT']._serialized_end=11308 + _globals['_TOOLMODE']._serialized_start=11310 + _globals['_TOOLMODE']._serialized_end=11407 + _globals['_FORMATTYPE']._serialized_start=11409 + _globals['_FORMATTYPE']._serialized_end=11526 + _globals['_TOOLCALLTYPE']._serialized_start=11529 + _globals['_TOOLCALLTYPE']._serialized_end=11834 + _globals['_TOOLCALLSTATUS']._serialized_start=11837 + _globals['_TOOLCALLSTATUS']._serialized_end=11981 + _globals['_SEARCHMODE']._serialized_start=11983 + _globals['_SEARCHMODE']._serialized_end=12083 _globals['_GETCOMPLETIONSREQUEST']._serialized_start=196 _globals['_GETCOMPLETIONSREQUEST']._serialized_end=1532 _globals['_GETCHATCOMPLETIONRESPONSE']._serialized_start=1535 @@ -146,6 +146,10 @@ _globals['_DELETESTOREDCOMPLETIONRESPONSE']._serialized_end=9867 _globals['_DEBUGOUTPUT']._serialized_start=9870 _globals['_DEBUGOUTPUT']._serialized_end=10312 - _globals['_CHAT']._serialized_start=11813 - _globals['_CHAT']._serialized_end=12393 + _globals['_COMPACTCONTEXTREQUEST']._serialized_start=10314 + _globals['_COMPACTCONTEXTREQUEST']._serialized_end=10399 + _globals['_COMPACTCONTEXTRESPONSE']._serialized_start=10402 + _globals['_COMPACTCONTEXTRESPONSE']._serialized_end=10585 + _globals['_CHAT']._serialized_start=12086 + _globals['_CHAT']._serialized_end=12751 # @@protoc_insertion_point(module_scope) diff --git a/src/xai_sdk/proto/v5/chat_pb2.pyi b/src/xai_sdk/proto/v5/chat_pb2.pyi index 4378a6e..76531a4 100644 --- a/src/xai_sdk/proto/v5/chat_pb2.pyi +++ b/src/xai_sdk/proto/v5/chat_pb2.pyi @@ -457,18 +457,18 @@ class MCP(_message.Message): def __init__(self, server_label: _Optional[str] = ..., server_description: _Optional[str] = ..., server_url: _Optional[str] = ..., allowed_tool_names: _Optional[_Iterable[str]] = ..., authorization: _Optional[str] = ..., extra_headers: _Optional[_Mapping[str, str]] = ...) -> None: ... class WebSearch(_message.Message): - __slots__ = ("excluded_domains", "allowed_domains", "enable_image_understanding", "enable_image_search", "user_location") + __slots__ = ("excluded_domains", "allowed_domains", "enable_image_understanding", "user_location", "enable_image_search") EXCLUDED_DOMAINS_FIELD_NUMBER: _ClassVar[int] ALLOWED_DOMAINS_FIELD_NUMBER: _ClassVar[int] ENABLE_IMAGE_UNDERSTANDING_FIELD_NUMBER: _ClassVar[int] - ENABLE_IMAGE_SEARCH_FIELD_NUMBER: _ClassVar[int] USER_LOCATION_FIELD_NUMBER: _ClassVar[int] + ENABLE_IMAGE_SEARCH_FIELD_NUMBER: _ClassVar[int] excluded_domains: _containers.RepeatedScalarFieldContainer[str] allowed_domains: _containers.RepeatedScalarFieldContainer[str] enable_image_understanding: bool - enable_image_search: bool user_location: WebSearchUserLocation - def __init__(self, excluded_domains: _Optional[_Iterable[str]] = ..., allowed_domains: _Optional[_Iterable[str]] = ..., enable_image_understanding: bool = ..., enable_image_search: bool = ..., user_location: _Optional[_Union[WebSearchUserLocation, _Mapping]] = ...) -> None: ... + enable_image_search: bool + def __init__(self, excluded_domains: _Optional[_Iterable[str]] = ..., allowed_domains: _Optional[_Iterable[str]] = ..., enable_image_understanding: bool = ..., user_location: _Optional[_Union[WebSearchUserLocation, _Mapping]] = ..., enable_image_search: bool = ...) -> None: ... class WebSearchUserLocation(_message.Message): __slots__ = ("country", "city", "region", "timezone") @@ -711,3 +711,23 @@ class DebugOutput(_message.Message): lb_address: str sampler_tag: str def __init__(self, attempts: _Optional[int] = ..., request: _Optional[str] = ..., prompt: _Optional[str] = ..., engine_request: _Optional[str] = ..., responses: _Optional[_Iterable[str]] = ..., chunks: _Optional[_Iterable[str]] = ..., cache_read_count: _Optional[int] = ..., cache_read_input_bytes: _Optional[int] = ..., cache_write_count: _Optional[int] = ..., cache_write_input_bytes: _Optional[int] = ..., lb_address: _Optional[str] = ..., sampler_tag: _Optional[str] = ...) -> None: ... + +class CompactContextRequest(_message.Message): + __slots__ = ("model", "input") + MODEL_FIELD_NUMBER: _ClassVar[int] + INPUT_FIELD_NUMBER: _ClassVar[int] + model: str + input: _containers.RepeatedCompositeFieldContainer[Message] + def __init__(self, model: _Optional[str] = ..., input: _Optional[_Iterable[_Union[Message, _Mapping]]] = ...) -> None: ... + +class CompactContextResponse(_message.Message): + __slots__ = ("id", "encrypted_content", "dropped_message_count", "usage") + ID_FIELD_NUMBER: _ClassVar[int] + ENCRYPTED_CONTENT_FIELD_NUMBER: _ClassVar[int] + DROPPED_MESSAGE_COUNT_FIELD_NUMBER: _ClassVar[int] + USAGE_FIELD_NUMBER: _ClassVar[int] + id: str + encrypted_content: str + dropped_message_count: int + usage: _usage_pb2.SamplingUsage + def __init__(self, id: _Optional[str] = ..., encrypted_content: _Optional[str] = ..., dropped_message_count: _Optional[int] = ..., usage: _Optional[_Union[_usage_pb2.SamplingUsage, _Mapping]] = ...) -> None: ... diff --git a/src/xai_sdk/proto/v5/chat_pb2_grpc.py b/src/xai_sdk/proto/v5/chat_pb2_grpc.py index f0ce1d8..2aa8e2d 100644 --- a/src/xai_sdk/proto/v5/chat_pb2_grpc.py +++ b/src/xai_sdk/proto/v5/chat_pb2_grpc.py @@ -46,6 +46,11 @@ def __init__(self, channel): request_serializer=xai_dot_api_dot_v1_dot_chat__pb2.DeleteStoredCompletionRequest.SerializeToString, response_deserializer=xai_dot_api_dot_v1_dot_chat__pb2.DeleteStoredCompletionResponse.FromString, _registered_method=True) + self.CompactContext = channel.unary_unary( + '/xai_api.Chat/CompactContext', + request_serializer=xai_dot_api_dot_v1_dot_chat__pb2.CompactContextRequest.SerializeToString, + response_deserializer=xai_dot_api_dot_v1_dot_chat__pb2.CompactContextResponse.FromString, + _registered_method=True) class ChatServicer(object): @@ -98,6 +103,16 @@ def DeleteStoredCompletion(self, request, context): context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') + def CompactContext(self, request, context): + """Compacts a full responses input context and returns a compacted context. + The client sends the current input items and receives back a compacted + set of items (with an opaque compaction summary) suitable for use as + the input to the next /v1/responses call. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + def add_ChatServicer_to_server(servicer, server): rpc_method_handlers = { @@ -131,6 +146,11 @@ def add_ChatServicer_to_server(servicer, server): request_deserializer=xai_dot_api_dot_v1_dot_chat__pb2.DeleteStoredCompletionRequest.FromString, response_serializer=xai_dot_api_dot_v1_dot_chat__pb2.DeleteStoredCompletionResponse.SerializeToString, ), + 'CompactContext': grpc.unary_unary_rpc_method_handler( + servicer.CompactContext, + request_deserializer=xai_dot_api_dot_v1_dot_chat__pb2.CompactContextRequest.FromString, + response_serializer=xai_dot_api_dot_v1_dot_chat__pb2.CompactContextResponse.SerializeToString, + ), } generic_handler = grpc.method_handlers_generic_handler( 'xai_api.Chat', rpc_method_handlers) @@ -304,3 +324,30 @@ def DeleteStoredCompletion(request, timeout, metadata, _registered_method=True) + + @staticmethod + def CompactContext(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/xai_api.Chat/CompactContext', + xai_dot_api_dot_v1_dot_chat__pb2.CompactContextRequest.SerializeToString, + xai_dot_api_dot_v1_dot_chat__pb2.CompactContextResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) diff --git a/src/xai_sdk/proto/v6/chat_pb2.py b/src/xai_sdk/proto/v6/chat_pb2.py index 376e23d..411364b 100644 --- a/src/xai_sdk/proto/v6/chat_pb2.py +++ b/src/xai_sdk/proto/v6/chat_pb2.py @@ -30,7 +30,7 @@ from . import usage_pb2 as xai_dot_api_dot_v1_dot_usage__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15xai/api/v1/chat.proto\x12\x07xai_api\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x19xai/api/v1/deferred.proto\x1a\x1axai/api/v1/documents.proto\x1a\x16xai/api/v1/image.proto\x1a\x17xai/api/v1/sample.proto\x1a\x16xai/api/v1/usage.proto\"\xb8\n\n\x15GetCompletionsRequest\x12,\n\x08messages\x18\x01 \x03(\x0b\x32\x10.xai_api.MessageR\x08messages\x12\x14\n\x05model\x18\x02 \x01(\tR\x05model\x12\x12\n\x04user\x18\x10 \x01(\tR\x04user\x12\x11\n\x01n\x18\x08 \x01(\x05H\x00R\x01n\x88\x01\x01\x12\"\n\nmax_tokens\x18\x07 \x01(\x05H\x01R\tmaxTokens\x88\x01\x01\x12\x17\n\x04seed\x18\x0b \x01(\x05H\x02R\x04seed\x88\x01\x01\x12\x12\n\x04stop\x18\x0c \x03(\tR\x04stop\x12%\n\x0btemperature\x18\x0e \x01(\x02H\x03R\x0btemperature\x88\x01\x01\x12\x18\n\x05top_p\x18\x0f \x01(\x02H\x04R\x04topP\x88\x01\x01\x12\x1a\n\x08logprobs\x18\x05 \x01(\x08R\x08logprobs\x12&\n\x0ctop_logprobs\x18\x06 \x01(\x05H\x05R\x0btopLogprobs\x88\x01\x01\x12#\n\x05tools\x18\x11 \x03(\x0b\x32\r.xai_api.ToolR\x05tools\x12\x34\n\x0btool_choice\x18\x12 \x01(\x0b\x32\x13.xai_api.ToolChoiceR\ntoolChoice\x12@\n\x0fresponse_format\x18\n \x01(\x0b\x32\x17.xai_api.ResponseFormatR\x0eresponseFormat\x12\x30\n\x11\x66requency_penalty\x18\x03 \x01(\x02H\x06R\x10\x66requencyPenalty\x88\x01\x01\x12.\n\x10presence_penalty\x18\t \x01(\x02H\x07R\x0fpresencePenalty\x88\x01\x01\x12H\n\x10reasoning_effort\x18\x13 \x01(\x0e\x32\x18.xai_api.ReasoningEffortH\x08R\x0freasoningEffort\x88\x01\x01\x12K\n\x11search_parameters\x18\x14 \x01(\x0b\x32\x19.xai_api.SearchParametersH\tR\x10searchParameters\x88\x01\x01\x12\x33\n\x13parallel_tool_calls\x18\x15 \x01(\x08H\nR\x11parallelToolCalls\x88\x01\x01\x12\x35\n\x14previous_response_id\x18\x16 \x01(\tH\x0bR\x12previousResponseId\x88\x01\x01\x12%\n\x0estore_messages\x18\x17 \x01(\x08R\rstoreMessages\x12\x32\n\x15use_encrypted_content\x18\x18 \x01(\x08R\x13useEncryptedContent\x12 \n\tmax_turns\x18\x19 \x01(\x05H\x0cR\x08maxTurns\x88\x01\x01\x12\x30\n\x07include\x18\x1a \x03(\x0e\x32\x16.xai_api.IncludeOptionR\x07include\x12\x39\n\x0b\x61gent_count\x18\x1d \x01(\x0e\x32\x13.xai_api.AgentCountH\rR\nagentCount\x88\x01\x01\x42\x04\n\x02_nB\r\n\x0b_max_tokensB\x07\n\x05_seedB\x0e\n\x0c_temperatureB\x08\n\x06_top_pB\x0f\n\r_top_logprobsB\x14\n\x12_frequency_penaltyB\x13\n\x11_presence_penaltyB\x13\n\x11_reasoning_effortB\x14\n\x12_search_parametersB\x16\n\x14_parallel_tool_callsB\x17\n\x15_previous_response_idB\x0c\n\n_max_turnsB\x0e\n\x0c_agent_countJ\x04\x08\x04\x10\x05\"\x96\x03\n\x19GetChatCompletionResponse\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12\x33\n\x07outputs\x18\x02 \x03(\x0b\x32\x19.xai_api.CompletionOutputR\x07outputs\x12\x34\n\x07\x63reated\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x07\x63reated\x12\x14\n\x05model\x18\x06 \x01(\tR\x05model\x12-\n\x12system_fingerprint\x18\x07 \x01(\tR\x11systemFingerprint\x12,\n\x05usage\x18\t \x01(\x0b\x32\x16.xai_api.SamplingUsageR\x05usage\x12\x1c\n\tcitations\x18\n \x03(\tR\tcitations\x12\x34\n\x08settings\x18\x0b \x01(\x0b\x32\x18.xai_api.RequestSettingsR\x08settings\x12\x37\n\x0c\x64\x65\x62ug_output\x18\x0c \x01(\x0b\x32\x14.xai_api.DebugOutputR\x0b\x64\x65\x62ugOutput\"\xe2\x02\n\x16GetChatCompletionChunk\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12\x38\n\x07outputs\x18\x02 \x03(\x0b\x32\x1e.xai_api.CompletionOutputChunkR\x07outputs\x12\x34\n\x07\x63reated\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x07\x63reated\x12\x14\n\x05model\x18\x04 \x01(\tR\x05model\x12-\n\x12system_fingerprint\x18\x05 \x01(\tR\x11systemFingerprint\x12,\n\x05usage\x18\x06 \x01(\x0b\x32\x16.xai_api.SamplingUsageR\x05usage\x12\x1c\n\tcitations\x18\x07 \x03(\tR\tcitations\x12\x37\n\x0c\x64\x65\x62ug_output\x18\n \x01(\x0b\x32\x14.xai_api.DebugOutputR\x0b\x64\x65\x62ugOutput\"\xa2\x01\n\x1dGetDeferredCompletionResponse\x12/\n\x06status\x18\x02 \x01(\x0e\x32\x17.xai_api.DeferredStatusR\x06status\x12\x43\n\x08response\x18\x01 \x01(\x0b\x32\".xai_api.GetChatCompletionResponseH\x00R\x08response\x88\x01\x01\x42\x0b\n\t_response\"\xc9\x01\n\x10\x43ompletionOutput\x12:\n\rfinish_reason\x18\x01 \x01(\x0e\x32\x15.xai_api.FinishReasonR\x0c\x66inishReason\x12\x14\n\x05index\x18\x02 \x01(\x05R\x05index\x12\x34\n\x07message\x18\x03 \x01(\x0b\x32\x1a.xai_api.CompletionMessageR\x07message\x12-\n\x08logprobs\x18\x04 \x01(\x0b\x32\x11.xai_api.LogProbsR\x08logprobs\"\x9a\x02\n\x11\x43ompletionMessage\x12\x18\n\x07\x63ontent\x18\x01 \x01(\tR\x07\x63ontent\x12+\n\x11reasoning_content\x18\x04 \x01(\tR\x10reasoningContent\x12(\n\x04role\x18\x02 \x01(\x0e\x32\x14.xai_api.MessageRoleR\x04role\x12\x30\n\ntool_calls\x18\x03 \x03(\x0b\x32\x11.xai_api.ToolCallR\ttoolCalls\x12+\n\x11\x65ncrypted_content\x18\x05 \x01(\tR\x10\x65ncryptedContent\x12\x35\n\tcitations\x18\x06 \x03(\x0b\x32\x17.xai_api.InlineCitationR\tcitations\"\xbe\x01\n\x15\x43ompletionOutputChunk\x12$\n\x05\x64\x65lta\x18\x01 \x01(\x0b\x32\x0e.xai_api.DeltaR\x05\x64\x65lta\x12-\n\x08logprobs\x18\x02 \x01(\x0b\x32\x11.xai_api.LogProbsR\x08logprobs\x12:\n\rfinish_reason\x18\x03 \x01(\x0e\x32\x15.xai_api.FinishReasonR\x0c\x66inishReason\x12\x14\n\x05index\x18\x04 \x01(\x05R\x05index\"\x8e\x02\n\x05\x44\x65lta\x12\x18\n\x07\x63ontent\x18\x01 \x01(\tR\x07\x63ontent\x12+\n\x11reasoning_content\x18\x04 \x01(\tR\x10reasoningContent\x12(\n\x04role\x18\x02 \x01(\x0e\x32\x14.xai_api.MessageRoleR\x04role\x12\x30\n\ntool_calls\x18\x03 \x03(\x0b\x32\x11.xai_api.ToolCallR\ttoolCalls\x12+\n\x11\x65ncrypted_content\x18\x05 \x01(\tR\x10\x65ncryptedContent\x12\x35\n\tcitations\x18\x06 \x03(\x0b\x32\x17.xai_api.InlineCitationR\tcitations\"\xad\x02\n\x0eInlineCitation\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12\x1f\n\x0bstart_index\x18\x02 \x01(\x05R\nstartIndex\x12\x1b\n\tend_index\x18\x06 \x01(\x05R\x08\x65ndIndex\x12\x39\n\x0cweb_citation\x18\x03 \x01(\x0b\x32\x14.xai_api.WebCitationH\x00R\x0bwebCitation\x12\x33\n\nx_citation\x18\x04 \x01(\x0b\x32\x12.xai_api.XCitationH\x00R\txCitation\x12Q\n\x14\x63ollections_citation\x18\x05 \x01(\x0b\x32\x1c.xai_api.CollectionsCitationH\x00R\x13\x63ollectionsCitationB\n\n\x08\x63itation\"\x1f\n\x0bWebCitation\x12\x10\n\x03url\x18\x01 \x01(\tR\x03url\"\x1d\n\tXCitation\x12\x10\n\x03url\x18\x01 \x01(\tR\x03url\"\xab\x01\n\x13\x43ollectionsCitation\x12\x17\n\x07\x66ile_id\x18\x01 \x01(\tR\x06\x66ileId\x12\x19\n\x08\x63hunk_id\x18\x02 \x01(\tR\x07\x63hunkId\x12#\n\rchunk_content\x18\x03 \x01(\tR\x0c\x63hunkContent\x12\x14\n\x05score\x18\x04 \x01(\x02R\x05score\x12%\n\x0e\x63ollection_ids\x18\x05 \x03(\tR\rcollectionIds\"6\n\x08LogProbs\x12*\n\x07\x63ontent\x18\x01 \x03(\x0b\x32\x10.xai_api.LogProbR\x07\x63ontent\"\x87\x01\n\x07LogProb\x12\x14\n\x05token\x18\x01 \x01(\tR\x05token\x12\x18\n\x07logprob\x18\x02 \x01(\x02R\x07logprob\x12\x14\n\x05\x62ytes\x18\x03 \x01(\x0cR\x05\x62ytes\x12\x36\n\x0ctop_logprobs\x18\x04 \x03(\x0b\x32\x13.xai_api.TopLogProbR\x0btopLogprobs\"R\n\nTopLogProb\x12\x14\n\x05token\x18\x01 \x01(\tR\x05token\x12\x18\n\x07logprob\x18\x02 \x01(\x02R\x07logprob\x12\x14\n\x05\x62ytes\x18\x03 \x01(\x0cR\x05\x62ytes\"\x8f\x01\n\x07\x43ontent\x12\x14\n\x04text\x18\x01 \x01(\tH\x00R\x04text\x12\x37\n\timage_url\x18\x02 \x01(\x0b\x32\x18.xai_api.ImageUrlContentH\x00R\x08imageUrl\x12*\n\x04\x66ile\x18\x03 \x01(\x0b\x32\x14.xai_api.FileContentH\x00R\x04\x66ileB\t\n\x07\x63ontent\"\x85\x01\n\x0b\x46ileContent\x12\x17\n\x07\x66ile_id\x18\x01 \x01(\tR\x06\x66ileId\x12\x12\n\x04\x64\x61ta\x18\x02 \x01(\x0cR\x04\x64\x61ta\x12\x1a\n\x08\x66ilename\x18\x03 \x01(\tR\x08\x66ilename\x12\x1b\n\tmime_type\x18\x04 \x01(\tR\x08mimeType\x12\x10\n\x03url\x18\x05 \x01(\tR\x03url\"\xd2\x02\n\x07Message\x12*\n\x07\x63ontent\x18\x01 \x03(\x0b\x32\x10.xai_api.ContentR\x07\x63ontent\x12\x30\n\x11reasoning_content\x18\x05 \x01(\tH\x00R\x10reasoningContent\x88\x01\x01\x12(\n\x04role\x18\x02 \x01(\x0e\x32\x14.xai_api.MessageRoleR\x04role\x12\x12\n\x04name\x18\x03 \x01(\tR\x04name\x12\x30\n\ntool_calls\x18\x04 \x03(\x0b\x32\x11.xai_api.ToolCallR\ttoolCalls\x12+\n\x11\x65ncrypted_content\x18\x06 \x01(\tR\x10\x65ncryptedContent\x12%\n\x0ctool_call_id\x18\x07 \x01(\tH\x01R\ntoolCallId\x88\x01\x01\x42\x14\n\x12_reasoning_contentB\x0f\n\r_tool_call_id\"k\n\nToolChoice\x12\'\n\x04mode\x18\x01 \x01(\x0e\x32\x11.xai_api.ToolModeH\x00R\x04mode\x12%\n\rfunction_name\x18\x02 \x01(\tH\x00R\x0c\x66unctionNameB\r\n\x0btool_choice\"\x9d\x03\n\x04Tool\x12/\n\x08\x66unction\x18\x01 \x01(\x0b\x32\x11.xai_api.FunctionH\x00R\x08\x66unction\x12\x33\n\nweb_search\x18\x03 \x01(\x0b\x32\x12.xai_api.WebSearchH\x00R\twebSearch\x12-\n\x08x_search\x18\x04 \x01(\x0b\x32\x10.xai_api.XSearchH\x00R\x07xSearch\x12?\n\x0e\x63ode_execution\x18\x05 \x01(\x0b\x32\x16.xai_api.CodeExecutionH\x00R\rcodeExecution\x12K\n\x12\x63ollections_search\x18\x06 \x01(\x0b\x32\x1a.xai_api.CollectionsSearchH\x00R\x11\x63ollectionsSearch\x12 \n\x03mcp\x18\x07 \x01(\x0b\x32\x0c.xai_api.MCPH\x00R\x03mcp\x12H\n\x11\x61ttachment_search\x18\x08 \x01(\x0b\x32\x19.xai_api.AttachmentSearchH\x00R\x10\x61ttachmentSearchB\x06\n\x04tool\"\xe7\x02\n\x03MCP\x12!\n\x0cserver_label\x18\x01 \x01(\tR\x0bserverLabel\x12-\n\x12server_description\x18\x02 \x01(\tR\x11serverDescription\x12\x1d\n\nserver_url\x18\x03 \x01(\tR\tserverUrl\x12,\n\x12\x61llowed_tool_names\x18\x04 \x03(\tR\x10\x61llowedToolNames\x12)\n\rauthorization\x18\x05 \x01(\tH\x00R\rauthorization\x88\x01\x01\x12\x43\n\rextra_headers\x18\x06 \x03(\x0b\x32\x1e.xai_api.MCP.ExtraHeadersEntryR\x0c\x65xtraHeaders\x1a?\n\x11\x45xtraHeadersEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value:\x02\x38\x01\x42\x10\n\x0e_authorization\"\xea\x02\n\tWebSearch\x12)\n\x10\x65xcluded_domains\x18\x01 \x03(\tR\x0f\x65xcludedDomains\x12\'\n\x0f\x61llowed_domains\x18\x02 \x03(\tR\x0e\x61llowedDomains\x12\x41\n\x1a\x65nable_image_understanding\x18\x03 \x01(\x08H\x00R\x18\x65nableImageUnderstanding\x88\x01\x01\x12\x33\n\x13\x65nable_image_search\x18\x05 \x01(\x08H\x01R\x11\x65nableImageSearch\x88\x01\x01\x12H\n\ruser_location\x18\x04 \x01(\x0b\x32\x1e.xai_api.WebSearchUserLocationH\x02R\x0cuserLocation\x88\x01\x01\x42\x1d\n\x1b_enable_image_understandingB\x16\n\x14_enable_image_searchB\x10\n\x0e_user_location\"\xba\x01\n\x15WebSearchUserLocation\x12\x1d\n\x07\x63ountry\x18\x01 \x01(\tH\x00R\x07\x63ountry\x88\x01\x01\x12\x17\n\x04\x63ity\x18\x02 \x01(\tH\x01R\x04\x63ity\x88\x01\x01\x12\x1b\n\x06region\x18\x03 \x01(\tH\x02R\x06region\x88\x01\x01\x12\x1f\n\x08timezone\x18\x04 \x01(\tH\x03R\x08timezone\x88\x01\x01\x42\n\n\x08_countryB\x07\n\x05_cityB\t\n\x07_regionB\x0b\n\t_timezone\"\xb9\x03\n\x07XSearch\x12<\n\tfrom_date\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x00R\x08\x66romDate\x88\x01\x01\x12\x38\n\x07to_date\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x01R\x06toDate\x88\x01\x01\x12*\n\x11\x61llowed_x_handles\x18\x03 \x03(\tR\x0f\x61llowedXHandles\x12,\n\x12\x65xcluded_x_handles\x18\x04 \x03(\tR\x10\x65xcludedXHandles\x12\x41\n\x1a\x65nable_image_understanding\x18\x05 \x01(\x08H\x02R\x18\x65nableImageUnderstanding\x88\x01\x01\x12\x41\n\x1a\x65nable_video_understanding\x18\x06 \x01(\x08H\x03R\x18\x65nableVideoUnderstanding\x88\x01\x01\x42\x0c\n\n_from_dateB\n\n\x08_to_dateB\x1d\n\x1b_enable_image_understandingB\x1d\n\x1b_enable_video_understanding\"\x0f\n\rCodeExecution\"\x89\x03\n\x11\x43ollectionsSearch\x12%\n\x0e\x63ollection_ids\x18\x01 \x03(\tR\rcollectionIds\x12\x19\n\x05limit\x18\x02 \x01(\x05H\x01R\x05limit\x88\x01\x01\x12\'\n\x0cinstructions\x18\x03 \x01(\tH\x02R\x0cinstructions\x88\x01\x01\x12\x45\n\x10hybrid_retrieval\x18\x04 \x01(\x0b\x32\x18.xai_api.HybridRetrievalH\x00R\x0fhybridRetrieval\x12K\n\x12semantic_retrieval\x18\x05 \x01(\x0b\x32\x1a.xai_api.SemanticRetrievalH\x00R\x11semanticRetrieval\x12H\n\x11keyword_retrieval\x18\x06 \x01(\x0b\x32\x19.xai_api.KeywordRetrievalH\x00R\x10keywordRetrievalB\x10\n\x0eretrieval_modeB\x08\n\x06_limitB\x0f\n\r_instructions\"7\n\x10\x41ttachmentSearch\x12\x19\n\x05limit\x18\x02 \x01(\x05H\x00R\x05limit\x88\x01\x01\x42\x08\n\x06_limit\"x\n\x08\x46unction\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12 \n\x0b\x64\x65scription\x18\x02 \x01(\tR\x0b\x64\x65scription\x12\x16\n\x06strict\x18\x03 \x01(\x08R\x06strict\x12\x1e\n\nparameters\x18\x04 \x01(\tR\nparameters\"\xef\x01\n\x08ToolCall\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12)\n\x04type\x18\x02 \x01(\x0e\x32\x15.xai_api.ToolCallTypeR\x04type\x12/\n\x06status\x18\x03 \x01(\x0e\x32\x17.xai_api.ToolCallStatusR\x06status\x12(\n\rerror_message\x18\x04 \x01(\tH\x01R\x0c\x65rrorMessage\x88\x01\x01\x12\x33\n\x08\x66unction\x18\n \x01(\x0b\x32\x15.xai_api.FunctionCallH\x00R\x08\x66unctionB\x06\n\x04toolB\x10\n\x0e_error_message\"@\n\x0c\x46unctionCall\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x1c\n\targuments\x18\x02 \x01(\tR\targuments\"n\n\x0eResponseFormat\x12\x34\n\x0b\x66ormat_type\x18\x01 \x01(\x0e\x32\x13.xai_api.FormatTypeR\nformatType\x12\x1b\n\x06schema\x18\x02 \x01(\tH\x00R\x06schema\x88\x01\x01\x42\t\n\x07_schema\"\xc9\x02\n\x10SearchParameters\x12\'\n\x04mode\x18\x01 \x01(\x0e\x32\x13.xai_api.SearchModeR\x04mode\x12)\n\x07sources\x18\t \x03(\x0b\x32\x0f.xai_api.SourceR\x07sources\x12\x37\n\tfrom_date\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x08\x66romDate\x12\x33\n\x07to_date\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x06toDate\x12)\n\x10return_citations\x18\x07 \x01(\x08R\x0freturnCitations\x12\x31\n\x12max_search_results\x18\x08 \x01(\x05H\x00R\x10maxSearchResults\x88\x01\x01\x42\x15\n\x13_max_search_results\"\xaf\x01\n\x06Source\x12&\n\x03web\x18\x01 \x01(\x0b\x32\x12.xai_api.WebSourceH\x00R\x03web\x12)\n\x04news\x18\x02 \x01(\x0b\x32\x13.xai_api.NewsSourceH\x00R\x04news\x12 \n\x01x\x18\x03 \x01(\x0b\x32\x10.xai_api.XSourceH\x00R\x01x\x12&\n\x03rss\x18\x04 \x01(\x0b\x32\x12.xai_api.RssSourceH\x00R\x03rssB\x08\n\x06source\"\xaf\x01\n\tWebSource\x12+\n\x11\x65xcluded_websites\x18\x02 \x03(\tR\x10\x65xcludedWebsites\x12)\n\x10\x61llowed_websites\x18\x05 \x03(\tR\x0f\x61llowedWebsites\x12\x1d\n\x07\x63ountry\x18\x03 \x01(\tH\x00R\x07\x63ountry\x88\x01\x01\x12\x1f\n\x0bsafe_search\x18\x04 \x01(\x08R\nsafeSearchB\n\n\x08_country\"\x85\x01\n\nNewsSource\x12+\n\x11\x65xcluded_websites\x18\x02 \x03(\tR\x10\x65xcludedWebsites\x12\x1d\n\x07\x63ountry\x18\x03 \x01(\tH\x00R\x07\x63ountry\x88\x01\x01\x12\x1f\n\x0bsafe_search\x18\x04 \x01(\x08R\nsafeSearchB\n\n\x08_country\"\xf9\x01\n\x07XSource\x12,\n\x12included_x_handles\x18\x07 \x03(\tR\x10includedXHandles\x12,\n\x12\x65xcluded_x_handles\x18\x08 \x03(\tR\x10\x65xcludedXHandles\x12\x33\n\x13post_favorite_count\x18\t \x01(\x05H\x00R\x11postFavoriteCount\x88\x01\x01\x12+\n\x0fpost_view_count\x18\n \x01(\x05H\x01R\rpostViewCount\x88\x01\x01\x42\x16\n\x14_post_favorite_countB\x12\n\x10_post_view_countJ\x04\x08\x06\x10\x07\"!\n\tRssSource\x12\x14\n\x05links\x18\x01 \x03(\tR\x05links\"\x9f\x06\n\x0fRequestSettings\x12\"\n\nmax_tokens\x18\x01 \x01(\x05H\x00R\tmaxTokens\x88\x01\x01\x12.\n\x13parallel_tool_calls\x18\x02 \x01(\x08R\x11parallelToolCalls\x12\x35\n\x14previous_response_id\x18\x03 \x01(\tH\x01R\x12previousResponseId\x88\x01\x01\x12H\n\x10reasoning_effort\x18\x04 \x01(\x0e\x32\x18.xai_api.ReasoningEffortH\x02R\x0freasoningEffort\x88\x01\x01\x12%\n\x0btemperature\x18\x05 \x01(\x02H\x03R\x0btemperature\x88\x01\x01\x12@\n\x0fresponse_format\x18\x06 \x01(\x0b\x32\x17.xai_api.ResponseFormatR\x0eresponseFormat\x12\x34\n\x0btool_choice\x18\x07 \x01(\x0b\x32\x13.xai_api.ToolChoiceR\ntoolChoice\x12#\n\x05tools\x18\x08 \x03(\x0b\x32\r.xai_api.ToolR\x05tools\x12\x18\n\x05top_p\x18\t \x01(\x02H\x04R\x04topP\x88\x01\x01\x12\x12\n\x04user\x18\n \x01(\tR\x04user\x12K\n\x11search_parameters\x18\x0b \x01(\x0b\x32\x19.xai_api.SearchParametersH\x05R\x10searchParameters\x88\x01\x01\x12%\n\x0estore_messages\x18\x0c \x01(\x08R\rstoreMessages\x12\x32\n\x15use_encrypted_content\x18\r \x01(\x08R\x13useEncryptedContent\x12\x30\n\x07include\x18\x0e \x03(\x0e\x32\x16.xai_api.IncludeOptionR\x07includeB\r\n\x0b_max_tokensB\x17\n\x15_previous_response_idB\x13\n\x11_reasoning_effortB\x0e\n\x0c_temperatureB\x08\n\x06_top_pB\x14\n\x12_search_parameters\"=\n\x1aGetStoredCompletionRequest\x12\x1f\n\x0bresponse_id\x18\x01 \x01(\tR\nresponseId\"@\n\x1d\x44\x65leteStoredCompletionRequest\x12\x1f\n\x0bresponse_id\x18\x01 \x01(\tR\nresponseId\"A\n\x1e\x44\x65leteStoredCompletionResponse\x12\x1f\n\x0bresponse_id\x18\x01 \x01(\tR\nresponseId\"\xba\x03\n\x0b\x44\x65\x62ugOutput\x12\x1a\n\x08\x61ttempts\x18\x01 \x01(\x05R\x08\x61ttempts\x12\x18\n\x07request\x18\x02 \x01(\tR\x07request\x12\x16\n\x06prompt\x18\x03 \x01(\tR\x06prompt\x12%\n\x0e\x65ngine_request\x18\t \x01(\tR\rengineRequest\x12\x1c\n\tresponses\x18\x04 \x03(\tR\tresponses\x12\x16\n\x06\x63hunks\x18\x0c \x03(\tR\x06\x63hunks\x12(\n\x10\x63\x61\x63he_read_count\x18\x05 \x01(\rR\x0e\x63\x61\x63heReadCount\x12\x33\n\x16\x63\x61\x63he_read_input_bytes\x18\x06 \x01(\x04R\x13\x63\x61\x63heReadInputBytes\x12*\n\x11\x63\x61\x63he_write_count\x18\x07 \x01(\rR\x0f\x63\x61\x63heWriteCount\x12\x35\n\x17\x63\x61\x63he_write_input_bytes\x18\x08 \x01(\x04R\x14\x63\x61\x63heWriteInputBytes\x12\x1d\n\nlb_address\x18\n \x01(\tR\tlbAddress\x12\x1f\n\x0bsampler_tag\x18\x0b \x01(\tR\nsamplerTag*\x82\x03\n\rIncludeOption\x12\x1a\n\x16INCLUDE_OPTION_INVALID\x10\x00\x12)\n%INCLUDE_OPTION_WEB_SEARCH_CALL_OUTPUT\x10\x01\x12\'\n#INCLUDE_OPTION_X_SEARCH_CALL_OUTPUT\x10\x02\x12-\n)INCLUDE_OPTION_CODE_EXECUTION_CALL_OUTPUT\x10\x03\x12\x31\n-INCLUDE_OPTION_COLLECTIONS_SEARCH_CALL_OUTPUT\x10\x04\x12\x30\n,INCLUDE_OPTION_ATTACHMENT_SEARCH_CALL_OUTPUT\x10\x05\x12\"\n\x1eINCLUDE_OPTION_MCP_CALL_OUTPUT\x10\x06\x12#\n\x1fINCLUDE_OPTION_INLINE_CITATIONS\x10\x07\x12$\n INCLUDE_OPTION_VERBOSE_STREAMING\x10\x08*\x8d\x01\n\x0bMessageRole\x12\x10\n\x0cINVALID_ROLE\x10\x00\x12\r\n\tROLE_USER\x10\x01\x12\x12\n\x0eROLE_ASSISTANT\x10\x02\x12\x0f\n\x0bROLE_SYSTEM\x10\x03\x12\x15\n\rROLE_FUNCTION\x10\x04\x1a\x02\x08\x01\x12\r\n\tROLE_TOOL\x10\x05\x12\x12\n\x0eROLE_DEVELOPER\x10\x06*j\n\x0fReasoningEffort\x12\x12\n\x0eINVALID_EFFORT\x10\x00\x12\x0e\n\nEFFORT_LOW\x10\x01\x12\x11\n\rEFFORT_MEDIUM\x10\x02\x12\x0f\n\x0b\x45\x46\x46ORT_HIGH\x10\x03\x12\x0f\n\x0b\x45\x46\x46ORT_NONE\x10\x04*P\n\nAgentCount\x12\x1b\n\x17\x41GENT_COUNT_UNSPECIFIED\x10\x00\x12\x11\n\rAGENT_COUNT_4\x10\x01\x12\x12\n\x0e\x41GENT_COUNT_16\x10\x02*a\n\x08ToolMode\x12\x15\n\x11TOOL_MODE_INVALID\x10\x00\x12\x12\n\x0eTOOL_MODE_AUTO\x10\x01\x12\x12\n\x0eTOOL_MODE_NONE\x10\x02\x12\x16\n\x12TOOL_MODE_REQUIRED\x10\x03*u\n\nFormatType\x12\x17\n\x13\x46ORMAT_TYPE_INVALID\x10\x00\x12\x14\n\x10\x46ORMAT_TYPE_TEXT\x10\x01\x12\x1b\n\x17\x46ORMAT_TYPE_JSON_OBJECT\x10\x02\x12\x1b\n\x17\x46ORMAT_TYPE_JSON_SCHEMA\x10\x03*\xb1\x02\n\x0cToolCallType\x12\x1a\n\x16TOOL_CALL_TYPE_INVALID\x10\x00\x12#\n\x1fTOOL_CALL_TYPE_CLIENT_SIDE_TOOL\x10\x01\x12\"\n\x1eTOOL_CALL_TYPE_WEB_SEARCH_TOOL\x10\x02\x12 \n\x1cTOOL_CALL_TYPE_X_SEARCH_TOOL\x10\x03\x12&\n\"TOOL_CALL_TYPE_CODE_EXECUTION_TOOL\x10\x04\x12*\n&TOOL_CALL_TYPE_COLLECTIONS_SEARCH_TOOL\x10\x05\x12\x1b\n\x17TOOL_CALL_TYPE_MCP_TOOL\x10\x06\x12)\n%TOOL_CALL_TYPE_ATTACHMENT_SEARCH_TOOL\x10\x07*\x90\x01\n\x0eToolCallStatus\x12 \n\x1cTOOL_CALL_STATUS_IN_PROGRESS\x10\x00\x12\x1e\n\x1aTOOL_CALL_STATUS_COMPLETED\x10\x01\x12\x1f\n\x1bTOOL_CALL_STATUS_INCOMPLETE\x10\x02\x12\x1b\n\x17TOOL_CALL_STATUS_FAILED\x10\x03*d\n\nSearchMode\x12\x17\n\x13INVALID_SEARCH_MODE\x10\x00\x12\x13\n\x0fOFF_SEARCH_MODE\x10\x01\x12\x12\n\x0eON_SEARCH_MODE\x10\x02\x12\x14\n\x10\x41UTO_SEARCH_MODE\x10\x03\x32\xc4\x04\n\x04\x43hat\x12U\n\rGetCompletion\x12\x1e.xai_api.GetCompletionsRequest\x1a\".xai_api.GetChatCompletionResponse\"\x00\x12Y\n\x12GetCompletionChunk\x12\x1e.xai_api.GetCompletionsRequest\x1a\x1f.xai_api.GetChatCompletionChunk\"\x00\x30\x01\x12[\n\x17StartDeferredCompletion\x12\x1e.xai_api.GetCompletionsRequest\x1a\x1e.xai_api.StartDeferredResponse\"\x00\x12^\n\x15GetDeferredCompletion\x12\x1b.xai_api.GetDeferredRequest\x1a&.xai_api.GetDeferredCompletionResponse\"\x00\x12`\n\x13GetStoredCompletion\x12#.xai_api.GetStoredCompletionRequest\x1a\".xai_api.GetChatCompletionResponse\"\x00\x12k\n\x16\x44\x65leteStoredCompletion\x12&.xai_api.DeleteStoredCompletionRequest\x1a\'.xai_api.DeleteStoredCompletionResponse\"\x00\x42P\n\x0b\x63om.xai_apiB\tChatProtoP\x01\xa2\x02\x03XXX\xaa\x02\x06XaiApi\xca\x02\x06XaiApi\xe2\x02\x12XaiApi\\GPBMetadata\xea\x02\x06XaiApib\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15xai/api/v1/chat.proto\x12\x07xai_api\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x19xai/api/v1/deferred.proto\x1a\x1axai/api/v1/documents.proto\x1a\x16xai/api/v1/image.proto\x1a\x17xai/api/v1/sample.proto\x1a\x16xai/api/v1/usage.proto\"\xb8\n\n\x15GetCompletionsRequest\x12,\n\x08messages\x18\x01 \x03(\x0b\x32\x10.xai_api.MessageR\x08messages\x12\x14\n\x05model\x18\x02 \x01(\tR\x05model\x12\x12\n\x04user\x18\x10 \x01(\tR\x04user\x12\x11\n\x01n\x18\x08 \x01(\x05H\x00R\x01n\x88\x01\x01\x12\"\n\nmax_tokens\x18\x07 \x01(\x05H\x01R\tmaxTokens\x88\x01\x01\x12\x17\n\x04seed\x18\x0b \x01(\x05H\x02R\x04seed\x88\x01\x01\x12\x12\n\x04stop\x18\x0c \x03(\tR\x04stop\x12%\n\x0btemperature\x18\x0e \x01(\x02H\x03R\x0btemperature\x88\x01\x01\x12\x18\n\x05top_p\x18\x0f \x01(\x02H\x04R\x04topP\x88\x01\x01\x12\x1a\n\x08logprobs\x18\x05 \x01(\x08R\x08logprobs\x12&\n\x0ctop_logprobs\x18\x06 \x01(\x05H\x05R\x0btopLogprobs\x88\x01\x01\x12#\n\x05tools\x18\x11 \x03(\x0b\x32\r.xai_api.ToolR\x05tools\x12\x34\n\x0btool_choice\x18\x12 \x01(\x0b\x32\x13.xai_api.ToolChoiceR\ntoolChoice\x12@\n\x0fresponse_format\x18\n \x01(\x0b\x32\x17.xai_api.ResponseFormatR\x0eresponseFormat\x12\x30\n\x11\x66requency_penalty\x18\x03 \x01(\x02H\x06R\x10\x66requencyPenalty\x88\x01\x01\x12.\n\x10presence_penalty\x18\t \x01(\x02H\x07R\x0fpresencePenalty\x88\x01\x01\x12H\n\x10reasoning_effort\x18\x13 \x01(\x0e\x32\x18.xai_api.ReasoningEffortH\x08R\x0freasoningEffort\x88\x01\x01\x12K\n\x11search_parameters\x18\x14 \x01(\x0b\x32\x19.xai_api.SearchParametersH\tR\x10searchParameters\x88\x01\x01\x12\x33\n\x13parallel_tool_calls\x18\x15 \x01(\x08H\nR\x11parallelToolCalls\x88\x01\x01\x12\x35\n\x14previous_response_id\x18\x16 \x01(\tH\x0bR\x12previousResponseId\x88\x01\x01\x12%\n\x0estore_messages\x18\x17 \x01(\x08R\rstoreMessages\x12\x32\n\x15use_encrypted_content\x18\x18 \x01(\x08R\x13useEncryptedContent\x12 \n\tmax_turns\x18\x19 \x01(\x05H\x0cR\x08maxTurns\x88\x01\x01\x12\x30\n\x07include\x18\x1a \x03(\x0e\x32\x16.xai_api.IncludeOptionR\x07include\x12\x39\n\x0b\x61gent_count\x18\x1d \x01(\x0e\x32\x13.xai_api.AgentCountH\rR\nagentCount\x88\x01\x01\x42\x04\n\x02_nB\r\n\x0b_max_tokensB\x07\n\x05_seedB\x0e\n\x0c_temperatureB\x08\n\x06_top_pB\x0f\n\r_top_logprobsB\x14\n\x12_frequency_penaltyB\x13\n\x11_presence_penaltyB\x13\n\x11_reasoning_effortB\x14\n\x12_search_parametersB\x16\n\x14_parallel_tool_callsB\x17\n\x15_previous_response_idB\x0c\n\n_max_turnsB\x0e\n\x0c_agent_countJ\x04\x08\x04\x10\x05\"\x96\x03\n\x19GetChatCompletionResponse\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12\x33\n\x07outputs\x18\x02 \x03(\x0b\x32\x19.xai_api.CompletionOutputR\x07outputs\x12\x34\n\x07\x63reated\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x07\x63reated\x12\x14\n\x05model\x18\x06 \x01(\tR\x05model\x12-\n\x12system_fingerprint\x18\x07 \x01(\tR\x11systemFingerprint\x12,\n\x05usage\x18\t \x01(\x0b\x32\x16.xai_api.SamplingUsageR\x05usage\x12\x1c\n\tcitations\x18\n \x03(\tR\tcitations\x12\x34\n\x08settings\x18\x0b \x01(\x0b\x32\x18.xai_api.RequestSettingsR\x08settings\x12\x37\n\x0c\x64\x65\x62ug_output\x18\x0c \x01(\x0b\x32\x14.xai_api.DebugOutputR\x0b\x64\x65\x62ugOutput\"\xe2\x02\n\x16GetChatCompletionChunk\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12\x38\n\x07outputs\x18\x02 \x03(\x0b\x32\x1e.xai_api.CompletionOutputChunkR\x07outputs\x12\x34\n\x07\x63reated\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x07\x63reated\x12\x14\n\x05model\x18\x04 \x01(\tR\x05model\x12-\n\x12system_fingerprint\x18\x05 \x01(\tR\x11systemFingerprint\x12,\n\x05usage\x18\x06 \x01(\x0b\x32\x16.xai_api.SamplingUsageR\x05usage\x12\x1c\n\tcitations\x18\x07 \x03(\tR\tcitations\x12\x37\n\x0c\x64\x65\x62ug_output\x18\n \x01(\x0b\x32\x14.xai_api.DebugOutputR\x0b\x64\x65\x62ugOutput\"\xa2\x01\n\x1dGetDeferredCompletionResponse\x12/\n\x06status\x18\x02 \x01(\x0e\x32\x17.xai_api.DeferredStatusR\x06status\x12\x43\n\x08response\x18\x01 \x01(\x0b\x32\".xai_api.GetChatCompletionResponseH\x00R\x08response\x88\x01\x01\x42\x0b\n\t_response\"\xc9\x01\n\x10\x43ompletionOutput\x12:\n\rfinish_reason\x18\x01 \x01(\x0e\x32\x15.xai_api.FinishReasonR\x0c\x66inishReason\x12\x14\n\x05index\x18\x02 \x01(\x05R\x05index\x12\x34\n\x07message\x18\x03 \x01(\x0b\x32\x1a.xai_api.CompletionMessageR\x07message\x12-\n\x08logprobs\x18\x04 \x01(\x0b\x32\x11.xai_api.LogProbsR\x08logprobs\"\x9a\x02\n\x11\x43ompletionMessage\x12\x18\n\x07\x63ontent\x18\x01 \x01(\tR\x07\x63ontent\x12+\n\x11reasoning_content\x18\x04 \x01(\tR\x10reasoningContent\x12(\n\x04role\x18\x02 \x01(\x0e\x32\x14.xai_api.MessageRoleR\x04role\x12\x30\n\ntool_calls\x18\x03 \x03(\x0b\x32\x11.xai_api.ToolCallR\ttoolCalls\x12+\n\x11\x65ncrypted_content\x18\x05 \x01(\tR\x10\x65ncryptedContent\x12\x35\n\tcitations\x18\x06 \x03(\x0b\x32\x17.xai_api.InlineCitationR\tcitations\"\xbe\x01\n\x15\x43ompletionOutputChunk\x12$\n\x05\x64\x65lta\x18\x01 \x01(\x0b\x32\x0e.xai_api.DeltaR\x05\x64\x65lta\x12-\n\x08logprobs\x18\x02 \x01(\x0b\x32\x11.xai_api.LogProbsR\x08logprobs\x12:\n\rfinish_reason\x18\x03 \x01(\x0e\x32\x15.xai_api.FinishReasonR\x0c\x66inishReason\x12\x14\n\x05index\x18\x04 \x01(\x05R\x05index\"\x8e\x02\n\x05\x44\x65lta\x12\x18\n\x07\x63ontent\x18\x01 \x01(\tR\x07\x63ontent\x12+\n\x11reasoning_content\x18\x04 \x01(\tR\x10reasoningContent\x12(\n\x04role\x18\x02 \x01(\x0e\x32\x14.xai_api.MessageRoleR\x04role\x12\x30\n\ntool_calls\x18\x03 \x03(\x0b\x32\x11.xai_api.ToolCallR\ttoolCalls\x12+\n\x11\x65ncrypted_content\x18\x05 \x01(\tR\x10\x65ncryptedContent\x12\x35\n\tcitations\x18\x06 \x03(\x0b\x32\x17.xai_api.InlineCitationR\tcitations\"\xad\x02\n\x0eInlineCitation\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12\x1f\n\x0bstart_index\x18\x02 \x01(\x05R\nstartIndex\x12\x1b\n\tend_index\x18\x06 \x01(\x05R\x08\x65ndIndex\x12\x39\n\x0cweb_citation\x18\x03 \x01(\x0b\x32\x14.xai_api.WebCitationH\x00R\x0bwebCitation\x12\x33\n\nx_citation\x18\x04 \x01(\x0b\x32\x12.xai_api.XCitationH\x00R\txCitation\x12Q\n\x14\x63ollections_citation\x18\x05 \x01(\x0b\x32\x1c.xai_api.CollectionsCitationH\x00R\x13\x63ollectionsCitationB\n\n\x08\x63itation\"\x1f\n\x0bWebCitation\x12\x10\n\x03url\x18\x01 \x01(\tR\x03url\"\x1d\n\tXCitation\x12\x10\n\x03url\x18\x01 \x01(\tR\x03url\"\xab\x01\n\x13\x43ollectionsCitation\x12\x17\n\x07\x66ile_id\x18\x01 \x01(\tR\x06\x66ileId\x12\x19\n\x08\x63hunk_id\x18\x02 \x01(\tR\x07\x63hunkId\x12#\n\rchunk_content\x18\x03 \x01(\tR\x0c\x63hunkContent\x12\x14\n\x05score\x18\x04 \x01(\x02R\x05score\x12%\n\x0e\x63ollection_ids\x18\x05 \x03(\tR\rcollectionIds\"6\n\x08LogProbs\x12*\n\x07\x63ontent\x18\x01 \x03(\x0b\x32\x10.xai_api.LogProbR\x07\x63ontent\"\x87\x01\n\x07LogProb\x12\x14\n\x05token\x18\x01 \x01(\tR\x05token\x12\x18\n\x07logprob\x18\x02 \x01(\x02R\x07logprob\x12\x14\n\x05\x62ytes\x18\x03 \x01(\x0cR\x05\x62ytes\x12\x36\n\x0ctop_logprobs\x18\x04 \x03(\x0b\x32\x13.xai_api.TopLogProbR\x0btopLogprobs\"R\n\nTopLogProb\x12\x14\n\x05token\x18\x01 \x01(\tR\x05token\x12\x18\n\x07logprob\x18\x02 \x01(\x02R\x07logprob\x12\x14\n\x05\x62ytes\x18\x03 \x01(\x0cR\x05\x62ytes\"\x8f\x01\n\x07\x43ontent\x12\x14\n\x04text\x18\x01 \x01(\tH\x00R\x04text\x12\x37\n\timage_url\x18\x02 \x01(\x0b\x32\x18.xai_api.ImageUrlContentH\x00R\x08imageUrl\x12*\n\x04\x66ile\x18\x03 \x01(\x0b\x32\x14.xai_api.FileContentH\x00R\x04\x66ileB\t\n\x07\x63ontent\"\x85\x01\n\x0b\x46ileContent\x12\x17\n\x07\x66ile_id\x18\x01 \x01(\tR\x06\x66ileId\x12\x12\n\x04\x64\x61ta\x18\x02 \x01(\x0cR\x04\x64\x61ta\x12\x1a\n\x08\x66ilename\x18\x03 \x01(\tR\x08\x66ilename\x12\x1b\n\tmime_type\x18\x04 \x01(\tR\x08mimeType\x12\x10\n\x03url\x18\x05 \x01(\tR\x03url\"\xd2\x02\n\x07Message\x12*\n\x07\x63ontent\x18\x01 \x03(\x0b\x32\x10.xai_api.ContentR\x07\x63ontent\x12\x30\n\x11reasoning_content\x18\x05 \x01(\tH\x00R\x10reasoningContent\x88\x01\x01\x12(\n\x04role\x18\x02 \x01(\x0e\x32\x14.xai_api.MessageRoleR\x04role\x12\x12\n\x04name\x18\x03 \x01(\tR\x04name\x12\x30\n\ntool_calls\x18\x04 \x03(\x0b\x32\x11.xai_api.ToolCallR\ttoolCalls\x12+\n\x11\x65ncrypted_content\x18\x06 \x01(\tR\x10\x65ncryptedContent\x12%\n\x0ctool_call_id\x18\x07 \x01(\tH\x01R\ntoolCallId\x88\x01\x01\x42\x14\n\x12_reasoning_contentB\x0f\n\r_tool_call_id\"k\n\nToolChoice\x12\'\n\x04mode\x18\x01 \x01(\x0e\x32\x11.xai_api.ToolModeH\x00R\x04mode\x12%\n\rfunction_name\x18\x02 \x01(\tH\x00R\x0c\x66unctionNameB\r\n\x0btool_choice\"\x9d\x03\n\x04Tool\x12/\n\x08\x66unction\x18\x01 \x01(\x0b\x32\x11.xai_api.FunctionH\x00R\x08\x66unction\x12\x33\n\nweb_search\x18\x03 \x01(\x0b\x32\x12.xai_api.WebSearchH\x00R\twebSearch\x12-\n\x08x_search\x18\x04 \x01(\x0b\x32\x10.xai_api.XSearchH\x00R\x07xSearch\x12?\n\x0e\x63ode_execution\x18\x05 \x01(\x0b\x32\x16.xai_api.CodeExecutionH\x00R\rcodeExecution\x12K\n\x12\x63ollections_search\x18\x06 \x01(\x0b\x32\x1a.xai_api.CollectionsSearchH\x00R\x11\x63ollectionsSearch\x12 \n\x03mcp\x18\x07 \x01(\x0b\x32\x0c.xai_api.MCPH\x00R\x03mcp\x12H\n\x11\x61ttachment_search\x18\x08 \x01(\x0b\x32\x19.xai_api.AttachmentSearchH\x00R\x10\x61ttachmentSearchB\x06\n\x04tool\"\xe7\x02\n\x03MCP\x12!\n\x0cserver_label\x18\x01 \x01(\tR\x0bserverLabel\x12-\n\x12server_description\x18\x02 \x01(\tR\x11serverDescription\x12\x1d\n\nserver_url\x18\x03 \x01(\tR\tserverUrl\x12,\n\x12\x61llowed_tool_names\x18\x04 \x03(\tR\x10\x61llowedToolNames\x12)\n\rauthorization\x18\x05 \x01(\tH\x00R\rauthorization\x88\x01\x01\x12\x43\n\rextra_headers\x18\x06 \x03(\x0b\x32\x1e.xai_api.MCP.ExtraHeadersEntryR\x0c\x65xtraHeaders\x1a?\n\x11\x45xtraHeadersEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value:\x02\x38\x01\x42\x10\n\x0e_authorization\"\xea\x02\n\tWebSearch\x12)\n\x10\x65xcluded_domains\x18\x01 \x03(\tR\x0f\x65xcludedDomains\x12\'\n\x0f\x61llowed_domains\x18\x02 \x03(\tR\x0e\x61llowedDomains\x12\x41\n\x1a\x65nable_image_understanding\x18\x03 \x01(\x08H\x00R\x18\x65nableImageUnderstanding\x88\x01\x01\x12H\n\ruser_location\x18\x04 \x01(\x0b\x32\x1e.xai_api.WebSearchUserLocationH\x01R\x0cuserLocation\x88\x01\x01\x12\x33\n\x13\x65nable_image_search\x18\x05 \x01(\x08H\x02R\x11\x65nableImageSearch\x88\x01\x01\x42\x1d\n\x1b_enable_image_understandingB\x10\n\x0e_user_locationB\x16\n\x14_enable_image_search\"\xba\x01\n\x15WebSearchUserLocation\x12\x1d\n\x07\x63ountry\x18\x01 \x01(\tH\x00R\x07\x63ountry\x88\x01\x01\x12\x17\n\x04\x63ity\x18\x02 \x01(\tH\x01R\x04\x63ity\x88\x01\x01\x12\x1b\n\x06region\x18\x03 \x01(\tH\x02R\x06region\x88\x01\x01\x12\x1f\n\x08timezone\x18\x04 \x01(\tH\x03R\x08timezone\x88\x01\x01\x42\n\n\x08_countryB\x07\n\x05_cityB\t\n\x07_regionB\x0b\n\t_timezone\"\xb9\x03\n\x07XSearch\x12<\n\tfrom_date\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x00R\x08\x66romDate\x88\x01\x01\x12\x38\n\x07to_date\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x01R\x06toDate\x88\x01\x01\x12*\n\x11\x61llowed_x_handles\x18\x03 \x03(\tR\x0f\x61llowedXHandles\x12,\n\x12\x65xcluded_x_handles\x18\x04 \x03(\tR\x10\x65xcludedXHandles\x12\x41\n\x1a\x65nable_image_understanding\x18\x05 \x01(\x08H\x02R\x18\x65nableImageUnderstanding\x88\x01\x01\x12\x41\n\x1a\x65nable_video_understanding\x18\x06 \x01(\x08H\x03R\x18\x65nableVideoUnderstanding\x88\x01\x01\x42\x0c\n\n_from_dateB\n\n\x08_to_dateB\x1d\n\x1b_enable_image_understandingB\x1d\n\x1b_enable_video_understanding\"\x0f\n\rCodeExecution\"\x89\x03\n\x11\x43ollectionsSearch\x12%\n\x0e\x63ollection_ids\x18\x01 \x03(\tR\rcollectionIds\x12\x19\n\x05limit\x18\x02 \x01(\x05H\x01R\x05limit\x88\x01\x01\x12\'\n\x0cinstructions\x18\x03 \x01(\tH\x02R\x0cinstructions\x88\x01\x01\x12\x45\n\x10hybrid_retrieval\x18\x04 \x01(\x0b\x32\x18.xai_api.HybridRetrievalH\x00R\x0fhybridRetrieval\x12K\n\x12semantic_retrieval\x18\x05 \x01(\x0b\x32\x1a.xai_api.SemanticRetrievalH\x00R\x11semanticRetrieval\x12H\n\x11keyword_retrieval\x18\x06 \x01(\x0b\x32\x19.xai_api.KeywordRetrievalH\x00R\x10keywordRetrievalB\x10\n\x0eretrieval_modeB\x08\n\x06_limitB\x0f\n\r_instructions\"7\n\x10\x41ttachmentSearch\x12\x19\n\x05limit\x18\x02 \x01(\x05H\x00R\x05limit\x88\x01\x01\x42\x08\n\x06_limit\"x\n\x08\x46unction\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12 \n\x0b\x64\x65scription\x18\x02 \x01(\tR\x0b\x64\x65scription\x12\x16\n\x06strict\x18\x03 \x01(\x08R\x06strict\x12\x1e\n\nparameters\x18\x04 \x01(\tR\nparameters\"\xef\x01\n\x08ToolCall\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12)\n\x04type\x18\x02 \x01(\x0e\x32\x15.xai_api.ToolCallTypeR\x04type\x12/\n\x06status\x18\x03 \x01(\x0e\x32\x17.xai_api.ToolCallStatusR\x06status\x12(\n\rerror_message\x18\x04 \x01(\tH\x01R\x0c\x65rrorMessage\x88\x01\x01\x12\x33\n\x08\x66unction\x18\n \x01(\x0b\x32\x15.xai_api.FunctionCallH\x00R\x08\x66unctionB\x06\n\x04toolB\x10\n\x0e_error_message\"@\n\x0c\x46unctionCall\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x1c\n\targuments\x18\x02 \x01(\tR\targuments\"n\n\x0eResponseFormat\x12\x34\n\x0b\x66ormat_type\x18\x01 \x01(\x0e\x32\x13.xai_api.FormatTypeR\nformatType\x12\x1b\n\x06schema\x18\x02 \x01(\tH\x00R\x06schema\x88\x01\x01\x42\t\n\x07_schema\"\xc9\x02\n\x10SearchParameters\x12\'\n\x04mode\x18\x01 \x01(\x0e\x32\x13.xai_api.SearchModeR\x04mode\x12)\n\x07sources\x18\t \x03(\x0b\x32\x0f.xai_api.SourceR\x07sources\x12\x37\n\tfrom_date\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x08\x66romDate\x12\x33\n\x07to_date\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x06toDate\x12)\n\x10return_citations\x18\x07 \x01(\x08R\x0freturnCitations\x12\x31\n\x12max_search_results\x18\x08 \x01(\x05H\x00R\x10maxSearchResults\x88\x01\x01\x42\x15\n\x13_max_search_results\"\xaf\x01\n\x06Source\x12&\n\x03web\x18\x01 \x01(\x0b\x32\x12.xai_api.WebSourceH\x00R\x03web\x12)\n\x04news\x18\x02 \x01(\x0b\x32\x13.xai_api.NewsSourceH\x00R\x04news\x12 \n\x01x\x18\x03 \x01(\x0b\x32\x10.xai_api.XSourceH\x00R\x01x\x12&\n\x03rss\x18\x04 \x01(\x0b\x32\x12.xai_api.RssSourceH\x00R\x03rssB\x08\n\x06source\"\xaf\x01\n\tWebSource\x12+\n\x11\x65xcluded_websites\x18\x02 \x03(\tR\x10\x65xcludedWebsites\x12)\n\x10\x61llowed_websites\x18\x05 \x03(\tR\x0f\x61llowedWebsites\x12\x1d\n\x07\x63ountry\x18\x03 \x01(\tH\x00R\x07\x63ountry\x88\x01\x01\x12\x1f\n\x0bsafe_search\x18\x04 \x01(\x08R\nsafeSearchB\n\n\x08_country\"\x85\x01\n\nNewsSource\x12+\n\x11\x65xcluded_websites\x18\x02 \x03(\tR\x10\x65xcludedWebsites\x12\x1d\n\x07\x63ountry\x18\x03 \x01(\tH\x00R\x07\x63ountry\x88\x01\x01\x12\x1f\n\x0bsafe_search\x18\x04 \x01(\x08R\nsafeSearchB\n\n\x08_country\"\xf9\x01\n\x07XSource\x12,\n\x12included_x_handles\x18\x07 \x03(\tR\x10includedXHandles\x12,\n\x12\x65xcluded_x_handles\x18\x08 \x03(\tR\x10\x65xcludedXHandles\x12\x33\n\x13post_favorite_count\x18\t \x01(\x05H\x00R\x11postFavoriteCount\x88\x01\x01\x12+\n\x0fpost_view_count\x18\n \x01(\x05H\x01R\rpostViewCount\x88\x01\x01\x42\x16\n\x14_post_favorite_countB\x12\n\x10_post_view_countJ\x04\x08\x06\x10\x07\"!\n\tRssSource\x12\x14\n\x05links\x18\x01 \x03(\tR\x05links\"\x9f\x06\n\x0fRequestSettings\x12\"\n\nmax_tokens\x18\x01 \x01(\x05H\x00R\tmaxTokens\x88\x01\x01\x12.\n\x13parallel_tool_calls\x18\x02 \x01(\x08R\x11parallelToolCalls\x12\x35\n\x14previous_response_id\x18\x03 \x01(\tH\x01R\x12previousResponseId\x88\x01\x01\x12H\n\x10reasoning_effort\x18\x04 \x01(\x0e\x32\x18.xai_api.ReasoningEffortH\x02R\x0freasoningEffort\x88\x01\x01\x12%\n\x0btemperature\x18\x05 \x01(\x02H\x03R\x0btemperature\x88\x01\x01\x12@\n\x0fresponse_format\x18\x06 \x01(\x0b\x32\x17.xai_api.ResponseFormatR\x0eresponseFormat\x12\x34\n\x0btool_choice\x18\x07 \x01(\x0b\x32\x13.xai_api.ToolChoiceR\ntoolChoice\x12#\n\x05tools\x18\x08 \x03(\x0b\x32\r.xai_api.ToolR\x05tools\x12\x18\n\x05top_p\x18\t \x01(\x02H\x04R\x04topP\x88\x01\x01\x12\x12\n\x04user\x18\n \x01(\tR\x04user\x12K\n\x11search_parameters\x18\x0b \x01(\x0b\x32\x19.xai_api.SearchParametersH\x05R\x10searchParameters\x88\x01\x01\x12%\n\x0estore_messages\x18\x0c \x01(\x08R\rstoreMessages\x12\x32\n\x15use_encrypted_content\x18\r \x01(\x08R\x13useEncryptedContent\x12\x30\n\x07include\x18\x0e \x03(\x0e\x32\x16.xai_api.IncludeOptionR\x07includeB\r\n\x0b_max_tokensB\x17\n\x15_previous_response_idB\x13\n\x11_reasoning_effortB\x0e\n\x0c_temperatureB\x08\n\x06_top_pB\x14\n\x12_search_parameters\"=\n\x1aGetStoredCompletionRequest\x12\x1f\n\x0bresponse_id\x18\x01 \x01(\tR\nresponseId\"@\n\x1d\x44\x65leteStoredCompletionRequest\x12\x1f\n\x0bresponse_id\x18\x01 \x01(\tR\nresponseId\"A\n\x1e\x44\x65leteStoredCompletionResponse\x12\x1f\n\x0bresponse_id\x18\x01 \x01(\tR\nresponseId\"\xba\x03\n\x0b\x44\x65\x62ugOutput\x12\x1a\n\x08\x61ttempts\x18\x01 \x01(\x05R\x08\x61ttempts\x12\x18\n\x07request\x18\x02 \x01(\tR\x07request\x12\x16\n\x06prompt\x18\x03 \x01(\tR\x06prompt\x12%\n\x0e\x65ngine_request\x18\t \x01(\tR\rengineRequest\x12\x1c\n\tresponses\x18\x04 \x03(\tR\tresponses\x12\x16\n\x06\x63hunks\x18\x0c \x03(\tR\x06\x63hunks\x12(\n\x10\x63\x61\x63he_read_count\x18\x05 \x01(\rR\x0e\x63\x61\x63heReadCount\x12\x33\n\x16\x63\x61\x63he_read_input_bytes\x18\x06 \x01(\x04R\x13\x63\x61\x63heReadInputBytes\x12*\n\x11\x63\x61\x63he_write_count\x18\x07 \x01(\rR\x0f\x63\x61\x63heWriteCount\x12\x35\n\x17\x63\x61\x63he_write_input_bytes\x18\x08 \x01(\x04R\x14\x63\x61\x63heWriteInputBytes\x12\x1d\n\nlb_address\x18\n \x01(\tR\tlbAddress\x12\x1f\n\x0bsampler_tag\x18\x0b \x01(\tR\nsamplerTag\"U\n\x15\x43ompactContextRequest\x12\x14\n\x05model\x18\x01 \x01(\tR\x05model\x12&\n\x05input\x18\x02 \x03(\x0b\x32\x10.xai_api.MessageR\x05input\"\xb7\x01\n\x16\x43ompactContextResponse\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12+\n\x11\x65ncrypted_content\x18\x02 \x01(\tR\x10\x65ncryptedContent\x12\x32\n\x15\x64ropped_message_count\x18\x03 \x01(\rR\x13\x64roppedMessageCount\x12,\n\x05usage\x18\x04 \x01(\x0b\x32\x16.xai_api.SamplingUsageR\x05usage*\x82\x03\n\rIncludeOption\x12\x1a\n\x16INCLUDE_OPTION_INVALID\x10\x00\x12)\n%INCLUDE_OPTION_WEB_SEARCH_CALL_OUTPUT\x10\x01\x12\'\n#INCLUDE_OPTION_X_SEARCH_CALL_OUTPUT\x10\x02\x12-\n)INCLUDE_OPTION_CODE_EXECUTION_CALL_OUTPUT\x10\x03\x12\x31\n-INCLUDE_OPTION_COLLECTIONS_SEARCH_CALL_OUTPUT\x10\x04\x12\x30\n,INCLUDE_OPTION_ATTACHMENT_SEARCH_CALL_OUTPUT\x10\x05\x12\"\n\x1eINCLUDE_OPTION_MCP_CALL_OUTPUT\x10\x06\x12#\n\x1fINCLUDE_OPTION_INLINE_CITATIONS\x10\x07\x12$\n INCLUDE_OPTION_VERBOSE_STREAMING\x10\x08*\x8d\x01\n\x0bMessageRole\x12\x10\n\x0cINVALID_ROLE\x10\x00\x12\r\n\tROLE_USER\x10\x01\x12\x12\n\x0eROLE_ASSISTANT\x10\x02\x12\x0f\n\x0bROLE_SYSTEM\x10\x03\x12\x15\n\rROLE_FUNCTION\x10\x04\x1a\x02\x08\x01\x12\r\n\tROLE_TOOL\x10\x05\x12\x12\n\x0eROLE_DEVELOPER\x10\x06*j\n\x0fReasoningEffort\x12\x12\n\x0eINVALID_EFFORT\x10\x00\x12\x0e\n\nEFFORT_LOW\x10\x01\x12\x11\n\rEFFORT_MEDIUM\x10\x02\x12\x0f\n\x0b\x45\x46\x46ORT_HIGH\x10\x03\x12\x0f\n\x0b\x45\x46\x46ORT_NONE\x10\x04*P\n\nAgentCount\x12\x1b\n\x17\x41GENT_COUNT_UNSPECIFIED\x10\x00\x12\x11\n\rAGENT_COUNT_4\x10\x01\x12\x12\n\x0e\x41GENT_COUNT_16\x10\x02*a\n\x08ToolMode\x12\x15\n\x11TOOL_MODE_INVALID\x10\x00\x12\x12\n\x0eTOOL_MODE_AUTO\x10\x01\x12\x12\n\x0eTOOL_MODE_NONE\x10\x02\x12\x16\n\x12TOOL_MODE_REQUIRED\x10\x03*u\n\nFormatType\x12\x17\n\x13\x46ORMAT_TYPE_INVALID\x10\x00\x12\x14\n\x10\x46ORMAT_TYPE_TEXT\x10\x01\x12\x1b\n\x17\x46ORMAT_TYPE_JSON_OBJECT\x10\x02\x12\x1b\n\x17\x46ORMAT_TYPE_JSON_SCHEMA\x10\x03*\xb1\x02\n\x0cToolCallType\x12\x1a\n\x16TOOL_CALL_TYPE_INVALID\x10\x00\x12#\n\x1fTOOL_CALL_TYPE_CLIENT_SIDE_TOOL\x10\x01\x12\"\n\x1eTOOL_CALL_TYPE_WEB_SEARCH_TOOL\x10\x02\x12 \n\x1cTOOL_CALL_TYPE_X_SEARCH_TOOL\x10\x03\x12&\n\"TOOL_CALL_TYPE_CODE_EXECUTION_TOOL\x10\x04\x12*\n&TOOL_CALL_TYPE_COLLECTIONS_SEARCH_TOOL\x10\x05\x12\x1b\n\x17TOOL_CALL_TYPE_MCP_TOOL\x10\x06\x12)\n%TOOL_CALL_TYPE_ATTACHMENT_SEARCH_TOOL\x10\x07*\x90\x01\n\x0eToolCallStatus\x12 \n\x1cTOOL_CALL_STATUS_IN_PROGRESS\x10\x00\x12\x1e\n\x1aTOOL_CALL_STATUS_COMPLETED\x10\x01\x12\x1f\n\x1bTOOL_CALL_STATUS_INCOMPLETE\x10\x02\x12\x1b\n\x17TOOL_CALL_STATUS_FAILED\x10\x03*d\n\nSearchMode\x12\x17\n\x13INVALID_SEARCH_MODE\x10\x00\x12\x13\n\x0fOFF_SEARCH_MODE\x10\x01\x12\x12\n\x0eON_SEARCH_MODE\x10\x02\x12\x14\n\x10\x41UTO_SEARCH_MODE\x10\x03\x32\x99\x05\n\x04\x43hat\x12U\n\rGetCompletion\x12\x1e.xai_api.GetCompletionsRequest\x1a\".xai_api.GetChatCompletionResponse\"\x00\x12Y\n\x12GetCompletionChunk\x12\x1e.xai_api.GetCompletionsRequest\x1a\x1f.xai_api.GetChatCompletionChunk\"\x00\x30\x01\x12[\n\x17StartDeferredCompletion\x12\x1e.xai_api.GetCompletionsRequest\x1a\x1e.xai_api.StartDeferredResponse\"\x00\x12^\n\x15GetDeferredCompletion\x12\x1b.xai_api.GetDeferredRequest\x1a&.xai_api.GetDeferredCompletionResponse\"\x00\x12`\n\x13GetStoredCompletion\x12#.xai_api.GetStoredCompletionRequest\x1a\".xai_api.GetChatCompletionResponse\"\x00\x12k\n\x16\x44\x65leteStoredCompletion\x12&.xai_api.DeleteStoredCompletionRequest\x1a\'.xai_api.DeleteStoredCompletionResponse\"\x00\x12S\n\x0e\x43ompactContext\x12\x1e.xai_api.CompactContextRequest\x1a\x1f.xai_api.CompactContextResponse\"\x00\x42P\n\x0b\x63om.xai_apiB\tChatProtoP\x01\xa2\x02\x03XXX\xaa\x02\x06XaiApi\xca\x02\x06XaiApi\xe2\x02\x12XaiApi\\GPBMetadata\xea\x02\x06XaiApib\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -42,24 +42,24 @@ _globals['_MESSAGEROLE'].values_by_name["ROLE_FUNCTION"]._serialized_options = b'\010\001' _globals['_MCP_EXTRAHEADERSENTRY']._loaded_options = None _globals['_MCP_EXTRAHEADERSENTRY']._serialized_options = b'8\001' - _globals['_INCLUDEOPTION']._serialized_start=10315 - _globals['_INCLUDEOPTION']._serialized_end=10701 - _globals['_MESSAGEROLE']._serialized_start=10704 - _globals['_MESSAGEROLE']._serialized_end=10845 - _globals['_REASONINGEFFORT']._serialized_start=10847 - _globals['_REASONINGEFFORT']._serialized_end=10953 - _globals['_AGENTCOUNT']._serialized_start=10955 - _globals['_AGENTCOUNT']._serialized_end=11035 - _globals['_TOOLMODE']._serialized_start=11037 - _globals['_TOOLMODE']._serialized_end=11134 - _globals['_FORMATTYPE']._serialized_start=11136 - _globals['_FORMATTYPE']._serialized_end=11253 - _globals['_TOOLCALLTYPE']._serialized_start=11256 - _globals['_TOOLCALLTYPE']._serialized_end=11561 - _globals['_TOOLCALLSTATUS']._serialized_start=11564 - _globals['_TOOLCALLSTATUS']._serialized_end=11708 - _globals['_SEARCHMODE']._serialized_start=11710 - _globals['_SEARCHMODE']._serialized_end=11810 + _globals['_INCLUDEOPTION']._serialized_start=10588 + _globals['_INCLUDEOPTION']._serialized_end=10974 + _globals['_MESSAGEROLE']._serialized_start=10977 + _globals['_MESSAGEROLE']._serialized_end=11118 + _globals['_REASONINGEFFORT']._serialized_start=11120 + _globals['_REASONINGEFFORT']._serialized_end=11226 + _globals['_AGENTCOUNT']._serialized_start=11228 + _globals['_AGENTCOUNT']._serialized_end=11308 + _globals['_TOOLMODE']._serialized_start=11310 + _globals['_TOOLMODE']._serialized_end=11407 + _globals['_FORMATTYPE']._serialized_start=11409 + _globals['_FORMATTYPE']._serialized_end=11526 + _globals['_TOOLCALLTYPE']._serialized_start=11529 + _globals['_TOOLCALLTYPE']._serialized_end=11834 + _globals['_TOOLCALLSTATUS']._serialized_start=11837 + _globals['_TOOLCALLSTATUS']._serialized_end=11981 + _globals['_SEARCHMODE']._serialized_start=11983 + _globals['_SEARCHMODE']._serialized_end=12083 _globals['_GETCOMPLETIONSREQUEST']._serialized_start=196 _globals['_GETCOMPLETIONSREQUEST']._serialized_end=1532 _globals['_GETCHATCOMPLETIONRESPONSE']._serialized_start=1535 @@ -146,6 +146,10 @@ _globals['_DELETESTOREDCOMPLETIONRESPONSE']._serialized_end=9867 _globals['_DEBUGOUTPUT']._serialized_start=9870 _globals['_DEBUGOUTPUT']._serialized_end=10312 - _globals['_CHAT']._serialized_start=11813 - _globals['_CHAT']._serialized_end=12393 + _globals['_COMPACTCONTEXTREQUEST']._serialized_start=10314 + _globals['_COMPACTCONTEXTREQUEST']._serialized_end=10399 + _globals['_COMPACTCONTEXTRESPONSE']._serialized_start=10402 + _globals['_COMPACTCONTEXTRESPONSE']._serialized_end=10585 + _globals['_CHAT']._serialized_start=12086 + _globals['_CHAT']._serialized_end=12751 # @@protoc_insertion_point(module_scope) diff --git a/src/xai_sdk/proto/v6/chat_pb2.pyi b/src/xai_sdk/proto/v6/chat_pb2.pyi index 88e1d45..140be01 100644 --- a/src/xai_sdk/proto/v6/chat_pb2.pyi +++ b/src/xai_sdk/proto/v6/chat_pb2.pyi @@ -458,18 +458,18 @@ class MCP(_message.Message): def __init__(self, server_label: _Optional[str] = ..., server_description: _Optional[str] = ..., server_url: _Optional[str] = ..., allowed_tool_names: _Optional[_Iterable[str]] = ..., authorization: _Optional[str] = ..., extra_headers: _Optional[_Mapping[str, str]] = ...) -> None: ... class WebSearch(_message.Message): - __slots__ = ("excluded_domains", "allowed_domains", "enable_image_understanding", "enable_image_search", "user_location") + __slots__ = ("excluded_domains", "allowed_domains", "enable_image_understanding", "user_location", "enable_image_search") EXCLUDED_DOMAINS_FIELD_NUMBER: _ClassVar[int] ALLOWED_DOMAINS_FIELD_NUMBER: _ClassVar[int] ENABLE_IMAGE_UNDERSTANDING_FIELD_NUMBER: _ClassVar[int] - ENABLE_IMAGE_SEARCH_FIELD_NUMBER: _ClassVar[int] USER_LOCATION_FIELD_NUMBER: _ClassVar[int] + ENABLE_IMAGE_SEARCH_FIELD_NUMBER: _ClassVar[int] excluded_domains: _containers.RepeatedScalarFieldContainer[str] allowed_domains: _containers.RepeatedScalarFieldContainer[str] enable_image_understanding: bool - enable_image_search: bool user_location: WebSearchUserLocation - def __init__(self, excluded_domains: _Optional[_Iterable[str]] = ..., allowed_domains: _Optional[_Iterable[str]] = ..., enable_image_understanding: bool = ..., enable_image_search: bool = ..., user_location: _Optional[_Union[WebSearchUserLocation, _Mapping]] = ...) -> None: ... + enable_image_search: bool + def __init__(self, excluded_domains: _Optional[_Iterable[str]] = ..., allowed_domains: _Optional[_Iterable[str]] = ..., enable_image_understanding: bool = ..., user_location: _Optional[_Union[WebSearchUserLocation, _Mapping]] = ..., enable_image_search: bool = ...) -> None: ... class WebSearchUserLocation(_message.Message): __slots__ = ("country", "city", "region", "timezone") @@ -712,3 +712,23 @@ class DebugOutput(_message.Message): lb_address: str sampler_tag: str def __init__(self, attempts: _Optional[int] = ..., request: _Optional[str] = ..., prompt: _Optional[str] = ..., engine_request: _Optional[str] = ..., responses: _Optional[_Iterable[str]] = ..., chunks: _Optional[_Iterable[str]] = ..., cache_read_count: _Optional[int] = ..., cache_read_input_bytes: _Optional[int] = ..., cache_write_count: _Optional[int] = ..., cache_write_input_bytes: _Optional[int] = ..., lb_address: _Optional[str] = ..., sampler_tag: _Optional[str] = ...) -> None: ... + +class CompactContextRequest(_message.Message): + __slots__ = ("model", "input") + MODEL_FIELD_NUMBER: _ClassVar[int] + INPUT_FIELD_NUMBER: _ClassVar[int] + model: str + input: _containers.RepeatedCompositeFieldContainer[Message] + def __init__(self, model: _Optional[str] = ..., input: _Optional[_Iterable[_Union[Message, _Mapping]]] = ...) -> None: ... + +class CompactContextResponse(_message.Message): + __slots__ = ("id", "encrypted_content", "dropped_message_count", "usage") + ID_FIELD_NUMBER: _ClassVar[int] + ENCRYPTED_CONTENT_FIELD_NUMBER: _ClassVar[int] + DROPPED_MESSAGE_COUNT_FIELD_NUMBER: _ClassVar[int] + USAGE_FIELD_NUMBER: _ClassVar[int] + id: str + encrypted_content: str + dropped_message_count: int + usage: _usage_pb2.SamplingUsage + def __init__(self, id: _Optional[str] = ..., encrypted_content: _Optional[str] = ..., dropped_message_count: _Optional[int] = ..., usage: _Optional[_Union[_usage_pb2.SamplingUsage, _Mapping]] = ...) -> None: ... diff --git a/src/xai_sdk/proto/v6/chat_pb2_grpc.py b/src/xai_sdk/proto/v6/chat_pb2_grpc.py index f0ce1d8..2aa8e2d 100644 --- a/src/xai_sdk/proto/v6/chat_pb2_grpc.py +++ b/src/xai_sdk/proto/v6/chat_pb2_grpc.py @@ -46,6 +46,11 @@ def __init__(self, channel): request_serializer=xai_dot_api_dot_v1_dot_chat__pb2.DeleteStoredCompletionRequest.SerializeToString, response_deserializer=xai_dot_api_dot_v1_dot_chat__pb2.DeleteStoredCompletionResponse.FromString, _registered_method=True) + self.CompactContext = channel.unary_unary( + '/xai_api.Chat/CompactContext', + request_serializer=xai_dot_api_dot_v1_dot_chat__pb2.CompactContextRequest.SerializeToString, + response_deserializer=xai_dot_api_dot_v1_dot_chat__pb2.CompactContextResponse.FromString, + _registered_method=True) class ChatServicer(object): @@ -98,6 +103,16 @@ def DeleteStoredCompletion(self, request, context): context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') + def CompactContext(self, request, context): + """Compacts a full responses input context and returns a compacted context. + The client sends the current input items and receives back a compacted + set of items (with an opaque compaction summary) suitable for use as + the input to the next /v1/responses call. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + def add_ChatServicer_to_server(servicer, server): rpc_method_handlers = { @@ -131,6 +146,11 @@ def add_ChatServicer_to_server(servicer, server): request_deserializer=xai_dot_api_dot_v1_dot_chat__pb2.DeleteStoredCompletionRequest.FromString, response_serializer=xai_dot_api_dot_v1_dot_chat__pb2.DeleteStoredCompletionResponse.SerializeToString, ), + 'CompactContext': grpc.unary_unary_rpc_method_handler( + servicer.CompactContext, + request_deserializer=xai_dot_api_dot_v1_dot_chat__pb2.CompactContextRequest.FromString, + response_serializer=xai_dot_api_dot_v1_dot_chat__pb2.CompactContextResponse.SerializeToString, + ), } generic_handler = grpc.method_handlers_generic_handler( 'xai_api.Chat', rpc_method_handlers) @@ -304,3 +324,30 @@ def DeleteStoredCompletion(request, timeout, metadata, _registered_method=True) + + @staticmethod + def CompactContext(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/xai_api.Chat/CompactContext', + xai_dot_api_dot_v1_dot_chat__pb2.CompactContextRequest.SerializeToString, + xai_dot_api_dot_v1_dot_chat__pb2.CompactContextResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) diff --git a/src/xai_sdk/sync/chat.py b/src/xai_sdk/sync/chat.py index 1cc5c53..d758525 100644 --- a/src/xai_sdk/sync/chat.py +++ b/src/xai_sdk/sync/chat.py @@ -2,15 +2,16 @@ import json import time import warnings -from typing import Iterator, Optional, Sequence, TypeVar +from typing import Iterator, Optional, Sequence, TypeVar, Union from opentelemetry.trace import SpanKind from pydantic import BaseModel -from ..chat import BaseChat, BaseClient, Chunk, Response +from ..chat import BaseChat, BaseClient, Chunk, CompactContextResponse, Response from ..poll_timer import PollTimer from ..proto import chat_pb2, deferred_pb2 from ..telemetry import get_tracer +from ..types import ChatModel class Client(BaseClient["Chat"]): @@ -50,6 +51,39 @@ def get_stored_completion(self, response_id: str) -> Sequence[Response]: response = self._stub.GetStoredCompletion(chat_pb2.GetStoredCompletionRequest(response_id=response_id)) return [Response(response, i) for i in range(len(response.outputs))] + def compact_context( + self, + model: Union[ChatModel, str], + messages: Sequence[chat_pb2.Message], + ) -> CompactContextResponse: + """Compacts a conversation context into an opaque encrypted representation. + + Sends the current input messages to the server which returns a compacted + context. The resulting ``encrypted_content`` can be used in a follow-up + chat request via an assistant message with the ``encrypted_content`` field + set, allowing the model to hydrate the summarised context without sending + the full message history. + + Args: + model: Model to use for compaction, e.g. ``"grok-4.3"``. + messages: The conversation messages to compact. + + Returns: + CompactContextResponse: A response containing the ``encrypted_content`` + string, the number of dropped messages, and token usage. + + Example: + >>> from xai_sdk.chat import user, system + >>> compact = client.chat.compact_context( + ... model="grok-4.3", + ... messages=[system("You are helpful."), user("Summarise our chat.")], + ... ) + >>> print(compact.encrypted_content) + """ + request = chat_pb2.CompactContextRequest(model=model, input=messages) + response = self._stub.CompactContext(request) + return CompactContextResponse(response) + def delete_stored_completion(self, response_id: str) -> str: """Deletes a stored chat completion response from the xAI backend. @@ -82,6 +116,35 @@ def delete_stored_completion(self, response_id: str) -> str: class Chat(BaseChat): """Utility class for simplifying the interaction with Chat requests and responses.""" + def compact(self) -> CompactContextResponse: + """Compacts the current conversation history. + + Sends all messages to the CompactContext RPC and appends the resulting + compaction message to the conversation. Prior messages are kept + client-side; the server will automatically drop everything before the + last compaction message when processing the next request. + + Returns: + CompactContextResponse: The compaction response with token usage + and dropped message count. + + Example: + >>> chat = client.chat.create(model="grok-4.3") + >>> chat.append(user("Hello!")) + >>> response = chat.sample() + >>> chat.append(response) + >>> # ... many turns later ... + >>> compact = chat.compact() + >>> print(f"Dropped {compact.dropped_message_count} messages") + >>> # Continue chatting on top of compacted context + >>> chat.append(user("What did we discuss?")) + >>> response = chat.sample() + """ + response_pb = self._stub.CompactContext(self._make_compact_request()) + result = CompactContextResponse(response_pb) + self._apply_compaction(result) + return result + def sample(self) -> Response: """Samples a single chat completion response from the model. diff --git a/tests/aio/chat_test.py b/tests/aio/chat_test.py index c6e2a5d..dbc48d6 100644 --- a/tests/aio/chat_test.py +++ b/tests/aio/chat_test.py @@ -12,6 +12,7 @@ from xai_sdk import AsyncClient from xai_sdk.chat import ( + CompactContextResponse, ImageDetail, ReasoningEffort, Response, @@ -1885,3 +1886,112 @@ def test_chat_response_cost_usd_returns_none_when_unset(): usage=usage_pb2.SamplingUsage(), ) assert Response(proto, index=0).cost_usd is None + + +@pytest.mark.asyncio(loop_scope="session") +async def test_compact_context(client: AsyncClient): + messages = [ + system("You are a helpful assistant."), + user("Hello, how are you?"), + assistant("I'm doing well, thank you!"), + user("Tell me a joke."), + ] + compact = await client.chat.compact_context(model="grok-4.3", messages=messages) + + assert isinstance(compact, CompactContextResponse) + assert compact.id.startswith("compact-") + assert compact.encrypted_content == "compacted-encrypted-content" + assert compact.dropped_message_count == 2 + assert compact.usage.prompt_tokens == 40 + assert compact.usage.completion_tokens == 5 + assert compact.usage.total_tokens == 45 + + +@pytest.mark.asyncio(loop_scope="session") +async def test_compact_context_single_message(client: AsyncClient): + messages = [user("Hello")] + compact = await client.chat.compact_context(model="grok-4.3", messages=messages) + + assert compact.encrypted_content == "compacted-encrypted-content" + assert compact.dropped_message_count == 0 + assert compact.usage.prompt_tokens == 10 + + +@pytest.mark.asyncio(loop_scope="session") +async def test_compact_context_proto_accessible(client: AsyncClient): + messages = [user("Hello"), assistant("Hi there!")] + compact = await client.chat.compact_context(model="grok-4.3", messages=messages) + + assert compact.proto.id == compact.id + assert compact.proto.encrypted_content == compact.encrypted_content + assert compact.proto.dropped_message_count == compact.dropped_message_count + + +@pytest.mark.asyncio(loop_scope="session") +async def test_compact_context_empty_messages(client: AsyncClient): + compact = await client.chat.compact_context(model="grok-4.3", messages=[]) + + assert compact.encrypted_content == "compacted-encrypted-content" + assert compact.dropped_message_count == 0 + assert compact.usage.prompt_tokens == 0 + + +@pytest.mark.asyncio(loop_scope="session") +async def test_compact_context_then_use_in_chat(client: AsyncClient): + """End-to-end: compact a conversation, then use the encrypted_content in a follow-up chat.""" + messages = [ + system("You are a helpful assistant."), + user("Hello, how are you?"), + assistant("I'm doing well, thank you!"), + ] + compact = await client.chat.compact_context(model="grok-4.3", messages=messages) + + chat = client.chat.create(model="grok-4.3", use_encrypted_content=True) + chat.append(compact) + chat.append(user("Tell me a joke.")) + response = await chat.sample() + + assert response.content == "Hello, this is a test response!" + assert chat.messages[-1].role == chat_pb2.ROLE_USER + assert chat.messages[-2].role == chat_pb2.ROLE_USER + assert chat.messages[-2].encrypted_content == compact.encrypted_content + + +@pytest.mark.asyncio(loop_scope="session") +async def test_chat_compact_in_place(client: AsyncClient): + """Test that chat.compact() appends a compaction message to the conversation.""" + chat = client.chat.create(model="grok-4.3") + chat.append(system("You are helpful.")) + chat.append(user("Hello")) + chat.append(assistant("Hi there!")) + chat.append(user("Tell me a joke.")) + assert len(chat.messages) == 4 + + compact = await chat.compact() + + assert isinstance(compact, CompactContextResponse) + assert compact.encrypted_content == "compacted-encrypted-content" + assert compact.dropped_message_count == 2 + # Prior messages are dropped to reduce payload size + assert len(chat.messages) == 1 + assert chat.messages[0].role == chat_pb2.ROLE_USER + assert chat.messages[0].encrypted_content == "compacted-encrypted-content" + assert len(chat.messages[0].content) == 0 + + +@pytest.mark.asyncio(loop_scope="session") +async def test_chat_compact_then_continue(client: AsyncClient): + """Test that chat works normally after compaction.""" + chat = client.chat.create(model="grok-4.3") + chat.append(user("Hello")) + chat.append(assistant("Hi!")) + chat.append(user("How are you?")) + + await chat.compact() + + # Should be able to append and sample after compaction + chat.append(user("Tell me something.")) + response = await chat.sample() + assert response.content == "Hello, this is a test response!" + # compaction message + new user message + assert len(chat.messages) == 2 diff --git a/tests/chat_test.py b/tests/chat_test.py index 1db217d..d5c0cb1 100644 --- a/tests/chat_test.py +++ b/tests/chat_test.py @@ -1,6 +1,6 @@ import pytest -from xai_sdk.chat import Response, _agent_count_to_proto, developer +from xai_sdk.chat import CompactContextResponse, Response, _agent_count_to_proto, developer from xai_sdk.proto import chat_pb2, sample_pb2, usage_pb2 from xai_sdk.tools import get_tool_call_type @@ -706,3 +706,130 @@ def test_agent_count_on_request_proto(): agent_count=chat_pb2.AgentCount.AGENT_COUNT_16, ) assert request.agent_count == chat_pb2.AgentCount.AGENT_COUNT_16 + + +def test_compact_context_response_id(): + """Test that CompactContextResponse.id returns the id from the proto.""" + proto = chat_pb2.CompactContextResponse(id="compact-abc123") + response = CompactContextResponse(proto) + assert response.id == "compact-abc123" + + +def test_compact_context_response_encrypted_content(): + """Test that CompactContextResponse.encrypted_content returns the encrypted_content from the proto.""" + proto = chat_pb2.CompactContextResponse(encrypted_content="opaque-encrypted-blob") + response = CompactContextResponse(proto) + assert response.encrypted_content == "opaque-encrypted-blob" + + +def test_compact_context_response_dropped_message_count(): + """Test that CompactContextResponse.dropped_message_count returns the count from the proto.""" + proto = chat_pb2.CompactContextResponse(dropped_message_count=5) + response = CompactContextResponse(proto) + assert response.dropped_message_count == 5 + + +def test_compact_context_response_dropped_message_count_zero(): + """Test that dropped_message_count defaults to 0 when not set.""" + proto = chat_pb2.CompactContextResponse() + response = CompactContextResponse(proto) + assert response.dropped_message_count == 0 + + +def test_compact_context_response_usage(): + """Test that CompactContextResponse.usage returns the SamplingUsage from the proto.""" + usage = usage_pb2.SamplingUsage( + prompt_tokens=100, + completion_tokens=20, + total_tokens=120, + reasoning_tokens=10, + ) + proto = chat_pb2.CompactContextResponse(usage=usage) + response = CompactContextResponse(proto) + assert response.usage.prompt_tokens == 100 + assert response.usage.completion_tokens == 20 + assert response.usage.total_tokens == 120 + assert response.usage.reasoning_tokens == 10 + + +def test_compact_context_response_all_fields(): + """Test CompactContextResponse with all fields populated.""" + usage = usage_pb2.SamplingUsage( + prompt_tokens=50, + completion_tokens=10, + total_tokens=60, + ) + proto = chat_pb2.CompactContextResponse( + id="compact-xyz", + encrypted_content="encrypted-payload", + dropped_message_count=3, + usage=usage, + ) + response = CompactContextResponse(proto) + assert response.id == "compact-xyz" + assert response.encrypted_content == "encrypted-payload" + assert response.dropped_message_count == 3 + assert response.usage.prompt_tokens == 50 + assert response.usage.total_tokens == 60 + + +def test_compact_context_response_proto_accessible(): + """Test that the underlying proto is accessible via the .proto property.""" + proto = chat_pb2.CompactContextResponse( + id="compact-test", + encrypted_content="content", + dropped_message_count=1, + ) + response = CompactContextResponse(proto) + assert response.proto == proto + assert response.proto.id == "compact-test" + + +def test_compact_context_response_empty_encrypted_content(): + """Test CompactContextResponse when encrypted_content is empty.""" + proto = chat_pb2.CompactContextResponse(id="compact-empty", encrypted_content="") + response = CompactContextResponse(proto) + assert response.encrypted_content == "" + + +def test_append_compact_context_response_creates_user_message(): + """Test that append(CompactContextResponse) produces a ROLE_USER message with encrypted_content.""" + from xai_sdk.proto import chat_pb2_grpc + from xai_sdk.sync.chat import Chat as SyncChat + + proto = chat_pb2.CompactContextResponse( + id="compact-test", + encrypted_content="opaque-blob", + ) + compact_resp = CompactContextResponse(proto) + + # Create a minimal Chat to test append behavior. + stub = chat_pb2_grpc.ChatStub.__new__(chat_pb2_grpc.ChatStub) + chat = SyncChat(stub, None, None, model="grok-4.3") + chat.append(compact_resp) + + assert len(chat.messages) == 1 + assert chat.messages[0].role == chat_pb2.MessageRole.ROLE_USER + assert chat.messages[0].encrypted_content == "opaque-blob" + assert len(chat.messages[0].content) == 0 + + +def test_append_compact_context_response_clears_existing_messages(): + """Test that appending a CompactContextResponse clears prior messages.""" + from xai_sdk.chat import user as user_msg + from xai_sdk.proto import chat_pb2_grpc + from xai_sdk.sync.chat import Chat as SyncChat + + proto = chat_pb2.CompactContextResponse(encrypted_content="blob") + compact_resp = CompactContextResponse(proto) + + stub = chat_pb2_grpc.ChatStub.__new__(chat_pb2_grpc.ChatStub) + chat = SyncChat(stub, None, None, model="grok-4.3") + chat.append(user_msg("Hello")) + assert len(chat.messages) == 1 + + chat.append(compact_resp) + + assert len(chat.messages) == 1 + assert chat.messages[0].role == chat_pb2.MessageRole.ROLE_USER + assert chat.messages[0].encrypted_content == "blob" diff --git a/tests/server.py b/tests/server.py index 3afc671..95250db 100644 --- a/tests/server.py +++ b/tests/server.py @@ -572,6 +572,19 @@ def GetStoredCompletion(self, request: chat_pb2.GetStoredCompletionRequest, cont return self._stored_completions[request.response_id] + def CompactContext(self, request: chat_pb2.CompactContextRequest, context: grpc.ServicerContext): + """Returns a dummy compact context response.""" + _check_auth(context) + + return chat_pb2.CompactContextResponse( + id=f"compact-{uuid.uuid4()}", + encrypted_content="compacted-encrypted-content", + dropped_message_count=max(0, len(request.input) - 2), + usage=usage_pb2.SamplingUsage( + prompt_tokens=len(request.input) * 10, completion_tokens=5, total_tokens=len(request.input) * 10 + 5 + ), + ) + def DeleteStoredCompletion(self, request: chat_pb2.DeleteStoredCompletionRequest, context: grpc.ServicerContext): """Deletes a stored completion response.""" _check_auth(context) diff --git a/tests/sync/chat_test.py b/tests/sync/chat_test.py index 0d9341e..65338f5 100644 --- a/tests/sync/chat_test.py +++ b/tests/sync/chat_test.py @@ -12,6 +12,7 @@ from xai_sdk import Client from xai_sdk.chat import ( Chunk, + CompactContextResponse, ImageDetail, ReasoningEffort, Response, @@ -2008,3 +2009,105 @@ def test_chat_response_cost_usd_returns_none_when_unset(): usage=usage_pb2.SamplingUsage(), ) assert Response(proto, index=0).cost_usd is None + + +def test_compact_context(client: Client): + messages = [ + system("You are a helpful assistant."), + user("Hello, how are you?"), + assistant("I'm doing well, thank you!"), + user("Tell me a joke."), + ] + compact = client.chat.compact_context(model="grok-4.3", messages=messages) + + assert isinstance(compact, CompactContextResponse) + assert compact.id.startswith("compact-") + assert compact.encrypted_content == "compacted-encrypted-content" + assert compact.dropped_message_count == 2 + assert compact.usage.prompt_tokens == 40 + assert compact.usage.completion_tokens == 5 + assert compact.usage.total_tokens == 45 + + +def test_compact_context_single_message(client: Client): + messages = [user("Hello")] + compact = client.chat.compact_context(model="grok-4.3", messages=messages) + + assert compact.encrypted_content == "compacted-encrypted-content" + assert compact.dropped_message_count == 0 + assert compact.usage.prompt_tokens == 10 + + +def test_compact_context_proto_accessible(client: Client): + messages = [user("Hello"), assistant("Hi there!")] + compact = client.chat.compact_context(model="grok-4.3", messages=messages) + + assert compact.proto.id == compact.id + assert compact.proto.encrypted_content == compact.encrypted_content + assert compact.proto.dropped_message_count == compact.dropped_message_count + + +def test_compact_context_empty_messages(client: Client): + compact = client.chat.compact_context(model="grok-4.3", messages=[]) + + assert compact.encrypted_content == "compacted-encrypted-content" + assert compact.dropped_message_count == 0 + assert compact.usage.prompt_tokens == 0 + + +def test_compact_context_then_use_in_chat(client: Client): + """End-to-end: compact a conversation, then use the encrypted_content in a follow-up chat.""" + messages = [ + system("You are a helpful assistant."), + user("Hello, how are you?"), + assistant("I'm doing well, thank you!"), + ] + compact = client.chat.compact_context(model="grok-4.3", messages=messages) + + chat = client.chat.create(model="grok-4.3", use_encrypted_content=True) + chat.append(compact) + chat.append(user("Tell me a joke.")) + response = chat.sample() + + assert response.content == "Hello, this is a test response!" + assert chat.messages[-1].role == chat_pb2.ROLE_USER + assert chat.messages[-2].role == chat_pb2.ROLE_USER + assert chat.messages[-2].encrypted_content == compact.encrypted_content + + +def test_chat_compact_in_place(client: Client): + """Test that chat.compact() appends a compaction message to the conversation.""" + chat = client.chat.create(model="grok-4.3") + chat.append(system("You are helpful.")) + chat.append(user("Hello")) + chat.append(assistant("Hi there!")) + chat.append(user("Tell me a joke.")) + assert len(chat.messages) == 4 + + compact = chat.compact() + + assert isinstance(compact, CompactContextResponse) + assert compact.encrypted_content == "compacted-encrypted-content" + assert compact.dropped_message_count == 2 + # Prior messages are dropped to reduce payload size + assert len(chat.messages) == 1 + assert chat.messages[0].role == chat_pb2.ROLE_USER + assert chat.messages[0].encrypted_content == "compacted-encrypted-content" + assert len(chat.messages[0].content) == 0 + + +def test_chat_compact_then_continue(client: Client): + """Test that chat works normally after compaction.""" + chat = client.chat.create(model="grok-4.3") + chat.append(user("Hello")) + chat.append(assistant("Hi!")) + chat.append(user("How are you?")) + + chat.compact() + + # Should be able to append and sample after compaction + chat.append(user("Tell me something.")) + response = chat.sample() + assert response.content == "Hello, this is a test response!" + # compaction message + new user message + assert len(chat.messages) == 2