<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="pretty-atom-feed.xsl" type="text/xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  <title>Blog Title</title>
  <subtitle>This is a longer description about your blog.</subtitle>
  <link href="https://example.com/feed/feed.xml" rel="self" />
  <link href="https://example.com/" />
  <updated>2025-06-20T00:00:00Z</updated>
  <id>https://example.com/</id>
  <author>
    <name>Your Name</name>
  </author>
  <entry>
    <title>Karpathy&#39;s 3 Software Paradigms Expanded</title>
    <link href="https://example.com/blog/karpathy-software-paradigms-expanded/" />
    <updated>2025-06-20T00:00:00Z</updated>
    <id>https://example.com/blog/karpathy-software-paradigms-expanded/</id>
    <content type="html">&lt;p&gt;In June of 2025, Andrej Karpathy gave a talk at YC&#39;s AI Startup School
titled &lt;a href=&quot;https://www.youtube.com/watch?v=LCEmiRjPEtQ&quot;&gt;&amp;quot;Software is Changing
(Again)&amp;quot;&lt;/a&gt; where he
introduced three major software paradigms:&lt;/p&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://example.com/blog/karpathy-software-paradigms-expanded/RcZM3R9oKr-3448.avif 3448w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://example.com/blog/karpathy-software-paradigms-expanded/RcZM3R9oKr-3448.webp 3448w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://example.com/blog/karpathy-software-paradigms-expanded/RcZM3R9oKr-3448.png&quot; alt=&quot;Karpathy&#39;s Three Software Paradigms&quot; width=&quot;3448&quot; height=&quot;1840&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;To reiterate the categories:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Software 1.0 - code&lt;/li&gt;
&lt;li&gt;Software 2.0 - weights&lt;/li&gt;
&lt;li&gt;Software 3.0 - prompts&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is a thought provoking way to think about the recent paradigms of
software creation. I wanted to expand on the Software 1.0 because that
category encapsulates a number of paradigm shifts that have happened
in the software space.&lt;/p&gt;
&lt;h2 id=&quot;software-paradigms-expanded&quot;&gt;Software Paradigms Expanded&lt;/h2&gt;
&lt;div class=&quot;table-no-wrap&quot;&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Paradigm&lt;/th&gt;
&lt;th&gt;Start (≈)&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;Hard-wired logic&lt;/td&gt;
&lt;td&gt;1930s&lt;/td&gt;
&lt;td&gt;Programs built by physically wiring circuits; fast execution, no flexibility&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1a&lt;/td&gt;
&lt;td&gt;Low-level symbolic code&lt;/td&gt;
&lt;td&gt;1946&lt;/td&gt;
&lt;td&gt;Programs written in numeric opcodes or assembly; error-prone but foundational&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1b&lt;/td&gt;
&lt;td&gt;Compiled procedural&lt;/td&gt;
&lt;td&gt;1957&lt;/td&gt;
&lt;td&gt;Code written in high-level languages like Fortran and C; compiled to machine code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1c&lt;/td&gt;
&lt;td&gt;Managed and dynamic&lt;/td&gt;
&lt;td&gt;1984&lt;/td&gt;
&lt;td&gt;Code runs in VMs or interpreters; safe, high-level languages like Java, Python&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Neural networks&lt;/td&gt;
&lt;td&gt;2012&lt;/td&gt;
&lt;td&gt;Software learned from data via training; great for vision/language, opaque logic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;LLMs, reasoning, agents&lt;/td&gt;
&lt;td&gt;2022&lt;/td&gt;
&lt;td&gt;Natural language prompts create code or plans; tools and reasoning extend capabilities&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Software 0&lt;/em&gt;: There was no general notion of &amp;quot;software&amp;quot; as
a distinct entity or activity from hardware. The initial theory of
software would be developed in 1935 by Alan Turing. The term
&amp;quot;software&amp;quot; was coined by John Tukey in 1958 which is well after we
started creating &amp;quot;software&amp;quot; (programming). And it should be
mentioned that the first software was created by Ada Lovelace in
1843 for Babbage&#39;s Analytical Engine.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Software 1a&lt;/em&gt;: Software exists but is basically a direct mapping to
the machine code instructions that the processor executes. No
conceptual abstraction from the steps the computer is performing.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Software 1b&lt;/em&gt;: Higher level languages that are translated or
compiled to machine code and then executed. Introduces higher-level
abstractions like functions and data types, letting programmers
describe algorithms without managing individual instructions or
memory directly.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Software 1c&lt;/em&gt;: Software languages and tools now abstract the runtime
environment itself using managed memory, dynamic typing, reflection,
and interpreters. Code is no longer a static set of instructions but
a flexible, evolving system that can inspect, modify, and extend
itself while running.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;software-paradigms-expanded-again&quot;&gt;Software Paradigms Expanded (Again)&lt;/h2&gt;
&lt;p&gt;The above table is a useful, but I also want to see finer granularity.
So let&#39;s expand all three paradigm groups:&lt;/p&gt;
&lt;div class=&quot;table-no-wrap&quot;&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Paradigm&lt;/th&gt;
&lt;th&gt;Start (≈)&lt;/th&gt;
&lt;th&gt;Key innovations&lt;/th&gt;
&lt;th&gt;Typical tech / tools&lt;/th&gt;
&lt;th&gt;What “programming” looks like&lt;/th&gt;
&lt;th&gt;Human role&lt;/th&gt;
&lt;th&gt;Notes &amp;amp; trade-offs&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0.0&lt;/td&gt;
&lt;td&gt;Hard-wired logic&lt;/td&gt;
&lt;td&gt;1930s&lt;/td&gt;
&lt;td&gt;Logic encoded in wiring &amp;amp; relays&lt;/td&gt;
&lt;td&gt;IBM accounting machines, ENIAC plug-boards&lt;/td&gt;
&lt;td&gt;Re-patch cables, flip switches, resolder boards&lt;/td&gt;
&lt;td&gt;Electrical technician&lt;/td&gt;
&lt;td&gt;Fast once wired; change = physical labour; no “stored” software&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1.0&lt;/td&gt;
&lt;td&gt;Machine-code&lt;/td&gt;
&lt;td&gt;1946&lt;/td&gt;
&lt;td&gt;Stored-program computer + numeric op-codes&lt;/td&gt;
&lt;td&gt;IBM 701 punched cards, EDSAC paper tape&lt;/td&gt;
&lt;td&gt;Hand-encode op-codes; feed decks/tape&lt;/td&gt;
&lt;td&gt;Coder / calculator&lt;/td&gt;
&lt;td&gt;First real software; opaque &amp;amp; error-prone; debugging = re-punch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1.1&lt;/td&gt;
&lt;td&gt;Assembly language&lt;/td&gt;
&lt;td&gt;1950&lt;/td&gt;
&lt;td&gt;Mnemonics, labels, macros&lt;/td&gt;
&lt;td&gt;Autocoder, MASM, NASM&lt;/td&gt;
&lt;td&gt;One line per instruction; think in registers &amp;amp; jumps&lt;/td&gt;
&lt;td&gt;System programmer&lt;/td&gt;
&lt;td&gt;Easier than raw op-codes, still non-portable &amp;amp; low-level&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1.2&lt;/td&gt;
&lt;td&gt;Compiled procedural&lt;/td&gt;
&lt;td&gt;1957&lt;/td&gt;
&lt;td&gt;Compilers translate algebraic languages&lt;/td&gt;
&lt;td&gt;Fortran, Algol, C, Pascal, COBOL&lt;/td&gt;
&lt;td&gt;Describe algorithms; compiler handles optimisation&lt;/td&gt;
&lt;td&gt;Software engineer&lt;/td&gt;
&lt;td&gt;Portable &amp;amp; efficient; manual memory, explicit control flow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1.3&lt;/td&gt;
&lt;td&gt;Symbolic / functional&lt;/td&gt;
&lt;td&gt;1958&lt;/td&gt;
&lt;td&gt;REPL, garbage collection, code-as-data macros&lt;/td&gt;
&lt;td&gt;Lisp, Scheme, early Smalltalk&lt;/td&gt;
&lt;td&gt;Type at a prompt; meta-program; treat code as data&lt;/td&gt;
&lt;td&gt;Researcher / rapid-prototyper&lt;/td&gt;
&lt;td&gt;Pioneered GC &amp;amp; FP; concept-rich, slow on early HW&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1.4&lt;/td&gt;
&lt;td&gt;Managed object-oriented&lt;/td&gt;
&lt;td&gt;1984&lt;/td&gt;
&lt;td&gt;Virtual machines, JITs, static typing + GC&lt;/td&gt;
&lt;td&gt;Java/JVM, C#, CLR&lt;/td&gt;
&lt;td&gt;Class hierarchies; runtime hides memory&lt;/td&gt;
&lt;td&gt;Application developer&lt;/td&gt;
&lt;td&gt;Safety &amp;amp; tooling at scale; some perf overhead&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1.5&lt;/td&gt;
&lt;td&gt;Dynamic scripting&lt;/td&gt;
&lt;td&gt;1991&lt;/td&gt;
&lt;td&gt;Interpreters + batteries-included libs &amp;amp; REPLs&lt;/td&gt;
&lt;td&gt;Python, JavaScript, Ruby, Perl, Bash&lt;/td&gt;
&lt;td&gt;Write glue code quickly; duck-typing&lt;/td&gt;
&lt;td&gt;Scripter / web dev&lt;/td&gt;
&lt;td&gt;Rapid iteration; late error detection; slower runtime&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2.0&lt;/td&gt;
&lt;td&gt;Deep perception nets&lt;/td&gt;
&lt;td&gt;2012&lt;/td&gt;
&lt;td&gt;GPU-accelerated gradient descent for vision&lt;/td&gt;
&lt;td&gt;CNNs, ImageNet, TensorFlow 1.x&lt;/td&gt;
&lt;td&gt;Define architecture + dataset; training learns weights&lt;/td&gt;
&lt;td&gt;ML engineer&lt;/td&gt;
&lt;td&gt;Excels at perception; data/compute hungry; opaque logic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2.1&lt;/td&gt;
&lt;td&gt;Sequence &amp;amp; attention models&lt;/td&gt;
&lt;td&gt;2014&lt;/td&gt;
&lt;td&gt;RNNs, LSTMs, attention for language &amp;amp; time&lt;/td&gt;
&lt;td&gt;seq2seq, Bahdanau attention, early Torch&lt;/td&gt;
&lt;td&gt;Encode/dec sequence; training handles long context&lt;/td&gt;
&lt;td&gt;NLP engineer&lt;/td&gt;
&lt;td&gt;Better for language; still brittle, limited context&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2.2&lt;/td&gt;
&lt;td&gt;Self-supervised models&lt;/td&gt;
&lt;td&gt;2017&lt;/td&gt;
&lt;td&gt;Transformers &amp;amp; massive pre-training&lt;/td&gt;
&lt;td&gt;Transformer, BERT, GPT-2/3 pre-2022&lt;/td&gt;
&lt;td&gt;Pre-train on web data; fine-tune downstream&lt;/td&gt;
&lt;td&gt;Foundation-model engineer&lt;/td&gt;
&lt;td&gt;Broad knowledge; zero-shot transfer; huge training cost&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3.0&lt;/td&gt;
&lt;td&gt;LLM chat&lt;/td&gt;
&lt;td&gt;2022&lt;/td&gt;
&lt;td&gt;Conversational text &amp;amp; code gen, reasoning&lt;/td&gt;
&lt;td&gt;ChatGPT, Claude, Gemini, Deepseek&lt;/td&gt;
&lt;td&gt;Conversation, copy/paste code &amp;amp; errors&lt;/td&gt;
&lt;td&gt;Prompt engineer&lt;/td&gt;
&lt;td&gt;Great for synthesis &amp;amp; translation; needs validation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3.1&lt;/td&gt;
&lt;td&gt;LLM agents&lt;/td&gt;
&lt;td&gt;2025&lt;/td&gt;
&lt;td&gt;Autonomous tool use &amp;amp; multi-step planning&lt;/td&gt;
&lt;td&gt;Devin, Claude Code, Codex, Github Copilot&lt;/td&gt;
&lt;td&gt;Write instructions, review results, iterate&lt;/td&gt;
&lt;td&gt;Context engineer&lt;/td&gt;
&lt;td&gt;Delegates work; must sandbox &amp;amp; supervise for safety&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;The numbering has gotten a bit unwieldly, but I decided to keep it
this way so that it keeps a direct connection to Karpathy&#39;s numbering.&lt;/p&gt;
&lt;p&gt;A few thoughts on this table:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Software 2.*&lt;/em&gt;: These paradigms were foundational for what was to
come but for a number of reasons these had much narrower adoption in
the software industry than what came before and what has come after.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Software 3.1&lt;/em&gt;: Agentic LLMs feels like an entirely different mode
of developing software that is worthy of it&#39;s own paradigm.&lt;/li&gt;
&lt;li&gt;I originally had a separate &amp;quot;LLM reasoning&amp;quot; row but I realized this
was really just an improvement to the &amp;quot;LLM Chat&amp;quot; paradigm because it
doesn&#39;t change the fundamental mode of programming or the human role
so I combined it into &amp;quot;LLM Chat&amp;quot;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;note&quot;&gt;Note&lt;/h2&gt;
&lt;p&gt;I worked with ChatGPT (o3 and 4o) to populate and refine the tables
above (and double checked and refined using wikipedia). The rest of
the text was written by hand with some brainstorming and review by
ChatGPT 4o.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>A new LLM Coding Agent in 5 incremental steps and less than 80 lines of python</title>
    <link href="https://example.com/blog/llm-agent-in-five-steps/" />
    <updated>2025-06-12T00:00:00Z</updated>
    <id>https://example.com/blog/llm-agent-in-five-steps/</id>
    <content type="html">&lt;p&gt;&lt;strong&gt;Updates&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;2025-06-16: add Github Copilot authentication command to prerequisites&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;2025-06-20: example of output from Github Copilot device auth flow&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this post I will show you how to create a working LLM coding agent in 5 incremental steps. We will use Simon Willison&#39;s &lt;a href=&quot;https://github.com/simonw/llm&quot;&gt;llm&lt;/a&gt; library and John Daly&#39;s &lt;a href=&quot;https://github.com/jmdaly/llm-github-copilot&quot;&gt;llm-github-copilot&lt;/a&gt; plugin. The plugin gives us access to LLM models via Github Copilot which means all you need to get started is a github account (no LLM API sign-up/credit card required).&lt;/p&gt;
&lt;p&gt;This is very similar to a previous previous post &lt;a href=&quot;https://example.com/blog/litellm-agent-in-six-steps/&quot;&gt;An LLM Coding Agent in 6 incremental steps and about 140 lines of python&lt;/a&gt;. The key difference is the use of &lt;a href=&quot;https://github.com/simonw/llm&quot;&gt;llm&lt;/a&gt; instead of LiteLLM. The resulting agent is much more concise and hopefully easier to understand.&lt;/p&gt;
&lt;h1 id=&quot;step-0-prerequisites-uv-llm-etc&quot;&gt;Step 0: Prerequisites (uv, llm, etc)&lt;/h1&gt;
&lt;p&gt;You will either need a Github account (to access Github Copilot) or you will need LLM API keys with some billing credits. I recommend starting with the Github Copilot.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create a directory for your agent:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;em&gt;$ mkdir my-agent&lt;/em&gt;
&lt;em&gt;$ cd my-agent&lt;/em&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Install &lt;code&gt;uv&lt;/code&gt; (if you have not already) and then setup a python
virtual environment:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;em&gt;$ curl -LsSf https://astral.sh/uv/install.sh | sh&lt;/em&gt;
&lt;em&gt;$ uv venv&lt;/em&gt;
&lt;em&gt;$ source .venv/bin/activate&lt;/em&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Install versions of &lt;a href=&quot;https://github.com/simonw/llm&quot;&gt;llm&lt;/a&gt; and the
&lt;a href=&quot;https://github.com/jmdaly/llm-github-copilot&quot;&gt;llm-github-copilot&lt;/a&gt;
plugin that have sufficient tool calling support.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;em&gt;$ uv pip install &quot;git+https://github.com/simonw/llm.git&quot;&lt;/em&gt;
&lt;em&gt;$ uv pip install &quot;git+https://github.com/jmdaly/llm-github-copilot.git@refs/pull/18/head#egg=llm_github_copilot&quot;&lt;/em&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Authenticate with Github Copilot. You will be shown an 8 character
code that you need to fill in at the provided github URL in order to
authorize this client. Once you do this, API access token refreshes
will happen automatically.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;em&gt;$ llm github_copilot auth login&lt;/em&gt;
Starting GitHub Copilot login process to obtain an access_token &amp; API key...
Fetching API key...

Please visit https://github.com/login/device and enter code 1234-ABCD to authenticate GitHub Copilot.

Waiting for authorization... (attempt 1/12)
...
Authentication successful!&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We are now ready to start the fun!&lt;/p&gt;
&lt;p&gt;Notes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The full code for each of the steps can be found at &lt;a href=&quot;https://github.com/kanaka/llm-agent&quot;&gt;github.com/kanaka/llm-agent&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;In the examples that follow, user input that is typed into the agent is shown with a &lt;span style=&quot;color: plum&quot;&gt;plum&lt;/span&gt; color.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;step-1-single-api-call&quot;&gt;Step 1: Single API call&lt;/h1&gt;
&lt;picture&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://example.com/blog/llm-agent-in-five-steps/wmzkHP3yKq-582.avif 582w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://example.com/blog/llm-agent-in-five-steps/wmzkHP3yKq-582.webp 582w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://example.com/blog/llm-agent-in-five-steps/wmzkHP3yKq-582.png&quot; alt=&quot;Diagram of Step 1 - Single API call&quot; width=&quot;582&quot; height=&quot;422&quot;&gt;&lt;/picture&gt;
&lt;p&gt;First, we are going to make a single API prompt call to our
chosen LLM model and simply print the result. For this step, we will
pass the first argument on the command line as the prompt that we want
to send the LLM model.&lt;/p&gt;
&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;#!/usr/bin/env python3&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; llm
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; sys
DEFAULT_MODEL &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;github_copilot/o3-mini&quot;&lt;/span&gt;

model &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; llm&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get_model&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;DEFAULT_MODEL&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;prompt&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sys&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;argv&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now run your new &amp;quot;agent&amp;quot;:&lt;/p&gt;
&lt;pre class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;em&gt;$ chmod +x agent.py&lt;/em&gt;

&lt;em&gt;$ ./agent.py &quot;In a single sentence, define the word &#39;agent&#39;&quot;&lt;/em&gt;
An agent is someone or something that acts on behalf of another person or entity, or that produces a specific effect.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We make a single call LLM model and provide it with a single &amp;quot;user&amp;quot;
message. We then print the response message from the LLM.&lt;/p&gt;
&lt;p&gt;Notes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;With the Github Copilot free plan, you get 50 &amp;quot;&lt;a href=&quot;https://docs.github.com/en/copilot/managing-copilot/monitoring-usage-and-entitlements/about-premium-requests&quot;&gt;premium requests&lt;/a&gt;&amp;quot; per
month. The code above uses &amp;quot;&lt;code&gt;github_copilot/o3-mini&lt;/code&gt;&amp;quot; because it is
currently the least expensive model with excellent coding ability
(at 0.33 premium requests per call). The
&amp;quot;&lt;code&gt;github_copilot/gemini-2.0-flash-001&lt;/code&gt;&amp;quot; model is slightly cheaper
(at 0.25 per call) but does not have full tool calling support via
Github Copilot.  If you have paid plan then you can switch the model
to &lt;code&gt;github_copilot/gpt-4.1&lt;/code&gt; to get unlimited &lt;code&gt;completion&lt;/code&gt; calls.&lt;/li&gt;
&lt;li&gt;Refer to &lt;a href=&quot;https://llm.datasette.io/en/latest/python-api.html#basic-prompt-execution&quot;&gt;llm prompt API documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;step-2-chat-loop&quot;&gt;Step 2: Chat loop&lt;/h1&gt;
&lt;picture&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://example.com/blog/llm-agent-in-five-steps/amOhG10w1s-582.avif 582w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://example.com/blog/llm-agent-in-five-steps/amOhG10w1s-582.webp 582w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://example.com/blog/llm-agent-in-five-steps/amOhG10w1s-582.png&quot; alt=&quot;Diagram of Step 2 - Chat loop&quot; width=&quot;582&quot; height=&quot;422&quot;&gt;&lt;/picture&gt;
&lt;p&gt;Our current implementation makes a single query, prints the response,
and then exits. We don&#39;t have a way to &amp;quot;chat&amp;quot; with the model. LLM
models via their direct APIs are essentially stateless. The client
has to provide all the state/context for each call. The llm library
provides a conversation object that will accumlate this state for us.&lt;/p&gt;
&lt;p&gt;Let&#39;s construct a conversation instance and then wrap its prompt calls
in a loop. The loop prompts for a user prompt, calls the
&lt;code&gt;conversation.prompt&lt;/code&gt; API with the user prompt, and then prints the
response.&lt;/p&gt;
&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;#!/usr/bin/env python3&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; llm
DEFAULT_MODEL &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;github_copilot/o3-mini&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Conversation setup&lt;/span&gt;

model &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; llm&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get_model&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;DEFAULT_MODEL&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
conversation &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;conversation&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        user_input &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;user&gt; &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;except&lt;/span&gt; EOFError &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;

    response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; conversation&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;prompt&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;user_input&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;assistant&gt; &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Run our new version of the &amp;quot;agent&amp;quot; (user input is shown with a &lt;span style=&quot;color: plum&quot;&gt;plum&lt;/span&gt; color):&lt;/p&gt;
&lt;pre class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;em&gt;$ ./agent.py&lt;/em&gt;
user&gt; &lt;span style=&quot;color: plum&quot;&gt;List five funny names for a Linux computer (without any explanation):&lt;/span&gt;
assistant&gt; TuxTastic
KernelKicker
BashfulBot
PenguinPirate
SudoSultan
user&gt; &lt;span style=&quot;color: plum&quot;&gt;In a short sentence, explain why the fifth one is funny.&lt;/span&gt;
assistant&gt; SudoSultan is funny because it blends the superuser command &quot;sudo&quot; with a regal title, humorously elevating its authority.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The second user query asks about the assistant&#39;s first response.
A correct answer confirms that the context (previous user and
assistant messages) is being accumulated correctly, otherwise the
assistant would be unable to answer the followup question.&lt;/p&gt;
&lt;h1 id=&quot;step-3-tool-calling&quot;&gt;Step 3: Tool calling&lt;/h1&gt;
&lt;picture&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://example.com/blog/llm-agent-in-five-steps/yaZiPSIGgT-741.avif 741w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://example.com/blog/llm-agent-in-five-steps/yaZiPSIGgT-741.webp 741w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://example.com/blog/llm-agent-in-five-steps/yaZiPSIGgT-741.png&quot; alt=&quot;Diagram of Step 3 - Tool calling&quot; width=&quot;741&quot; height=&quot;422&quot;&gt;&lt;/picture&gt;
&lt;p&gt;Our &amp;quot;agent&amp;quot; does not have much agency; it can&#39;t do anything unless it
can convince the user to act on it&#39;s behalf. If I ask &amp;quot;Show me what&#39;s
in file ./README.md.&amp;quot;, the assistant will likely answer that it can&#39;t
do that, but will give suggestions to the user for how to view the
file themselves.&lt;/p&gt;
&lt;p&gt;Let&#39;s take a step towards greater agency by defining a tool that the
assistant can invoke. Define a function &lt;code&gt;read_file&lt;/code&gt; that the
assistant can invoke and add it to a tools list:&lt;/p&gt;
&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Tool definitions&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;read_file&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;Read the file at path. Returns a map {&#39;content&#39;:content}&quot;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;read&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

tools &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;read_file&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&#39;s also define some debug functions for concisely showing tool
calls and responses and then pass the tools&lt;/p&gt;
&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;trunc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;...&#39;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;max&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; s

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;before_call&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tool&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; tool_call&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;trunc&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;tool call&gt; &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;tool&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;tool_call&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;arguments&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;)&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;after_call&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tool&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; tool_call&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; tool_result&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;trunc&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;tool result&gt; &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;tool_result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;output&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We need to include the tools list and debug functions when we
instantiate our conversation instance:&lt;/p&gt;
&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;model &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; llm&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get_model&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;DEFAULT_MODEL&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
conversation &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;conversation&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    tools&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;tools&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    before_call&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;before_call&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    after_call&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;after_call&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, in our loop, we use the &lt;code&gt;conversation.chain&lt;/code&gt; method instead
of the &lt;code&gt;prompt&lt;/code&gt; method.&lt;/p&gt;
&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;    response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; conversation&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;chain&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;user_input&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;chain&lt;/code&gt; method will will automatically
detect when the assistant returns a response containing a tool call.
It will then run that tool and send the result of the tool to the
assistant. All tool calls are resolved before the &lt;code&gt;chain&lt;/code&gt; method
returns with the final assistant response.&lt;/p&gt;
&lt;p&gt;Run our new version of the &amp;quot;agent&amp;quot;:&lt;/p&gt;
&lt;pre class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;em&gt;$ ./agent.py&lt;/em&gt;
user&gt; &lt;span style=&quot;color: plum&quot;&gt;List the imports in ./agent.py&lt;/span&gt;
tool call&gt; read_file({&#39;path&#39;: &#39;./agent.py&#39;})
tool result&gt; {&quot;content&quot;: &quot;#!/usr/bin/env python3&#92;n&#92;nimport llm&#92;nDEFAULT_MODE...
assistant&gt; The file contains a single import:

import llm&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Refer to &lt;a href=&quot;https://llm.datasette.io/en/latest/python-api.html#conversations&quot;&gt;llm conversation API documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;step-4-file-editing-tools&quot;&gt;Step 4: File editing tools&lt;/h1&gt;
&lt;picture&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://example.com/blog/llm-agent-in-five-steps/6-ViYEXYzE-741.avif 741w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://example.com/blog/llm-agent-in-five-steps/6-ViYEXYzE-741.webp 741w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://example.com/blog/llm-agent-in-five-steps/6-ViYEXYzE-741.png&quot; alt=&quot;Diagram of Step 4 - file editing tools&quot; width=&quot;741&quot; height=&quot;422&quot;&gt;&lt;/picture&gt;
&lt;p&gt;Our agent has the ability to read files, now let&#39;s make the final
small change that will turn it into a true coding agent. All that is
need is a few more functions that give it the ability to list files,
edit files, and create files.&lt;/p&gt;
&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; subprocess

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ls_dir&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;Runs `ls -la path` to list files in the current directory.
    Returns a map {&#39;stdout&#39;:stdout,&#39;stderr&#39;:stderr,&#39;returncode&#39;:code}&quot;&quot;&quot;&lt;/span&gt;
    cp &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; subprocess&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;run&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ls&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;-la&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; path&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; capture_output&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; text&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    res &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;k&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;getattr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cp&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; k&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; k &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;stdout&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;stderr&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;returncode&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; res

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;edit_file&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; replace&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;Edit the file at &#39;path&#39; replacing the first occurence of
    &#39;match&#39; string with &#39;replace&#39; string. &#39;match&#39; and &#39;replace&#39; are
    raw strings and should not have escaped newlines, backslashes, etc.
    Returns an empty map on success&quot;&quot;&quot;&lt;/span&gt;
    orig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;read&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    new &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; orig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;replace&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; replace&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; new &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; orig&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;raise&lt;/span&gt; Exception&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;match string not found&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;w&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;write&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;new&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;create_file&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; content&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;Create (or replace) file at &#39;path&#39; with &#39;content&#39;.
    &#39;content&#39; is a raw string and does not need extra escaping.
    Returns an empty map on success&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;w&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;write&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

tools &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;read_file&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ls_dir&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; edit_file&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; create_file&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now let&#39;s use the new editing ability to make changes to a file:&lt;/p&gt;
&lt;pre class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;em&gt;$ echo &#39;hello NAME!&#39; &gt; greet.txt&lt;/em&gt;

&lt;em&gt;$ ./agent.py&lt;/em&gt;
user&gt; &lt;span style=&quot;color: plum&quot;&gt;Change the greeting in the text file to use my first name.&lt;/span&gt;
assistant&gt; I need a bit more information before proceeding. Could you please tell me the file name (or path) of the text file you want to change, and also provide your first name that should be used in the greeting?
user&gt; &lt;span style=&quot;color: plum&quot;&gt;My name is Joel. You find the file.&lt;/span&gt;
tool call&gt; ls_dir({&#39;path&#39;: &#39;.&#39;})
tool result&gt; {&quot;stdout&quot;: &quot;total 20&#92;ndrwxrwxr-x  3 joelmartin joelmartin 4096 ...
tool call&gt; read_file({&#39;path&#39;: &#39;greet.txt&#39;})
tool result&gt; {&quot;content&quot;: &quot;hello NAME!&#92;n&quot;}
tool call&gt; edit_file({&#39;match&#39;: &#39;NAME&#39;, &#39;path&#39;: &#39;greet.txt&#39;, &#39;replace&#39;: &#39;Joel&#39;})
tool result&gt; {}
assistant&gt; I&#39;ve updated greet.txt so that the greeting now reads &quot;hello Joel!&quot; Let me know if you need any further changes.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that sometimes the model will not ask the clarifying questions
and will use the result of &lt;code&gt;ls_dir&lt;/code&gt; to guess the first name based on
directory/file ownership.&lt;/p&gt;
&lt;h1 id=&quot;step-5-final-changes-and-a-sprinkle-of-inception&quot;&gt;Step 5: Final changes (and a sprinkle of inception)&lt;/h1&gt;
&lt;p&gt;Those four simple tools/abilities (list files, read a file, edit
a file, and create a file) are enough to give our agent the ability to
do coding tasks. So let&#39;s use our agent itself to make some final
improvements to its own code.&lt;/p&gt;
&lt;pre class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;em&gt;$ ./agent.py&lt;/em&gt;
user&gt; &lt;span style=&quot;color: plum&quot;&gt;Copy agent.py to agent2.py where we will make changes. Use correct python indenting for all future changes.&lt;/span&gt;
tool call&gt; read_file({&#39;path&#39;: &#39;agent.py&#39;})
tool result&gt; {&quot;content&quot;: &quot;#!/usr/bin/env python3&#92;n&#92;nimport llm&#92;nDEFAULT_MODE...
tool call&gt; create_file({&#39;content&#39;: &#39;#!/usr/bin/env python3&#92;n&#92;nimport llm&#92;nDE...
tool result&gt; {}
assistant&gt; agent2.py has been created with the same content as agent.py. Let me know what changes you&#39;d like to make next.
user&gt; &lt;span style=&quot;color: plum&quot;&gt;Add a friendly startup message showing the model.&lt;/span&gt;
tool call&gt; edit_file({&#39;match&#39;: &#39;)&#92;n&#92;nwhile True:&#39;, &#39;path&#39;: &#39;agent2.py&#39;, &#39;rep...
tool result&gt; {}
assistant&gt; I&#39;ve inserted a friendly startup message that displays the model in agent2.py. Let me know if you need any other modifications.
user&gt; &lt;span style=&quot;color: plum&quot;&gt;For the three prints and the input call, colorize the part before the &#39;&gt;&#39; using ASCII escape codes (red, green, blue, purple).&lt;/span&gt;
tool call&gt; edit_file({&#39;match&#39;: &#39;input(&quot;user&gt; &quot;&#39;, &#39;path&#39;: &#39;agent2.py&#39;, &#39;repla...
tool result&gt; {}
tool call&gt; edit_file({&#39;match&#39;: &#39;tool call&gt;&#39;, &#39;path&#39;: &#39;agent2.py&#39;, &#39;replace&#39;:...
tool result&gt; {}
tool call&gt; edit_file({&#39;match&#39;: &#39;tool result&gt;&#39;, &#39;path&#39;: &#39;agent2.py&#39;, &#39;replace...
tool result&gt; {}
tool call&gt; edit_file({&#39;match&#39;: &#39;assistant&gt;&#39;, &#39;path&#39;: &#39;agent2.py&#39;, &#39;replace&#39;:...
tool result&gt; {}
assistant&gt; I&#39;ve updated agent2.py to colorize the parts before the &#39;&gt;&#39; using the specified ASCII escape codes:
- The input prompt now colors &quot;user&quot; in red,
- The &quot;tool call&gt;&quot; prefix is colored in green,
- The &quot;tool result&gt;&quot; prefix is colored in blue,
- The &quot;assistant&gt;&quot; prefix is colored in purple.

Let me know if there are any further changes you&#39;d like to apply!
user&gt; &lt;span style=&quot;color: plum&quot;&gt;Before calling a tool, confirm with the user. If confirmed continue as before, otherwise raise a llm.CancelToolCall exception with a &quot;User Refused&quot; message.&lt;/span&gt;
tool call&gt; edit_file({&#39;match&#39;: &#39;print(trunc(f&quot;&#92;&#92;033[32mtool call&#92;&#92;033[0m&gt; {t...
tool result&gt; {}
assistant&gt; I&#39;ve updated the agent2.py before_call function to confirm with the user before calling a tool. The tool call will now prompt the user with &quot;Proceed with tool call? (y/n)&quot; and raise a llm.CancelToolCall exception if the user does not confirm.

Let me know if additional modifications are needed!&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now review the code changes and then test our agent modified agent:&lt;/p&gt;
&lt;pre class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;em&gt;$ diff -urp agent.py agent2.py&lt;/em&gt;
...

&lt;em&gt;$ chmod +x agent2.py&lt;/em&gt;

&lt;em&gt;$ ./agent2.py&lt;/em&gt;
Agent started with model: github_copilot/o3-mini
&lt;span style=&quot;color: red&quot;&gt;user&lt;/span&gt;&gt; &lt;span style=&quot;color: plum&quot;&gt;What is in ./greet.txt?&lt;/span&gt;
&lt;span style=&quot;color: green&quot;&gt;tool call&lt;/span&gt;&gt; read_file({&#39;path&#39;: &#39;./greet.txt&#39;})
Proceed with tool call? (y/n) &lt;span style=&quot;color: plum&quot;&gt;y&lt;/span&gt;
&lt;span style=&quot;color: blue&quot;&gt;tool result&lt;/span&gt;&gt; {&quot;content&quot;: &quot;hello Joel!&#92;n&quot;}
&lt;span style=&quot;color: purple&quot;&gt;assistant&lt;/span&gt;&gt; The file contains: &quot;hello Joel!&quot; followed by a newline.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The full code for each of the steps can be found at &lt;a href=&quot;https://github.com/kanaka/llm-agent&quot;&gt;github.com/kanaka/llm-agent&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;step-6-you-take-it-from-here&quot;&gt;Step 6: You take it from here!&lt;/h1&gt;
&lt;p&gt;You now have a basic working coding agent. The next steps are up to
you. Here are some ideas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add streaming output so that you can see the progress of the model
as it is generating longer responses.&lt;/li&gt;
&lt;li&gt;Make the tool confirmation more sophisticated and allow specific
actions or whole tools to be run without confirmation the next time.&lt;/li&gt;
&lt;li&gt;Add proper python argument parsing. Allow the model name, system
prompt, tool confirmation mode, etc to be specified as command
line. Allow the initial query to optionally be specified on the
command line (like step 1).&lt;/li&gt;
&lt;li&gt;Give it the ability to run tests.&lt;/li&gt;
&lt;/ul&gt;
</content>
  </entry>
  <entry>
    <title>An LLM Coding Agent in 6 incremental steps and about 140 lines of python</title>
    <link href="https://example.com/blog/litellm-agent-in-six-steps/" />
    <updated>2025-05-01T00:00:00Z</updated>
    <id>https://example.com/blog/litellm-agent-in-six-steps/</id>
    <content type="html">&lt;p&gt;&lt;strong&gt;[Refer to &lt;a href=&quot;https://example.com/blog/llm-agent-in-five-steps&quot;&gt;LLM Agent in Five Steps&lt;/a&gt; for a shorter/simpler version of this tutorial that leverages the llm python module instead of LiteLLM]&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Updates&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;2025-05-06: more detail around tool calling and parameter inspection&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;2025-06-20: simplify litellm dependency install.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this post I will show you how to create a working LLM coding agent in 6 incremental steps. We will use the python LiteLLM library and use Github Copilot which means all you need is a github account (in other words, no LLM API sign-up is needed to get started). The full code for each step shown below can be found at &lt;a href=&quot;https://github.com/kanaka/litellm-agent&quot;&gt;github.com/kanaka/litellm-agent&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&quot;step-0-prerequisites-uv-litellm-etc&quot;&gt;Step 0: Prerequisites (uv, LiteLLM, etc)&lt;/h1&gt;
&lt;p&gt;You will either need a Github account (to access Github Copilot) or you will need LLM API keys with some billing credits. I recommend starting with the Github Copilot.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create a directory for your agent:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;em&gt;$ mkdir my-agent&lt;/em&gt;
&lt;em&gt;$ cd my-agent&lt;/em&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Install &lt;code&gt;uv&lt;/code&gt; (if you have not already) and then setup a virtual
environment:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;em&gt;$ curl -LsSf https://astral.sh/uv/install.sh | sh&lt;/em&gt;
&lt;em&gt;$ uv venv&lt;/em&gt;
&lt;em&gt;$ source .venv/bin/activate&lt;/em&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Install a branch of the LiteLLM project (into the venv) that has
support for Github Copilot models.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;em&gt;$ uv pip install git+https://github.com/BerriAI/litellm.git@litellm_dev_03_05_2025_contributor_prs&lt;/em&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note: in the examples that follow, user input that is typed into the agent is shown with a &lt;span style=&quot;color: plum&quot;&gt;plum&lt;/span&gt; color.&lt;/p&gt;
&lt;p&gt;We are now ready to start the fun!&lt;/p&gt;
&lt;h1 id=&quot;step-1-single-api-call&quot;&gt;Step 1: Single API call&lt;/h1&gt;
&lt;picture&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://example.com/blog/litellm-agent-in-six-steps/xBMWhq-GCX-661.avif 661w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://example.com/blog/litellm-agent-in-six-steps/xBMWhq-GCX-661.webp 661w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://example.com/blog/litellm-agent-in-six-steps/xBMWhq-GCX-661.png&quot; alt=&quot;Diagram of Step 1 - Single API call&quot; width=&quot;661&quot; height=&quot;421&quot;&gt;&lt;/picture&gt;
&lt;p&gt;First, we are going to make a single API &amp;quot;completion&amp;quot; call to our
chosen LLM model and simply print the result. For this step, we will
pass the first argument on the command line as the query that we want
to send the LLM model.&lt;/p&gt;
&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;#!/usr/bin/env python3&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; litellm &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; completion
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; sys

model &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;github_copilot/o3-mini&quot;&lt;/span&gt;
extra_headers &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;editor-version&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;vscode/1.85.1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; completion&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    extra_headers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;extra_headers&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    messages&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; sys&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;argv&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;choices&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now run your new &amp;quot;agent&amp;quot;:&lt;/p&gt;
&lt;pre class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;em&gt;$ chmod +x agent.py&lt;/em&gt;

&lt;em&gt;$ ./agent.py &quot;In a single sentence, define the word &#39;agent&#39;&quot;&lt;/em&gt;
An agent is someone or something that acts on behalf of another person or entity, or that produces a specific effect.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We make a single call LLM model and provide it with a single &amp;quot;user&amp;quot;
message. We then extract the response message from the LLM and print
it. The LiteLLM &lt;code&gt;completion&lt;/code&gt; function is based on OpenAPI defined API.
While other providers have similar APIs, they do have differences.
LiteLLM provides a common API that has the same input and output
format across all the providers.&lt;/p&gt;
&lt;p&gt;Notes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The first time you run your agent with a Github Copilot model, you
will be shown an 8 character code that you need to fill in at the
provided github URL in order to authorize this client. Once you do
this, API access token refreshes will happen automatically.&lt;/li&gt;
&lt;li&gt;With the Github Copilot free plan, you get 50 &amp;quot;&lt;a href=&quot;https://docs.github.com/en/copilot/managing-copilot/monitoring-usage-and-entitlements/about-premium-requests&quot;&gt;premium requests&lt;/a&gt;&amp;quot; per
month. The code above uses &amp;quot;&lt;code&gt;github_copilot/o3-mini&lt;/code&gt;&amp;quot; because it is
currently the least expensive model with excellent coding ability
(at 0.33 premium requests per call). The
&amp;quot;&lt;code&gt;github_copilot/gemini-2.0-flash-001&lt;/code&gt;&amp;quot; model is slightly cheaper
(at 0.25 per call) but my experience is that it has trouble using
tools correctly. If you have paid plan then you can switch the model
to &lt;code&gt;github_copilot/gpt-4&lt;/code&gt; to get unlimited &lt;code&gt;completion&lt;/code&gt; calls.&lt;/li&gt;
&lt;li&gt;The &amp;quot;editor-version&amp;quot; HTTP header is needed for now in order to use
the &amp;quot;Github Copilot&amp;quot; functionality in the LiteLLM branch.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;step-2-chat-loop&quot;&gt;Step 2: Chat loop&lt;/h1&gt;
&lt;picture&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://example.com/blog/litellm-agent-in-six-steps/kovDu6KVix-661.avif 661w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://example.com/blog/litellm-agent-in-six-steps/kovDu6KVix-661.webp 661w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://example.com/blog/litellm-agent-in-six-steps/kovDu6KVix-661.png&quot; alt=&quot;Diagram of Step 2 - Chat loop&quot; width=&quot;661&quot; height=&quot;421&quot;&gt;&lt;/picture&gt;
&lt;p&gt;Our current implementation makes a single query, prints the response,
and then exits. We don&#39;t have a way to &amp;quot;chat&amp;quot; with the model. LLM
models via the API are essentially stateless. The client program has
to provide all the state/context for each call.&lt;/p&gt;
&lt;p&gt;Let&#39;s wrap the completion call and output in a loop. Prior to the loop
we initialize a messages list (context) with our initial system
prompt. The loop prompts for a user query, adds this to the context,
calls the &lt;code&gt;completion&lt;/code&gt; API, and then adds the assistant (LLM model)
response to the messages list in addition to printing it out.&lt;/p&gt;
&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;messages &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;You are a coding agent&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;system&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        user_input &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;user&gt; &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;except&lt;/span&gt; EOFError &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;
    messages&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; user_input&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; completion&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        extra_headers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;extra_headers&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        messages&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;messages&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    resp_message &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;choices&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;message
    messages&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;resp_message&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;model_dump&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;assistant&gt; &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;resp_message&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Run our new version of the &amp;quot;agent&amp;quot; (user input is shown with a &lt;span style=&quot;color: plum&quot;&gt;plum&lt;/span&gt; color):&lt;/p&gt;
&lt;pre class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;em&gt;$ ./agent.py&lt;/em&gt;
user&gt; &lt;span style=&quot;color: plum&quot;&gt;List five funny names for a Linux computer (without any explanation):&lt;/span&gt;
assistant&gt; TuxTastic
KernelKicker
BashfulBot
PenguinPirate
SudoSultan
user&gt; &lt;span style=&quot;color: plum&quot;&gt;In a short sentence, explain why the fifth one is funny.&lt;/span&gt;
assistant&gt; SudoSultan is funny because it blends the superuser command &quot;sudo&quot; with a regal title, humorously elevating its authority.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The second user query asks about the assistant&#39;s first response.
A correct answer confirms that the context (messages list) is being
accumulated correctly, otherwise the assistant would not be able to
answer the followup.&lt;/p&gt;
&lt;h1 id=&quot;step-3-tool-calling&quot;&gt;Step 3: Tool calling&lt;/h1&gt;
&lt;picture&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://example.com/blog/litellm-agent-in-six-steps/wuJSFjvRin-661.avif 661w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://example.com/blog/litellm-agent-in-six-steps/wuJSFjvRin-661.webp 661w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://example.com/blog/litellm-agent-in-six-steps/wuJSFjvRin-661.png&quot; alt=&quot;Diagram of Step 3 - Tool calling&quot; width=&quot;661&quot; height=&quot;421&quot;&gt;&lt;/picture&gt;
&lt;p&gt;Our &amp;quot;agent&amp;quot; does not have much agency; it can&#39;t do anything unless it
can convince the user to act on it&#39;s behalf. If I ask &amp;quot;Show me what&#39;s
in file ./README.md.&amp;quot;, the assistant will likely answer that it can&#39;t
do that, but will give suggestions to the user for how to view the
file themselves.&lt;/p&gt;
&lt;p&gt;Let&#39;s take a step towards greater agency by defining a tool that the
assistant can invoke. First, create an API data structure
that defines tools in a format the assistant understands. The
following defines a single tool &lt;code&gt;read_file&lt;/code&gt; that the assistant can
invoke:&lt;/p&gt;
&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; json
tools &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;function&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;function&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token string&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;read_file&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Read the file at path. Returns a map {&#39;content&#39;:content}&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string&quot;&gt;&quot;parameters&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token string&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;object&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token string&quot;&gt;&quot;properties&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token string&quot;&gt;&quot;path&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;string&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token string&quot;&gt;&quot;required&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;path&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We pass this new tools structure in the &lt;code&gt;completion&lt;/code&gt; call:&lt;/p&gt;
&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;    response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; completion&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        extra_headers&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;extra_headers&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        messages&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;messages&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        tools&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;tools&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&#39;s add a &lt;code&gt;trunc&lt;/code&gt; function for abbreviating long output messages
that we&#39;ll use in the next step:&lt;/p&gt;
&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;trunc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;...&#39;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;max&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; s&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If the assistant decides that it wants to call a tool, then the
response message will contain a populated &lt;code&gt;tool_calls&lt;/code&gt; field. If this
field is set and the tool name is &lt;code&gt;read_file&lt;/code&gt;, then we parse
the arguments (which are encoded as a JSON string), then we read the
file referred to in the &lt;code&gt;path&lt;/code&gt; argument, and finally we append a tool
call response to the context (messages list). The response message
contains the original unique ID for this tool call and has a &amp;quot;content&amp;quot;
field that contains the JSON encoded result of the tool call. Replace
the assistant output message line as follows:&lt;/p&gt;
&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;    tool_calls &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; resp_message&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tool_calls
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;not&lt;/span&gt; tool_calls&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;assistant&gt; &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;resp_message&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;continue&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; tc &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; tool_calls&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        fn &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; tc&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;function&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; fn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;read_file&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            fn_args &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; json&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;loads&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;fn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;arguments&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;trunc&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;calling read_file(&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;fn_args&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;)&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            fn_result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;fn_args&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;path&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;read&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            res_str &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; json&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dumps&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;fn_result&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;trunc&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;result: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;res_str&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            messages&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token string&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;tool&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token string&quot;&gt;&quot;tool_call_id&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; tc&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;id&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token string&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token string&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; res_str&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;raise&lt;/span&gt; Exception&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;Unknown tool call: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;fn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There is one additional change that we need to make to the top of our
loop. If the last message from the assistant is a tool call, then we
should skip the user input/prompt and just send the tool call result
that we added:&lt;/p&gt;
&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; messages&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;tool&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            user_input &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;user&gt; &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;except&lt;/span&gt; EOFError &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;
        messages&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; user_input&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;role&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Run our new version of the &amp;quot;agent&amp;quot;:&lt;/p&gt;
&lt;pre class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;em&gt;$ ./agent.py&lt;/em&gt;
user&gt; &lt;span style=&quot;color: plum&quot;&gt;What is the first line of file ./agent.py?&lt;/span&gt;
calling read_file({&#39;path&#39;: &#39;./agent.py&#39;})
result: {&quot;content&quot;: &quot;#!/usr/bin/env python3&#92;n&#92;nfrom litellm import completio...
assistant&gt; The first line of the file is: #!/usr/bin/env python3&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&quot;step-4-generic-tools-interface&quot;&gt;Step 4: Generic tools interface&lt;/h1&gt;
&lt;picture&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://example.com/blog/litellm-agent-in-six-steps/pH2GiUzlw3-661.avif 661w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://example.com/blog/litellm-agent-in-six-steps/pH2GiUzlw3-661.webp 661w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://example.com/blog/litellm-agent-in-six-steps/pH2GiUzlw3-661.png&quot; alt=&quot;Diagram of Step 4 - generic tools&quot; width=&quot;661&quot; height=&quot;581&quot;&gt;&lt;/picture&gt;
&lt;p&gt;The current implementation uses a hard-coded definition for the
&lt;code&gt;read_file&lt;/code&gt; tool that is passed to the &lt;code&gt;completion&lt;/code&gt; API. Instead of
creating a new definition for each tool that we want to support, we
can use python&#39;s introspection to generate this definition from the
python functions themselves. The &lt;code&gt;inspect.signature&lt;/code&gt; function returns
detailed information about each parameter of a python function. We use
this information to construct the map of parameter map needed for the
&lt;code&gt;completion&lt;/code&gt; call.&lt;/p&gt;
&lt;p&gt;Define a function that that takes a map of tools names to functions
and returns the &lt;code&gt;tools&lt;/code&gt; value needed for the &lt;code&gt;completion&lt;/code&gt; API:&lt;/p&gt;
&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; inspect

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;get_tools_param&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tools_map&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    typemap &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;integer&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;number&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;boolean&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    tools &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; fn &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; tools_map&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;items&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        props&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; req &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; p &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; inspect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;signature&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;fn&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;parameters&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;values&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;kind&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;startswith&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;VAR&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# skip *args/**kw&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;continue&lt;/span&gt;
            props&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; typemap&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;annotation&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;string&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;default &lt;span class=&quot;token keyword&quot;&gt;is&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;empty&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
                req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        tools&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token string&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;function&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token string&quot;&gt;&quot;function&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token string&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token string&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;fn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;__doc__ &lt;span class=&quot;token keyword&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;strip&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token string&quot;&gt;&quot;parameters&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token string&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;object&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;token string&quot;&gt;&quot;properties&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; props&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;token operator&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;required&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; req&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; req &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; tools&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then define the tool functions with a sufficient docstring and result
format that makes it clear to the assistant how the tools should be
used:&lt;/p&gt;
&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;read_file&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;Read the file at path.
    Returns a map {&#39;content&#39;:content} (raw file string in content)&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;read&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; subprocess

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ls_dir&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;Runs `ls -la path` to list files in the current directory.
    Returns a map {&#39;stdout&#39;:stdout,&#39;stderr&#39;:stderr,&#39;returncode&#39;:code}&quot;&quot;&quot;&lt;/span&gt;
    cp &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; subprocess&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;run&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ls&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;-la&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; path&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; capture_output&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; text&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    res &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;k&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;getattr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cp&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; k&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; k &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;stdout&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;stderr&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;returncode&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; res&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Remove the global &lt;code&gt;tools&lt;/code&gt; variable and add a new tools map (after the
tool functions) that enumerates the available tools including the new
&lt;code&gt;ls_dir&lt;/code&gt; tool/function.&lt;/p&gt;
&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;TOOLS_MAP &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;read_file&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; read_file&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;ls_dir&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ls_dir&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Prior to our main loop use the &lt;code&gt;get_tools_param&lt;/code&gt; function to
initialize the &lt;code&gt;tools&lt;/code&gt; value that is passed to the &lt;code&gt;completion&lt;/code&gt; call:&lt;/p&gt;
&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;tools &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; get_tools_param&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;TOOLS_MAP&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, adjust the tool calling loop to use a more generic mechanism
for calling the tools defined in the &lt;code&gt;TOOLS_MAP&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; tc &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; tool_calls&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        fn &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; tc&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;function&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; fn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; TOOLS_MAP&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            fn_args &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; json&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;loads&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;fn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;arguments&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;trunc&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;calling &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;fn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;fn_args&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;)&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            fn_result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; TOOLS_MAP&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;fn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;**&lt;/span&gt;fn_args&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&#39;s try it out:&lt;/p&gt;
&lt;pre class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;em&gt;$ ./agent.py&lt;/em&gt;
user&gt; &lt;span style=&quot;color: plum&quot;&gt;Summarize the functionality of the python file in this dir in one sentence.&lt;/span&gt;
calling ls_dir({&#39;path&#39;: &#39;.&#39;})
result: {&quot;stdout&quot;: &quot;total 16&#92;ndrwxrwxr-x@  7 joelmartin  staff   224 May  2 ...
calling read_file({&#39;path&#39;: &#39;./agent.py&#39;})
result: {&quot;content&quot;: &quot;#!/usr/bin/env python3&#92;n&#92;nfrom litellm import completio...
assistant&gt; This Python script implements an interactive command-line coding agent that leverages a language model to process user inputs and execute defined filesystem tools (such as reading files and listing directory contents) based on dynamically generated tool calls.&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&quot;step-5-file-editing-tools&quot;&gt;Step 5: File editing tools&lt;/h1&gt;
&lt;picture&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://example.com/blog/litellm-agent-in-six-steps/kVS9jZklWR-661.avif 661w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://example.com/blog/litellm-agent-in-six-steps/kVS9jZklWR-661.webp 661w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://example.com/blog/litellm-agent-in-six-steps/kVS9jZklWR-661.png&quot; alt=&quot;Diagram of Step 5 - file editing tools&quot; width=&quot;661&quot; height=&quot;581&quot;&gt;&lt;/picture&gt;
&lt;p&gt;Our agent has the ability to list and read files, now let&#39;s make the
final improvement that will actually turn this into a coding agent.&lt;/p&gt;
&lt;p&gt;Define the functions that will allow the agent to edit and
create new files and add them to the &lt;code&gt;TOOLS_MAP&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;edit_file&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; replace&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;Edit the file at &#39;path&#39; replacing the first occurence of
    &#39;match&#39; string with &#39;replace&#39; string. &#39;match&#39; and &#39;replace&#39; are
    raw strings and should not have escaped newlines, backslashes, etc.
    Returns an empty map on success&quot;&quot;&quot;&lt;/span&gt;
    orig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;read&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    new &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; orig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;replace&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; replace&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; new &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; orig&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;raise&lt;/span&gt; Exception&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;match string not found&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;w&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;write&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;new&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;create_file&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; content&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token triple-quoted-string string&quot;&gt;&quot;&quot;&quot;Create (or replace) file at &#39;path&#39; with &#39;content&#39;.
    &#39;content&#39; is a raw string and does not need extra escaping.
    Returns an empty map on success&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;w&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;write&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

TOOLS_MAP &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;read_file&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; read_file&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;ls_dir&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ls_dir&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;edit_file&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; edit_file&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;create_file&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; create_file&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Those new tools enable a large amount of agentic coding ability. Let&#39;s
improve the error handling and format of the tool calling messages:&lt;/p&gt;
&lt;pre class=&quot;language-python&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;            &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;trunc&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;tool call&gt; &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;fn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;fn_args&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;)&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
                fn_result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; TOOLS_MAP&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;fn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;**&lt;/span&gt;fn_args&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;except&lt;/span&gt; Exception &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
                fn_result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;error&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            res_str &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; json&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dumps&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;fn_result&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;trunc&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;tool result&gt; &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;res_str&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            message&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;append&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now let&#39;s use the new editing ability to make changes to a file:&lt;/p&gt;
&lt;pre class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;em&gt;$ echo &#39;hello NAME!&#39; &gt; greet.txt&lt;/em&gt;

&lt;em&gt;$ ./agent.py&lt;/em&gt;
user&gt; &lt;span style=&quot;color: plum&quot;&gt;Change the greeting in the text file to use my first name.&lt;/span&gt;
assistant&gt; Could you please clarify two things for me?
1. What is the path or name of the text file you&#39;re referring to?
2. What is your first name that you would like to use in the greeting?
user&gt; &lt;span style=&quot;color: plum&quot;&gt;My name is Joel. You find the file.&lt;/span&gt;
tool call&gt; ls_dir({&#39;path&#39;: &#39;.&#39;})
tool result&gt; {&quot;stdout&quot;: &quot;total 16&#92;ndrwxrwxr-x@  7 joelmartin  staff   224 Ma...
tool call&gt; read_file({&#39;path&#39;: &#39;greet.txt&#39;})
tool result&gt; {&quot;content&quot;: &quot;hello NAME!&#92;n&quot;}
tool call&gt; edit_file({&#39;match&#39;: &#39;NAME&#39;, &#39;replace&#39;: &#39;Joel&#39;, &#39;path&#39;: &#39;greet.txt&#39;})
tool result&gt; {}
assistant&gt; The greeting in greet.txt has been updated to &quot;hello Joel!&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that sometimes the model will not ask the clarifying questions
and will use the result of &lt;code&gt;ls_dir&lt;/code&gt; to guess the first name based on
directory/file ownership.&lt;/p&gt;
&lt;h1 id=&quot;step-6-final-touch-ups&quot;&gt;Step 6: Final touch ups&lt;/h1&gt;
&lt;p&gt;Those four simple tools/abilities (list files, read a file, create a file, and
edit a file) are enough to give our agent the ability to do coding
tasks. So let&#39;s use our agent itself to make some final improvements
to its own code.&lt;/p&gt;
&lt;pre class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;em&gt;$ ./agent.py&lt;/em&gt;
user&gt; &lt;span style=&quot;color: plum&quot;&gt;Copy agent.py to agent2.py where we will make changes. Start by adding a friendly startup message (with model).&lt;/span&gt;
tool call&gt; read_file({&#39;path&#39;: &#39;agent.py&#39;})
tool result&gt; {&quot;content&quot;: &quot;#!/usr/bin/env python3&#92;n&#92;nfrom litellm import comp...
tool call&gt; create_file({&#39;content&#39;: &#39;#!/usr/bin/env python3&#92;n&#92;nfrom litellm i...
tool result&gt; {}
assistant&gt; I&#39;ve created agent2.py with a friendly startup message that prints the model being used.
user&gt; &lt;span style=&quot;color: plum&quot;&gt;For the three prints and the input call, colorize the part before the &#39;&gt;&#39; using ASCII escape codes (red, green, blue, purple).&lt;/span&gt;
tool call&gt; create_file({&#39;content&#39;: &#39;#!/usr/bin/env python3&#92;n&#92;nfrom litellm i...
tool result&gt; {}
assistant&gt; I&#39;ve updated agent2.py to colorize the prompt and prints. Red is now used for the user input, green for tool call, blue for tool result, and purple for assistant&#39;s plain output.
user&gt; &lt;span style=&quot;color: plum&quot;&gt;Before calling a tool, confirm with the user. If confirmed continue as before, otherwise add a response map to the messages with a &quot;User Refused&quot; error.&lt;/span&gt;
tool call&gt; create_file({&#39;content&#39;: &#39;#!/usr/bin/env python3&#92;n&#92;nfrom litellm i...
tool result&gt; {}
assistant&gt; I&#39;ve updated agent2.py to prompt the user for confirmation before calling any tool. If you enter anything other than &#39;y&#39;, the tool call will be skipped and an error message (&quot;User Refused&quot;) will be added to the messages.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now test the agent driven code changes:&lt;/p&gt;
&lt;pre class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&lt;em&gt;$ chmod +x agent2.py&lt;/em&gt;

&lt;em&gt;$ ./agent2.py&lt;/em&gt;
Welcome! Starting agent with model: github_copilot/o3-mini
&lt;span style=&quot;color: red&quot;&gt;user&lt;/span&gt;&gt; &lt;span style=&quot;color: plum&quot;&gt;What is in ./greet.txt?&lt;/span&gt;
&lt;span style=&quot;color: yellow&quot;&gt;Confirm calling tool &#39;read_file&#39; with arguments {&#39;path&#39;: &#39;./greet.txt&#39;}? (y/N)&lt;/span&gt;&gt; y
&lt;span style=&quot;color: green&quot;&gt;tool call&lt;/span&gt;&gt; read_file({&#39;path&#39;: &#39;./greet.txt&#39;})
&lt;span style=&quot;color: blue&quot;&gt;tool result&lt;/span&gt;&gt; {&quot;content&quot;: &quot;hello Joel!&#92;n&quot;}
&lt;span style=&quot;color: purple&quot;&gt;assistant&lt;/span&gt;&gt; The content of &quot;./greet.txt&quot; is:
hello Joel!&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The full code for each of the above steps can be found at &lt;a href=&quot;https://github.com/kanaka/litellm-agent&quot;&gt;github.com/kanaka/litellm-agent&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&quot;step-7-you-take-it-from-here&quot;&gt;Step 7: You take it from here!&lt;/h1&gt;
&lt;p&gt;You now have a basic working coding agent. The next steps are up to
you. Here are some ideas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add streaming output so that you can see the progress of the model
as it is generating longer responses.&lt;/li&gt;
&lt;li&gt;Make the tool confirmation more sophisticated and allow specific
actions or whole tools to be run without confirmation the next time.&lt;/li&gt;
&lt;li&gt;Add proper python argument parsing. Allow the model name, system
prompt, tool confirmation mode, etc to be specified as command
line. Allow the initial query to optionally be specified on the
command line (like step 1).&lt;/li&gt;
&lt;li&gt;Add the ability to continue a previous session (save/pickle the
context and reload it if requested).&lt;/li&gt;
&lt;li&gt;Give it the ability to run tests.&lt;/li&gt;
&lt;li&gt;Get it working reliably with other models. For example,
&lt;code&gt;github_copilot/gemini-2.0-flash-001&lt;/code&gt; is the cheapest model but it
has trouble using the tools the way they are currently defined.&lt;/li&gt;
&lt;/ul&gt;
</content>
  </entry>
  <entry>
    <title>The Most Important Parts of HTML5</title>
    <link href="https://example.com/blog/most-important-parts-of-html5/blog-n01se-net-p-375/" />
    <updated>2011-08-06T00:00:00Z</updated>
    <id>https://example.com/blog/most-important-parts-of-html5/blog-n01se-net-p-375/</id>
    <content type="html">
&lt;article class=&quot;entry&quot;&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;content&quot;&gt;&lt;h2 style=&quot;text-align: center&quot; id=&quot;or-why-video-and-audio-are-boring&quot;&gt;or &lt;em&gt;&lt;strong&gt;Why &amp;lt;video&amp;gt; and &amp;lt;audio&amp;gt; are Boring&lt;/strong&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;h2 style=&quot;text-align: center&quot; id=&quot;or-the-new-web-platform&quot;&gt;or &lt;em&gt;&lt;strong&gt;The New Web Platform&lt;/strong&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;h2 style=&quot;text-align: center&quot; id=&quot;or-an-introduction-to-html5&quot;&gt;or &lt;em&gt;&lt;strong&gt;An Introduction to HTML5&lt;/strong&gt;&lt;/em&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;b&gt;[This page was originally published at &lt;a href=&quot;http://blog.n01se.net/?p=375&quot;&gt;http://blog.n01se.net/?p=375&lt;/a&gt;. That site no longer exists. On 2025-05-06 I resurrected the content here for posterity. I have update many of the links if I was able to find a modern versions of the same (or similar) content. Otherwise I have linked to Internet Archive Wayback Machine versions of those pages. The original version of this page (along with the terrible background) in the Wayback Machine is &lt;a href=&quot;https://web.archive.org/web/20201112022805/http://blog.n01se.net/blog-n01se-net-p-375.html&quot;&gt;here&lt;/a&gt;.]&lt;/b&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;a-little-perspective&quot;&gt;A Little Perspective&lt;/h2&gt;
&lt;h4 id=&quot;the-birth-of-the-web&quot;&gt;The Birth of the Web&lt;/h4&gt;
&lt;p&gt;20 years ago today (Aug 6th, 1991), Tim Berners-Lee &lt;a title=&quot;Email from Berners-Lee on Aug 6th, 1981&quot; href=&quot;http://www.w3.org/People/Berners-Lee/1991/08/art-6484.txt&quot;&gt;released&lt;/a&gt; the World Wide Web on the world while working at &lt;a title=&quot;European Organization for Nuclear Research&quot; href=&quot;http://www.cern.ch/&quot;&gt;CERN&lt;/a&gt;.  Actually what he released was a program called &quot;WorldWideWeb&quot; which was eventually renamed &quot;Nexus&quot; to clarify the distinction between the concept of the World Wide Web and the browser itself.&lt;span id=&quot;more-375&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The initial browser could render documents written in HyperText Markup Language (HTML). The first HTML supported some limited formatting and hyperlinks (we just call them links now) to other documents.  Here is a screenshot from 2 years later when color and inline images were added:&lt;/p&gt;
&lt;div class=&quot;wp-caption aligncenter&quot; style=&quot;width: 410px&quot;&gt;&lt;picture&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://example.com/blog/most-important-parts-of-html5/blog-n01se-net-p-375/DeGS_nQX-Y-400.avif 400w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://example.com/blog/most-important-parts-of-html5/blog-n01se-net-p-375/DeGS_nQX-Y-400.webp 400w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://example.com/blog/most-important-parts-of-html5/blog-n01se-net-p-375/DeGS_nQX-Y-400.gif&quot; class=&quot;  &quot; alt=&quot;WorldWideWeb browser running on a NeXT System&quot; width=&quot;400&quot; height=&quot;297&quot;&gt;&lt;/picture&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;WorldWideWeb Browser Running on a NeXT System&lt;/p&gt;&lt;/div&gt;
&lt;h4 id=&quot;the-rise-of-the-web&quot;&gt;﻿﻿The Rise of the Web&lt;/h4&gt;
&lt;p&gt;In the next 10 years &quot;the Web&quot; exploded in terms of innovation, standardization (&lt;a href=&quot;https://example.com/blog/most-important-parts-of-html5/blog-n01se-net-p-375/#footnote1&quot;&gt;Footnote 1&lt;/a&gt;), number of users, browsers (installs and variations), web servers (installs and variations), and economic impact. With the release of Mosaic (at &lt;a title=&quot;The National Center for Supercomputing Applications at the University of Illinois&quot; href=&quot;http://www.ncsa.illinois.edu/&quot;&gt;NCSA&lt;/a&gt;) in 1993, with its seamless integration of graphics and text, the World Wide Web quickly grew to become the dominant use of the Internet and the driving force behind Internet adoption. In fact, for most computer users &quot;the Web&quot; and &quot;the Internet&quot; have become synonymous.&lt;/p&gt;
&lt;h4 id=&quot;the-fall-of-the-web&quot;&gt;The Fall of the Web&lt;/h4&gt;
&lt;p&gt;At the turn of the century, Web innovation slowed due to the emergence of Microsoft&#39;s Internet Explorer as a near monopoly in the web browser market.  Once Microsoft achieved a controlling share of the web browser market they lost interest in driving or cooperating on new Web standards and technologies because this might threaten their profitable Windows platform.&lt;/p&gt;
&lt;h4 id=&quot;the-rise-of-the-web-again&quot;&gt;The Rise of the Web (Again)&lt;/h4&gt;
&lt;p&gt;In the last three years there has been a new explosion of Web innovation.  The Web has been released from its cage by three main trends: the rise of Mozilla Firefox (a spiritual descendant of the Mosaic browser), the rise of Google Chrome, and the rise of mobile devices.&lt;/p&gt;
&lt;div class=&quot;wp-caption aligncenter&quot; style=&quot;width: 410px&quot;&gt;&lt;picture&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://example.com/blog/most-important-parts-of-html5/blog-n01se-net-p-375/2rQlsHBKkA-400.avif 400w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://example.com/blog/most-important-parts-of-html5/blog-n01se-net-p-375/2rQlsHBKkA-400.webp 400w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://example.com/blog/most-important-parts-of-html5/blog-n01se-net-p-375/2rQlsHBKkA-400.png&quot; class=&quot; &quot; alt=&quot;Web Browser Market Share 2008-2011 (Wikimedia)&quot; width=&quot;400&quot; height=&quot;400&quot;&gt;&lt;/picture&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;Web Browser Market Share (Wikimedia)&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;A core part of human nature is to &lt;a title=&quot;Genesis 2:19-20&quot; href=&quot;http://www.biblegateway.com/passage/?search=Genesis+2%3A19-20&amp;amp;version=NIV&quot;&gt;give names to everything&lt;/a&gt; including to abstract concepts. The new energy and innovation surrounding the Web platform is no exception; it needs a name. Which brings us to &quot;HTML5&quot; ...&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;html5&quot;&gt;&quot;HTML5&quot;&lt;/h3&gt;
&lt;p&gt;Technically, HTML5 is a &lt;a title=&quot;W3C HTML5 Specification&quot; href=&quot;http://www.w3.org/TR/html5/&quot;&gt;specification&lt;/a&gt; from the World Wide Web Consortium (W3C)  (&lt;a href=&quot;https://example.com/blog/most-important-parts-of-html5/blog-n01se-net-p-375/#footnote2&quot;&gt;Footnote 2&lt;/a&gt;). Many pedants will claim this is the only correct usage. For the rest of us, HTML5 is a useful term to describe the rapid changes that are currently happening to the Web platform. This is what I will mean when I use the term &quot;HTML5&quot;. I will refer to the formal specification as &quot;W3C HTML5&quot;.&lt;/p&gt;
&lt;h3 id=&quot;w3c-html5&quot;&gt;W3C HTML5&lt;/h3&gt;
&lt;p&gt;Although the W3C HTML5 specification is not going to be officially complete until 2014, &lt;a title=&quot;W3C HTML5 End of Last Call&quot; href=&quot;http://blog.whatwg.org/weekly-end-of-last-call&quot;&gt;the specification finished last call review&lt;/a&gt; earlier this week (Aug 3rd) so there are unlikely to be any radical changes in the next three years before finalization.&lt;/p&gt;
&lt;h4 id=&quot;w3c-html5-is-boring&quot;&gt;W3C HTML5 is Boring&lt;/h4&gt;
&lt;p&gt;The W3C HTML5 is very important at one level, but it is also pretty boring. It is basically a formal description of the state-of-the art in the Web platform from 3 years ago. The actual content of the specification is pretty mundane (even apart from the dry and technical nature of specification documents). The most interesting API in the W3C HTML5 is the Canvas 2D Context and that is defined in a &lt;a title=&quot;W3C Canvas 2D Context Specification&quot; href=&quot;https://web.archive.org/web/20201112022805/http://dev.w3.org/html5/2dcontext/&quot;&gt;separate document&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&quot;w3c-html5-is-important&quot;&gt;W3C HTML5 is Important&lt;/h4&gt;
&lt;p&gt;However, the W3C HTML5 is important because it makes official all the good ideas that have been learned over the years and it attempts to remove most of the things that are now considered mistakes. It also brings a great deal of consistency and completeness to the various DOM APIs and HTML elements. And probably most importantly, it has brought the various browser makers into agreement. This means web developers that develop against what is defined in the W3C HTML5 specification should have one application that works well on all recent browsers versions without the need for browser specific kludges.&lt;/p&gt;
&lt;h3 id=&quot;w3c-html5-vs-html5&quot;&gt;W3C HTML5 vs HTML5&lt;/h3&gt;
&lt;p&gt;If I were to sum up the differences between the W3C HTML5 specification and the larger concept of HTML5 it would be this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The W3C HTML5 promotes many of the existing second class elements of the Web such as video, audio, animations, smart forms, etc into first class elements.&lt;/li&gt;
&lt;li&gt;HTML5 (the common usage) takes those new elements and adds power and functionality to them that was not previously possible. HTML5 also creates a whole new set of first class elements out of technologies that were not part of the Web in the first place such as hardware device access, binary data, file system access, multiprocessing, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Or another way of summing up the relationship between the two:&lt;/p&gt;
&lt;p style=&quot;padding-left: 30px&quot;&gt;The W3C HTML5 specification serves as the foundation and framework upon which all the interesting HTML5 developments are happening.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;the-most-important-parts-of-html5&quot;&gt;The Most Important Parts of HTML5&lt;/h2&gt;
&lt;p&gt;Now we come to my purpose for this article: to list and describe the HTML5 APIs, standards, and technologies that are most important (and most interesting). I have tried to imagine the Web as it will exist five years from now and from that vantage point determine what parts of HTML5 were most crucial in bringing us to that imagined future.&lt;/p&gt;
&lt;p&gt;The following list is ordered from most to least important. Obviously this is just my opinion. I do web application development (&lt;a title=&quot;noVNC - HTML5 VNC Client&quot; href=&quot;https://github.com/kanaka/noVNC&quot;&gt;noVNC&lt;/a&gt;, &lt;a title=&quot;websockify - WebSocket to TCP socket proxy/bridge&quot; href=&quot;https://github.com/kanaka/websockify&quot;&gt;websockify&lt;/a&gt;) and participate in HTML5 working groups and discussions, but the future is always more interesting (and less) than any experts can predict.&lt;/p&gt;
&lt;p&gt;So without further ado...&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;1-faster-javascript-engines&quot;&gt;1. Faster Javascript Engines&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt; &lt;/strong&gt; The Web as a application platform is built on this more than anything else. The new Javascript engines are the warp drive for the Web. Without the warp drive, Star Trek is a story that takes place on earth (or at best in one solar system). Without the massive increase in Javascript performance we would still be talking about web pages and not web applications.&lt;/p&gt;
&lt;h3 id=&quot;2-websockets&quot;&gt;2. WebSockets&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt; &lt;/strong&gt;This moves the browser solidly into the space of highly interactive networked applications. After fast Javascript engines, low-latency networking has the largest potential for allowing the Web to conquer new application domains.&lt;/p&gt;
&lt;h3 id=&quot;3-binary-data-types-typed-arrays-and-blobs&quot;&gt;3. Binary Data Types (Typed Arrays and Blobs)&lt;/h3&gt;
&lt;p&gt;Javascript started its life as a way to do validation of textual form data.  However, many of the first class elements introduced in HTML5 contain, receive and/or output binary data and so native binary data types in Javascript has become a necessity. Developers have used various hacks to encode binary data in old Javascript data types for many years. But using these hacks is a significant barrier and the full power of HTML5 will not be unleashed without native binary data support.&lt;/p&gt;
&lt;h3 id=&quot;4-web-audio-api&quot;&gt;4. Web Audio API&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt; &lt;/strong&gt; This is not the &amp;lt;audio&amp;gt; tag but rather the APIs/proposals for allowing low-latency, direct audio manipulation from Javascript.  The &amp;lt;audio&amp;gt; tag (which is part of W3C HTML5) allows an audio file to be embedded directly in a web page and it provides a playback and synchronization API.&lt;/p&gt;
&lt;p&gt;The Web Audio API proposals allows for direct creation and manipulation of audio waveforms and also address issues of high-latency playback that exist in current &amp;lt;audio&amp;gt; tag implementations. These proposals are still very young and the final solutions may merge with the &amp;lt;audio&amp;gt; tag, but the issues addressed by the Web Audio API proposals will be in future browsers in one form or another.&lt;/p&gt;
&lt;h3 id=&quot;5-canvas-2d-context&quot;&gt;5. Canvas 2D Context&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt; &lt;/strong&gt;Direct pixel manipulation. Everybody agrees it is important so there is not much I will add. I put it below the Web Audio API because much of what can be done with Canvas 2D Content can be done with other methods (SVG, WebGL, CSS3).&lt;/p&gt;
&lt;h3 id=&quot;6-css3-and-woff&quot;&gt;6. CSS3 and WOFF&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt; &lt;/strong&gt;Cascading Style Sheets 3 and the Web Open Font Format together bring the full power of design, typography, layout, and visual transformation to the web. Also, with CSS3 (in particular the Flexible Box Model), web applications will finally have a simple and powerful way of doing user interface layout without the element positioning mess that is necessary with CSS2.&lt;/p&gt;
&lt;h3 id=&quot;7-local-storage-offline-applications-and-the-file-apis&quot;&gt;7. Local Storage, Offline Applications and the File APIs&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt; &lt;/strong&gt; There are many application domains that are just not feasible without fast, local and persistent storage (at least not until everyone has cheap Gigabit Internet connections). Some form of local storage is also necessary for web applications to be usable when there is no Internet connection available. There are a number of APIs/standards being developed in this area but they are all addressing different aspects of the same fundamental limitation of pre-HTML5 browsers.&lt;/p&gt;
&lt;h3 id=&quot;8-web-workers&quot;&gt;8. Web Workers&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt; &lt;/strong&gt;Moore&#39;s Law is dead, long live Moore&#39;s Law! The year-after-year exponential increase in CPU frequency due to Moore&#39;s Law ended several years ago. But Moore&#39;s Law  was actually a statement about transistor cost/density and this has not changed, it simply has a new face: processor cores per square inch of chip. In a few years, even your mobile phone will have more processor cores than you have fingers.&lt;/p&gt;
&lt;p&gt;New software models are required to take full advantage of the new multi-core reality of Moore&#39;s Law. Fortunately, even though Javascript has always been a single threaded language it was also designed from the beginning to an event driven language. This means that while multiple lines of Javascript in the same web application cannot be running simultaneously, the browser can be doing multiple things at once on behalf of that Javascript code that is running.&lt;/p&gt;
&lt;p&gt;Being event driven only goes so far. The Web Workers specification was created to allow a single web application to have multiple threads of Javascript running simultaneously. To avoid the massive complexity that usually comes with multi-threaded programming (locks, special data structures, etc), Web Workers are independent Javascript contexts and they can only interact with each other and with the main Javascript thread using event driven message passing.&lt;/p&gt;
&lt;h3 id=&quot;9-svg-1-1-2-0&quot;&gt;9. SVG 1.1/2.0&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt; &lt;/strong&gt; The SVG (Scalable Vector Graphics) format has been around for a long time and some browsers have been able to embed SVG images into web pages. SVG is finally starting to be adopted by all browser makers in a form that adds powerful APIs and that allows full access and manipulation to the contained elements (i.e. a truly first class element).&lt;/p&gt;
&lt;p&gt;SVG is actually a difficult one to place in the list. Many (perhaps even most) of the uses of the Canvas 2D Context are actually more appropriate to SVG and in many ways SVG is far more powerful. However, SVG has had an uneven history and I fear that it has accumulated some unjustified mental baggage that will prevent it from being as fundamental and important as it otherwise would be. I will be happy to be proved wrong if it turns out to be more important than I have rated it.&lt;/p&gt;
&lt;h3 id=&quot;10-webgl&quot;&gt;10. WebGL&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt; &lt;/strong&gt; This is the Canvas 3D Context and it is basically a hardware accelerated OpenGL API for the Web. Like SVG, this is potentially a very important piece of HTML5. But I say potentially because Microsoft has been somewhat dismissive of WebGL (possibly since it is defined in terms of OpenGL rather than their own DirectX API) and so there is uncertainty about whether this will ever make it into Internet Explorer. If there were less uncertainty I would place this higher in the list because it brings the Web to the doorstep of so many new application domains (including 3D games).&lt;/p&gt;
&lt;h3 id=&quot;11-all-the-rest&quot;&gt;11. All the Rest&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt; &lt;/strong&gt;The ultimate vision of many who are pushing forward the Web platform is to make the Web platform as powerful, capable and comprehensive as native applications.  The first 10 items each open up the Web platform to large new application domains that have historically only been possible with native applications. But they leave many gaps that must be filled before we reach a future where the question asked by developers is no longer &quot;&lt;em&gt;&lt;strong&gt;Can I build this as a web application?&lt;/strong&gt;&lt;/em&gt;&quot; but rather &quot;&lt;em&gt;&lt;strong&gt;Do I want to build this as a web application?&lt;/strong&gt;&lt;/em&gt;&quot;&lt;/p&gt;
&lt;p&gt;There are numerous proposals that are being worked on to address the gaps in web application functionality. Several of them would probably be higher on the list if they were further along or had less uncertainty about whether they will be universally adopted by all browser makers. Here are just a few of the proposals/APIs that are attempting to fill the gaps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;WebRTC/Stream API&lt;/strong&gt;: Peer-to-peer video conferencing.&lt;/li&gt;
&lt;li&gt;﻿&lt;strong&gt;Geolocation&lt;/strong&gt;: Where in the World am I?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Orientation&lt;/strong&gt;: Which way is up?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Crypto&lt;/strong&gt;: Encrypt/decrypt efficiently in Javascript&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WebCL&lt;/strong&gt;: The Web version of OpenCL. Who wouldn&#39;t want to use the GPU directly for computation from Javascript?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WebNotifications&lt;/strong&gt;: Tell me what&#39;s happening, but gently.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Web Intents&lt;/strong&gt;: Associate data types with default actions and pass data back and forth between web applications. Your favorite web application for editing images will inevitably be different then the default one for that web based slideshow application. Shout with me: &quot;OLE!&quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Page Visibility&lt;/strong&gt;: Imagine how much energy the world would be save if those animations and movies stopped rendering when you aren&#39;t looking at them.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;requestAnimationFrame&lt;/strong&gt;: with setTimeout you get 100 FPS or you get 2 FPS (often within the same second). Now you can get a consistent 30 FPS. And there was much rejoicing.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Microdata&lt;/strong&gt;: unambiguous parsing of embedded machine-readable data.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Etc&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Etc&lt;/strong&gt; (&lt;a href=&quot;https://example.com/blog/most-important-parts-of-html5/blog-n01se-net-p-375/#footnote3&quot;&gt;Footnote 3&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;wp-caption aligncenter&quot; style=&quot;width: 210px&quot;&gt;&lt;picture&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://example.com/blog/most-important-parts-of-html5/blog-n01se-net-p-375/9CrLwhDZRl-200.avif 200w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://example.com/blog/most-important-parts-of-html5/blog-n01se-net-p-375/9CrLwhDZRl-200.webp 200w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://example.com/blog/most-important-parts-of-html5/blog-n01se-net-p-375/9CrLwhDZRl-200.png&quot; alt=&quot;Mac vs PC vs Browser (xkcd.com)&quot; width=&quot;200&quot; height=&quot;371&quot;&gt;&lt;/picture&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;Mac vs PC vs Browser (from xkcd.com)&lt;/p&gt;&lt;/div&gt;
&lt;h3 id=&quot;what-about-video-and-audio&quot;&gt;What about &amp;lt;video&amp;gt; and &amp;lt;audio&amp;gt;?&lt;/h3&gt;
&lt;p&gt;The &amp;lt;video&amp;gt; and &amp;lt;audio&amp;gt; tags are probably the HTML5 features that have caused the most excitement (and angst) on the web regarding HTML5. In fact, some of you may have scanned ahead looking for them in the list and were surprised they were not #1 and #2. These two elements are part of W3C HTML5 and while they do make first class elements out of what has traditionally been second class (e.g. done with Flash), they are still really just a better way of doing what has already been done. The &amp;lt;video&amp;gt; and &amp;lt;audio&amp;gt; tags don&#39;t significantly expand the scope of what web applications are capable of so that is one reason why they are not on the list. Another problem with these tags is that the list of supported media formats is inconsistent across browsers. Until this is resolved, their adoption will be hampered. (&lt;a href=&quot;https://example.com/blog/most-important-parts-of-html5/blog-n01se-net-p-375/#footnote4&quot;&gt;Footnote 4&lt;/a&gt;)&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;footnotes&quot;&gt;Footnotes&lt;/h2&gt;
&lt;p&gt;These were originally inline in the article and they seemed to interrupt the flow so I moved them here. And even without these notes the article is still too long.&lt;/p&gt;
&lt;h4 id=&quot;footnote-1&quot;&gt;&lt;a name=&quot;footnote1&quot;&gt;Footnote 1&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Here are some notable standards that developed around the Web platform in the first few years after the first web browser was released by Tim Berners-Lee:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1995 - &lt;a title=&quot;IETF HTML 2.0 Specification&quot; href=&quot;http://tools.ietf.org/html/rfc1866&quot;&gt;HTML 2.0&lt;/a&gt; is published as the first official HTML standard.&lt;/li&gt;
&lt;li&gt;1995 - HTML make the first baby step toward becoming dynamic and interactive when JavaScript is created by Brendan Eich and added to Netscape Navigator 2.&lt;/li&gt;
&lt;li&gt;1996 - The CSS1 (Cascading Style Sheets) specification is completed and parts of it appear in Internet Explorer 3. Part of the reason for CSS is to separate web page appearance from content and functionality. This follows as well established principle in computer science of separating concerns.&lt;/li&gt;
&lt;li&gt;1998 - The DOM Level 1 (Document Object Model) specification, the API of HTML elements on a page, is published by the W3C.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;footnote-2&quot;&gt;&lt;a name=&quot;footnote2&quot;&gt;Footnote 2&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;I should note another important group (with a long and forgettable name) that is involved in HTML standards is the &lt;a title=&quot;WHATWG&quot; href=&quot;http://www.whatwg.org/&quot;&gt;Web Hypertext Application Technology Working Group (WHATWG)&lt;/a&gt;. Many (perhaps most) of the people at WHATWG also participate in work at the W3C. The WHATWG can be thought as a more dynamic and less restricted version of the W3C.&lt;/p&gt;
&lt;p&gt;The WHATWG maintains two overarching standards documents. The first is &lt;a title=&quot;WHATWG HTML Specification&quot; href=&quot;http://www.whatwg.org/specs/web-apps/current-work/multipage/&quot;&gt;HTML&lt;/a&gt;.  Many of the ideas that are in the W3C HTML5 were first documented here. This document can be thought of HTML5+. The second standard document is called &lt;a title=&quot;WHATWG Web Apps 1.0 Specification&quot; href=&quot;https://web.archive.org/web/20111105131330/http://www.whatwg.org/specs/web-apps/current-work/multipage&quot;&gt;Web Apps 1.0&lt;/a&gt;.  This contains the content of the HTML document and adds many of the APIs that are considered important for the Web to become a full fledged application platform.&lt;/p&gt;
&lt;p&gt;The WHATWG Web Apps 1.0 document is much closer to what people generally mean when they use the term &quot;HTML5&quot;, however, even that does not encapsulate the whole meaning. There are many other APIs and proposals that are part of the new energy of the Web that are or will make their way into most browsers (either via the standards process or not).&lt;/p&gt;
&lt;h4 id=&quot;footnote-3&quot;&gt;&lt;a name=&quot;footnote3&quot;&gt;Footnote 3&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Etc. I am not aware of a web proposal/API yet with those three letters. The question is will this article will make it more or less likely that there will be one soon?&lt;/p&gt;
&lt;h4 id=&quot;footnote-4&quot;&gt;&lt;a name=&quot;footnote4&quot;&gt;Footnote 4&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;By combining fast Javascript, WebSockets, Canvas, Web Audio, and binary data types you can have video and audio without the &amp;lt;video&amp;gt;/&amp;lt;audio&amp;gt; tags and without any plugins. The frame rate and resolution might be lower than desired but it is possible.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a title=&quot;Dive Into HTML5&quot; href=&quot;https://web.archive.org/web/20201109001654/http://diveintohtml5.info/&quot;&gt;Dive Into HTML5&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a title=&quot;HTML5Rocks&quot; href=&quot;https://web.archive.org/web/20110902005801/http://www.html5rocks.com/en/&quot;&gt;HTML5Rocks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Excellent &lt;a title=&quot;HTML5Rocks Presentation&quot; href=&quot;https://web.archive.org/web/20100728045138/http://slides.html5rocks.com/#slide1&quot;&gt;Presentation on HTML5&lt;/a&gt; from HTML5Rocks&lt;/li&gt;
&lt;li&gt;&lt;a title=&quot;Can I use...&quot; href=&quot;http://caniuse.com/&quot;&gt;When can I use... &lt;/a&gt; Compatibility tables for support of HTML5, CSS3, SVG and more in desktop and mobile browsers.&lt;/li&gt;
&lt;li&gt;&lt;a title=&quot;HTML5 Readiness&quot; href=&quot;http://html5readiness.com/&quot;&gt;HTML5 Readiness&lt;/a&gt; - Flower chart of HTML5 &amp;amp; CSS3 features in major browser versions&lt;/li&gt;
&lt;li&gt;&lt;a title=&quot;The HTML5 Test&quot; href=&quot;http://beta.html5test.com/&quot;&gt;The HTML5 Test&lt;/a&gt; - How well does your browser support HTML5?&lt;/li&gt;
&lt;li&gt;&lt;a title=&quot;HTML5 Browser API list&quot; href=&quot;https://html-now.github.io/&quot;&gt;The Web Platform: Browser technologies&lt;/a&gt; ()&lt;/li&gt;
&lt;li&gt;&lt;a title=&quot;HTML5 Twitter Page&quot; href=&quot;https://x.com/html5&quot;&gt;HTML5 Tweets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a title=&quot;W3C blog&quot; href=&quot;https://w3.org/blog&quot;&gt;W3C Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a title=&quot;WHATWG blog&quot; href=&quot;https://blog.whatwg.org/&quot;&gt;WHATWG Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a title=&quot;Google Chrome blog&quot; href=&quot;https://blog.google/products/chrome/&quot;&gt;Google Chrome Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a title=&quot;Mozilla Firefox blog&quot; href=&quot;https://blog.mozilla.org/en/firefox/&quot;&gt;Mozilla Firefox Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a title=&quot;Opera Developer blog&quot; href=&quot;https://blogs.opera.com/news/&quot;&gt;Opera Developer Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a title=&quot;Microsoft IE blog&quot; href=&quot;https://web.archive.org/web/20111113231351/http://blogs.msdn.com/b/ie/&quot;&gt;Microsoft Internet Explorer Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a title=&quot;&amp;quot;An Open Web&amp;quot; online book&quot; href=&quot;https://web.archive.org/web/20191018044201/https://en.flossmanuals.net/an-open-web/_info/&quot;&gt;&quot;An Open Web&quot; book&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a title=&quot;20 Things Google comic&quot; href=&quot;https://web.archive.org/web/20111112140028/http://www.20thingsilearned.com/en-US&quot;&gt;&quot;20 Things I Learned About Browsers and The Web&quot;&lt;/a&gt; Google comic&lt;/li&gt;
&lt;li&gt;&lt;a title=&quot;What is HTML5 (oreilly.com)&quot; href=&quot;https://web.archive.org/web/20201112022805/http://radar.oreilly.com/2011/07/what-is-html5.html&quot;&gt;&quot;What is HTML5&quot;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;links&quot;&gt;Links&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a title=&quot;Early Web History (W3C)&quot; href=&quot;http://www.w3.org/History.html)&quot;&gt;Early History of the Web&lt;/a&gt; (W3C)&lt;/li&gt;
&lt;li&gt;&lt;a title=&quot;Where the web was born (CERN)&quot; href=&quot;http://public.web.cern.ch/public/en/about/web-en.html)&quot;&gt;Where the web was born&lt;/a&gt; (CERN)&lt;/li&gt;
&lt;li&gt;&lt;a title=&quot;W3C&quot; href=&quot;http://www.w3.org/&quot;&gt;W3C&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a title=&quot;W3C HTML5&quot; href=&quot;https://web.archive.org/web/20201112022805/http://www.w3.org/TR/html5/&quot;&gt;W3C HTML5&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a title=&quot;WHATWG&quot; href=&quot;https://web.archive.org/web/20201112022805/http://www.whatwg.org/&quot;&gt;WHATWG&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a title=&quot;WHATWG HTML Specification&quot; href=&quot;https://web.archive.org/web/20201112022805/http://www.whatwg.org/specs/web-apps/current-work/multipage/&quot;&gt;WHATWG HTML&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a title=&quot;WHATWG Web Apps 1.0 Specification&quot; href=&quot;https://web.archive.org/web/20201112022805/http://www.whatwg.org/specs/web-apps/current-work/complete/&quot;&gt;WHATWG Web Apps 1.0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;1. EcmaScript/Javascript: &lt;a title=&quot;ECMA-262 Standard&quot; href=&quot;https://ecma-international.org/publications-and-standards/standards/ecma-262/&quot;&gt;ECMA-262&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2. WebSockets
&lt;ul&gt;
&lt;li&gt;API: &lt;a title=&quot;W3C WebSockets API&quot; href=&quot;https://web.archive.org/web/20201112022805/http://dev.w3.org/html5/websockets/&quot;&gt;W3C&lt;/a&gt;, &lt;a title=&quot;W3C WebSockets API&quot; href=&quot;https://web.archive.org/web/20201112022805/http://www.whatwg.org/specs/web-apps/current-work/complete/network.html&quot;&gt;WHATWG&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Protocol: &lt;a title=&quot;IETF/HyBi WebSockets Protocol&quot; href=&quot;https://web.archive.org/web/20201112022805/http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-10&quot;&gt;IETF/HyBi&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3. Binary Data Types
&lt;ul&gt;
&lt;li&gt;&lt;a title=&quot;Typed Array Specification&quot; href=&quot;https://web.archive.org/web/20201112022805/http://www.khronos.org/registry/typedarray/specs/latest/&quot;&gt;Typed Arrays&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a title=&quot;Blob Type Specification&quot; href=&quot;https://web.archive.org/web/20201112022805/http://www.w3.org/TR/FileAPI/#blob&quot;&gt;Blob Type&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;4. Web Audio: &lt;a title=&quot;Google Web Audio API&quot; href=&quot;https://web.archive.org/web/20201112022805/http://chromium.googlecode.com/svn/trunk/samples/audio/specification/specification.html&quot;&gt;Google&lt;/a&gt;, &lt;a title=&quot;Mozilla Audio Data API&quot; href=&quot;https://web.archive.org/web/20201112022805/https://wiki.mozilla.org/Audio_Data_API&quot;&gt;Mozilla&lt;/a&gt;, &lt;a title=&quot;W3C Audio&quot; href=&quot;https://web.archive.org/web/20201112022805/http://www.w3.org/2011/audio/&quot;&gt;W3C&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;5. Canvas 2D Context: &lt;a title=&quot;W3C Canvas 2D Context Specification&quot; href=&quot;https://web.archive.org/web/20201112022805/http://www.w3.org/TR/2dcontext/&quot;&gt;W3C&lt;/a&gt;, &lt;a title=&quot;WHATWG Canvas Specification&quot; href=&quot;https://web.archive.org/web/20201112022805/http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html&quot;&gt;WHATWG&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;6. CSS and WOFF
&lt;ul&gt;
&lt;li&gt;CSS3: &lt;a title=&quot;W3C CSS&quot; href=&quot;https://web.archive.org/web/20201112022805/http://www.w3.org/Style/CSS/current-work&quot;&gt;W3C&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;WOFF: &lt;a title=&quot;W3C WOFF Specification&quot; href=&quot;https://web.archive.org/web/20201112022805/http://www.w3.org/TR/WOFF/&quot;&gt;W3C&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;7. Local Storage, Offline Application and the File APIs
&lt;ul&gt;
&lt;li&gt;Web Storage: &lt;a title=&quot;W3C Web Storage Specification&quot; href=&quot;https://web.archive.org/web/20201112022805/http://dev.w3.org/html5/webstorage/&quot;&gt;W3C&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;IndexedDB: &lt;a title=&quot;W3C IndexedDB Specification&quot; href=&quot;https://web.archive.org/web/20201112022805/http://www.w3.org/TR/IndexedDB/&quot;&gt;W3C&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Offline Applications: &lt;a title=&quot;W3C Offline Applications Specification&quot; href=&quot;https://web.archive.org/web/20201112022805/http://dev.w3.org/html5/spec/offline.html&quot;&gt;W3C&lt;/a&gt;, &lt;a title=&quot;WHATWG Offline Applications Specification&quot; href=&quot;https://web.archive.org/web/20201112022805/http://www.whatwg.org/specs/web-apps/current-work/multipage/offline.html&quot;&gt;WHATWG&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;File/Reader: &lt;a title=&quot;W3C File (Reader) API Specification&quot; href=&quot;https://web.archive.org/web/20201112022805/http://dev.w3.org/2006/webapi/FileAPI/&quot;&gt;W3C&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;File Writer: &lt;a title=&quot;W3C File Writer API Specification&quot; href=&quot;https://web.archive.org/web/20201112022805/http://dev.w3.org/2009/dap/file-system/file-writer.html&quot;&gt;W3C&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;File Dir/System: &lt;a title=&quot;W3C File Directories/System API Specification&quot; href=&quot;https://web.archive.org/web/20201112022805/http://dev.w3.org/2009/dap/file-system/file-dir-sys.html&quot;&gt;W3C&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;8. Web Workers: &lt;a title=&quot;W3C Web Workers Specification&quot; href=&quot;https://web.archive.org/web/20201112022805/http://dev.w3.org/html5/workers/&quot;&gt;W3C&lt;/a&gt;, &lt;a title=&quot;WHATWG Web Workers Specification&quot; href=&quot;https://web.archive.org/web/20201112022805/http://www.whatwg.org/specs/web-apps/current-work/complete/workers.html&quot;&gt;WHATWG&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;9. SVG 1.1/2.0:
&lt;ul&gt;
&lt;li&gt;&lt;a title=&quot;W3C SVG 1.1 Specification&quot; href=&quot;https://web.archive.org/web/20201112022805/http://www.w3.org/TR/SVG/&quot;&gt;W3C 1.1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a title=&quot;W3C SVG 2.0 Roadmap&quot; href=&quot;https://web.archive.org/web/20201112022805/http://www.w3.org/Graphics/SVG/WG/wiki/Roadmap&quot;&gt;SVG 2.0 W3C Roadmap&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10. &lt;a title=&quot;Khronos WebGL 1.0 Specification&quot; href=&quot;https://web.archive.org/web/20201112022805/https://www.khronos.org/registry/webgl/specs/1.0/&quot;&gt;WebGL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;11. All the Rest
&lt;ul&gt;
&lt;li&gt;&lt;a title=&quot;Google WebRTC Project&quot; href=&quot;https://web.archive.org/web/20201112022805/https://sites.google.com/site/webrtc/&quot;&gt;WebRTC&lt;/a&gt;/Stream API&lt;/li&gt;
&lt;li&gt;&lt;a title=&quot;W3C Geolocation Specification&quot; href=&quot;https://web.archive.org/web/20201112022805/http://dev.w3.org/geo/api/spec-source-v2&quot;&gt;Geolocation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a title=&quot;W3C Orientation Specification&quot; href=&quot;https://web.archive.org/web/20201112022805/http://dev.w3.org/geo/api/spec-source-orientation&quot;&gt;Orientation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a title=&quot;Mozilla DomCrypto API Proposal&quot; href=&quot;https://web.archive.org/web/20201112022805/https://wiki.mozilla.org/Privacy/Features/DOMCryptAPISpec/Latest&quot;&gt;Crypto&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a title=&quot;Khronos WebCL&quot; href=&quot;https://web.archive.org/web/20201112022805/http://www.khronos.org/webcl/&quot;&gt;WebCL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a title=&quot;W3C WebNotifications API Specification&quot; href=&quot;https://web.archive.org/web/20201112022805/http://dev.w3.org/2006/webapi/WebNotifications/&quot;&gt;WebNotifications&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a title=&quot;Google Web Intents Project&quot; href=&quot;https://web.archive.org/web/20201112022805/http://webintents.org/&quot;&gt;Web Intents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a title=&quot;W3C Page Visibility API Specification&quot; href=&quot;https://web.archive.org/web/20201112022805/http://www.w3.org/TR/2011/WD-page-visibility-20110602/&quot;&gt;Page Visibility&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a title=&quot;Google requestAnimationFrame Proposal&quot; href=&quot;https://web.archive.org/web/20201112022805/http://webstuff.nfshost.com/anim-timing/Overview.html&quot;&gt;requestAnimationFrame&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a title=&quot;W3C Microdata specification&quot; href=&quot;https://web.archive.org/web/20201112022805/http://www.w3.org/TR/microdata/&quot;&gt;Microdata&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/article&gt;
</content>
  </entry>
</feed>