Buckets:
| import{s as Il,n as ol,o as cl}from"../chunks/scheduler.ad421418.js";import{S as il,i as rl,e as p,s as n,c as y,h as ul,a as w,d as M,b as t,f as wl,j as e,g as C,k as Cl,l as Al,m as a,n as U,t as J,o as j,p as T}from"../chunks/index.4dad9295.js";import{C as hl,H as o,E as dl}from"../chunks/MermaidChart.svelte_svelte_type_style_lang.189cd3c7.js";import{C as I}from"../chunks/CodeBlock.6fe5e04b.js";function ml(Ls){let c,ys,ns,es,i,Us,r,Js,u,Ks="This section adds two tools — <code>web_fetch</code> and <code>hf_search</code> — and runs the harness against several models.",js,A,Ts,h,Ps="Add to your nano_harness.py:",ps,d,ws,m,Os="A byte cap prevents loading huge responses, the <code>timeout</code> stops the request from hanging, and errors are returned as strings so the agent can react.",Cs,b,Ds="<strong>In system prompt:</strong>",Is,B,os,E,sl="<strong>Example usage:</strong>",cs,f,is,Z,rs,Q,ll="Add to nano_harness.py:",us,g,As,V,Ml="The API key stays in the environment, results are capped by <code>limit</code>, and errors are caught and returned.",hs,k,al="<strong>In system prompt:</strong>",ds,q,ms,G,nl="<strong>Example usage:</strong>",bs,N,Bs,S,Es,X,tl="Create <code>nano_harness_extended.py</code> with all tools. This version uses the Responses API so the same loop works against the Hugging Face router and a direct OpenAI endpoint without changing the control flow.",fs,R,Zs,_,yl="This extended version keeps the same safety model as the base harness: <code>write_file</code> is still disabled until you flip <code>ALLOW_WRITE</code>, <code>exec()</code> runs without Python’s default builtins, and each loop feeds back stdout, stderr, a final answer, or a structured error string.",Qs,W,gs,F,el="Run it against <code>zai-org/GLM-5.1</code> on Hugging Face Inference Providers:",Vs,z,ks,H,Ul="Inference Providers route the request to a backing provider automatically. If you want to try a different HF model, set <code>NANO_MODEL</code> to any text-generation repo that’s enabled on Inference Providers — the loop and tool set stay the same.",qs,x,Gs,Y,Jl="Add these tools yourself:",Ns,$,Ss,v,Xs,L,Rs,K,_s,P,Ws,O,Fs,D,jl="Add these to the harness and watch how the agent’s traces change.",zs,ss,Hs,ls,Tl="Tools connect the agent to the world. Every tool needs size limits, timeouts, and informative error strings so the agent can adapt. The same loop runs unchanged against any model on Hugging Face Inference Providers.",xs,Ms,pl="Next, the unit 6 quiz.",Ys,as,$s,ts,vs;return i=new hl({props:{containerStyle:"float: right; margin-left: 10px; display: inline-flex; position: relative; z-index: 10;"}}),r=new o({props:{title:"Hands-On: Extending Nano Harness",local:"hands-on-extending-nano-harness",headingTag:"h1"}}),A=new o({props:{title:"Extension 1: Add web_fetch Tool",local:"extension-1-add-webfetch-tool",headingTag:"h2"}}),d=new I({props:{code:"aW1wb3J0JTIwdXJsbGliLnJlcXVlc3QlMEFpbXBvcnQlMjB1cmxsaWIuZXJyb3IlMEElMEFkZWYlMjB3ZWJfZmV0Y2godXJsJTJDJTIwbWF4X2J5dGVzJTNEMTAwMDApJTNBJTBBJTIwJTIwJTIwJTIwJTIyJTIyJTIyRmV0Y2glMjB3ZWIlMjBwYWdlJTIwY29udGVudCUyMHdpdGglMjBzaXplJTIwbGltaXQuJTIyJTIyJTIyJTBBJTIwJTIwJTIwJTIwdHJ5JTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwd2l0aCUyMHVybGxpYi5yZXF1ZXN0LnVybG9wZW4odXJsJTJDJTIwdGltZW91dCUzRFRJTUVPVVRfUyklMjBhcyUyMHJlc3BvbnNlJTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwY29udGVudCUyMCUzRCUyMHJlc3BvbnNlLnJlYWQobWF4X2J5dGVzJTIwJTJCJTIwMSklMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBpZiUyMGxlbihjb250ZW50KSUyMCUzRSUyMG1heF9ieXRlcyUzQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGNvbnRlbnQlMjAlM0QlMjBjb250ZW50JTVCJTNBbWF4X2J5dGVzJTVEJTIwJTJCJTIwYiUyMiU1Q24uLi4lNUJ0cnVuY2F0ZWQlNUQlMjIlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjByZXR1cm4lMjBjb250ZW50LmRlY29kZSglMjJ1dGYtOCUyMiUyQyUyMGVycm9ycyUzRCUyMnJlcGxhY2UlMjIpJTBBJTIwJTIwJTIwJTIwZXhjZXB0JTIwdXJsbGliLmVycm9yLlVSTEVycm9yJTIwYXMlMjBlJTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmV0dXJuJTIwZiUyMkVycm9yJTNBJTIwRmFpbGVkJTIwdG8lMjBmZXRjaCUyMCU3QnVybCU3RCUzQSUyMCU3QmUlN0QlMjIlMEElMjAlMjAlMjAlMjBleGNlcHQlMjBFeGNlcHRpb24lMjBhcyUyMGUlM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjByZXR1cm4lMjBmJTIyRXJyb3IlM0ElMjAlN0J0eXBlKGUpLl9fbmFtZV9fJTdEJTNBJTIwJTdCc3RyKGUpJTdEJTIy",highlighted:`<span class="hljs-keyword">import</span> urllib.request | |
| <span class="hljs-keyword">import</span> urllib.error | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">web_fetch</span>(<span class="hljs-params">url, max_bytes=<span class="hljs-number">10000</span></span>): | |
| <span class="hljs-string">"""Fetch web page content with size limit."""</span> | |
| <span class="hljs-keyword">try</span>: | |
| <span class="hljs-keyword">with</span> urllib.request.urlopen(url, timeout=TIMEOUT_S) <span class="hljs-keyword">as</span> response: | |
| content = response.read(max_bytes + <span class="hljs-number">1</span>) | |
| <span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(content) > max_bytes: | |
| content = content[:max_bytes] + <span class="hljs-string">b"\\n...[truncated]"</span> | |
| <span class="hljs-keyword">return</span> content.decode(<span class="hljs-string">"utf-8"</span>, errors=<span class="hljs-string">"replace"</span>) | |
| <span class="hljs-keyword">except</span> urllib.error.URLError <span class="hljs-keyword">as</span> e: | |
| <span class="hljs-keyword">return</span> <span class="hljs-string">f"Error: Failed to fetch <span class="hljs-subst">{url}</span>: <span class="hljs-subst">{e}</span>"</span> | |
| <span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> e: | |
| <span class="hljs-keyword">return</span> <span class="hljs-string">f"Error: <span class="hljs-subst">{<span class="hljs-built_in">type</span>(e).__name__}</span>: <span class="hljs-subst">{<span class="hljs-built_in">str</span>(e)}</span>"</span>`,wrap:!1}}),B=new I({props:{code:"",highlighted:`SYSTEM_PROMPT = <span class="hljs-string">""" | |
| ... | |
| Tools: | |
| - web_fetch(url, max_bytes=10000) → fetch webpage | |
| ... | |
| """</span>`,wrap:!1}}),f=new I({props:{code:"JTIzJTIwQWdlbnQlMjB3cml0ZXMlM0ElMEFjb250ZW50JTIwJTNEJTIwd2ViX2ZldGNoKCUyMmh0dHBzJTNBJTJGJTJGaHVnZ2luZ2ZhY2UuY28lMkYlMjIpJTBBJTBBJTIzJTIwT3IlMjB3aXRoJTIwc2l6ZSUyMGxpbWl0JTNBJTBBY29udGVudCUyMCUzRCUyMHdlYl9mZXRjaCglMjJodHRwcyUzQSUyRiUyRmh1Z2dpbmdmYWNlLmNvJTJGJTIyJTJDJTIwbWF4X2J5dGVzJTNENTAwMCk=",highlighted:`<span class="hljs-comment"># Agent writes:</span> | |
| content = web_fetch(<span class="hljs-string">"https://huggingface.co/"</span>) | |
| <span class="hljs-comment"># Or with size limit:</span> | |
| content = web_fetch(<span class="hljs-string">"https://huggingface.co/"</span>, max_bytes=<span class="hljs-number">5000</span>)`,wrap:!1}}),Z=new o({props:{title:"Extension 2: Add hf_search Tool",local:"extension-2-add-hfsearch-tool",headingTag:"h2"}}),g=new I({props:{code:"ZGVmJTIwaGZfc2VhcmNoKHF1ZXJ5JTJDJTIwcmVzb3VyY2VfdHlwZSUzRCUyMm1vZGVscyUyMiUyQyUyMGxpbWl0JTNENSklM0ElMEElMjAlMjAlMjAlMjAlMjIlMjIlMjJTZWFyY2glMjBIdWdnaW5nJTIwRmFjZSUyMEh1YiUyMChyZXF1aXJlcyUyMEhGX1RPS0VOKS4lMjIlMjIlMjIlMEElMjAlMjAlMjAlMjBpZiUyMG5vdCUyMEFQSV9LRVklM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjByZXR1cm4lMjAlMjJFcnJvciUzQSUyMEhGX1RPS0VOJTIwbm90JTIwc2V0LiUyMENhbid0JTIwYWNjZXNzJTIwSHVnZ2luZyUyMEZhY2UlMjBBUEkuJTIyJTBBJTIwJTIwJTIwJTIwJTBBJTIwJTIwJTIwJTIwdHJ5JTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwdXJsJTIwJTNEJTIwZiUyMmh0dHBzJTNBJTJGJTJGaHVnZ2luZ2ZhY2UuY28lMkZhcGklMkYlN0JyZXNvdXJjZV90eXBlJTdEJTIyJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcGFyYW1zJTIwJTNEJTIwZiUyMiUzRnNlYXJjaCUzRCU3QnF1ZXJ5JTdEJTI2bGltaXQlM0QlN0JsaW1pdCU3RCUyMiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHJlcSUyMCUzRCUyMHVybGxpYi5yZXF1ZXN0LlJlcXVlc3QoJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwdXJsJTIwJTJCJTIwcGFyYW1zJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwaGVhZGVycyUzRCU3QiUyMkF1dGhvcml6YXRpb24lMjIlM0ElMjBmJTIyQmVhcmVyJTIwJTdCQVBJX0tFWSU3RCUyMiU3RCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCklMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjB3aXRoJTIwdXJsbGliLnJlcXVlc3QudXJsb3BlbihyZXElMkMlMjB0aW1lb3V0JTNEVElNRU9VVF9TKSUyMGFzJTIwcmVzcG9uc2UlM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBkYXRhJTIwJTNEJTIwanNvbi5sb2FkcyhyZXNwb25zZS5yZWFkKCkpJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIzJTIwRm9ybWF0JTIwcmVzdWx0cyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHJlc3VsdHMlMjAlM0QlMjAlNUIlNUQlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBmb3IlMjBpdGVtJTIwaW4lMjBkYXRhJTVCJTNBbGltaXQlNUQlM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjByZXN1bHRzLmFwcGVuZCglN0IlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJpZCUyMiUzQSUyMGl0ZW0uZ2V0KCUyMmlkJTIyKSUyQyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMmRvd25sb2FkcyUyMiUzQSUyMGl0ZW0uZ2V0KCUyMmRvd25sb2FkcyUyMiUyQyUyMDApJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIyZGVzY3JpcHRpb24lMjIlM0ElMjBpdGVtLmdldCglMjJkZXNjcmlwdGlvbiUyMiUyQyUyMCUyMiUyMiklNUIlM0EyMDAlNUQlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlN0QpJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmV0dXJuJTIwcmVzdWx0cyUwQSUyMCUyMCUyMCUyMCUwQSUyMCUyMCUyMCUyMGV4Y2VwdCUyMEV4Y2VwdGlvbiUyMGFzJTIwZSUzQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHJldHVybiUyMGYlMjJFcnJvciUzQSUyMCU3QnR5cGUoZSkuX19uYW1lX18lN0QlM0ElMjAlN0JzdHIoZSklN0QlMjI=",highlighted:`<span class="hljs-keyword">def</span> <span class="hljs-title function_">hf_search</span>(<span class="hljs-params">query, resource_type=<span class="hljs-string">"models"</span>, limit=<span class="hljs-number">5</span></span>): | |
| <span class="hljs-string">"""Search Hugging Face Hub (requires HF_TOKEN)."""</span> | |
| <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> API_KEY: | |
| <span class="hljs-keyword">return</span> <span class="hljs-string">"Error: HF_TOKEN not set. Can't access Hugging Face API."</span> | |
| <span class="hljs-keyword">try</span>: | |
| url = <span class="hljs-string">f"https://huggingface.co/api/<span class="hljs-subst">{resource_type}</span>"</span> | |
| params = <span class="hljs-string">f"?search=<span class="hljs-subst">{query}</span>&limit=<span class="hljs-subst">{limit}</span>"</span> | |
| req = urllib.request.Request( | |
| url + params, | |
| headers={<span class="hljs-string">"Authorization"</span>: <span class="hljs-string">f"Bearer <span class="hljs-subst">{API_KEY}</span>"</span>} | |
| ) | |
| <span class="hljs-keyword">with</span> urllib.request.urlopen(req, timeout=TIMEOUT_S) <span class="hljs-keyword">as</span> response: | |
| data = json.loads(response.read()) | |
| <span class="hljs-comment"># Format results</span> | |
| results = [] | |
| <span class="hljs-keyword">for</span> item <span class="hljs-keyword">in</span> data[:limit]: | |
| results.append({ | |
| <span class="hljs-string">"id"</span>: item.get(<span class="hljs-string">"id"</span>), | |
| <span class="hljs-string">"downloads"</span>: item.get(<span class="hljs-string">"downloads"</span>, <span class="hljs-number">0</span>), | |
| <span class="hljs-string">"description"</span>: item.get(<span class="hljs-string">"description"</span>, <span class="hljs-string">""</span>)[:<span class="hljs-number">200</span>] | |
| }) | |
| <span class="hljs-keyword">return</span> results | |
| <span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> e: | |
| <span class="hljs-keyword">return</span> <span class="hljs-string">f"Error: <span class="hljs-subst">{<span class="hljs-built_in">type</span>(e).__name__}</span>: <span class="hljs-subst">{<span class="hljs-built_in">str</span>(e)}</span>"</span>`,wrap:!1}}),q=new I({props:{code:"",highlighted:`SYSTEM_PROMPT = <span class="hljs-string">""" | |
| ... | |
| Tools: | |
| - hf_search(query, resource_type='models', limit=10) → search HF | |
| ... | |
| """</span>`,wrap:!1}}),N=new I({props:{code:"JTIzJTIwQWdlbnQlMjB3cml0ZXMlM0ElMEFyZXN1bHRzJTIwJTNEJTIwaGZfc2VhcmNoKCUyMmJlcnQlMjIlMkMlMjByZXNvdXJjZV90eXBlJTNEJTIybW9kZWxzJTIyJTJDJTIwbGltaXQlM0Q1KSUwQWZpbmFsX2Fuc3dlcihyZXN1bHRzKQ==",highlighted:`<span class="hljs-comment"># Agent writes:</span> | |
| results = hf_search(<span class="hljs-string">"bert"</span>, resource_type=<span class="hljs-string">"models"</span>, limit=<span class="hljs-number">5</span>) | |
| final_answer(results)`,wrap:!1}}),S=new o({props:{title:"Full Extended Example",local:"full-extended-example",headingTag:"h2"}}),R=new I({props:{code:"JTIzISUyRnVzciUyRmJpbiUyRmVudiUyMHB5dGhvbjMlMEFpbXBvcnQlMjBpbyUwQWltcG9ydCUyMGpzb24lMEFpbXBvcnQlMjBvcyUwQWltcG9ydCUyMHJlJTBBaW1wb3J0JTIwc3VicHJvY2VzcyUwQWltcG9ydCUyMHVybGxpYi5lcnJvciUwQWltcG9ydCUyMHVybGxpYi5yZXF1ZXN0JTBBZnJvbSUyMGNvbnRleHRsaWIlMjBpbXBvcnQlMjByZWRpcmVjdF9zdGRlcnIlMkMlMjByZWRpcmVjdF9zdGRvdXQlMEFmcm9tJTIwcGF0aGxpYiUyMGltcG9ydCUyMFBhdGglMEFmcm9tJTIwb3BlbmFpJTIwaW1wb3J0JTIwT3BlbkFJJTBBJTBBJTIzJTIwQ29uZmlndXJhdGlvbiUwQVRBU0slMjAlM0QlMjAlMjJTZWFyY2glMjBmb3IlMjBiZXJ0JTIwbW9kZWxzJTIwb24lMjBIdWdnaW5nJTIwRmFjZSUyMGFuZCUyMHN1bW1hcml6ZSUyMHRvcCUyMDMuJTIyJTBBTU9ERUwlMjAlM0QlMjBvcy5nZXRlbnYoJTIyTkFOT19NT0RFTCUyMiUyQyUyMCUyMnphaS1vcmclMkZHTE0tNS4xJTIyKSUwQUJBU0VfVVJMJTIwJTNEJTIwb3MuZ2V0ZW52KCUyMk9QRU5BSV9CQVNFX1VSTCUyMiUyQyUyMCUyMmh0dHBzJTNBJTJGJTJGcm91dGVyLmh1Z2dpbmdmYWNlLmNvJTJGdjElMjIpJTBBQVBJX0tFWSUyMCUzRCUyMG9zLmdldGVudiglMjJIRl9UT0tFTiUyMiklMjBvciUyMG9zLmdldGVudiglMjJPUEVOQUlfQVBJX0tFWSUyMiUyQyUyMCUyMiUyMiklMEFXT1JLU1BBQ0UlMjAlM0QlMjBzdHIoUGF0aC5jd2QoKSklMEFNQVhfU1RFUFMlMjAlM0QlMjA1MCUwQVRJTUVPVVRfUyUyMCUzRCUyMDMwJTBBTUFYX0NIQVJTJTIwJTNEJTIwODAwMCUwQUFMTE9XX1dSSVRFJTIwJTNEJTIwRmFsc2UlMEFBTExPV19DT01NQU5EUyUyMCUzRCUyMCU1QiUyMmxzJTIyJTJDJTIwJTIyY2F0JTIyJTJDJTIwJTIycHdkJTIyJTJDJTIwJTIyZWNobyUyMiUyQyUyMCUyMmhlYWQlMjIlMkMlMjAlMjJ0YWlsJTIyJTJDJTIwJTIyd2MlMjIlMkMlMjAlMjJyZyUyMiU1RCUwQVRFTVBFUkFUVVJFJTIwJTNEJTIwMC4yJTBBJTBBU1lTVEVNX1BST01QVCUyMCUzRCUyMGYlMjIlMjIlMjJZb3UlMjBhcmUlMjBhJTIwY29kZS1maXJzdCUyMGFnZW50LiUwQVJlcGx5JTIwd2l0aCUyMGV4ZWN1dGFibGUlMjBQeXRob24lMjBvbmx5LiUwQSUwQVRvb2xzJTNBJTBBJTIwJTIwLSUyMGxpc3RfZGlyKHBhdGglM0QnLicpJTIwJUUyJTg2JTkyJTIwbGlzdCUyMGZpbGVzJTBBJTIwJTIwLSUyMHJlYWRfZmlsZShwYXRoJTJDJTIwbWF4X2NoYXJzJTNENDAwMCklMjAlRTIlODYlOTIlMjByZWFkJTIwZmlsZSUwQSUyMCUyMC0lMjB3cml0ZV9maWxlKHBhdGglMkMlMjBjb250ZW50KSUyMCVFMiU4NiU5MiUyMHdyaXRlJTIwZmlsZSUyMChvbmx5JTIwaWYlMjBBTExPV19XUklURSUzRFRydWUpJTBBJTIwJTIwLSUyMGV4ZWNfY21kKGFyZ3MpJTIwJUUyJTg2JTkyJTIwcnVuJTIwYWxsb3dlZCUyMGNvbW1hbmQlMEElMjAlMjAtJTIwd2ViX2ZldGNoKHVybCUyQyUyMG1heF9ieXRlcyUzRDEwMDAwKSUyMCVFMiU4NiU5MiUyMGZldGNoJTIwd2VicGFnZSUwQSUyMCUyMC0lMjBoZl9zZWFyY2gocXVlcnklMkMlMjBsaW1pdCUzRDUpJTIwJUUyJTg2JTkyJTIwc2VhcmNoJTIwSEYlMjBIdWIlMEElMjAlMjAlMEFBbGxvd2VkJTIwY29tbWFuZHMlM0ElMjAlN0JBTExPV19DT01NQU5EUyU3RCUwQVdyaXRlcyUyMGVuYWJsZWQlM0ElMjAlN0JBTExPV19XUklURSU3RCUwQSUwQVdoZW4lMjBkb25lJTJDJTIwY2FsbCUyMGZpbmFsX2Fuc3dlcihyZXN1bHQpLiUwQU91dHB1dCUyMG9ubHklMjBQeXRob24lMjBjb2RlJTJDJTIwbm8lMjBwcm9zZS4lMjIlMjIlMjIlMEElMEFkZWYlMjBjbGlwKHglMkMlMjBuJTNETUFYX0NIQVJTKSUzQSUwQSUyMCUyMCUyMCUyMHMlMjAlM0QlMjBzdHIoeCklMEElMjAlMjAlMjAlMjByZXR1cm4lMjBzJTVCJTNBbiU1RCUyMCUyQiUyMGYlMjIlNUNuLi4uJTVCdHJ1bmNhdGVkJTVEJTIyJTIwaWYlMjBsZW4ocyklMjAlM0UlMjBuJTIwZWxzZSUyMHMlMEElMEFkZWYlMjBtYWluKCklM0ElMEElMjAlMjAlMjAlMjB3cyUyMCUzRCUyMFBhdGgoV09SS1NQQUNFKS5yZXNvbHZlKCklMEElMjAlMjAlMjAlMjBkb25lJTIwJTNEJTIwRmFsc2UlMEElMjAlMjAlMjAlMjBmaW5hbF9yZXN1bHQlMjAlM0QlMjBOb25lJTBBJTIwJTIwJTIwJTIwJTBBJTIwJTIwJTIwJTIwZGVmJTIwc2FmZV9wYXRoKHBhdGgpJTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcCUyMCUzRCUyMCh3cyUyMCUyRiUyMHBhdGgpLnJlc29sdmUoKSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHRyeSUzQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHAucmVsYXRpdmVfdG8od3MpJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwZXhjZXB0JTIwVmFsdWVFcnJvciUzQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHJhaXNlJTIwVmFsdWVFcnJvcihmJTIyUGF0aCUyMGVzY2FwZXMlMjB3b3Jrc3BhY2UlM0ElMjAlN0JwYXRoJTdEJTIyKSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHJldHVybiUyMHAlMEElMjAlMjAlMjAlMjAlMEElMjAlMjAlMjAlMjBkZWYlMjBsaXN0X2RpcihwYXRoJTNEJTIyLiUyMiklM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBwJTIwJTNEJTIwc2FmZV9wYXRoKHBhdGgpJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmV0dXJuJTIwc29ydGVkKHgubmFtZSUyMCUyQiUyMCglMjIlMkYlMjIlMjBpZiUyMHguaXNfZGlyKCklMjBlbHNlJTIwJTIyJTIyKSUyMGZvciUyMHglMjBpbiUyMHAuaXRlcmRpcigpKSUwQSUyMCUyMCUyMCUyMCUwQSUyMCUyMCUyMCUyMGRlZiUyMHJlYWRfZmlsZShwYXRoJTJDJTIwbWF4X2NoYXJzJTNENDAwMCklM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBwJTIwJTNEJTIwc2FmZV9wYXRoKHBhdGgpJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmV0dXJuJTIwY2xpcChwLnJlYWRfdGV4dChlcnJvcnMlM0QlMjJyZXBsYWNlJTIyKSUyQyUyMG1pbihtYXhfY2hhcnMlMkMlMjBNQVhfQ0hBUlMpKSUwQSUyMCUyMCUyMCUyMCUwQSUyMCUyMCUyMCUyMGRlZiUyMHdyaXRlX2ZpbGUocGF0aCUyQyUyMGNvbnRlbnQpJTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwaWYlMjBub3QlMjBBTExPV19XUklURSUzQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHJhaXNlJTIwUGVybWlzc2lvbkVycm9yKCUyMndyaXRlX2ZpbGUlMjBkaXNhYmxlZCUyMiklMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBwJTIwJTNEJTIwc2FmZV9wYXRoKHBhdGgpJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcC5wYXJlbnQubWtkaXIocGFyZW50cyUzRFRydWUlMkMlMjBleGlzdF9vayUzRFRydWUpJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcC53cml0ZV90ZXh0KHN0cihjb250ZW50KSUyQyUyMGVuY29kaW5nJTNEJTIydXRmLTglMjIpJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmV0dXJuJTIwZiUyMldyb3RlJTIwJTdCbGVuKHN0cihjb250ZW50KSklN0QlMjBieXRlcyUyMiUwQSUyMCUyMCUyMCUyMCUwQSUyMCUyMCUyMCUyMGRlZiUyMGV4ZWNfY21kKGFyZ3MpJTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwaWYlMjBhcmdzJTVCMCU1RCUyMG5vdCUyMGluJTIwQUxMT1dfQ09NTUFORFMlM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjByYWlzZSUyMFBlcm1pc3Npb25FcnJvcihmJTIyQ29tbWFuZCUyMCU3QmFyZ3MlNUIwJTVEJTdEJTIwbm90JTIwYWxsb3dlZCUyMiklMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjByZXN1bHQlMjAlM0QlMjBzdWJwcm9jZXNzLnJ1biglMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBhcmdzJTJDJTIwY2FwdHVyZV9vdXRwdXQlM0RUcnVlJTJDJTIwdGltZW91dCUzRFRJTUVPVVRfUyUyQyUyMHRleHQlM0RUcnVlJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwKSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMG91dHB1dF9wYXJ0cyUyMCUzRCUyMCU1QiU1RCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGlmJTIwcmVzdWx0LnN0ZG91dCUzQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMG91dHB1dF9wYXJ0cy5hcHBlbmQoZiUyMnN0ZG91dCUzQSU1Q24lN0JyZXN1bHQuc3Rkb3V0JTdEJTIyKSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGlmJTIwcmVzdWx0LnN0ZGVyciUzQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMG91dHB1dF9wYXJ0cy5hcHBlbmQoZiUyMnN0ZGVyciUzQSU1Q24lN0JyZXN1bHQuc3RkZXJyJTdEJTIyKSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMG91dHB1dCUyMCUzRCUyMCUyMiU1Q24lNUNuJTIyLmpvaW4ob3V0cHV0X3BhcnRzKSUyMG9yJTIwZiUyMihleGl0JTIwY29kZSUyMCU3QnJlc3VsdC5yZXR1cm5jb2RlJTdEJTIwd2l0aCUyMG5vJTIwb3V0cHV0KSUyMiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHJldHVybiUyMGNsaXAob3V0cHV0JTJDJTIwTUFYX0NIQVJTKSUwQSUyMCUyMCUyMCUyMCUwQSUyMCUyMCUyMCUyMGRlZiUyMHdlYl9mZXRjaCh1cmwlMkMlMjBtYXhfYnl0ZXMlM0QxMDAwMCklM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjB0cnklM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjB3aXRoJTIwdXJsbGliLnJlcXVlc3QudXJsb3Blbih1cmwlMkMlMjB0aW1lb3V0JTNEVElNRU9VVF9TKSUyMGFzJTIwciUzQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGNvbnRlbnQlMjAlM0QlMjByLnJlYWQobWF4X2J5dGVzKSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHJldHVybiUyMGNvbnRlbnQuZGVjb2RlKCUyMnV0Zi04JTIyJTJDJTIwZXJyb3JzJTNEJTIycmVwbGFjZSUyMiklMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBleGNlcHQlMjBFeGNlcHRpb24lMjBhcyUyMGUlM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjByZXR1cm4lMjBmJTIyRXJyb3IlM0ElMjAlN0J0eXBlKGUpLl9fbmFtZV9fJTdEJTNBJTIwJTdCc3RyKGUpJTdEJTIyJTBBJTIwJTIwJTIwJTIwJTBBJTIwJTIwJTIwJTIwZGVmJTIwaGZfc2VhcmNoKHF1ZXJ5JTJDJTIwcmVzb3VyY2VfdHlwZSUzRCUyMm1vZGVscyUyMiUyQyUyMGxpbWl0JTNENSklM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBpZiUyMG5vdCUyMEFQSV9LRVklM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjByZXR1cm4lMjAlMjJFcnJvciUzQSUyMEhGX1RPS0VOJTIwbm90JTIwc2V0JTIyJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwdHJ5JTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwdXJsJTIwJTNEJTIwZiUyMmh0dHBzJTNBJTJGJTJGaHVnZ2luZ2ZhY2UuY28lMkZhcGklMkYlN0JyZXNvdXJjZV90eXBlJTdEJTIyJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmVxJTIwJTNEJTIwdXJsbGliLnJlcXVlc3QuUmVxdWVzdCglMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBmJTIyJTdCdXJsJTdEJTNGc2VhcmNoJTNEJTdCcXVlcnklN0QlMjZsaW1pdCUzRCU3QmxpbWl0JTdEJTIyJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwaGVhZGVycyUzRCU3QiUyMkF1dGhvcml6YXRpb24lMjIlM0ElMjBmJTIyQmVhcmVyJTIwJTdCQVBJX0tFWSU3RCUyMiU3RCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCklMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjB3aXRoJTIwdXJsbGliLnJlcXVlc3QudXJsb3BlbihyZXElMkMlMjB0aW1lb3V0JTNEVElNRU9VVF9TKSUyMGFzJTIwciUzQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGRhdGElMjAlM0QlMjBqc29uLmxvYWRzKHIucmVhZCgpKSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHJldHVybiUyMCU1QiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU3QiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMmlkJTIyJTNBJTIwaXRlbS5nZXQoJTIyaWQlMjIpJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIyZG93bmxvYWRzJTIyJTNBJTIwaXRlbS5nZXQoJTIyZG93bmxvYWRzJTIyJTJDJTIwMCklMkMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJkZXNjcmlwdGlvbiUyMiUzQSUyMGl0ZW0uZ2V0KCUyMmRlc2NyaXB0aW9uJTIyJTJDJTIwJTIyJTIyKSU1QiUzQTEwMCU1RCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU3RCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGZvciUyMGl0ZW0lMjBpbiUyMGRhdGElNUIlM0FsaW1pdCU1RCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU1RCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGV4Y2VwdCUyMEV4Y2VwdGlvbiUyMGFzJTIwZSUzQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHJldHVybiUyMGYlMjJFcnJvciUzQSUyMCU3QnN0cihlKSU3RCUyMiUwQSUyMCUyMCUyMCUyMCUwQSUyMCUyMCUyMCUyMGRlZiUyMGZpbmFsX2Fuc3dlcih2YWx1ZSklM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBub25sb2NhbCUyMGRvbmUlMkMlMjBmaW5hbF9yZXN1bHQlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBkb25lJTIwJTNEJTIwVHJ1ZSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGZpbmFsX3Jlc3VsdCUyMCUzRCUyMHZhbHVlJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmV0dXJuJTIwdmFsdWUlMEElMjAlMjAlMjAlMjAlMEElMjAlMjAlMjAlMjAlMjMlMjBJbml0aWFsaXplJTBBJTIwJTIwJTIwJTIwY2xpZW50JTIwJTNEJTIwT3BlbkFJKCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGFwaV9rZXklM0RBUElfS0VZJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwYmFzZV91cmwlM0RCQVNFX1VSTCUwQSUyMCUyMCUyMCUyMCklMEElMjAlMjAlMjAlMjAlMEElMjAlMjAlMjAlMjBtZXNzYWdlcyUyMCUzRCUyMCU1QiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU3QiUyMnJvbGUlMjIlM0ElMjAlMjJzeXN0ZW0lMjIlMkMlMjAlMjJjb250ZW50JTIyJTNBJTIwU1lTVEVNX1BST01QVCU3RCUyQyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU3QiUyMnJvbGUlMjIlM0ElMjAlMjJ1c2VyJTIyJTJDJTIwJTIyY29udGVudCUyMiUzQSUyMFRBU0slN0QlMEElMjAlMjAlMjAlMjAlNUQlMEElMjAlMjAlMjAlMjAlMEElMjAlMjAlMjAlMjAlMjMlMjBNYWluJTIwbG9vcCUwQSUyMCUyMCUyMCUyMGZvciUyMHN0ZXAlMjBpbiUyMHJhbmdlKE1BWF9TVEVQUyklM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBwcmludChmJTIyJTVDbiU1QlN0ZXAlMjAlN0JzdGVwJTIwJTJCJTIwMSU3RCU1RCUyMiklMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjMlMjBDYWxsJTIwTExNJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmVzcG9uc2UlMjAlM0QlMjBjbGllbnQucmVzcG9uc2VzLmNyZWF0ZSglMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBtb2RlbCUzRE1PREVMJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwdGVtcGVyYXR1cmUlM0RURU1QRVJBVFVSRSUyQyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGlucHV0JTNEbWVzc2FnZXMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjApJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwY29udGVudCUyMCUzRCUyMHJlc3BvbnNlLm91dHB1dF90ZXh0JTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcHJpbnQoZiUyMk1vZGVsJTNBJTVDbiU3QmNvbnRlbnQlNUIlM0EzMDAlNUQlN0QuLi4lMjIpJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwbWVzc2FnZXMuYXBwZW5kKCU3QiUyMnJvbGUlMjIlM0ElMjAlMjJhc3Npc3RhbnQlMjIlMkMlMjAlMjJjb250ZW50JTIyJTNBJTIwY29udGVudCU3RCklMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjMlMjBFeGVjdXRlJTIwY29kZSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHRyeSUzQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGNvZGVfbWF0Y2glMjAlM0QlMjByZS5zZWFyY2gociUyMiU2MCU2MCU2MHB5dGhvbiU1Q24oLiolM0YpJTVDbiU2MCU2MCU2MCUyMiUyQyUyMGNvbnRlbnQlMkMlMjByZS5ET1RBTEwpJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwaWYlMjBub3QlMjBjb2RlX21hdGNoJTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmFpc2UlMjBWYWx1ZUVycm9yKCUyMk5vJTIwUHl0aG9uJTIwY29kZSUyMGJsb2NrJTIwZm91bmQlMjIpJTBBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwc3Rkb3V0X2J1ZmZlciUyMCUzRCUyMGlvLlN0cmluZ0lPKCklMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBzdGRlcnJfYnVmZmVyJTIwJTNEJTIwaW8uU3RyaW5nSU8oKSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGV4ZWNfZ2xvYmFscyUyMCUzRCUyMCU3QiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMl9fYnVpbHRpbnNfXyUyMiUzQSUyMCU3QiU3RCUyQyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMmxpc3RfZGlyJTIyJTNBJTIwbGlzdF9kaXIlMkMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJyZWFkX2ZpbGUlMjIlM0ElMjByZWFkX2ZpbGUlMkMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJ3cml0ZV9maWxlJTIyJTNBJTIwd3JpdGVfZmlsZSUyQyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMmV4ZWNfY21kJTIyJTNBJTIwZXhlY19jbWQlMkMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJ3ZWJfZmV0Y2glMjIlM0ElMjB3ZWJfZmV0Y2glMkMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJoZl9zZWFyY2glMjIlM0ElMjBoZl9zZWFyY2glMkMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJmaW5hbF9hbnN3ZXIlMjIlM0ElMjBmaW5hbF9hbnN3ZXIlMkMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJqc29uJTIyJTNBJTIwanNvbiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU3RCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHdpdGglMjByZWRpcmVjdF9zdGRvdXQoc3Rkb3V0X2J1ZmZlciklMkMlMjByZWRpcmVjdF9zdGRlcnIoc3RkZXJyX2J1ZmZlciklM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBleGVjKGNvZGVfbWF0Y2guZ3JvdXAoMSklMkMlMjBleGVjX2dsb2JhbHMpJTBBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwc3Rkb3V0X3RleHQlMjAlM0QlMjBzdGRvdXRfYnVmZmVyLmdldHZhbHVlKCkuc3RyaXAoKSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHN0ZGVycl90ZXh0JTIwJTNEJTIwc3RkZXJyX2J1ZmZlci5nZXR2YWx1ZSgpLnN0cmlwKCklMEElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBpZiUyMGRvbmUlM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjByZXN1bHQlMjAlM0QlMjBmJTIyRmluYWwlMjBhbnN3ZXIlM0ElMjAlN0JjbGlwKGZpbmFsX3Jlc3VsdCklN0QlMjIlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBlbHNlJTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwb2JzZXJ2YXRpb25zJTIwJTNEJTIwJTVCJTVEJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwaWYlMjBzdGRvdXRfdGV4dCUzQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMG9ic2VydmF0aW9ucy5hcHBlbmQoZiUyMnN0ZG91dCUzQSU1Q24lN0JjbGlwKHN0ZG91dF90ZXh0KSU3RCUyMiklMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBpZiUyMHN0ZGVycl90ZXh0JTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwb2JzZXJ2YXRpb25zLmFwcGVuZChmJTIyc3RkZXJyJTNBJTVDbiU3QmNsaXAoc3RkZXJyX3RleHQpJTdEJTIyKSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHJlc3VsdCUyMCUzRCUyMCUyMiU1Q24lNUNuJTIyLmpvaW4ob2JzZXJ2YXRpb25zKSUyMG9yJTIwJTIyRXhlY3V0ZWQlMjBzdWNjZXNzZnVsbHklMjAobm8lMjBvdXRwdXQpJTIyJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwZXhjZXB0JTIwRmlsZU5vdEZvdW5kRXJyb3IlM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjByZXN1bHQlMjAlM0QlMjAlMjJFcnJvciUzQSUyMEZpbGVOb3RGb3VuZEVycm9yJTNBJTIwRmlsZSUyMG5vdCUyMGZvdW5kJTIyJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwZXhjZXB0JTIwUGVybWlzc2lvbkVycm9yJTIwYXMlMjBlJTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmVzdWx0JTIwJTNEJTIwZiUyMkVycm9yJTNBJTIwUGVybWlzc2lvbkVycm9yJTNBJTIwJTdCc3RyKGUpJTdEJTIyJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwZXhjZXB0JTIwc3VicHJvY2Vzcy5UaW1lb3V0RXhwaXJlZCUzQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHJlc3VsdCUyMCUzRCUyMCUyMkVycm9yJTNBJTIwVGltZW91dEVycm9yJTNBJTIwQ29tbWFuZCUyMHRvb2slMjB0b28lMjBsb25nJTIyJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwZXhjZXB0JTIwRXhjZXB0aW9uJTIwYXMlMjBlJTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmVzdWx0JTIwJTNEJTIwZiUyMkVycm9yJTNBJTIwJTdCdHlwZShlKS5fX25hbWVfXyU3RCUzQSUyMCU3QnN0cihlKSU3RCUyMiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGlmJTIwZG9uZSUzQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHByaW50KGYlMjIlRTIlOUMlOTMlMjBUYXNrJTIwY29tcGxldGUlM0ElMjAlN0JmaW5hbF9yZXN1bHQlN0QlMjIpJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwYnJlYWslMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBtZXNzYWdlcy5hcHBlbmQoJTdCJTIycm9sZSUyMiUzQSUyMCUyMnVzZXIlMjIlMkMlMjAlMjJjb250ZW50JTIyJTNBJTIwcmVzdWx0JTdEKSUwQSUyMCUyMCUyMCUyMCUwQSUyMCUyMCUyMCUyMGlmJTIwbm90JTIwZG9uZSUzQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHByaW50KGYlMjIlRTIlOUMlOTclMjBNYXglMjBzdGVwcyUyMHJlYWNoZWQlMjIpJTBBJTBBaWYlMjBfX25hbWVfXyUyMCUzRCUzRCUyMCUyMl9fbWFpbl9fJTIyJTNBJTBBJTIwJTIwJTIwJTIwbWFpbigp",highlighted:`<span class="hljs-comment">#!/usr/bin/env python3</span> | |
| <span class="hljs-keyword">import</span> io | |
| <span class="hljs-keyword">import</span> json | |
| <span class="hljs-keyword">import</span> os | |
| <span class="hljs-keyword">import</span> re | |
| <span class="hljs-keyword">import</span> subprocess | |
| <span class="hljs-keyword">import</span> urllib.error | |
| <span class="hljs-keyword">import</span> urllib.request | |
| <span class="hljs-keyword">from</span> contextlib <span class="hljs-keyword">import</span> redirect_stderr, redirect_stdout | |
| <span class="hljs-keyword">from</span> pathlib <span class="hljs-keyword">import</span> Path | |
| <span class="hljs-keyword">from</span> openai <span class="hljs-keyword">import</span> OpenAI | |
| <span class="hljs-comment"># Configuration</span> | |
| TASK = <span class="hljs-string">"Search for bert models on Hugging Face and summarize top 3."</span> | |
| MODEL = os.getenv(<span class="hljs-string">"NANO_MODEL"</span>, <span class="hljs-string">"zai-org/GLM-5.1"</span>) | |
| BASE_URL = os.getenv(<span class="hljs-string">"OPENAI_BASE_URL"</span>, <span class="hljs-string">"https://router.huggingface.co/v1"</span>) | |
| API_KEY = os.getenv(<span class="hljs-string">"HF_TOKEN"</span>) <span class="hljs-keyword">or</span> os.getenv(<span class="hljs-string">"OPENAI_API_KEY"</span>, <span class="hljs-string">""</span>) | |
| WORKSPACE = <span class="hljs-built_in">str</span>(Path.cwd()) | |
| MAX_STEPS = <span class="hljs-number">50</span> | |
| TIMEOUT_S = <span class="hljs-number">30</span> | |
| MAX_CHARS = <span class="hljs-number">8000</span> | |
| ALLOW_WRITE = <span class="hljs-literal">False</span> | |
| ALLOW_COMMANDS = [<span class="hljs-string">"ls"</span>, <span class="hljs-string">"cat"</span>, <span class="hljs-string">"pwd"</span>, <span class="hljs-string">"echo"</span>, <span class="hljs-string">"head"</span>, <span class="hljs-string">"tail"</span>, <span class="hljs-string">"wc"</span>, <span class="hljs-string">"rg"</span>] | |
| TEMPERATURE = <span class="hljs-number">0.2</span> | |
| SYSTEM_PROMPT = <span class="hljs-string">f"""You are a code-first agent. | |
| Reply with executable Python only. | |
| Tools: | |
| - list_dir(path='.') → list files | |
| - read_file(path, max_chars=4000) → read file | |
| - write_file(path, content) → write file (only if ALLOW_WRITE=True) | |
| - exec_cmd(args) → run allowed command | |
| - web_fetch(url, max_bytes=10000) → fetch webpage | |
| - hf_search(query, limit=5) → search HF Hub | |
| Allowed commands: <span class="hljs-subst">{ALLOW_COMMANDS}</span> | |
| Writes enabled: <span class="hljs-subst">{ALLOW_WRITE}</span> | |
| When done, call final_answer(result). | |
| Output only Python code, no prose."""</span> | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">clip</span>(<span class="hljs-params">x, n=MAX_CHARS</span>): | |
| s = <span class="hljs-built_in">str</span>(x) | |
| <span class="hljs-keyword">return</span> s[:n] + <span class="hljs-string">f"\\n...[truncated]"</span> <span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(s) > n <span class="hljs-keyword">else</span> s | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">main</span>(): | |
| ws = Path(WORKSPACE).resolve() | |
| done = <span class="hljs-literal">False</span> | |
| final_result = <span class="hljs-literal">None</span> | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">safe_path</span>(<span class="hljs-params">path</span>): | |
| p = (ws / path).resolve() | |
| <span class="hljs-keyword">try</span>: | |
| p.relative_to(ws) | |
| <span class="hljs-keyword">except</span> ValueError: | |
| <span class="hljs-keyword">raise</span> ValueError(<span class="hljs-string">f"Path escapes workspace: <span class="hljs-subst">{path}</span>"</span>) | |
| <span class="hljs-keyword">return</span> p | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">list_dir</span>(<span class="hljs-params">path=<span class="hljs-string">"."</span></span>): | |
| p = safe_path(path) | |
| <span class="hljs-keyword">return</span> <span class="hljs-built_in">sorted</span>(x.name + (<span class="hljs-string">"/"</span> <span class="hljs-keyword">if</span> x.is_dir() <span class="hljs-keyword">else</span> <span class="hljs-string">""</span>) <span class="hljs-keyword">for</span> x <span class="hljs-keyword">in</span> p.iterdir()) | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">read_file</span>(<span class="hljs-params">path, max_chars=<span class="hljs-number">4000</span></span>): | |
| p = safe_path(path) | |
| <span class="hljs-keyword">return</span> clip(p.read_text(errors=<span class="hljs-string">"replace"</span>), <span class="hljs-built_in">min</span>(max_chars, MAX_CHARS)) | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">write_file</span>(<span class="hljs-params">path, content</span>): | |
| <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> ALLOW_WRITE: | |
| <span class="hljs-keyword">raise</span> PermissionError(<span class="hljs-string">"write_file disabled"</span>) | |
| p = safe_path(path) | |
| p.parent.mkdir(parents=<span class="hljs-literal">True</span>, exist_ok=<span class="hljs-literal">True</span>) | |
| p.write_text(<span class="hljs-built_in">str</span>(content), encoding=<span class="hljs-string">"utf-8"</span>) | |
| <span class="hljs-keyword">return</span> <span class="hljs-string">f"Wrote <span class="hljs-subst">{<span class="hljs-built_in">len</span>(<span class="hljs-built_in">str</span>(content))}</span> bytes"</span> | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">exec_cmd</span>(<span class="hljs-params">args</span>): | |
| <span class="hljs-keyword">if</span> args[<span class="hljs-number">0</span>] <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> ALLOW_COMMANDS: | |
| <span class="hljs-keyword">raise</span> PermissionError(<span class="hljs-string">f"Command <span class="hljs-subst">{args[<span class="hljs-number">0</span>]}</span> not allowed"</span>) | |
| result = subprocess.run( | |
| args, capture_output=<span class="hljs-literal">True</span>, timeout=TIMEOUT_S, text=<span class="hljs-literal">True</span> | |
| ) | |
| output_parts = [] | |
| <span class="hljs-keyword">if</span> result.stdout: | |
| output_parts.append(<span class="hljs-string">f"stdout:\\n<span class="hljs-subst">{result.stdout}</span>"</span>) | |
| <span class="hljs-keyword">if</span> result.stderr: | |
| output_parts.append(<span class="hljs-string">f"stderr:\\n<span class="hljs-subst">{result.stderr}</span>"</span>) | |
| output = <span class="hljs-string">"\\n\\n"</span>.join(output_parts) <span class="hljs-keyword">or</span> <span class="hljs-string">f"(exit code <span class="hljs-subst">{result.returncode}</span> with no output)"</span> | |
| <span class="hljs-keyword">return</span> clip(output, MAX_CHARS) | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">web_fetch</span>(<span class="hljs-params">url, max_bytes=<span class="hljs-number">10000</span></span>): | |
| <span class="hljs-keyword">try</span>: | |
| <span class="hljs-keyword">with</span> urllib.request.urlopen(url, timeout=TIMEOUT_S) <span class="hljs-keyword">as</span> r: | |
| content = r.read(max_bytes) | |
| <span class="hljs-keyword">return</span> content.decode(<span class="hljs-string">"utf-8"</span>, errors=<span class="hljs-string">"replace"</span>) | |
| <span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> e: | |
| <span class="hljs-keyword">return</span> <span class="hljs-string">f"Error: <span class="hljs-subst">{<span class="hljs-built_in">type</span>(e).__name__}</span>: <span class="hljs-subst">{<span class="hljs-built_in">str</span>(e)}</span>"</span> | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">hf_search</span>(<span class="hljs-params">query, resource_type=<span class="hljs-string">"models"</span>, limit=<span class="hljs-number">5</span></span>): | |
| <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> API_KEY: | |
| <span class="hljs-keyword">return</span> <span class="hljs-string">"Error: HF_TOKEN not set"</span> | |
| <span class="hljs-keyword">try</span>: | |
| url = <span class="hljs-string">f"https://huggingface.co/api/<span class="hljs-subst">{resource_type}</span>"</span> | |
| req = urllib.request.Request( | |
| <span class="hljs-string">f"<span class="hljs-subst">{url}</span>?search=<span class="hljs-subst">{query}</span>&limit=<span class="hljs-subst">{limit}</span>"</span>, | |
| headers={<span class="hljs-string">"Authorization"</span>: <span class="hljs-string">f"Bearer <span class="hljs-subst">{API_KEY}</span>"</span>} | |
| ) | |
| <span class="hljs-keyword">with</span> urllib.request.urlopen(req, timeout=TIMEOUT_S) <span class="hljs-keyword">as</span> r: | |
| data = json.loads(r.read()) | |
| <span class="hljs-keyword">return</span> [ | |
| { | |
| <span class="hljs-string">"id"</span>: item.get(<span class="hljs-string">"id"</span>), | |
| <span class="hljs-string">"downloads"</span>: item.get(<span class="hljs-string">"downloads"</span>, <span class="hljs-number">0</span>), | |
| <span class="hljs-string">"description"</span>: item.get(<span class="hljs-string">"description"</span>, <span class="hljs-string">""</span>)[:<span class="hljs-number">100</span>] | |
| } | |
| <span class="hljs-keyword">for</span> item <span class="hljs-keyword">in</span> data[:limit] | |
| ] | |
| <span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> e: | |
| <span class="hljs-keyword">return</span> <span class="hljs-string">f"Error: <span class="hljs-subst">{<span class="hljs-built_in">str</span>(e)}</span>"</span> | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">final_answer</span>(<span class="hljs-params">value</span>): | |
| <span class="hljs-keyword">nonlocal</span> done, final_result | |
| done = <span class="hljs-literal">True</span> | |
| final_result = value | |
| <span class="hljs-keyword">return</span> value | |
| <span class="hljs-comment"># Initialize</span> | |
| client = OpenAI( | |
| api_key=API_KEY, | |
| base_url=BASE_URL | |
| ) | |
| messages = [ | |
| {<span class="hljs-string">"role"</span>: <span class="hljs-string">"system"</span>, <span class="hljs-string">"content"</span>: SYSTEM_PROMPT}, | |
| {<span class="hljs-string">"role"</span>: <span class="hljs-string">"user"</span>, <span class="hljs-string">"content"</span>: TASK} | |
| ] | |
| <span class="hljs-comment"># Main loop</span> | |
| <span class="hljs-keyword">for</span> step <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(MAX_STEPS): | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">f"\\n[Step <span class="hljs-subst">{step + <span class="hljs-number">1</span>}</span>]"</span>) | |
| <span class="hljs-comment"># Call LLM</span> | |
| response = client.responses.create( | |
| model=MODEL, | |
| temperature=TEMPERATURE, | |
| <span class="hljs-built_in">input</span>=messages | |
| ) | |
| content = response.output_text | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">f"Model:\\n<span class="hljs-subst">{content[:<span class="hljs-number">300</span>]}</span>..."</span>) | |
| messages.append({<span class="hljs-string">"role"</span>: <span class="hljs-string">"assistant"</span>, <span class="hljs-string">"content"</span>: content}) | |
| <span class="hljs-comment"># Execute code</span> | |
| <span class="hljs-keyword">try</span>: | |
| code_match = re.search(<span class="hljs-string">r"\`\`\`python\\n(.*?)\\n\`\`\`"</span>, content, re.DOTALL) | |
| <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> code_match: | |
| <span class="hljs-keyword">raise</span> ValueError(<span class="hljs-string">"No Python code block found"</span>) | |
| stdout_buffer = io.StringIO() | |
| stderr_buffer = io.StringIO() | |
| exec_globals = { | |
| <span class="hljs-string">"__builtins__"</span>: {}, | |
| <span class="hljs-string">"list_dir"</span>: list_dir, | |
| <span class="hljs-string">"read_file"</span>: read_file, | |
| <span class="hljs-string">"write_file"</span>: write_file, | |
| <span class="hljs-string">"exec_cmd"</span>: exec_cmd, | |
| <span class="hljs-string">"web_fetch"</span>: web_fetch, | |
| <span class="hljs-string">"hf_search"</span>: hf_search, | |
| <span class="hljs-string">"final_answer"</span>: final_answer, | |
| <span class="hljs-string">"json"</span>: json | |
| } | |
| <span class="hljs-keyword">with</span> redirect_stdout(stdout_buffer), redirect_stderr(stderr_buffer): | |
| <span class="hljs-built_in">exec</span>(code_match.group(<span class="hljs-number">1</span>), exec_globals) | |
| stdout_text = stdout_buffer.getvalue().strip() | |
| stderr_text = stderr_buffer.getvalue().strip() | |
| <span class="hljs-keyword">if</span> done: | |
| result = <span class="hljs-string">f"Final answer: <span class="hljs-subst">{clip(final_result)}</span>"</span> | |
| <span class="hljs-keyword">else</span>: | |
| observations = [] | |
| <span class="hljs-keyword">if</span> stdout_text: | |
| observations.append(<span class="hljs-string">f"stdout:\\n<span class="hljs-subst">{clip(stdout_text)}</span>"</span>) | |
| <span class="hljs-keyword">if</span> stderr_text: | |
| observations.append(<span class="hljs-string">f"stderr:\\n<span class="hljs-subst">{clip(stderr_text)}</span>"</span>) | |
| result = <span class="hljs-string">"\\n\\n"</span>.join(observations) <span class="hljs-keyword">or</span> <span class="hljs-string">"Executed successfully (no output)"</span> | |
| <span class="hljs-keyword">except</span> FileNotFoundError: | |
| result = <span class="hljs-string">"Error: FileNotFoundError: File not found"</span> | |
| <span class="hljs-keyword">except</span> PermissionError <span class="hljs-keyword">as</span> e: | |
| result = <span class="hljs-string">f"Error: PermissionError: <span class="hljs-subst">{<span class="hljs-built_in">str</span>(e)}</span>"</span> | |
| <span class="hljs-keyword">except</span> subprocess.TimeoutExpired: | |
| result = <span class="hljs-string">"Error: TimeoutError: Command took too long"</span> | |
| <span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> e: | |
| result = <span class="hljs-string">f"Error: <span class="hljs-subst">{<span class="hljs-built_in">type</span>(e).__name__}</span>: <span class="hljs-subst">{<span class="hljs-built_in">str</span>(e)}</span>"</span> | |
| <span class="hljs-keyword">if</span> done: | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">f"✓ Task complete: <span class="hljs-subst">{final_result}</span>"</span>) | |
| <span class="hljs-keyword">break</span> | |
| messages.append({<span class="hljs-string">"role"</span>: <span class="hljs-string">"user"</span>, <span class="hljs-string">"content"</span>: result}) | |
| <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> done: | |
| <span class="hljs-built_in">print</span>(<span class="hljs-string">f"✗ Max steps reached"</span>) | |
| <span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>: | |
| main()`,wrap:!1}}),W=new o({props:{title:"Running the Harness",local:"running-the-harness",headingTag:"h2"}}),z=new I({props:{code:"ZXhwb3J0JTIwSEZfVE9LRU4lM0QlMjJoZl8uLi4lMjIlMEFleHBvcnQlMjBOQU5PX01PREVMJTNEJTIyemFpLW9yZyUyRkdMTS01LjElMjIlMEFweXRob24lMjBuYW5vX2hhcm5lc3NfZXh0ZW5kZWQucHk=",highlighted:`<span class="hljs-built_in">export</span> HF_TOKEN=<span class="hljs-string">"hf_..."</span> | |
| <span class="hljs-built_in">export</span> NANO_MODEL=<span class="hljs-string">"zai-org/GLM-5.1"</span> | |
| python nano_harness_extended.py`,wrap:!1}}),x=new o({props:{title:"Exercise: Extend Further",local:"exercise-extend-further",headingTag:"h2"}}),$=new o({props:{title:"1. git_log Tool",local:"1-gitlog-tool",headingTag:"h3"}}),v=new I({props:{code:"JTIzJTIwQWRkJTIwJTIyZ2l0JTIyJTIwdG8lMjBBTExPV19DT01NQU5EUyUyMGZpcnN0JTJDJTIwdGhlbiUzQSUwQWRlZiUyMGdpdF9sb2cobGltaXQlM0QxMCklM0ElMEElMjAlMjAlMjAlMjAlMjIlMjIlMjJHZXQlMjByZWNlbnQlMjBnaXQlMjBjb21taXRzLiUyMiUyMiUyMiUwQSUyMCUyMCUyMCUyMHJldHVybiUyMGV4ZWNfY21kKCU1QiUyMmdpdCUyMiUyQyUyMCUyMmxvZyUyMiUyQyUyMCUyMi0tb25lbGluZSUyMiUyQyUyMGYlMjItJTdCbGltaXQlN0QlMjIlNUQp",highlighted:`<span class="hljs-comment"># Add "git" to ALLOW_COMMANDS first, then:</span> | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">git_log</span>(<span class="hljs-params">limit=<span class="hljs-number">10</span></span>): | |
| <span class="hljs-string">"""Get recent git commits."""</span> | |
| <span class="hljs-keyword">return</span> exec_cmd([<span class="hljs-string">"git"</span>, <span class="hljs-string">"log"</span>, <span class="hljs-string">"--oneline"</span>, <span class="hljs-string">f"-<span class="hljs-subst">{limit}</span>"</span>])`,wrap:!1}}),L=new o({props:{title:"2. json_parse Tool",local:"2-jsonparse-tool",headingTag:"h3"}}),K=new I({props:{code:"ZGVmJTIwanNvbl9wYXJzZShqc29uX3N0cmluZyklM0ElMEElMjAlMjAlMjAlMjAlMjIlMjIlMjJQYXJzZSUyMEpTT04lMjBzYWZlbHkuJTIyJTIyJTIyJTBBJTIwJTIwJTIwJTIwdHJ5JTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmV0dXJuJTIwanNvbi5sb2Fkcyhqc29uX3N0cmluZyklMEElMjAlMjAlMjAlMjBleGNlcHQlMjBqc29uLkpTT05EZWNvZGVFcnJvciUyMGFzJTIwZSUzQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHJldHVybiUyMGYlMjJFcnJvciUzQSUyMCU3QnN0cihlKSU3RCUyMg==",highlighted:`<span class="hljs-keyword">def</span> <span class="hljs-title function_">json_parse</span>(<span class="hljs-params">json_string</span>): | |
| <span class="hljs-string">"""Parse JSON safely."""</span> | |
| <span class="hljs-keyword">try</span>: | |
| <span class="hljs-keyword">return</span> json.loads(json_string) | |
| <span class="hljs-keyword">except</span> json.JSONDecodeError <span class="hljs-keyword">as</span> e: | |
| <span class="hljs-keyword">return</span> <span class="hljs-string">f"Error: <span class="hljs-subst">{<span class="hljs-built_in">str</span>(e)}</span>"</span>`,wrap:!1}}),P=new o({props:{title:"3. compute_stats Tool",local:"3-computestats-tool",headingTag:"h3"}}),O=new I({props:{code:"ZGVmJTIwY29tcHV0ZV9zdGF0cyhudW1iZXJzKSUzQSUwQSUyMCUyMCUyMCUyMCUyMiUyMiUyMkNvbXB1dGUlMjBtaW4lMkMlMjBtYXglMkMlMjBtZWFuLiUyMiUyMiUyMiUwQSUyMCUyMCUyMCUyMG51bXMlMjAlM0QlMjBsaXN0KG1hcChmbG9hdCUyQyUyMG51bWJlcnMpKSUwQSUyMCUyMCUyMCUyMHJldHVybiUyMCU3QiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMm1pbiUyMiUzQSUyMG1pbihudW1zKSUyQyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMm1heCUyMiUzQSUyMG1heChudW1zKSUyQyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMm1lYW4lMjIlM0ElMjBzdW0obnVtcyklMjAlMkYlMjBsZW4obnVtcyklMkMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJjb3VudCUyMiUzQSUyMGxlbihudW1zKSUwQSUyMCUyMCUyMCUyMCU3RA==",highlighted:`<span class="hljs-keyword">def</span> <span class="hljs-title function_">compute_stats</span>(<span class="hljs-params">numbers</span>): | |
| <span class="hljs-string">"""Compute min, max, mean."""</span> | |
| nums = <span class="hljs-built_in">list</span>(<span class="hljs-built_in">map</span>(<span class="hljs-built_in">float</span>, numbers)) | |
| <span class="hljs-keyword">return</span> { | |
| <span class="hljs-string">"min"</span>: <span class="hljs-built_in">min</span>(nums), | |
| <span class="hljs-string">"max"</span>: <span class="hljs-built_in">max</span>(nums), | |
| <span class="hljs-string">"mean"</span>: <span class="hljs-built_in">sum</span>(nums) / <span class="hljs-built_in">len</span>(nums), | |
| <span class="hljs-string">"count"</span>: <span class="hljs-built_in">len</span>(nums) | |
| }`,wrap:!1}}),ss=new o({props:{title:"Key Takeaways",local:"key-takeaways",headingTag:"h2"}}),as=new dl({props:{source:"https://github.com/huggingface/context-course/blob/main/units/en/unit6/hands-on.mdx"}}),{c(){c=p("meta"),ys=n(),ns=p("p"),es=n(),y(i.$$.fragment),Us=n(),y(r.$$.fragment),Js=n(),u=p("p"),u.innerHTML=Ks,js=n(),y(A.$$.fragment),Ts=n(),h=p("p"),h.textContent=Ps,ps=n(),y(d.$$.fragment),ws=n(),m=p("p"),m.innerHTML=Os,Cs=n(),b=p("p"),b.innerHTML=Ds,Is=n(),y(B.$$.fragment),os=n(),E=p("p"),E.innerHTML=sl,cs=n(),y(f.$$.fragment),is=n(),y(Z.$$.fragment),rs=n(),Q=p("p"),Q.textContent=ll,us=n(),y(g.$$.fragment),As=n(),V=p("p"),V.innerHTML=Ml,hs=n(),k=p("p"),k.innerHTML=al,ds=n(),y(q.$$.fragment),ms=n(),G=p("p"),G.innerHTML=nl,bs=n(),y(N.$$.fragment),Bs=n(),y(S.$$.fragment),Es=n(),X=p("p"),X.innerHTML=tl,fs=n(),y(R.$$.fragment),Zs=n(),_=p("p"),_.innerHTML=yl,Qs=n(),y(W.$$.fragment),gs=n(),F=p("p"),F.innerHTML=el,Vs=n(),y(z.$$.fragment),ks=n(),H=p("p"),H.innerHTML=Ul,qs=n(),y(x.$$.fragment),Gs=n(),Y=p("p"),Y.textContent=Jl,Ns=n(),y($.$$.fragment),Ss=n(),y(v.$$.fragment),Xs=n(),y(L.$$.fragment),Rs=n(),y(K.$$.fragment),_s=n(),y(P.$$.fragment),Ws=n(),y(O.$$.fragment),Fs=n(),D=p("p"),D.textContent=jl,zs=n(),y(ss.$$.fragment),Hs=n(),ls=p("p"),ls.textContent=Tl,xs=n(),Ms=p("p"),Ms.textContent=pl,Ys=n(),y(as.$$.fragment),$s=n(),ts=p("p"),this.h()},l(s){const l=ul("svelte-u9bgzb",document.head);c=w(l,"META",{name:!0,content:!0}),l.forEach(M),ys=t(s),ns=w(s,"P",{}),wl(ns).forEach(M),es=t(s),e(i.$$.fragment,s),Us=t(s),e(r.$$.fragment,s),Js=t(s),u=w(s,"P",{"data-svelte-h":!0}),C(u)!=="svelte-167swwi"&&(u.innerHTML=Ks),js=t(s),e(A.$$.fragment,s),Ts=t(s),h=w(s,"P",{"data-svelte-h":!0}),C(h)!=="svelte-tclhzn"&&(h.textContent=Ps),ps=t(s),e(d.$$.fragment,s),ws=t(s),m=w(s,"P",{"data-svelte-h":!0}),C(m)!=="svelte-jsbop7"&&(m.innerHTML=Os),Cs=t(s),b=w(s,"P",{"data-svelte-h":!0}),C(b)!=="svelte-cj5i9t"&&(b.innerHTML=Ds),Is=t(s),e(B.$$.fragment,s),os=t(s),E=w(s,"P",{"data-svelte-h":!0}),C(E)!=="svelte-1n8vwmi"&&(E.innerHTML=sl),cs=t(s),e(f.$$.fragment,s),is=t(s),e(Z.$$.fragment,s),rs=t(s),Q=w(s,"P",{"data-svelte-h":!0}),C(Q)!=="svelte-3g8tvo"&&(Q.textContent=ll),us=t(s),e(g.$$.fragment,s),As=t(s),V=w(s,"P",{"data-svelte-h":!0}),C(V)!=="svelte-1tfydg9"&&(V.innerHTML=Ml),hs=t(s),k=w(s,"P",{"data-svelte-h":!0}),C(k)!=="svelte-cj5i9t"&&(k.innerHTML=al),ds=t(s),e(q.$$.fragment,s),ms=t(s),G=w(s,"P",{"data-svelte-h":!0}),C(G)!=="svelte-1n8vwmi"&&(G.innerHTML=nl),bs=t(s),e(N.$$.fragment,s),Bs=t(s),e(S.$$.fragment,s),Es=t(s),X=w(s,"P",{"data-svelte-h":!0}),C(X)!=="svelte-dt21o9"&&(X.innerHTML=tl),fs=t(s),e(R.$$.fragment,s),Zs=t(s),_=w(s,"P",{"data-svelte-h":!0}),C(_)!=="svelte-oxwqla"&&(_.innerHTML=yl),Qs=t(s),e(W.$$.fragment,s),gs=t(s),F=w(s,"P",{"data-svelte-h":!0}),C(F)!=="svelte-16qzabf"&&(F.innerHTML=el),Vs=t(s),e(z.$$.fragment,s),ks=t(s),H=w(s,"P",{"data-svelte-h":!0}),C(H)!=="svelte-1xmdlfy"&&(H.innerHTML=Ul),qs=t(s),e(x.$$.fragment,s),Gs=t(s),Y=w(s,"P",{"data-svelte-h":!0}),C(Y)!=="svelte-1kp53wi"&&(Y.textContent=Jl),Ns=t(s),e($.$$.fragment,s),Ss=t(s),e(v.$$.fragment,s),Xs=t(s),e(L.$$.fragment,s),Rs=t(s),e(K.$$.fragment,s),_s=t(s),e(P.$$.fragment,s),Ws=t(s),e(O.$$.fragment,s),Fs=t(s),D=w(s,"P",{"data-svelte-h":!0}),C(D)!=="svelte-10miomk"&&(D.textContent=jl),zs=t(s),e(ss.$$.fragment,s),Hs=t(s),ls=w(s,"P",{"data-svelte-h":!0}),C(ls)!=="svelte-196793x"&&(ls.textContent=Tl),xs=t(s),Ms=w(s,"P",{"data-svelte-h":!0}),C(Ms)!=="svelte-1qfy60r"&&(Ms.textContent=pl),Ys=t(s),e(as.$$.fragment,s),$s=t(s),ts=w(s,"P",{}),wl(ts).forEach(M),this.h()},h(){Cl(c,"name","hf:doc:metadata"),Cl(c,"content",bl)},m(s,l){Al(document.head,c),a(s,ys,l),a(s,ns,l),a(s,es,l),U(i,s,l),a(s,Us,l),U(r,s,l),a(s,Js,l),a(s,u,l),a(s,js,l),U(A,s,l),a(s,Ts,l),a(s,h,l),a(s,ps,l),U(d,s,l),a(s,ws,l),a(s,m,l),a(s,Cs,l),a(s,b,l),a(s,Is,l),U(B,s,l),a(s,os,l),a(s,E,l),a(s,cs,l),U(f,s,l),a(s,is,l),U(Z,s,l),a(s,rs,l),a(s,Q,l),a(s,us,l),U(g,s,l),a(s,As,l),a(s,V,l),a(s,hs,l),a(s,k,l),a(s,ds,l),U(q,s,l),a(s,ms,l),a(s,G,l),a(s,bs,l),U(N,s,l),a(s,Bs,l),U(S,s,l),a(s,Es,l),a(s,X,l),a(s,fs,l),U(R,s,l),a(s,Zs,l),a(s,_,l),a(s,Qs,l),U(W,s,l),a(s,gs,l),a(s,F,l),a(s,Vs,l),U(z,s,l),a(s,ks,l),a(s,H,l),a(s,qs,l),U(x,s,l),a(s,Gs,l),a(s,Y,l),a(s,Ns,l),U($,s,l),a(s,Ss,l),U(v,s,l),a(s,Xs,l),U(L,s,l),a(s,Rs,l),U(K,s,l),a(s,_s,l),U(P,s,l),a(s,Ws,l),U(O,s,l),a(s,Fs,l),a(s,D,l),a(s,zs,l),U(ss,s,l),a(s,Hs,l),a(s,ls,l),a(s,xs,l),a(s,Ms,l),a(s,Ys,l),U(as,s,l),a(s,$s,l),a(s,ts,l),vs=!0},p:ol,i(s){vs||(J(i.$$.fragment,s),J(r.$$.fragment,s),J(A.$$.fragment,s),J(d.$$.fragment,s),J(B.$$.fragment,s),J(f.$$.fragment,s),J(Z.$$.fragment,s),J(g.$$.fragment,s),J(q.$$.fragment,s),J(N.$$.fragment,s),J(S.$$.fragment,s),J(R.$$.fragment,s),J(W.$$.fragment,s),J(z.$$.fragment,s),J(x.$$.fragment,s),J($.$$.fragment,s),J(v.$$.fragment,s),J(L.$$.fragment,s),J(K.$$.fragment,s),J(P.$$.fragment,s),J(O.$$.fragment,s),J(ss.$$.fragment,s),J(as.$$.fragment,s),vs=!0)},o(s){j(i.$$.fragment,s),j(r.$$.fragment,s),j(A.$$.fragment,s),j(d.$$.fragment,s),j(B.$$.fragment,s),j(f.$$.fragment,s),j(Z.$$.fragment,s),j(g.$$.fragment,s),j(q.$$.fragment,s),j(N.$$.fragment,s),j(S.$$.fragment,s),j(R.$$.fragment,s),j(W.$$.fragment,s),j(z.$$.fragment,s),j(x.$$.fragment,s),j($.$$.fragment,s),j(v.$$.fragment,s),j(L.$$.fragment,s),j(K.$$.fragment,s),j(P.$$.fragment,s),j(O.$$.fragment,s),j(ss.$$.fragment,s),j(as.$$.fragment,s),vs=!1},d(s){s&&(M(ys),M(ns),M(es),M(Us),M(Js),M(u),M(js),M(Ts),M(h),M(ps),M(ws),M(m),M(Cs),M(b),M(Is),M(os),M(E),M(cs),M(is),M(rs),M(Q),M(us),M(As),M(V),M(hs),M(k),M(ds),M(ms),M(G),M(bs),M(Bs),M(Es),M(X),M(fs),M(Zs),M(_),M(Qs),M(gs),M(F),M(Vs),M(ks),M(H),M(qs),M(Gs),M(Y),M(Ns),M(Ss),M(Xs),M(Rs),M(_s),M(Ws),M(Fs),M(D),M(zs),M(Hs),M(ls),M(xs),M(Ms),M(Ys),M($s),M(ts)),M(c),T(i,s),T(r,s),T(A,s),T(d,s),T(B,s),T(f,s),T(Z,s),T(g,s),T(q,s),T(N,s),T(S,s),T(R,s),T(W,s),T(z,s),T(x,s),T($,s),T(v,s),T(L,s),T(K,s),T(P,s),T(O,s),T(ss,s),T(as,s)}}}const bl='{"title":"Hands-On: Extending Nano Harness","local":"hands-on-extending-nano-harness","sections":[{"title":"Extension 1: Add web_fetch Tool","local":"extension-1-add-webfetch-tool","sections":[],"depth":2},{"title":"Extension 2: Add hf_search Tool","local":"extension-2-add-hfsearch-tool","sections":[],"depth":2},{"title":"Full Extended Example","local":"full-extended-example","sections":[],"depth":2},{"title":"Running the Harness","local":"running-the-harness","sections":[],"depth":2},{"title":"Exercise: Extend Further","local":"exercise-extend-further","sections":[{"title":"1. git_log Tool","local":"1-gitlog-tool","sections":[],"depth":3},{"title":"2. json_parse Tool","local":"2-jsonparse-tool","sections":[],"depth":3},{"title":"3. compute_stats Tool","local":"3-computestats-tool","sections":[],"depth":3}],"depth":2},{"title":"Key Takeaways","local":"key-takeaways","sections":[],"depth":2}],"depth":1}';function Bl(Ls){return cl(()=>{new URLSearchParams(window.location.search).get("fw")}),[]}class gl extends il{constructor(c){super(),rl(this,c,Bl,ml,Il,{})}}export{gl as component}; | |
Xet Storage Details
- Size:
- 58.3 kB
- Xet hash:
- d0b4886a9c0ceb5822aa8aa60a8269abdd5f6b375e3f3572ae9c1b9818b4a382
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.