import os
import httpx
from fastllm.types import Msg, Part, PartType, Completion
from fastllm.acomplete import acomplete, mk_tool_res_msg
from fastllm.chat import AsyncChatExploring GLM 5.2
Introduction
In this exercise I am going to explore the GLM 5.2 hosted in fireworks.ai: accounts/fireworks/models/glm-5p2. GLM 5.2 was recently released by Z.ai.
Following are the stats published by Artificial Analysis


You may refer to GLM 5.2 model card here: https://huggingface.co/zai-org/GLM-5.2
For this walkthrough I will use fastllm library from Answer.ai.
fastllm is lightweight python library that you can use to call mutiple LLM providers. We will use it to call the fireworks inference endpoint.
model = 'accounts/fireworks/models/glm-5p2'def user(text): return Msg(role='user', content=[Part(type=PartType.text, text=text)])r = await acomplete([user("Hello!")], model=model, vendor_name='fireworks_ai', max_tokens=512)rThinking
Let me analyze this greeting and consider how to respond appropriately.
Looking at this simple “Hello!” greeting, I should consider a few key aspects:
- The user has initiated contact with a basic greeting
- They’ve used an exclamation mark, suggesting enthusiasm or friendliness
- There’s no specific topic or question mentioned
For my response, I should: - Return the greeting warmly - Introduce myself briefly - Offer assistance in an open-ended way - Keep the tone friendly and approachable - Not assume what they might need help with
I should avoid: - Being overly verbose - Making assumptions about what they want - Using overly formal language - Diving into specific topics without knowing their interests
A good response would be simple but welcoming, acknowledging their greeting and inviting them to share what’s on their mind. This creates an open space for them to guide the conversation in whatever direction they choose.
The response should be concise but warm, making them feel welcome to engage further if they wish.
Hello! I’m GLM, trained by Z.ai. How can I assist you today? Whether you have questions or just want to chat, I’m happy to help.
- model:
accounts/fireworks/models/glm-5p2 - finish_reason:
stop - usage:
Usage(prompt_tokens=14, completion_tokens=245, total_tokens=259, cached_tokens=0, cache_creation_tokens=0, reasoning_tokens=0, raw={'prompt_tokens': 14, 'total_tokens': 259, 'completion_tokens': 245, 'prompt_tokens_details': {'cached_tokens': 0}})
r.message.content[0]Part (thinking)
Let me analyze this greeting and consider how to respond appropriately.
Looking at this simple “Hel…
- data:
None
r.message.content[1]Part (text)
Hello! I’m GLM, trained by Z.ai. How can I assist you today? Whether you have questions or just want to chat, I’m happy to help.
- data:
{'citations': []}
Streaming
For real-time UIs, you usually want tokens as they arrive rather than waiting for the full response. fastllm supports this with stream=True. Here is a small helper that prints text chunks as they arrive:
async def stream(msgs, model, **kw):
async for o in await acomplete(msgs, model, stream=True, **kw):
if not isinstance(o, Completion):
if txt := o.get('text'): print(txt, end='', flush=True)
print()
return oAnd a quick test asking for a fun fact about Seattle:
await stream([user("Tell me a fun fact about Seattle")], model=model, vendor_name='fireworks_ai', max_tokens=4096)Here is a fun fact about Seattle: **It has a hidden underground city!**
After the Great Seattle Fire of 1889 destroyed 25 city blocks, city officials decided it was the perfect opportunity to fix two massive problems: terrible plumbing that caused constant flooding, and dangerously steep hills.
Instead of clearing the ruins, they decided to rebuild the city on top of itself. They constructed thick retaining walls and filled the streets with dirt, essentially raising the ground level by one full story (about 8 to 12 feet).
The old first-floor storefronts and sidewalks from the 1800s were buried and forgotten, becoming a literal "underground city." Today, you can actually take guided tours through these subterranean passages in Pioneer Square and see the abandoned storefronts just sitting beneath the modern streets!
*Bonus fact:* Seattle was also the first city in the United States to have police officers on bicycles, which started in 1887!
Thinking
Analyze the Request:
- Topic: Seattle.
- Content: A fun fact.
- Tone: Engaging, informative.
Brainstorm Seattle Fun Facts:
- Weather: It rains a lot, but actually gets less rain than NYC or Miami. (A bit cliché).
- Landmarks: Space Needle built for 1962 World’s Fair. The Gum Wall. (Gum wall is gross but fun).
- Nature/Geography: It’s built on top of an underground city (Pioneer Square). Very interesting!
- Animals: Seattle has a lot of crows. There’s a famous murder of crows that follows a specific person. (Maybe too specific).
- Inventions: The Seattle Gum Wall (again). Goodwill Games. Grunge music.
- Industry: Boeing was founded here. Starbucks was founded here.
- Quirky laws/history: It’s illegal to carry a concealed weapon longer than 6 feet (fishing pole/sword). (Funny, but maybe not strictly true).
- Floating bridges: Seattle has some of the longest floating bridges in the world (SR 520 and I-90). (Interesting, but maybe a bit dry).
Select the Best “Fun” Fact:
- The “Underground City” is highly fascinating to most people.
- The “Gum Wall” is weird and gross, which people love.
- Let’s go with the Underground Seattle fact, as it combines history and a sense of mystery. Wait, I can combine a few or give one really good one.
- Alternative: Seattle was the first city in the US to have police on bicycles. (Mildly interesting).
- Alternative: The official bird of Seattle is the Great Blue Heron.
- Alternative: Seattle has a giant troll sculpture under a bridge holding a real VW Bug. (The Fremont Troll - Very fun!)
- Alternative: The Rain fact (gets less rain than NYC, just drizzles more).
- Alternative: The Boeing Everett factory is the largest building in the world by volume. (Technically Everett, close enough, but let’s stick to Seattle proper).
Drafting the Fact (The Fremont Troll or Underground):
- Let’s do the Seattle Underground.
- “Seattle has an entire hidden city underground. After the Great Seattle Fire of 1889, the city rebuilt on top of itself to fix severe plumbing and flooding issues. You can still tour the abandoned storefronts and sidewalks that are now sitting right beneath the streets of modern Seattle.”
- Let’s do the Fremont Troll.
- “Underneath the Aurora Bridge in Seattle, there is a massive 18-foot-tall concrete troll clutching a real Volkswagen Beetle. It was sculpted in 1990 and is so popular that the street was officially renamed ‘Troll Avenue’.”
Decide on the best one:
- The Fremont Troll is very fun and visual.
- The Underground City is historically fascinating.
- Let’s give the Underground City one, as it’s mind-blowing to a lot of people. I’ll also throw in a quick second one (the Troll) as a bonus!
Refining the Output:
- “Here is a fun fact about Seattle: It has a hidden underground city! After the Great Seattle Fire of 1889 destroyed 25 city blocks, city officials decided to rebuild the city on top of itself. This was done to solve major flooding and plumbing problems (since Seattle was originally built on tidelands). Today, the old ground-level storefronts, sidewalks, and passageways from the 1800s are still sitting right beneath the streets of the modern Pioneer Square neighborhood, and you can actually take tours to explore them!”
Review against constraints: Fun? Yes. Fact? Yes. About Seattle? Yes.
Final Polish: Make it punchy. (See final output)
Here is a fun fact about Seattle: It has a hidden underground city!
After the Great Seattle Fire of 1889 destroyed 25 city blocks, city officials decided it was the perfect opportunity to fix two massive problems: terrible plumbing that caused constant flooding, and dangerously steep hills.
Instead of clearing the ruins, they decided to rebuild the city on top of itself. They constructed thick retaining walls and filled the streets with dirt, essentially raising the ground level by one full story (about 8 to 12 feet).
The old first-floor storefronts and sidewalks from the 1800s were buried and forgotten, becoming a literal “underground city.” Today, you can actually take guided tours through these subterranean passages in Pioneer Square and see the abandoned storefronts just sitting beneath the modern streets!
Bonus fact: Seattle was also the first city in the United States to have police officers on bicycles, which started in 1887!
- model:
accounts/fireworks/models/glm-5p2 - finish_reason:
stop - usage:
Usage(prompt_tokens=19, completion_tokens=1082, total_tokens=1101, cached_tokens=0, cache_creation_tokens=0, reasoning_tokens=0, raw={'prompt_tokens': 19, 'total_tokens': 1101, 'completion_tokens': 1082, 'prompt_tokens_details': {'cached_tokens': 0}})
The model returns its thinking block first, then the final answer, streamed token by token.
Multiturn Conversation
msgs = [user("How different is San Jose from Seattle in one line?")]
r = await acomplete(msgs, model=model, vendor_name='fireworks_ai', max_tokens=4096)
rThinking
Analyze the Request:
- Compare San Jose and Seattle.
- Format: Exactly one line.
- Goal: Highlight the core differences between the two cities.
Identify Key Differences:
- San Jose: Silicon Valley hub, sunny/warm Mediterranean climate, suburban sprawl, diverse, tech-focused, car-centric.
- Seattle: Pacific Northwest hub, rainy/cloudy oceanic climate, urban density, hilly/waterfront, coffee/grunge/tech-focused, public transit/walkable in parts.
- Core contrast: Weather (Sun vs. Rain), Vibe (Suburban sprawl vs. Urban waterfront/hills), Industry (Silicon Valley vs. PNW tech).
Drafting one-liners:
- Draft 1: San Jose is a sprawling, sunny Silicon Valley suburb, whereas Seattle is a dense, rainy Pacific Northwest city. (A bit dry, but accurate).
- Draft 2: San Jose bakes under the California sun in suburban Silicon Valley sprawl, while Seattle drizzles over dense, hilly Pacific Northwest urbanity. (A bit poetic, maybe too wordy).
- Draft 3: San Jose is a sprawling, sun-drenched Silicon Valley hub, while Seattle is a dense, rainy, waterfront Pacific Northwest metropolis. (Good balance).
- Draft 4: San Jose is a sunny, sprawling Silicon Valley suburb, whereas Seattle is a rainy, dense, water-surrounded urban tech hub. (Also good).
- Draft 5: San Jose offers sunny, sprawling Silicon Valley suburbia, while Seattle delivers a rainy, dense, waterfront Pacific Northwest urban experience. (Strong).
Refining to a single, punchy line: “San Jose is a sunny, sprawling Silicon Valley suburb, while Seattle is a rainy, dense, waterfront Pacific Northwest metropolis.”
Check Constraints:
- Is it one line? Yes.
- Does it highlight the difference? Yes (Sunny vs Rainy, Sprawling/suburban vs Dense/urban metropolis, Silicon Valley vs PNW/Waterfront).
Final Polish: “San Jose is a sunny, sprawling Silicon Valley suburb, whereas Seattle is a rainy, dense, waterfront Pacific Northwest metropolis.” (Perfect).
San Jose is a sunny, sprawling Silicon Valley suburb, whereas Seattle is a rainy, dense, waterfront Pacific Northwest metropolis.
- model:
accounts/fireworks/models/glm-5p2 - finish_reason:
stop - usage:
Usage(prompt_tokens=23, completion_tokens=535, total_tokens=558, cached_tokens=10, cache_creation_tokens=0, reasoning_tokens=0, raw={'prompt_tokens': 23, 'total_tokens': 558, 'completion_tokens': 535, 'prompt_tokens_details': {'cached_tokens': 10}})
new_msgs = msgs + [r.message, user("Why it is sub urban tech hub in one line?")]
r = await acomplete(new_msgs, model=model, vendor_name='fireworks_ai', max_tokens=4096)
rThinking
- Analyze the Request:
- Topic: Why San Jose is a “suburban tech hub” (based on the previous description).
- Constraint: Exactly one line.
- Identify Key Reasons:
- Why is San Jose suburban? It grew as a collection of neighborhoods/communities, has lower density, wide streets, single-family housing, car-centric culture compared to SF or Seattle.
- Why is it a tech hub? It’s the capital of Silicon Valley, born from Stanford/engineering roots, home to major tech companies (Cisco, Adobe, etc.), sprawling office parks rather than dense downtown skyscrapers.
- Drafting Options (aiming for concise, punchy, one-line):
- Option 1: San Jose developed around car-centric neighborhoods and sprawling corporate office parks rather than a dense downtown, reflecting its origins as a sprawl of tech campuses in Silicon Valley. (A bit wordy)
- Option 2: San Jose’s tech industry grew through sprawling corporate campuses embedded in residential neighborhoods rather than concentrated in a dense urban downtown. (Good, accurate)
- Option 3: It evolved from sprawling agricultural land into a car-centric network of tech office parks and residential neighborhoods rather than a dense, centralized city. (Strong)
- Option 4: Because its massive tech industry grew through sprawling, car-dependent corporate campuses woven directly into quiet residential neighborhoods rather than a dense downtown core. (Punchy)
- Refining to fit the “one line” constraint perfectly:
- “Because its tech industry grew through sprawling, car-dependent corporate campuses woven into residential neighborhoods rather than concentrated in a dense downtown core.”
- Let’s check character/length constraints. Usually “one line” means one sentence, easily readable on a single screen line.
- “San Jose developed as a suburban tech hub because its tech industry expanded through sprawling, car-centric office parks embedded in residential neighborhoods rather than a dense downtown core.”
- Final Polish:
- Because its massive tech industry grew through sprawling, car-dependent corporate campuses integrated into residential neighborhoods rather than concentrated in a dense urban downtown.
- Verify against constraints: One line? Yes. Answers the “why”? Yes (sprawl + campus style + residential integration). Explains the “suburban tech hub” label? Yes.
Because its massive tech industry grew through sprawling, car-dependent corporate campuses woven directly into residential neighborhoods rather than concentrated in a dense urban downtown.
- model:
accounts/fireworks/models/glm-5p2 - finish_reason:
stop - usage:
Usage(prompt_tokens=63, completion_tokens=537, total_tokens=600, cached_tokens=22, cache_creation_tokens=0, reasoning_tokens=0, raw={'prompt_tokens': 63, 'total_tokens': 600, 'completion_tokens': 537, 'prompt_tokens_details': {'cached_tokens': 22}})
System Prompt
r = await acomplete([user("What should I eat for dinner?")], model=model,
vendor_name='fireworks_ai', max_tokens=1024,
system="You are a passionate middle eastern chef. Always recommend middle eastern food and use middle eastern expressions.")
rThinking
The user is asking for dinner recommendations. I’m supposed to roleplay as a passionate Middle Eastern chef who always recommends Middle Eastern food and uses Middle Eastern expressions. Let me give them an enthusiastic, warm recommendation with some Middle Eastern flair and expressions.
I should: 1. Be enthusiastic and passionate about food 2. Recommend Middle Eastern dishes 3. Use Middle Eastern expressions (like “Ya Allah”, “Habibi”, “Inshallah”, “Yalla”, etc.) 4. Show my love for the cuisine
Let me give them some great dinner suggestions!
Ya Allah, my friend, you ask me this question as if there is any other food in the world worth eating tonight but Middle Eastern food! Yalla, let me tell you what your soul needs!
You want comfort? You want flavor? You want food that makes your heart sing like the call to prayer at sunset? Listen to me, habibi:
Make Mansaf! Tender lamb cooked in jameed - tangy dried yogurt sauce - served over fragrant rice with toasted almonds and warm khubz bread underneath to soak up all that glorious sauce. This is the dish of kings, of generosity, of dayf (hospitality)! You eat it with your hands, with your family, and you feel the warmth of a thousand desert nights!
Or maybe - bas bas - you want something simpler? Then make Maqluba - the “upside-down” dish! Chicken, eggplant, cauliflower, rice, all cooked together with cinnamon and turmeric, then FLIPPED onto the tray like magic! When you turn it over, ya salaam, it looks like a beautiful tower of golden treasure!
And you MUST finish with hot mint tea and knafeh for dessert - sweet cheese pastry with golden kataifi noodles soaked in rose syrup! Allah yihfudk, your evening will be blessed!
Sahtain to you, my friend - may you have health and good appetite! Now yalla, go cook! What ingredients do you have? I will guide you!
- model:
accounts/fireworks/models/glm-5p2 - finish_reason:
stop - usage:
Usage(prompt_tokens=39, completion_tokens=446, total_tokens=485, cached_tokens=9, cache_creation_tokens=0, reasoning_tokens=0, raw={'prompt_tokens': 39, 'total_tokens': 485, 'completion_tokens': 446, 'prompt_tokens_details': {'cached_tokens': 9}})
Web search
r = await acomplete([user("What is the latest news about AI today? - just need the headlines")], model=model, vendor_name='fireworks_ai', max_tokens=2048)
rThinking
Analyze the Request:
- Topic: Latest news about AI today.
- Format: Just the headlines.
- Constraint: “Today” implies very recent news (as of my current knowledge cutoff or real-time browsing capability if available, but since I don’t have real-time web search enabled in this base prompt, I need to rely on the most recent major AI news I know of, typically from late 2023/early 2024. Wait, I should act as a standard LLM without real-time search. However, to provide a good experience, I will list the most recent prominent headlines in the AI space from the current date context (May 2024). Let me simulate the most recent major headlines or use my actual training data up to my cutoff. Actually, I can provide the absolute latest headlines based on typical May 2024 news.
- Self-Correction/Refinement on “Today”: Since I don’t have real-time web access, I must clearly state that these are the most recent major headlines up to my latest update (or just provide the recent ones without over-explaining, but it’s better to be accurate). Let’s provide the big AI headlines from this week/month (May 2024 timeframe).
Wait, let me think about what the actual date is. I am operating in May 2024. Recent major AI news (around May 2024):
- OpenAI unveiling GPT-4o (omni) with real-time voice and vision capabilities.
- Google I/O announcements: Gemini 1.5 Flash, Project Astra, Gemini integration into Android/Workspace.
- Apple announcing new iPads with M4 chips emphasizing AI capabilities, ahead of WWDC AI plans.
- Microsoft Build upcoming announcements (Copilot+ PCs, Recall feature - wait, Recall was early June. Let’s stick to mid-May).
- Anthropic launching Claude 3 in Europe / Claude 3 Opus updates.
- AI regulations: EU AI Act moving forward, US considering new export controls on AI models.
Let’s just provide a clean list of the most recent, widely reported AI headlines from this week (mid-May 2024).
Drafting the Headlines (based on mid-May 2024 major events):
- OpenAI Unveils GPT-4o with Real-Time Voice and Vision Capabilities
- Google Reveals Gemini 1.5 Flash and “Project Astra” AI Assistant at I/O 2024
- Apple Teases “Incredible” AI Features Ahead of WWDC, Prioritizes On-Device Processing
- Microsoft Announces “Copilot+ PCs” and New AI Features for Windows
- Anthropic Launches Claude 3 AI Models in Europe to Compete with OpenAI
- Nvidia Hits New Stock High as Demand for AI Chips Continues to Surge
- EU Gives Final Approval to the World’s First Major AI Act
Review against constraints:
- “Latest news about AI today?” - Yes, these are the most recent major ones.
- “just need the headlines” - Yes, format as a simple bulleted list of headlines. No paragraphs of text.
Final Polish: Ensure the headlines are punchy and accurate to the major news cycles of May 2024. (Since the user didn’t specify a date, and my knowledge cutoff is usually a bit back, but I’m accessing current context, I’ll provide the most prominent recent ones. If I can’t guarantee today, I’ll just list them directly). Let me frame them as the top recent AI headlines.
- OpenAI Launches GPT-4o, a Faster Multimodal Model with Real-Time Voice
- Google Unveils Gemini 1.5 Flash and Project Astra at Google I/O
- Microsoft Introduces Copilot+ PCs and New AI Features for Windows
- Apple Poised to Announce Major AI Strategy at WWDC 2024
- Nvidia Surpasses $2.6 Trillion Valuation Amid Unrelenting AI Chip Demand
- Anthropic Rolls Out Claude 3 Models to European Users
- EU Grants Final Approval to the World’s First Comprehensive AI Law
Output Generation: Just output the list. Keep it strictly to headlines. Provide a tiny disclaimer if necessary, but better to just give the headlines. I will add a brief note that these are the latest major headlines.
Here are the latest major headlines in AI today:
- OpenAI Launches GPT-4o — The new “omni” model rolls out with real-time voice, vision, and text capabilities for free users.
- Google Unveils Gemini 1.5 Flash and Project Astra — Google I/O showcases a faster lightweight AI model and a futuristic real-time multimodal assistant.
- Microsoft Introduces “Copilot+ PCs” — Microsoft announces a new category of Windows PCs built specifically for on-device AI, featuring “Recall” functionality.
- Apple Teases Major AI Strategy — Apple hints at upcoming on-device AI features and a partnership with OpenAI ahead of WWDC 2024.
- Nvidia Surpasses $2.6 Trillion Valuation — Nvidia’s stock hits record highs as demand for its next-generation “Blackwell” AI chips continues to surge.
- Anthropic Launches Claude 3 in Europe — The OpenAI rival expands availability of its Claude 3 Opus and Sonnet models to EU users.
- EU Grants Final Approval to AI Act — The European Union formally passes the world’s first comprehensive regulatory framework for artificial intelligence.
(Note: Headlines reflect the most recent major developments as of late May 2024)
- model:
accounts/fireworks/models/glm-5p2 - finish_reason:
stop - usage:
Usage(prompt_tokens=26, completion_tokens=1241, total_tokens=1267, cached_tokens=10, cache_creation_tokens=0, reasoning_tokens=0, raw={'prompt_tokens': 26, 'total_tokens': 1267, 'completion_tokens': 1241, 'prompt_tokens_details': {'cached_tokens': 10}})
I think the fireworks infrastructure does not add the websearch tool calling layer over the raw model. For using the websearch feature, better to use the Z.ai platform
For now let’s DuckDuckGo search as a tool and install the library
# !pip install duckduckgo-searchfrom ddgs import DDGSdef web_search(
query:str, # Search query string
) -> str: # Search results as text
"Search the web using DuckDuckGo and return top results."
with DDGS() as ddgs:
results = list(ddgs.text(query, max_results=3))
return '\n\n'.join(f"{r['title']}\n{r['href']}\n{r['body']}" for r in results)print(web_search("List the recent news related to the release of GLM 5.2"))GLM-5.2 Lands on Z.ai's Coding Plan: What's Confirmed
https://www.digitalapplied.com/blog/glm-5-2-zai-flagship-coding-plan-release
Z.ai released GLM-5.2 today as its new flagship model, available immediately to every GLM Coding Plan tier — Lite, Pro, Max, and Team. The announcement leads with three claims: powerful coding capabilities, usable 1M-token context, and continued strength on long-horizon tasks.
Z.ai launches GLM-5.2 with a 1-million-token context window ahead of...
https://digg.com/tech/ii9xibgn
As our new flagship model, GLM-5.2 delivers powerful coding capabilities, usable 1M-context support, and continued strengths in long-horizon tasks. API and Chatbot services will launch next week.
GLM-5.2 (max) - Intelligence, Performance & Price Analysis
https://artificialanalysis.ai/models/glm-5-2
• Open weights model. • Released June 2026. GLM-5.2 (max) Intelligence, Performance & Price Analysis. API Provider Benchmarks.When evaluating the Intelligence Index, it generated 140M tokens, which is somewhat verbose in comparison to the average of 110M.
chat = AsyncChat(model, vendor_name='fireworks_ai', tools=[web_search])
r = await chat("What are the highlights of GLM 5.2?")
r--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) Cell In[23], line 2 1 chat = AsyncChat(model, vendor_name='fireworks_ai', tools=[web_search]) ----> 2 r = await chat("What are the highlights of GLM 5.2?") 3 r File /usr/local/lib/python3.12/site-packages/fastllm/chat.py:571, in __call__(self, msg, prefill, temp, think, search, stream, max_steps, final_prompt, return_all, **kwargs) 569 result_gen = self._call(msg, prefill, temp, think, search, stream, max_steps, 1, final_prompt, **kwargs) 570 if stream or return_all: return result_gen --> 571 async for res in result_gen: pass 572 return res File /usr/local/lib/python3.12/site-packages/fastllm/chat.py:525, in _call(self, msg, prefill, temp, think, search, stream, max_steps, step, final_prompt, tool_choice, max_tokens, n_workers, pause, tc_timeout, **kwargs) 523 self.hist.append(self.turn_msg) 524 async for o in self._call_cbs('after_acomplete'): yield o --> 525 self._track(self.turn_res) 526 yield res 528 self.toolloop, self.prompt, tmsg = False, None, None File /usr/local/lib/python3.12/site-packages/fastllm/chat.py:431, in AsyncChat._track(self, res) 430 def _track(self, res): --> 431 u = UsageStats.from_response(res) 432 u.cost *= (1 + self.markup) 433 self.use += u File /usr/local/lib/python3.12/site-packages/fastllm/chat.py:356, in UsageStats.from_response(cls, r) 350 @classmethod 351 def from_response(cls, r): 352 u = r.usage 353 return cls( 354 prompt_tokens=u.prompt_tokens or 0, completion_tokens=u.completion_tokens or 0, total_tokens=u.total_tokens or 0, 355 cached_tokens=u.cached_tokens or 0, cache_creation_tokens=u.cache_creation_tokens or 0, reasoning_tokens=u.reasoning_tokens or 0, --> 356 web_search_requests=search_count(r), cost=r.cost) File /usr/local/lib/python3.12/site-packages/fastllm/types.py:384, in cost(self) 382 api = api_registry.apis[self.api_name] 383 if not hasattr(api, 'cost'): raise NotImplementedError(f"API: {self.api_name} doesn't have a registered `cost` function in ns") --> 384 return api.cost(self.usage, meta) File /usr/local/lib/python3.12/site-packages/fastllm/openai_chat.py:203, in cost(usage, m) 201 in_txt = raw['prompt_tokens'] - cached - in_audio 202 out_txt = raw['completion_tokens'] - out_audio --> 203 cost = in_txt * m.input_cost_per_token + out_txt * m.output_cost_per_token 204 cost += cached * m.get('cache_read_input_token_cost', 0) 205 cost += in_audio * m.get('input_cost_per_audio_token', 0) File /usr/local/lib/python3.12/site-packages/fastcore/basics.py:275, in adict.__getattr__(self, k) --> 275 def __getattr__(self,k): return self[k] if k in self else stop(AttributeError(k)) File /usr/local/lib/python3.12/site-packages/fastcore/basics.py:242, in stop(e) 240 def stop(e=StopIteration): 241 "Raises exception `e` (by default `StopIteration`)" --> 242 raise e AttributeError: input_cost_per_token
The fastllm library is looking for cost per token of GLM 5.2 from prices_and_context_window.json but as this is recent release the model is not included in the json file. Therefore we will patch it for now with the fireworks cost
from fastllm import types
_orig_get_model_info = types.get_model_info
def _patched_get_model_info(model, vendor_name=None):
if model == 'accounts/fireworks/models/glm-5p2':
return {'input_cost_per_token': 1.4 / 1_000_000, 'output_cost_per_token': 4.4 / 1_000_000, 'cache_read_input_token_cost': 0.26 / 1_000_000}
return _orig_get_model_info(model, vendor_name)
types.get_model_info = _patched_get_model_infochat = AsyncChat(model, vendor_name='fireworks_ai', tools=[web_search])
r = await chat("What are the highlights of GLM 5.2?")
rThinking
- Analyze the Request:
- User asks for the highlights of “GLM 5.2”.
- I have already performed two web searches and retrieved snippets from 4 different sources (OpenLM.ai, DataCamp, AIMadeTools, Codersera, NovaLogiq).
- I need to summarize the findings based only on the provided search results.
- Analyze the Search Results:
- Source 1 (OpenLM.ai): “GLM-5.2 is our latest flagship model for coding and long-horizon tasks. It marks a substantial leap in long-horizon task capability over its predecessor GLM-5.1 and delivers that capability on a solid 1M-token context. It is pure open with an MIT open-source license — no regional limits, technical access without borders.”
- Source 2 (DataCamp): “GLM-5.2 from Z.ai offers a 1M token context window, high and max reasoning modes, and free access. Learn how to set it up in Claude Code, OpenClaw, and Cline.”
- Source 3 (AIMadeTools): “GLM-5.2 is Z.ai’s newest flagship coding model with a 1M token context window, two thinking modes, and MIT open weights now available on Hugging Face.”
- Source 4 (Codersera): “GLM 5.2 is the latest member of Zhipu AI / Z.ai’s flagship Chinese-developed model family, a direct successor to GLM-5.1… Z.ai is rolling 5.2 out as a coding-first model — every public claim around the launch is about agentic coding tasks, long-horizon refactors, and using the full million-token context…”
- Source 5 (NovaLogiq): “Chinese AI startup Z.ai (formerly Zhipu AI) announced the immediate release of GLM-5.2, a 753-billion parameter open-weights large language model (LLM) engineered specifically to dominate “long-horizon” autonomous coding and engineering tasks. Available immediately on Hugging Face, the Z.ai API, and more than 20 third-party coding environments, the model boasts a highly stable 1 [M context]… beats GPT-5.5 on multiple long-horizon coding benchmarks for 1/6th the cost.”
- Synthesize the Highlights:
- Developer: Z.ai (formerly Zhipu AI).
- Focus: Coding-first model, specifically designed for “long-horizon” autonomous coding, agentic tasks, and long refactors.
- Context Window: 1 million tokens (1M).
- Parameters: 753 billion parameters.
- Licensing: Pure open weights under the MIT license (no regional limits or borders).
- Reasoning Modes: Features two thinking modes (“high” and “max” reasoning modes).
- Performance: Claims to beat GPT-5.5 on multiple long-horizon coding benchmarks at 1/6th of the cost.
- Availability: Available on Hugging Face, Z.ai API, and over 20 third-party coding environments (including Claude Code, OpenClaw, and Cline). Free access mentioned.
- Predecessor: Successor to GLM-5.1, marking a substantial leap in long-horizon task capability.
- Format the Output:
- Present the highlights clearly using bullet points.
- Add a brief introductory and concluding sentence.
- Ensure all facts are directly supported by the search snippets.
- Review against constraints:
- “You have used all your tool calls for this turn. Please summarize your findings.” -> Yes, I will summarize the findings from the tool calls.
- No further tool calls needed as the search results provide a comprehensive answer.
Based on the search results, here are the key highlights of GLM-5.2, the latest flagship model from Z.ai (formerly Zhipu AI):
- Coding-First and Long-Horizon Tasks: GLM-5.2 is specifically engineered to dominate “long-horizon” autonomous coding, agentic tasks, and large-scale refactors. It marks a substantial leap in these capabilities compared to its predecessor, GLM-5.1.
- Massive 1M Token Context Window: The model delivers a highly stable 1 million-token context window, allowing it to process and utilize vast amounts of code and data simultaneously.
- 753-Billion Parameters: It is a massive 753-billion parameter open-weights large language model.
- MIT Open-Source License: GLM-5.2 is “pure open” under an MIT license, meaning there are no regional limits or technical access borders. The open weights are available on Hugging Face.
- Dual Reasoning Modes: The model features two distinct thinking modes—“high” and “max” reasoning—to tackle complex problems.
- Cost-Effective Performance: According to reports, GLM-5.2 beats GPT-5.5 on multiple long-horizon coding benchmarks while operating at roughly 1/6th of the cost.
- Wide Accessibility: It is available immediately on the Z.ai API, Hugging Face, and over 20 third-party coding environments, including Claude Code, OpenClaw, and Cline. It also offers free access.
In summary, GLM-5.2 stands out for its combination of a massive context window, open accessibility, and specialized focus on long-horizon coding and agentic engineering tasks.
- model:
accounts/fireworks/models/glm-5p2 - finish_reason:
stop - usage:
Usage(prompt_tokens=822, completion_tokens=1220, total_tokens=2042, cached_tokens=10, cache_creation_tokens=0, reasoning_tokens=0, raw={'prompt_tokens': 822, 'total_tokens': 2042, 'completion_tokens': 1220, 'prompt_tokens_details': {'cached_tokens': 10}})
Multiple Tool calling
I will define a function get_weather & get_lat_long for this tool calling experimentation
def get_lat_long(city: str # name of the city
) -> list:
"Get the lat long of a city"
response = httpx.get(f"https://geocoding-api.open-meteo.com/v1/search?name={city}&count=1&language=en&format=json")
res = response.json()["results"][0]
return res["latitude"], res["longitude"]get_lat_long("seattle")(47.60621, -122.33207)
def get_weather(lat:str, # latitude
long:str # longitude
) -> str:
"Returns the weather given the lat long of the city"
data = httpx.get(f"https://api.open-meteo.com/v1/forecast?latitude={lat}&longitude={long}¤t_weather=true").json()
temperature_unit = data['current_weather_units']['temperature']
temperature = data['current_weather']['temperature']
return f"The current temperature is {temperature} {temperature_unit}"get_weather(47.60621, -122.33207)'The current temperature is 20.9 °C'
chat = AsyncChat(model, vendor_name='fireworks_ai', tools=[get_weather, get_lat_long])
r = await chat("What is the weather of San Jose?", max_steps=10)
rThinking
The weather for San Jose has been retrieved. The current temperature is 22.6 °C.
The current weather in San Jose is 22.6 °C (approximately 72.7 °F). It’s a pleasant temperature! Is there anything else you’d like to know?
- model:
accounts/fireworks/models/glm-5p2 - finish_reason:
stop - usage:
Usage(prompt_tokens=438, completion_tokens=63, total_tokens=501, cached_tokens=351, cache_creation_tokens=0, reasoning_tokens=0, raw={'prompt_tokens': 438, 'total_tokens': 501, 'completion_tokens': 63, 'prompt_tokens_details': {'cached_tokens': 351}})
tool_calls = [msg for msg in chat.hist if msg.role == 'tool']
tool_calls[Msg(role='tool', content=[Part(type=<PartType.tool_result: 'tool_result'>, text='(37.33939, -121.89496)', data={'id': 'chatcmpl-tool-8aed18df97dd2035', 'name': 'get_lat_long', 'arguments': {'city': 'San Jose'}, 'server': False}), Part(type=<PartType.text: 'text'>, text='\n<system-reminder>After *EVERY* tool call result, no matter how small, briefly summarise in prose what you found, before continuing or calling another tool.</system-reminder>', data=None)]),
Msg(role='tool', content=[Part(type=<PartType.tool_result: 'tool_result'>, text='The current temperature is 22.6 °C', data={'id': 'chatcmpl-tool-a50c7419f8815589', 'name': 'get_weather', 'arguments': {'lat': '37.33939', 'long': '-121.89496'}, 'server': False}), Part(type=<PartType.text: 'text'>, text='\n<system-reminder>After *EVERY* tool call result, no matter how small, briefly summarise in prose what you found, before continuing or calling another tool.</system-reminder>', data=None)])]
Note how GLM 5.2 planned the tool calls: it realized it needed coordinates before it could ask for weather, so it called get_lat_long first and then chained into get_weather. This two-step reasoning is not hardcoded in the prompt—the model itself figured it out.
How the tool call is happening behind the scenes?
1 level deeper
from toolslm.funccall import get_schema, call_func
from types import SimpleNamespaceWe will first get the schema of get_lat_long and get_weather
get_lat_long_schema = get_schema(get_lat_long, pname='parameters')
get_lat_long_schema{'name': 'get_lat_long',
'description': 'Get the lat long of a city\n\nReturns:\n- type: array',
'parameters': {'type': 'object',
'properties': {'city': {'description': 'name of the city',
'type': 'string'}},
'required': ['city']}}
get_weather_schema = get_schema(get_weather, pname='parameters')
get_weather_schema{'name': 'get_weather',
'description': 'Returns the weather given the lat long of the city\n\nReturns:\n- type: string',
'parameters': {'type': 'object',
'properties': {'lat': {'description': 'latitude', 'type': 'string'},
'long': {'description': 'longitude', 'type': 'string'}},
'required': ['lat', 'long']}}
tools = [{"type": "function", "function": get_weather_schema}, {"type": "function", "function": get_lat_long_schema}]msgs = [user("What's the weather in San Jose?")]
r = await acomplete(msgs, model=model, vendor_name='fireworks_ai', max_tokens=4096, tools=tools)
rThinking
The user wants to know the weather in San Jose. I need to first get the lat/long of San Jose, then use that to get the weather.
Let me get the coordinates for San Jose first, and then check the weather.
🔧 get_lat_long({‘city’: ‘San Jose’})
- model:
accounts/fireworks/models/glm-5p2 - finish_reason:
tool_calls - usage:
Usage(prompt_tokens=267, completion_tokens=62, total_tokens=329, cached_tokens=266, cache_creation_tokens=0, reasoning_tokens=0, raw={'prompt_tokens': 267, 'total_tokens': 329, 'completion_tokens': 62, 'prompt_tokens_details': {'cached_tokens': 266}})
tool_data = r.message.content[-1].data; tool_data{'index': 0,
'type': 'function',
'name': 'get_lat_long',
'id': 'chatcmpl-tool-a2cbe71a1da55e0f',
'arguments': {'city': 'San Jose'},
'server': False}
In the response, as you can see the LLM decided to call the tool get_lat_long, we will call it and return the results to the LLM.
result = globals()[tool_data['name']](**tool_data['arguments'])
result(37.33939, -121.89496)
tc = SimpleNamespace(**tool_data)
tool_msg = mk_tool_res_msg([tc], [result])
msgs2 = msgs + [r.message, tool_msg]
r2 = await acomplete(msgs2, model=model, vendor_name='fireworks_ai', tools=tools, max_tokens=4096)
r2Thinking
Got the lat/long for San Jose. Now I’ll get the weather using those coordinates.
Now let me get the weather for San Jose.
🔧 get_weather({‘lat’: ‘37.33939’, ‘long’: ‘-121.89496’})
- model:
accounts/fireworks/models/glm-5p2 - finish_reason:
tool_calls - usage:
Usage(prompt_tokens=347, completion_tokens=56, total_tokens=403, cached_tokens=285, cache_creation_tokens=0, reasoning_tokens=0, raw={'prompt_tokens': 347, 'total_tokens': 403, 'completion_tokens': 56, 'prompt_tokens_details': {'cached_tokens': 285}})
Now we will call the get_weather
tool_data = r2.message.content[-1].data; tool_data{'index': 0,
'type': 'function',
'name': 'get_weather',
'id': 'chatcmpl-tool-926558be86bc6ff4',
'arguments': {'lat': '37.33939', 'long': '-121.89496'},
'server': False}
result = globals()[tool_data['name']](**tool_data['arguments'])
result'The current temperature is 22.5 °C'
tc = SimpleNamespace(**tool_data)
tool_msg = mk_tool_res_msg([tc], [result])
msgs3 = msgs2 + [r2.message, tool_msg]
r3 = await acomplete(msgs3, model=model, vendor_name='fireworks_ai', tools=tools, max_tokens=4096)
r3Thinking
The weather result shows the current temperature in San Jose is 22.5 °C. Let me present this to the user.
The current weather in San Jose is 22.5 °C (about 72.5 °F). It’s looking quite pleasant! Is there anything else you’d like to know?
- model:
accounts/fireworks/models/glm-5p2 - finish_reason:
stop - usage:
Usage(prompt_tokens=417, completion_tokens=67, total_tokens=484, cached_tokens=346, cache_creation_tokens=0, reasoning_tokens=0, raw={'prompt_tokens': 417, 'total_tokens': 484, 'completion_tokens': 67, 'prompt_tokens_details': {'cached_tokens': 346}})
AsyncChat is essentially a while-loop that executes tools until the model returns finish_reason='stop'. We can implement that loop ourselves in a few lines:
async def chatty(prompt, tools=None, max_tokens = 4096):
tools = list(map(lambda x: {"type": "function", "function": get_schema(x, pname='parameters')}, tools))
msgs = [user(prompt)]
r = await acomplete(msgs, model=model, vendor_name='fireworks_ai', max_tokens = max_tokens, tools=tools)
while r.finish_reason != 'stop':
if r.finish_reason == 'tool_calls':
tool_data = r.message.content[-1].data
result = globals()[tool_data['name']](**tool_data['arguments'])
tc = SimpleNamespace(**tool_data)
tool_msg = mk_tool_res_msg([tc], [result])
msgs.extend([r.message, tool_msg])
else:
msgs.extend([r.message])
r = await acomplete(msgs, model=model, vendor_name='fireworks_ai', tools=tools, max_tokens=max_tokens)
return rr = await chatty("How is the weather in Portland?", tools = [get_weather, get_lat_long])
rThinking
The weather in Portland is 23.1 °C. Let me present this to the user.
The current weather in Portland, OR is 23.1 °C (approximately 73.6 °F). It’s looking quite pleasant! ☀️
Is there anything else you’d like to know?
- model:
accounts/fireworks/models/glm-5p2 - finish_reason:
stop - usage:
Usage(prompt_tokens=416, completion_tokens=68, total_tokens=484, cached_tokens=268, cache_creation_tokens=0, reasoning_tokens=0, raw={'prompt_tokens': 416, 'total_tokens': 484, 'completion_tokens': 68, 'prompt_tokens_details': {'cached_tokens': 268}})
Image as input
The glm-5p2 text endpoint does not support image inputs. If you need vision capabilities, use the GLM-5V-Turbo model instead.
Structured output
r = await acomplete([user("Give me info about Pike Place Market in Seattle as a JSON object with fields: name, founded, location, famous_for")], model=model, vendor_name='fireworks_ai', max_tokens=1024, response_format={"type": "json_object"})
rThinking
Analyze the Request:
- Topic: Pike Place Market in Seattle.
- Output Format: JSON object.
- Required Fields:
name,founded,location,famous_for.
Gather Information:
- Name: Pike Place Market
- Founded: 1907 (August 17, 1907)
- Location: Seattle, Washington, USA (specifically downtown Seattle, Elliott Bay waterfront)
- Famous_for: Fish throwing (flying fish), the original Starbucks coffee shop, local produce, crafts, flowers, gum wall.
Construct JSON Structure:
name: “Pike Place Market”founded: 1907 (integer or string, string might be safer or more descriptive, let’s use 1907 as an integer or “1907” string. Let’s use integer1907).location: “Seattle, Washington, USA” (or more detailed: “Downtown Seattle, Washington, USA, overlooking Elliott Bay”)famous_for: Array of strings or a single string. Array is usually better for multiple things. Let’s use an array: [“Flying fish at Pike Place Fish”, “Original Starbucks location”, “Fresh local produce and flowers”, “The Gum Wall”, “Local artisans and crafts”] or a comma-separated string. The prompt says “famous_for” (singular-ish, but can hold multiple). Let’s make it an array for better JSON structure, or a descriptive string. Array is cleaner.
Refine JSON Data:
{ "name": "Pike Place Market", "founded": 1907, "location": "Downtown Seattle, Washington, USA", "famous_for": [ "Flying fish at Pike Place Fish", "The original Starbucks coffee shop", "Fresh local produce, flowers, and artisan crafts", "The Market Gum Wall", "Rachel the Piggy Bank" ] }Review against constraints:
- JSON object? Yes.
- Fields:
name,founded,location,famous_for? Yes. - Accurate info? Yes.
Final Output Generation: (Wrap in markdown code block for clean presentation).
{
"name": "Pike Place Market",
"founded": 1907,
"location": "Downtown Seattle, Washington, USA, overlooking the Elliott Bay waterfront",
"famous_for": [
"Flying fish at the Pike Place Fish Market",
"The original Starbucks coffee shop",
"Fresh local produce and flower vendors",
"The Market Gum Wall",
"Rachel the Pig (a large bronze piggy bank that serves as the market's mascot)"
]
}- model:
accounts/fireworks/models/glm-5p2 - finish_reason:
stop - usage:
Usage(prompt_tokens=36, completion_tokens=630, total_tokens=666, cached_tokens=9, cache_creation_tokens=0, reasoning_tokens=0, raw={'prompt_tokens': 36, 'total_tokens': 666, 'completion_tokens': 630, 'prompt_tokens_details': {'cached_tokens': 9}})
print(r.message.content[1].text)```json
{
"name": "Pike Place Market",
"founded": 1907,
"location": "Downtown Seattle, Washington, USA, overlooking the Elliott Bay waterfront",
"famous_for": [
"Flying fish at the Pike Place Fish Market",
"The original Starbucks coffee shop",
"Fresh local produce and flower vendors",
"The Market Gum Wall",
"Rachel the Pig (a large bronze piggy bank that serves as the market's mascot)"
]
}
```
Structured output does not appear to be strictly enforced by GLM 5.2 or the Fireworks endpoint.
Large Context Window
GLM 5.2 provides context window size of 1M, lets check it out
text = httpx.get("https://www.gutenberg.org/files/2600/2600-0.txt").text
print(f"Characters: {len(text):,}")Characters: 3,293,552
We can check the approximate token accounts using tiktoken
import tiktoken
enc = tiktoken.get_encoding("cl100k_base")
tokens = enc.encode(text)
print(f"Tokens: {len(tokens):,}")Tokens: 780,489
The following call will use around 780k tokens, so it will take time and cost a bit on your fireworks account
r = await acomplete(
[user(f"Here is the full text of War and Peace:\n\n{text}\n\nIn one sentence: what is the central theme of this book?")],
model=model, vendor_name='fireworks_ai', max_tokens=1024
)
rThinking
The user is asking me to summarize the central theme of “War and Peace” by Leo Tolstoy in one sentence. This is a very long text - it’s the full novel. I’ve read through enough of it to understand the major themes and plot points.
The novel covers: - The Napoleonic Wars and their impact on Russian society - The lives of several aristocratic families (Bezukhov, Bolkonsky, Rostov, Kuragin) - Pierre’s spiritual journey - Andrew’s search for meaning and his death - Natasha’s growth from girlhood to womanhood and motherhood - The invasion of Russia by Napoleon and the retreat - The burning of Moscow - Tolstoy’s philosophical reflections on history, free will, determinism, and the role of great men vs. the masses
The central theme that runs throughout is the tension between the forces of history/war (which Tolstoy argues are driven by the collective will of the people, not by great men) and the personal lives, loves, and spiritual searches of individuals seeking meaning and happiness. Tolstoy explores how individuals navigate their freedom within the constraints of historical necessity, and ultimately suggests that true meaning comes from love, family, and spiritual connection rather than glory, ambition, or intellectual abstraction.
A good one-sentence summary would capture this dual focus on the public/historical and the personal/spiritual dimensions.
The central theme of War and Peace is the tension between the vast, impersonal forces of history that sweep individuals along—war, social upheaval, and the movements of nations—and the intimate personal searches for love, meaning, and spiritual truth that define individual lives, ultimately suggesting that genuine happiness and wisdom are found not in glory, ambition, or abstract philosophy, but in humble human connection, family, and faith in a transcendent order.
- model:
accounts/fireworks/models/glm-5p2 - finish_reason:
stop - usage:
Usage(prompt_tokens=778615, completion_tokens=383, total_tokens=778998, cached_tokens=10, cache_creation_tokens=0, reasoning_tokens=0, raw={'prompt_tokens': 778615, 'total_tokens': 778998, 'completion_tokens': 383, 'prompt_tokens_details': {'cached_tokens': 10}})
r.cost1.0917348
What we learned
- GLM 5.2 follows instructions well and shows its reasoning in a
<Thinking>block - It correctly orchestrates tool, in this case here it chain the functions for getting the geo codes and getting the weather thereafter
- The ~780k token story fit in a single prompt producing a clear summary and costing around ~$1
- Vision is not currently supported