<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: adi-ray</title>
    <description>The latest articles on DEV Community by adi-ray (@adiray).</description>
    <link>https://dev.to/adiray</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F958046%2F4ed05c52-f98e-4208-9ca7-743e604685f8.jpg</url>
      <title>DEV Community: adi-ray</title>
      <link>https://dev.to/adiray</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/adiray"/>
    <language>en</language>
    <item>
      <title>EOD Report: my daily status report to the CEO, drafted by a local Gemma 4</title>
      <dc:creator>adi-ray</dc:creator>
      <pubDate>Sun, 25 Oct 2026 17:49:55 +0000</pubDate>
      <link>https://dev.to/adiray/eod-report-my-daily-status-report-to-the-ceo-drafted-by-a-local-gemma-4-bpp</link>
      <guid>https://dev.to/adiray/eod-report-my-daily-status-report-to-the-ceo-drafted-by-a-local-gemma-4-bpp</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week3-2026-10-19"&gt;Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;Every day before I log off, I send our CEO a status report:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;how long I was on the system&lt;/li&gt;
&lt;li&gt;what I worked on&lt;/li&gt;
&lt;li&gt;what it changed&lt;/li&gt;
&lt;li&gt;how long each task took from start to finish (our TAT, turnaround time)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;EOD Report&lt;/strong&gt; writes it for me. I run one command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;eod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It reads what my laptop already knows about my day, asks &lt;strong&gt;Gemma 4 running locally in Ollama&lt;/strong&gt; to turn that evidence into tasks a CEO understands, and opens a small review page. I tick what's finished, fix a name if Gemma got it wrong, press &lt;strong&gt;Copy report&lt;/strong&gt;, and paste a table into the email:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;th&gt;Started&lt;/th&gt;
&lt;th&gt;TAT&lt;/th&gt;
&lt;th&gt;Impact&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Booking change audit trail&lt;/td&gt;
&lt;td&gt;Done&lt;/td&gt;
&lt;td&gt;22 Oct&lt;/td&gt;
&lt;td&gt;4 days&lt;/td&gt;
&lt;td&gt;Every booking edit now shows who changed it and when&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Faster fare search for agents&lt;/td&gt;
&lt;td&gt;Done&lt;/td&gt;
&lt;td&gt;25 Oct&lt;/td&gt;
&lt;td&gt;1 day&lt;/td&gt;
&lt;td&gt;Search results load in about half the time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Legacy system migration plan&lt;/td&gt;
&lt;td&gt;WIP · day 3&lt;/td&gt;
&lt;td&gt;23 Oct&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;td&gt;Bookings and wallet mapped; payments next&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;(Synthetic demo data. My real reports have private repo names in them.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The person who gets to be lazier is me, at 7 pm, every working day.&lt;/p&gt;

&lt;h3&gt;
  
  
  What it reads
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Source&lt;/th&gt;
&lt;th&gt;What it gives the report&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Git&lt;/strong&gt;, every repo under my work folders&lt;/td&gt;
&lt;td&gt;The work itself. A feature branch is a task, and merging it into main marks it &lt;strong&gt;Done&lt;/strong&gt; automatically.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Claude Code sessions&lt;/strong&gt;, including the VS Code extension&lt;/td&gt;
&lt;td&gt;Work with no commits yet: investigations, debugging, deploys. My own prompts name the task.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Windows event log&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;When I sat down and when I stopped: sign-in, wake and sleep events, no admin rights needed.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;WakaTime&lt;/strong&gt;, optional&lt;/td&gt;
&lt;td&gt;Today's coding time, from the CLI I already had installed.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  TAT that spans days
&lt;/h3&gt;

&lt;p&gt;This is the part a git-log summary can't do. A task starts on the first day it has activity. Each day I keep working on it, it shows as &lt;strong&gt;WIP · day N&lt;/strong&gt;. On the day it's done, by a merge or by me ticking the box, its TAT is the days from start to done, counting both ends. Task state persists locally, so Gemma's job each evening includes "does today's work continue something that's still open?" When it does, the start date carries over and the TAT stays honest.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;It's plain Python with &lt;strong&gt;zero runtime dependencies&lt;/strong&gt;: the standard library, plus HTTP calls to Ollama on localhost.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git log ──────────────┐
Claude Code sessions ─┼─► evidence ─► Gemma 4 (Ollama) ─► task store ─► review page ─► table
Windows events ───────┘               group, name,        TAT across    127.0.0.1
                                      match open tasks    days
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;1. Evidence, deterministically.&lt;/strong&gt; For each day it collects my commits across repos, skipping stashes and other people's commits. It also collects my Claude Code prompts from that day, with IDE context and skill boilerplate stripped. A session only counts if it has at least two prompts or actually edited something, so a quick question doesn't become a "task". Anything already linked to a known task (the same branch, or the same session continuing) is matched without the model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Gemma 4 does the part rules can't.&lt;/strong&gt; Commits made straight to a shared branch don't say which feature they belong to. Gemma gets the leftovers plus my open tasks and replies in strict JSON. It groups related commits and sessions into 2 to 6 tasks, names them in plain business English ("Booking change audit trail", not &lt;code&gt;feat(audit): add actor col&lt;/code&gt;), matches continuations to open tasks, and writes a 12-word impact line for each. I call Ollama's native &lt;code&gt;/api/chat&lt;/code&gt; with &lt;code&gt;format: "json"&lt;/code&gt; and &lt;code&gt;think: false&lt;/code&gt;. On my 4 GB laptop GPU it takes about a minute, which is nothing for something that runs once a day.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. The model never gets the last word.&lt;/strong&gt; Every reply is validated: each piece of evidence must land in exactly one task, and a match must point at a real open task. If not, the validator's complaint goes back to Gemma for one retry. If Ollama isn't running at all, it falls back to one task per branch or repo, so the report still gets written. Every row on the review page links to the commits and prompts behind it. If it's not in the evidence, it doesn't go to the CEO.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Time on system, honestly.&lt;/strong&gt; My first version said I'd been active for 17 hours. Windows had woken itself at 3 am for an update, and I'd treated every wake event as "I'm at my desk". Now a wake or sign-in only counts if I actually do something within 30 minutes, only my own prompts count as signs of life (not the assistant's replies), and a 30-minute silence means I was away. The README says plainly that this is an estimate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Your edits stick.&lt;/strong&gt; Renames, merges, Done ticks and impact edits are saved. Untouched drafts are regenerated on each run, so a rough first pass never hardens into the record.&lt;/p&gt;

&lt;p&gt;There are 23 tests: TAT maths, carrying tasks across days, auto-Done on merge, Gemma reply validation and fallback, secret redaction, the review API's read-only and CSRF rules, and the exact table layout.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;Look at what this tool reads: every commit message in my company's private repos, the full transcript of every conversation I've had with my coding assistant, and a log of when I sat down and walked away. &lt;strong&gt;I'm not sending that to a hosted API to save myself ten minutes.&lt;/strong&gt; With an open-weight model on my own laptop, none of it leaves the machine. The review page listens on &lt;code&gt;127.0.0.1&lt;/code&gt; only, a redactor masks keys and tokens before anything reaches the model, and the only thing that ever goes out is the table I paste myself.&lt;/p&gt;

&lt;p&gt;It also costs nothing to run. A daily task forever is exactly the kind of habit a per-token bill quietly makes expensive. And because it's my model on my machine, I could tune its behaviour freely: the prompt, the JSON contract, and a validator that sends Gemma its own mistakes back. If a better open model comes out next month, switching is one environment variable: &lt;code&gt;EOD_MODEL&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A closed API would have done the grouping too. I just couldn't have pointed it at this data.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Lazy Payoff
&lt;/h2&gt;

&lt;p&gt;Writing this report by hand took me &lt;strong&gt;15 to 20 minutes every evening&lt;/strong&gt;, after my working hours were already over. It wasn't the typing. It was:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;recalling exactly what I had done that day, across several repos and a dozen conversations with my coding assistant&lt;/li&gt;
&lt;li&gt;describing the thought process behind each piece&lt;/li&gt;
&lt;li&gt;spelling out the impact of work that was already finished&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In effect I was doing my day's work twice: once for real, and once again from memory for the report.&lt;/p&gt;

&lt;p&gt;Now that recall is the machine's job, because the evidence was sitting on my laptop all along. &lt;code&gt;eod&lt;/code&gt; gathers it, Gemma spends about a minute turning it into tasks with impact lines, and my part is a quick review: tick what's finished, fix a name if needed, copy.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>productivity</category>
      <category>gemma</category>
    </item>
    <item>
      <title>A cheapest-day fare calendar for travel agents: Gemma 4 reads the supplier APIs, Chronos fills the gaps</title>
      <dc:creator>adi-ray</dc:creator>
      <pubDate>Fri, 16 Oct 2026 21:58:33 +0000</pubDate>
      <link>https://dev.to/adiray/a-cheapest-day-fare-calendar-for-travel-agents-gemma-4-reads-the-supplier-apis-chronos-fills-the-3aj4</link>
      <guid>https://dev.to/adiray/a-cheapest-day-fare-calendar-for-travel-agents-gemma-4-reads-the-supplier-apis-chronos-fills-the-3aj4</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week2-2026-10-12"&gt;Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I build software for a travel agency that runs a &lt;strong&gt;B2B flight booking portal&lt;/strong&gt;: sub-agents log in, search, and book across 13 suppliers (a GDS, low-cost carriers, NDC airlines and fixed-departure consolidators).&lt;/p&gt;

&lt;p&gt;Watch an agent with a customer on the phone and you'll see the same thing every time:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Is Tuesday cheaper than Wednesday?" &lt;em&gt;search.&lt;/em&gt; "What about Thursday?" &lt;em&gt;search.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Every search fans out to every supplier. It's slow for the customer, and it burns supplier quota: GDS look-to-book ratios are a real cost.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fare Calendar&lt;/strong&gt; answers "which day is cheapest?" before the agent searches. It's a date picker that shows the lowest fare under every date:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;● seen&lt;/strong&gt;: a real fare an agent got for that date in the last 3 days&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;est.&lt;/strong&gt;: a model estimate, with a likely range, for dates nobody searched recently&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's built entirely from &lt;strong&gt;the portal's own server logs&lt;/strong&gt;, so it reflects the fares &lt;em&gt;our&lt;/em&gt; suppliers actually return to &lt;em&gt;our&lt;/em&gt; agents, not a public metasearch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who pays:&lt;/strong&gt; B2B travel agencies and booking platforms. It plugs into an existing portal as a &lt;code&gt;&amp;lt;fare-calendar&amp;gt;&lt;/code&gt; web component, reads logs the platform already writes, and runs on the agency's own hardware.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Public demo (synthetic data):&lt;/strong&gt; &lt;a href="https://fare-calendar-demo.onrender.com" rel="noopener noreferrer"&gt;https://fare-calendar-demo.onrender.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production deploy:&lt;/strong&gt; behind a sign-in page for our agents. It serves real forecasts for &lt;strong&gt;557 routes and 23,626 priced dates&lt;/strong&gt; from 114k observed fares.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8xpm89lr2si6heik0xe9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8xpm89lr2si6heik0xe9.jpg" alt="Fare calendar: a fare profile strip above the month, the lowest fare under every date, and a panel explaining the picked day" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The strip above the month&lt;/strong&gt; is a fare profile, one bar per day. The cheap troughs are visible before you read a single number.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Each day&lt;/strong&gt; shows its lowest fare. Seen fares get a dot, estimates a dotted underline, and the cheapest day is marked in magenta.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Picking a day&lt;/strong&gt; explains it: "₹6,210, likely ₹5,340 to ₹7,270, estimated from nearby dates because nobody searched this day recently."&lt;/li&gt;
&lt;li&gt;It works with the keyboard, in dark mode and on a phone, and everything is labelled indicative. Agents reprice live before booking.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/adi-ray/fare-calendar" rel="noopener noreferrer"&gt;https://github.com/adi-ray/fare-calendar&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Python (FastAPI, pandas), a dependency-free web component, and 60 tests. Real logs, fares and private supplier mappings are git-ignored. The repo ships only synthetic data and the public Amadeus mapping.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;Two open-weight models do two very different jobs.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Gemma 4 reads the suppliers' APIs
&lt;/h3&gt;

&lt;p&gt;The fares are buried in 13 different response formats: SOAP XML from a GDS, Navitaire XML, IATA NDC XML, and assorted JSON. Hand-writing 13 parsers before a deadline wasn't going to happen.&lt;/p&gt;

&lt;p&gt;So I wrote a tiny &lt;strong&gt;mapping language&lt;/strong&gt; that works the same over JSON and XML, and had &lt;strong&gt;Gemma 4 write the mappings&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rows"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"faresAvailable{*}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"fields"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"fare"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fares[*].passengerFares[*].fareAmount"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"origin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"meta.origin"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"destination"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"meta.destination"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"departure_date"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"meta.departure_date"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"generated_by"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gemma4 (validated on 6/6 responses)"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Gemma sees a shrunken sample of one response. &lt;strong&gt;Code, not Gemma, decides whether a mapping is good.&lt;/strong&gt; It applies the mapping to 6 real responses and rejects it unless:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;most responses produce rows&lt;/li&gt;
&lt;li&gt;fares look like per-adult totals, not IDs or base fares&lt;/li&gt;
&lt;li&gt;the route the agent actually searched shows up&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Failures go back to Gemma as specific feedback:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;'fareComponentList' does not exist under …originDestinationOptionList[*]; keys there: ['fareComponentGroupList']. did you mean 'fareComponentGroupList'? 'fareComponentList' exists further down at 'fareComponentGroupList.fareComponentList'&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Gemma never touches a fare at run time. Mappings are small JSON files a human can review.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The results:&lt;/strong&gt; Gemma (local &lt;code&gt;gemma4&lt;/code&gt;, 7.5B Q4, via Ollama on a &lt;strong&gt;4 GB laptop GPU&lt;/strong&gt;) mapped &lt;strong&gt;7 suppliers&lt;/strong&gt; in 1–6 attempts each. Three, IndiGo, SpiceJet and an NDC carrier, didn't converge in 11 attempts, so I hand-wrote those and labelled them as hand-written. IndiGo and SpiceJet store each fare as separate charges, &lt;strong&gt;with discounts as positive amounts&lt;/strong&gt;, which needed &lt;code&gt;sum:charges[ChargeType!=Discount] − sum:charges[ChargeType=Discount]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;What I learned getting a small model to do this reliably:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Turn thinking off.&lt;/strong&gt; Gemma 4's thinking mode is on by default in Ollama. On my GPU it turned a 5-second answer into a 58-second one, and the answer was &lt;em&gt;worse&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Watch the context window.&lt;/strong&gt; Ollama's default context silently dropped the start of long prompts, which is where my instructions were. Every early failure looked like "Gemma ignored the spec".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make feedback name the fix.&lt;/strong&gt; "Check your path" got repeated mistakes. "Use &lt;code&gt;^^.segment.from&lt;/code&gt;" got fixed mappings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bend the language toward the model.&lt;/strong&gt; Gemma kept writing field paths from the document root, so the extractor now resolves those to the row's own ancestor.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  2. Chronos-Bolt fills the empty dates
&lt;/h3&gt;

&lt;p&gt;Agents search a handful of dates. To fill the rest:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A &lt;strong&gt;lead-time model&lt;/strong&gt; separates "which day you fly" from "how far ahead you searched", since fares climb as departure nears.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/amazon-science/chronos-forecasting" rel="noopener noreferrer"&gt;Chronos-Bolt&lt;/a&gt;&lt;/strong&gt; &lt;em&gt;base&lt;/em&gt; (open weights, zero-shot, CPU) forecasts each unsearched stretch of the calendar from the departure dates before it. Missing days are passed as gaps, not invented. Its forecast is &lt;strong&gt;averaged with a same-weekday baseline&lt;/strong&gt;: the two make different mistakes, and the average beats both.&lt;/li&gt;
&lt;li&gt;The estimate is re-priced for today's lead time and blended with older searches for that exact date.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  3. Data hygiene was half the work
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Placeholders.&lt;/strong&gt; One consolidator lists some dates at &lt;strong&gt;₹100&lt;/strong&gt; (seats on request). In a &lt;em&gt;lowest&lt;/em&gt;-fare calendar that wins every day, and it took my backtest error to 308%. Fares under ₹500, and anything outside 0.25×–4× the route median, are now dropped and counted.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Per-leg pricing.&lt;/strong&gt; Some carriers price connecting itineraries per leg, so a DEL→HYD→BOM search could pose as a cheap "DEL-HYD fare". Only the searched route is kept.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Group totals.&lt;/strong&gt; Some suppliers price "2 adults" as one total, so only single-adult searches are used (85% of traffic).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  4. Serving it on Render
&lt;/h3&gt;

&lt;p&gt;Chronos runs where the logs live and writes a &lt;strong&gt;565 KB &lt;code&gt;forecasts.json&lt;/code&gt;&lt;/strong&gt;. The API on Render is FastAPI plus the standard library, with no PyTorch. Two services come from one blueprint:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Public demo:&lt;/strong&gt; synthetic data, free plan.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Private:&lt;/strong&gt; Starter with a disk (paid with the Render credit). Agents sign in on a sign-in page with a signed session cookie, and the portal can embed it with an API key. It takes nightly uploads, and a Secret File fallback serves whichever forecast is newer.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Results (honest version)
&lt;/h3&gt;

&lt;p&gt;The backtest uses 14 cutoff days (Oct 1–14). The calendar is built only from earlier logs and compared with the lowest fare agents actually got over the next two days, across &lt;strong&gt;11,544 searched dates&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;seen fares only&lt;/th&gt;
&lt;th&gt;weekday baseline&lt;/th&gt;
&lt;th&gt;Chronos-Bolt base + baseline&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;searched dates with a fare shown&lt;/td&gt;
&lt;td&gt;36%&lt;/td&gt;
&lt;td&gt;41%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;41%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;error when showing a real recent fare&lt;/td&gt;
&lt;td&gt;1.0%&lt;/td&gt;
&lt;td&gt;1.0%&lt;/td&gt;
&lt;td&gt;1.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;error on estimated dates (591)&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;td&gt;18.7%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;16.2%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;How I picked the forecaster (5 cutoffs, 498 estimated dates):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;forecaster&lt;/th&gt;
&lt;th&gt;error on estimated dates&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;weekday baseline&lt;/td&gt;
&lt;td&gt;18.4%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chronos-Bolt &lt;em&gt;small&lt;/em&gt;, alone&lt;/td&gt;
&lt;td&gt;20.1%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chronos-Bolt &lt;em&gt;base&lt;/em&gt;, alone&lt;/td&gt;
&lt;td&gt;17.6%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chronos-Bolt &lt;em&gt;small&lt;/em&gt; + baseline&lt;/td&gt;
&lt;td&gt;17.9%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Chronos-Bolt &lt;em&gt;base&lt;/em&gt; + baseline&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;15.1%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The calendar's value is mostly coverage.&lt;/strong&gt; It puts a number on 41% of the dates agents go on to search, up from 36%, and the "seen" fares are accurate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Estimates are rough but measurably better than the obvious baseline.&lt;/strong&gt; My first deploy used Chronos-Bolt &lt;em&gt;small&lt;/em&gt;, which did &lt;em&gt;worse&lt;/em&gt; than "same weekday, last few weeks". The bigger &lt;em&gt;base&lt;/em&gt; model, averaged with that baseline, cuts estimate error by about 13% over 14 cutoffs. One honest caveat: on a separate 5-day subset with only 63 estimated dates, the ensemble came out slightly worse (20.3% vs 19.0%). It's one month of noisy, mixed GDS and fixed-departure history, and the backtest re-runs as logs accumulate.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The data can't leave.&lt;/strong&gt; Supplier fares are &lt;em&gt;negotiated&lt;/em&gt; rates, and supplier responses are commercially confidential. Pasting them into a hosted LLM to "help write a parser" is a non-starter. Gemma 4 runs locally, so every supplier response it read stayed on the laptop.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It costs nothing per use.&lt;/strong&gt; Mapping a supplier is a one-off job on a 4 GB laptop GPU. Forecasts for 557 routes take a few minutes on a CPU. The deployed API needs no GPU and no AI vendor.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I could change how the model behaves.&lt;/strong&gt; Turning thinking off, setting the context size and forcing JSON output are all switches I control. A closed API would have left me guessing why answers degraded.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Swapping models was a one-line change.&lt;/strong&gt; When Chronos-Bolt small lost to the baseline, I tried a 4× bigger open model the same afternoon, backtested five variants on real data, and shipped the winner at no cost. No vendor pricing page, no waiting list.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No lock-in.&lt;/strong&gt; The mappings are plain JSON, the forecaster is configurable (&lt;code&gt;FARECAL_FORECASTER&lt;/code&gt;, &lt;code&gt;FARECAL_MODEL_ID&lt;/code&gt;), and Gemma can be replaced by any OpenAI-compatible local server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open models plus deterministic checks is the pattern that worked.&lt;/strong&gt; The model proposes, code verifies against real data. That's what made a 7.5B model trustworthy enough to touch production data.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  My Agent Session
&lt;/h2&gt;

&lt;p&gt;This is a curated version of the build session with Claude Code: the turning points, including the wrong turns. Local paths, the private backend's internals and real per-route fares are removed.&lt;/p&gt;


&lt;div class="ltag-agent-session"&gt;
  &lt;div class="agent-session-header"&gt;
    
    &lt;span class="agent-session-tool-icon-badge" title="Claude Code"&gt;
&lt;/span&gt;
    &lt;span class="agent-session-title"&gt;Fare Calendar: Gemma 4 reads the supplier APIs, Chronos fills the gaps (curated build session)&lt;/span&gt;
  &lt;/div&gt;

  &lt;div class="agent-session-scroll"&gt;

      &lt;div class="agent-session-message agent-session-user"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-user"&gt;
          You
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;Week 2 theme is Side Hustle. I'm thinking of a fare-price calendar for our B2B flight booking app, so agents can see the estimated lowest fare at the time of choosing dates.&lt;/p&gt;

                &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div class="agent-session-message agent-session-assistant"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-assistant"&gt;
          Agent
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;Good fit: travel agencies pay for this, and your own agents are the first users. Proposed core: an open-weight time-series model (Chronos-Bolt, Apache-2.0, CPU) learning from the agency's own fare history, so search data never goes to a third-party API. Three questions before building: where does fare history come from, which model, and API + embeddable widget or inside the existing app?&lt;/p&gt;

                &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div class="agent-session-message agent-session-user"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-user"&gt;
          You
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;Our search/booking logs. Chronos-Bolt. Standalone API + embeddable widget.&lt;/p&gt;

                &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div class="agent-session-message agent-session-assistant"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-assistant"&gt;
          Agent
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;Built the skeleton against a documented CSV schema with clearly labelled SYNTHETIC logs: a lead-time fixed-effects model (fares climb as departure nears), a Chronos-Bolt forecaster with a seasonal-naive baseline, a FastAPI service and a &amp;lt;fare-calendar&amp;gt; web component. Synthetic backtest: Chronos 8.5% vs baseline 10.5% MAPE.&lt;/p&gt;

                &lt;/div&gt;
              &lt;div class="agent-session-tool-call"&gt;
                
                  &lt;span class="agent-session-chevron"&gt;▸&lt;/span&gt;
                  &lt;span class="tool-name tool-name-bash"&gt;Bash&lt;/span&gt;
                    &lt;span class="tool-input-preview"&gt;python scripts/backtest.py --data data/sample_search_logs.SYNTHETIC.csv&lt;/span&gt;
                
                &lt;div class="agent-session-tool-detail"&gt;
                    &lt;div class="tool-section"&gt;
                      &lt;div class="tool-section-label"&gt;Input&lt;/div&gt;
                      &lt;pre class="agent-session-pre agent-session-terminal"&gt;&lt;code&gt;$ python scripts/backtest.py --data data/sample_search_logs.SYNTHETIC.csv&lt;/code&gt;&lt;/pre&gt;
                    &lt;/div&gt;
                    &lt;div class="tool-section"&gt;
                      &lt;div class="tool-section-label"&gt;Output&lt;/div&gt;
                      &lt;pre class="agent-session-pre"&gt;&lt;code&gt;overall: seasonal-naive 10.5% MAPE | chronos-bolt-small 8.5% MAPE&lt;/code&gt;&lt;/pre&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div class="agent-session-message agent-session-user"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-user"&gt;
          You
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;Here are the real server logs. Also: can we enter Best Use of Gemma?&lt;/p&gt;

                &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div class="agent-session-message agent-session-assistant"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-assistant"&gt;
          Agent
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;The logs aren't a CSV: they're per-request folders, one per supplier call. 2,250 searches over 30 days, fanning out to 13 suppliers in different formats (GDS SOAP XML, Navitaire XML, IATA NDC XML, assorted JSON). Hand-writing 13 parsers isn't realistic before the deadline, which gives Gemma a genuine job: read a sample of each supplier's response and write the extraction mapping, run locally so negotiated supplier fares never leave the machine. Code validates every mapping against real responses.&lt;/p&gt;

                &lt;/div&gt;
              &lt;div class="agent-session-tool-call"&gt;
                
                  &lt;span class="agent-session-chevron"&gt;▸&lt;/span&gt;
                  &lt;span class="tool-name tool-name-bash"&gt;Bash&lt;/span&gt;
                    &lt;span class="tool-input-preview"&gt;count RS files per supplier (names only)&lt;/span&gt;
                
                &lt;div class="agent-session-tool-detail"&gt;
                    &lt;div class="tool-section"&gt;
                      &lt;div class="tool-section-label"&gt;Input&lt;/div&gt;
                      &lt;pre class="agent-session-pre agent-session-terminal"&gt;&lt;code&gt;$ count RS files per supplier (names only)&lt;/code&gt;&lt;/pre&gt;
                    &lt;/div&gt;
                    &lt;div class="tool-section"&gt;
                      &lt;div class="tool-section-label"&gt;Output&lt;/div&gt;
                      &lt;pre class="agent-session-pre"&gt;&lt;code&gt;amadeus 824, oms 1798, scoot 792, starair 774, cheapfixdeparture 688, batikair 586, indigo 579, airiq 566, aix 410, spicejet 419, emirates 251, aeroprime 94, kandhari 15&lt;/code&gt;&lt;/pre&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div class="agent-session-message agent-session-assistant"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-assistant"&gt;
          Agent
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;Wrote a small mapping language that works the same over JSON and XML, plus a hand-written Amadeus mapping as Gemma's worked example. First real backtest on Amadeus-only data looked promising but tiny: Chronos 4.4% vs baseline 10.4% over 18 estimated dates. I flagged it as too small to trust.&lt;/p&gt;

                &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div class="agent-session-message agent-session-assistant"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-assistant"&gt;
          Agent
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;First Gemma pass mapped only 3 of 12. The failures weren't the model's fault: (1) Ollama's default ~4k context silently dropped the start of long prompts, which is where the instructions were, so Gemma answered as if it never saw them; (2) the sample-shrinker cut deep SOAP responses at depth 14; (3) retry feedback only said 'check the path'. Fixed all three: native Ollama API with a larger context, deeper samples, and feedback that says exactly where a path breaks.&lt;/p&gt;

                &lt;/div&gt;
              &lt;div class="agent-session-tool-call"&gt;
                
                  &lt;span class="agent-session-chevron"&gt;▸&lt;/span&gt;
                  &lt;span class="tool-name tool-name-mapsuppliergemmafeedback"&gt;map_supplier (Gemma feedback)&lt;/span&gt;
                    &lt;span class="tool-input-preview"&gt;aeroprime attempt 1&lt;/span&gt;
                
                &lt;div class="agent-session-tool-detail"&gt;
                    &lt;div class="tool-section"&gt;
                      &lt;div class="tool-section-label"&gt;Input&lt;/div&gt;
                      &lt;pre class="agent-session-pre"&gt;&lt;code&gt;aeroprime attempt 1&lt;/code&gt;&lt;/pre&gt;
                    &lt;/div&gt;
                    &lt;div class="tool-section"&gt;
                      &lt;div class="tool-section-label"&gt;Output&lt;/div&gt;
                      &lt;pre class="agent-session-pre"&gt;&lt;code&gt;'fareComponentList' does not exist under …originDestinationOptionList[*]; keys there: ['fareComponentGroupList']. did you mean 'fareComponentGroupList'?&lt;/code&gt;&lt;/pre&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div class="agent-session-message agent-session-assistant"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-assistant"&gt;
          Agent
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;Gemma was generating at ~1.4 tokens/s. Measured why: Gemma 4's thinking mode is on by default in Ollama.&lt;/p&gt;

                &lt;/div&gt;
              &lt;div class="agent-session-tool-call"&gt;
                
                  &lt;span class="agent-session-chevron"&gt;▸&lt;/span&gt;
                  &lt;span class="tool-name tool-name-bash"&gt;Bash&lt;/span&gt;
                    &lt;span class="tool-input-preview"&gt;same tiny prompt, think=true vs think=false&lt;/span&gt;
                
                &lt;div class="agent-session-tool-detail"&gt;
                    &lt;div class="tool-section"&gt;
                      &lt;div class="tool-section-label"&gt;Input&lt;/div&gt;
                      &lt;pre class="agent-session-pre agent-session-terminal"&gt;&lt;code&gt;$ same tiny prompt, think=true vs think=false&lt;/code&gt;&lt;/pre&gt;
                    &lt;/div&gt;
                    &lt;div class="tool-section"&gt;
                      &lt;div class="tool-section-label"&gt;Output&lt;/div&gt;
                      &lt;pre class="agent-session-pre"&gt;&lt;code&gt;think=True: 58s, 248 tokens, wrong answer | think=False: 5s, 9 tokens, correct answer&lt;/code&gt;&lt;/pre&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div class="agent-session-message agent-session-assistant"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-assistant"&gt;
          Agent
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;More language gaps surfaced by Gemma's near-misses, each fixed and tested: {*} for fares keyed by opaque IDs (AIX), [&lt;em&gt;][&lt;/em&gt;] lint for lists of lists (BatikAir), [-1]/[last] for the final flight leg, sum: for fares split into charges, and an automatic '^' rewrite when Gemma writes field paths from the document root. Also caught myself: a new 'base fare vs total' check flagged AIX, but AIX's fareAmount was already the per-passenger total; the bigger 'total' summed all passengers. Narrowed the check to same-passenger siblings.&lt;/p&gt;

                &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div class="agent-session-message agent-session-assistant"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-assistant"&gt;
          Agent
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;With 7 suppliers mapped the backtest said 308% error on 'seen' fares, which should be near-exact. Investigated instead of reporting it: one consolidator lists some dates at ₹100 (seats on request), and a lowest-fare calendar picks that every time.&lt;/p&gt;

                &lt;/div&gt;
              &lt;div class="agent-session-tool-call"&gt;
                
                  &lt;span class="agent-session-chevron"&gt;▸&lt;/span&gt;
                  &lt;span class="tool-name tool-name-bash"&gt;Bash&lt;/span&gt;
                    &lt;span class="tool-input-preview"&gt;share of fares below 30% of route median, by supplier&lt;/span&gt;
                
                &lt;div class="agent-session-tool-detail"&gt;
                    &lt;div class="tool-section"&gt;
                      &lt;div class="tool-section-label"&gt;Input&lt;/div&gt;
                      &lt;pre class="agent-session-pre agent-session-terminal"&gt;&lt;code&gt;$ share of fares below 30% of route median, by supplier&lt;/code&gt;&lt;/pre&gt;
                    &lt;/div&gt;
                    &lt;div class="tool-section"&gt;
                      &lt;div class="tool-section-label"&gt;Output&lt;/div&gt;
                      &lt;pre class="agent-session-pre"&gt;&lt;code&gt;kandhari: 528 rows at ₹100 on a route whose median is tens of thousands&lt;/code&gt;&lt;/pre&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;Fix: drop fares under ₹500 and per-route outliers outside 0.25x-4x the median, and count them. Seen-fare error back to 1.3%.&lt;/p&gt;

                &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div class="agent-session-message agent-session-user"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-user"&gt;
          You
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;Rest of the suppliers need to be mapped, except OMS and Aeroprime. Try Gemma again now that RAM is free.&lt;/p&gt;

                &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div class="agent-session-message agent-session-assistant"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-assistant"&gt;
          Agent
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;Gemma mapped Emirates on attempt 6. IndiGo, SpiceJet and an NDC carrier didn't converge in 11 attempts each, even though the feedback named the exact location, so I hand-wrote those and labelled them hand-written. IndiGo and SpiceJet store discounts as positive amounts, so a plain sum would add them: added item filters and signed sums.&lt;/p&gt;

                &lt;/div&gt;
              &lt;div class="agent-session-tool-call"&gt;
                
                  &lt;span class="agent-session-chevron"&gt;▸&lt;/span&gt;
                  &lt;span class="tool-name tool-name-bash"&gt;Bash&lt;/span&gt;
                    &lt;span class="tool-input-preview"&gt;count Navitaire charge types and discount signs&lt;/span&gt;
                
                &lt;div class="agent-session-tool-detail"&gt;
                    &lt;div class="tool-section"&gt;
                      &lt;div class="tool-section-label"&gt;Input&lt;/div&gt;
                      &lt;pre class="agent-session-pre agent-session-terminal"&gt;&lt;code&gt;$ count Navitaire charge types and discount signs&lt;/code&gt;&lt;/pre&gt;
                    &lt;/div&gt;
                    &lt;div class="tool-section"&gt;
                      &lt;div class="tool-section-label"&gt;Output&lt;/div&gt;
                      &lt;pre class="agent-session-pre"&gt;&lt;code&gt;charge types: FarePrice, Tax, Discount | discount amounts: positive 27/27&lt;/code&gt;&lt;/pre&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;Mapping: sum:charges[ChargeType!=Discount].Amount - sum:charges[ChargeType=Discount].Amount. Also: connecting itineraries are priced per leg, so only the searched route is kept (11,195 leg rows dropped).&lt;/p&gt;

                &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div class="agent-session-message agent-session-assistant"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-assistant"&gt;
          Agent
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;Honest result with 11 suppliers: coverage 17% -&amp;gt; 23%, but Chronos-Bolt small (20.1%) did NOT beat the weekday baseline (18.4%) on estimated dates. Put that in the README and the post rather than the earlier small-sample number.&lt;/p&gt;

                &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div class="agent-session-message agent-session-user"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-user"&gt;
          You
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;Can we increase the accuracy since you downgraded to 64 because of less RAM?&lt;/p&gt;

                &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div class="agent-session-message agent-session-assistant"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-assistant"&gt;
          Agent
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;Correction first: 256 -&amp;gt; 64 was Chronos's batch size, which doesn't change accuracy, only memory. What can help is model size and ensembling, so I measured five options on the real backtest.&lt;/p&gt;

                &lt;/div&gt;
              &lt;div class="agent-session-tool-call"&gt;
                
                  &lt;span class="agent-session-chevron"&gt;▸&lt;/span&gt;
                  &lt;span class="tool-name tool-name-bash"&gt;Bash&lt;/span&gt;
                    &lt;span class="tool-input-preview"&gt;backtest --models naive,chronos,chronos-base,ensemble,ensemble-base&lt;/span&gt;
                
                &lt;div class="agent-session-tool-detail"&gt;
                    &lt;div class="tool-section"&gt;
                      &lt;div class="tool-section-label"&gt;Input&lt;/div&gt;
                      &lt;pre class="agent-session-pre agent-session-terminal"&gt;&lt;code&gt;$ backtest --models naive,chronos,chronos-base,ensemble,ensemble-base&lt;/code&gt;&lt;/pre&gt;
                    &lt;/div&gt;
                    &lt;div class="tool-section"&gt;
                      &lt;div class="tool-section-label"&gt;Output&lt;/div&gt;
                      &lt;pre class="agent-session-pre"&gt;&lt;code&gt;baseline 18.4% | chronos small 20.1% | chronos base 17.6% | small+baseline 17.9% | base+baseline 15.1%&lt;/code&gt;&lt;/pre&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;Picking the best of five on one backtest flatters the winner, so I re-checked on different cutoffs: on a 63-date subset it went the other way (20.3% vs 19.0%). Then ran all 14 cutoffs (591 estimated dates): ensemble 16.2% vs baseline 18.7%. Shipped the ensemble and reported both checks.&lt;/p&gt;

                &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div class="agent-session-message agent-session-assistant"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-assistant"&gt;
          Agent
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;Deployment on Render: Chronos runs where the logs live and writes a compact forecasts.json (columnar, 1.85 MB -&amp;gt; 565 KB so it fits a Secret File); the API serves it with no PyTorch. A public synthetic demo plus a private service behind a login, upgraded to Starter + disk with the Render credit. Redesigned the UI: a fare profile strip above the month, the route as the headline, a panel explaining each picked day, keyboard navigation.&lt;/p&gt;

                &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div class="agent-session-message agent-session-user"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-user"&gt;
          You
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;The private site shows the browser's sign-in popup, and cancelling it shows raw JSON. The route dropdown opens with giant faint text.&lt;/p&gt;

                &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div class="agent-session-message agent-session-assistant"&gt;
        &lt;div class="agent-session-role-badge agent-session-role-assistant"&gt;
          Agent
        &lt;/div&gt;
        &lt;div class="agent-session-content"&gt;
                &lt;div class="agent-session-text"&gt;
                  &lt;p&gt;Replaced Basic-auth popups with a sign-in page and a signed, HttpOnly, SameSite=Lax session cookie; API calls without credentials get 401 JSON without the popup header; pages redirect to /login with same-site-only next targets. Tests cover open redirects, forged cookies and script injection via next. The headline codes stay large while an invisible native select sits on top, so the list opens at normal size in theme colours.&lt;/p&gt;

                &lt;/div&gt;
              &lt;div class="agent-session-tool-call"&gt;
                
                  &lt;span class="agent-session-chevron"&gt;▸&lt;/span&gt;
                  &lt;span class="tool-name tool-name-bash"&gt;Bash&lt;/span&gt;
                    &lt;span class="tool-input-preview"&gt;pytest -q&lt;/span&gt;
                
                &lt;div class="agent-session-tool-detail"&gt;
                    &lt;div class="tool-section"&gt;
                      &lt;div class="tool-section-label"&gt;Input&lt;/div&gt;
                      &lt;pre class="agent-session-pre agent-session-terminal"&gt;&lt;code&gt;$ pytest -q&lt;/code&gt;&lt;/pre&gt;
                    &lt;/div&gt;
                    &lt;div class="tool-section"&gt;
                      &lt;div class="tool-section-label"&gt;Output&lt;/div&gt;
                      &lt;pre class="agent-session-pre"&gt;&lt;code&gt;60 passed&lt;/code&gt;&lt;/pre&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;
  &lt;/div&gt;

  &lt;div class="agent-session-footer"&gt;
    &lt;span class="agent-session-meta"&gt;
        19 of 18 messages
    &lt;/span&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;h2&gt;
  
  
  My First User
&lt;/h2&gt;

&lt;p&gt;During beta testing, our ops team switched Fare Calendar on for a few of our agents and some of our own staff.&lt;/p&gt;

&lt;p&gt;They liked it, and they told our tech team it’s one of the features most in demand from our clients and agents. They’d been asking for something like this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Gemma&lt;/strong&gt;: Gemma 4, run locally, writes the supplier mappings that the whole pipeline depends on (7 of 11), verified by code against real responses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Render&lt;/strong&gt;: two services from one blueprint. A public demo on the free plan, and a private Starter service with a persistent disk for nightly forecast uploads, behind a sign-in page.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;What shaped the approach:&lt;/em&gt; "&lt;a href="https://dev.to/arritola92/the-fare-observation-schema-id-build-before-a-flight-scraper-2kjn"&gt;The Fare Observation Schema I'd Build Before a Flight Scraper&lt;/a&gt;" by arritola92 is why "seen" and "estimate" are kept apart and nothing is presented as bookable. "&lt;a href="https://dev.to/team-parseable/chronos-vs-toto-zero-shot-forecasting-benchmark-results-1101"&gt;Chronos vs Toto: Zero-Shot Forecasting Benchmark Results&lt;/a&gt;" by Team Parseable is why I tried a zero-shot forecaster before training anything. "&lt;a href="https://dev.to/ishemah/i-priced-150-flights-across-november-tuesday-was-the-cheapest-day-to-fly-friday-cost-20-more-3i7i"&gt;I priced 150 flights across November…&lt;/a&gt;" by ishemah matched the weekday effects I built the synthetic demo around.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Built with an AI coding agent (Claude Code) and reviewed by me. The product itself runs on open-weight models: Gemma 4 and Chronos-Bolt.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>gemma</category>
      <category>ai</category>
    </item>
    <item>
      <title>Trip Buddy — I built my friend a budget trip planner on an open-weight model</title>
      <dc:creator>adi-ray</dc:creator>
      <pubDate>Sun, 04 Oct 2026 17:20:33 +0000</pubDate>
      <link>https://dev.to/adiray/trip-buddy-i-built-my-friend-a-budget-trip-planner-on-an-open-weight-model-1ilb</link>
      <guid>https://dev.to/adiray/trip-buddy-i-built-my-friend-a-budget-trip-planner-on-an-open-weight-model-1ilb</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-weekend-2026-10-01"&gt;Hacktoberfest Weekend Challenge: Build for a Friend&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;MY FRIENDS loves to travel but plans trips the hard way: one tab for trains, five for hostels, a dozen blog posts listing "top 10 things to do", and a mental map that never quite fits into the days available. They're heading to Manali next month with three days and a student budget."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trip Buddy&lt;/strong&gt; turns that into one form. Enter where you're starting, where you're going, how many days, a budget, and what you're into. You get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Getting there&lt;/strong&gt;: train / bus / flight options from your city, cheapest first, with rough costs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Where to stay cheaply&lt;/strong&gt;: three affordable areas with nightly price ranges and why each one works&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Getting around&lt;/strong&gt;: local transport options and what they cost&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What to see, in what order&lt;/strong&gt;: the famous sights grouped into days &lt;em&gt;by geography&lt;/em&gt;, each day routed as a loop from where you're staying, with start times, travel minutes, and a lunch break, all on a map&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;The key decision: &lt;strong&gt;the LLM researches, plain code optimises.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;form ──► /api/plan ──┬─► open-weight LLM (Llama 3.3 70B, OpenAI-compatible API)
                     │     → transport, stays, sights with coordinates (strict JSON)
                     ├─► OpenStreetMap Nominatim
                     │     → real coordinates for the destination
                     └─► optimize.js (no AI)
                           priority-select within the time budget
                           → k-means into days → nearest-neighbour + 2-opt per day
                           → timed schedule
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Research (open-weight model).&lt;/strong&gt; One call to Llama 3.3 70B returns structured JSON: transport options, budget stays with coordinates, 10–16 attractions with coordinates, realistic time-on-site, must-see flags, entry fees and best time to visit. Temperature is low, and the prompt asks for price &lt;em&gt;ranges&lt;/em&gt;, never exact prices.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Grounding (OpenStreetMap).&lt;/strong&gt; Models sometimes place things in the wrong city. I geocode the destination with Nominatim and drop any "attraction" more than 80 km away. In testing, a stray "Taj Mahal" in a Jaipur plan was filtered out.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optimisation (deterministic code).&lt;/strong&gt; Asking an LLM to "order these optimally" gives a plausible-looking but unverifiable answer. So &lt;code&gt;optimize.js&lt;/code&gt;:

&lt;ul&gt;
&lt;li&gt;picks sights by priority (must-sees first) until the day budget is full&lt;/li&gt;
&lt;li&gt;clusters them into days with k-means (farthest-point init, so it's deterministic), then rebalances overloaded days&lt;/li&gt;
&lt;li&gt;routes each day as a loop from the stay: nearest-neighbour, then 2-opt&lt;/li&gt;
&lt;li&gt;converts that into a timed schedule with travel estimates and lunch&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In my Jaipur test, Amber Fort, Jaigarh Fort and Nahargarh landed on one day, and City Palace, Jantar Mantar and Hawa Mahal (a few hundred metres apart) on another. That's what a local would tell you.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Frontend.&lt;/strong&gt; One HTML page with Leaflet and OpenStreetMap tiles. Each day gets its own colour on the map.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No npm dependencies: Node's built-in &lt;code&gt;http&lt;/code&gt; and &lt;code&gt;fetch&lt;/code&gt;, plus 7 unit tests with &lt;code&gt;node:test&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;I can swap the brain in two lines.&lt;/strong&gt; The app speaks the OpenAI-compatible protocol, so Llama on Groq, Qwen on OpenRouter, or a model on my own laptop through Ollama all work by changing &lt;code&gt;LLM_BASE_URL&lt;/code&gt; and &lt;code&gt;LLM_MODEL&lt;/code&gt;. No vendor lock-in for a tool I'm handing to a friend.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It costs my friend nothing.&lt;/strong&gt; Open-weight models on free inference tiers, OpenStreetMap for maps and geocoding, no paid map SDK. A student trip planner shouldn't need a credit card.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It can go fully offline and private.&lt;/strong&gt; Point it at Ollama and the trip plan (where you're going, when, and your budget) never leaves the laptop.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open data keeps the model honest.&lt;/strong&gt; OpenStreetMap lets me check the model's coordinates against real geography for free. That's why the itinerary is grounded instead of just sounding right.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I control the behaviour, not a black box.&lt;/strong&gt; The parts that must be correct (what fits in a day, what order to go in) are code I can read, test and fix. The open model does what it's good at: knowing that Jaipur has a ₹300 composite ticket and that you should hit Amber Fort before the heat.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How I Worked
&lt;/h2&gt;

&lt;p&gt;I built this with Claude Code, from idea to tested app in one sitting.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI Disclosure
&lt;/h2&gt;

&lt;p&gt;Code and this write-up were produced with help from an AI coding agent (Claude Code), reviewed and tested by me. Trip Buddy itself runs on an open-weight model (Llama 3.3 70B).&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>hf26challenge</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Building a Stone Paper Scissors Game with Amazon Q CLI: A Step-by-Step Guide</title>
      <dc:creator>adi-ray</dc:creator>
      <pubDate>Sat, 31 May 2025 19:10:00 +0000</pubDate>
      <link>https://dev.to/adiray/building-a-stone-paper-scissors-game-with-amazon-q-cli-a-step-by-step-guide-4d40</link>
      <guid>https://dev.to/adiray/building-a-stone-paper-scissors-game-with-amazon-q-cli-a-step-by-step-guide-4d40</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;This blog walks you through the development of a &lt;strong&gt;Stone Paper Scissors&lt;/strong&gt; game built using &lt;strong&gt;Amazon Q CLI&lt;/strong&gt;, an AI-powered coding assistant that made development faster, smoother, and more enjoyable.&lt;/p&gt;

&lt;p&gt;I chose this project because it's a fun and simple way to learn &lt;strong&gt;Python&lt;/strong&gt;, explore &lt;strong&gt;clean code architecture&lt;/strong&gt;, and test the power of &lt;strong&gt;Amazon Q CLI&lt;/strong&gt; in an interactive development environment.  &lt;/p&gt;

&lt;p&gt;By the end of this blog, you'll learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to install and configure Amazon Q CLI&lt;/li&gt;
&lt;li&gt;How to iteratively build a Python game using AI-generated suggestions&lt;/li&gt;
&lt;li&gt;How Amazon Q simplifies testing, debugging, and structuring code&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Project Setup &amp;amp; Development
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Setting Up Amazon Q CLI
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Prerequisites
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;An &lt;strong&gt;AWS account&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;A working &lt;strong&gt;Python environment&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;WSL (for &lt;strong&gt;Windows&lt;/strong&gt; users)
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Installation Steps
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;For Windows Users (WSL Setup):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wsl &lt;span class="nt"&gt;-d&lt;/span&gt; Ubuntu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;💡 If you get &lt;code&gt;WSL_E_DISTRO_NOT_FOUND&lt;/code&gt;, the below command will install Ubuntu distribution&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wsl &lt;span class="nt"&gt;--install&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; Ubuntu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;🔗 I referred to this &lt;a href="https://community.aws/content/2v5PptEEYT2y0lRmZbFQtECA66M/the-essential-guide-to-installing-amazon-q-developer-cli-on-windows?trk=e07eca93-fa2f-4351-b567-f293b83eb635&amp;amp;sc_channel=el_" rel="noopener noreferrer"&gt;guide for installing Amazon Q CLI on Windows&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Start chatting with Amazon Q:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;q chat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Planning the Game
&lt;/h3&gt;

&lt;p&gt;I first outlined the core requirements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Player vs Computer gameplay&lt;/li&gt;
&lt;li&gt;Score tracking&lt;/li&gt;
&lt;li&gt;Replay option&lt;/li&gt;
&lt;li&gt;Clean terminal UI with color support&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then, I structured the project with the following folders:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;project-root/
│
├── src/
│   ├── game_engine.py
│   ├── utils.py
│   └── run_game.py
│
├── assets/
│   └── ascii_art.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Building with Amazon Q CLI
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Initial Prompt
&lt;/h4&gt;

&lt;p&gt;I started by asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Help me create a stone paper scissors game in Python with a clean architecture. &lt;br&gt;
AI Prompt: Stone-Paper-Scissors with Pixel Art &amp;amp; 8-Bit Music&lt;br&gt;&lt;br&gt;
Target Library: PyGame (with Pyganim for pixel animations)&lt;br&gt;&lt;br&gt;
Style: Retro arcade vibe, dynamic AI, and special moves"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Amazon Q provided a basic structure with separate functions for input handling, logic, and scoring.&lt;/p&gt;

&lt;h4&gt;
  
  
  Iterative Development
&lt;/h4&gt;

&lt;p&gt;I used follow-up prompts like:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;"Add colorful terminal output to the game"&lt;/em&gt; &lt;/li&gt;
&lt;li&gt;&lt;em&gt;"Implement score tracking functionality"&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Amazon Q responded with helpful suggestions using libraries like &lt;code&gt;colorama&lt;/code&gt; and added features step-by-step, reducing manual effort.&lt;/p&gt;

&lt;h4&gt;
  
  
  Key Code Components
&lt;/h4&gt;

&lt;p&gt;Some valuable code snippets from Q included:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A score dictionary to track wins&lt;/li&gt;
&lt;li&gt;A function for randomized computer moves&lt;/li&gt;
&lt;li&gt;A clean game loop with replay options
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I refined variable names, added error handling, and tweaked color schemes for better UX.&lt;/p&gt;




&lt;h3&gt;
  
  
  Testing &amp;amp; Debugging with Amazon Q
&lt;/h3&gt;

&lt;p&gt;Whenever I faced errors (like input mismatches or color issues), I simply asked:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Fix this ValueError when input is invalid"&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;"Add unit tests for the game logic"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Amazon Q provided clear fixes and even mocked &lt;code&gt;input()&lt;/code&gt; for testable functions.&lt;/p&gt;




&lt;h2&gt;
  
  
  Deployment
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Running the Game
&lt;/h3&gt;

&lt;p&gt;To play the game, simply run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python src/run_game.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Colorful prompts&lt;/li&gt;
&lt;li&gt;Real-time score updates&lt;/li&gt;
&lt;li&gt;ASCII visuals (from &lt;code&gt;assets/&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Screenshots
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuk71sfxve5bkb6g7193g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuk71sfxve5bkb6g7193g.png" alt="Gameplay Screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/X96WRRz-Zzs"&gt;
  &lt;/iframe&gt;
&lt;br&gt;
&lt;em&gt;Click the image above to watch the gameplay demo on YouTube&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Pros of Using Amazon Q CLI
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Super-fast prototyping
&lt;/li&gt;
&lt;li&gt;Clean, modular code generation
&lt;/li&gt;
&lt;li&gt;Helpful debugging prompts
&lt;/li&gt;
&lt;li&gt;Smart suggestions for best practices&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tips for Others
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Break down tasks into short prompts
&lt;/li&gt;
&lt;li&gt;Use follow-ups to refine code
&lt;/li&gt;
&lt;li&gt;Always test generated code manually&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This project demonstrated how &lt;strong&gt;Amazon Q CLI&lt;/strong&gt; can accelerate even small projects like games while encouraging clean architecture and modular design.  &lt;/p&gt;

&lt;p&gt;If you’re learning Python or want to prototype apps efficiently, give Amazon Q CLI a try!   &lt;/p&gt;




&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🎥 &lt;a href="https://youtu.be/X96WRRz-Zzs" rel="noopener noreferrer"&gt;Gameplay Demo Video&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🔗 &lt;a href="https://github.com/adi-ray/rps-arcade-game" rel="noopener noreferrer"&gt;GitHub Repository – Stone Paper Scissors Game&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📘 &lt;a href="https://aws.amazon.com/blogs/devops/introducing-the-enhanced-command-line-interface-in-amazon-q-developer/" rel="noopener noreferrer"&gt;Amazon Q CLI Documentation&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aws</category>
      <category>amazonqcli</category>
      <category>python</category>
      <category>ai</category>
    </item>
    <item>
      <title>🛰How AI Helped Chandrayaan-3 Achieve Its Lunar Mission? 💡🚀 📡</title>
      <dc:creator>adi-ray</dc:creator>
      <pubDate>Thu, 24 Aug 2023 14:54:22 +0000</pubDate>
      <link>https://dev.to/adiray/how-ai-helped-chandrayaan-3-achieve-its-lunar-mission-4o2i</link>
      <guid>https://dev.to/adiray/how-ai-helped-chandrayaan-3-achieve-its-lunar-mission-4o2i</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;ISRO’s Chandrayaan-3, the third lunar mission has set history by touching down on moon’s surface.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;ISRO, or the Indian Space Research Organisation, has pioneered space exploration by launching everything from small satellites to big moon missions. This demonstration of India's technological prowess has helped to establish the country's flag in the international space landscape.&lt;/p&gt;

&lt;h4&gt;
  
  
  Chandrayaan-3: A Giant Leap to the Moon's South Pole
&lt;/h4&gt;

&lt;p&gt;Chandrayaan-3, the successor to Chandrayaan-2, represents the pinnacle of India's space technology. This lunar mission aims to soft-land a rover near the Moon's south pole. This achievement could catapult India's space industry to unprecedented heights and inspire future generations to reach for the stars. By integrating AI, ISRO joins the global space community in its quest to tap into this technology's potential to unearth cosmic truths.&lt;/p&gt;

&lt;p&gt;During the last stage of its landing, the Chandrayaan-3 spacecraft has gone through a window of "17 minutes of terror", where it was carrying out a series of maneuvers which was crucial for landing. It included altitude adjustments, firing thrusters, &amp;amp; scanning the surface for any obstacles - all of that was done with the help of AI. During this period, the Chandrayaan-3 team was able to monitor its progress from the ISRO Telemetry, Tracking, &amp;amp; Command Network in Bengaluru, while Al was at the helm of the Vikram lander. ISRO has already confirmed that the lander used autonomously controlled by Al using Machine Learning that operated its guidance, navigation, control &amp;amp; other systems.&lt;/p&gt;

&lt;h4&gt;
  
  
  Artificial Intelligence: Guiding the Lunar Rover
&lt;/h4&gt;

&lt;p&gt;At the core of this mission is the pivotal role of Artificial Intelligence (AI). Lander &amp;amp; rover, as well as entire ship is designed &amp;amp; developed using AI, The spacecraft’s design is being optimized for weight, performance, and safety using AI algorithms.&lt;br&gt;
It uses this tech to examine lunar soil, identify obstacles, and send priceless data back to Earth. Built to operate for a lunar day, the rover's AI-driven abilities could broaden our understanding of the lunar surface, atmosphere, and possible water existence.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqt6k5pv1n77exgxtsifx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqt6k5pv1n77exgxtsifx.png" alt="Chandrayaan-3 rover" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Artificial Intelligence Reshaping the Space Industry
&lt;/h4&gt;

&lt;p&gt;Given the vast and unpredictable expanse of space, AI's problem-solving and data-analysis abilities can be crucial. AI can help make critical real-time choices, eliminate human errors, and improve overall mission performance.&lt;br&gt;
As we look to the future, the intersection of AI and space exploration promises to push the boundaries of what we thought was possible. AI might become a vital tool for everything from forecasting mission abnormalities to identifying new celestial bodies and potentially organizing interstellar communities.&lt;/p&gt;

&lt;p&gt;So, Chandrayaan-3's significance goes beyond its scientific goals. It symbolizes the merging of AI and space exploration, opening a new era where both will jointly fuel our quest to decipher the universe. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;     Space technology in the Service of humankind.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;p&gt;Feel free to share this article with your peers and do hit a ❤️ if you liked it. If you have any query, feel free to ask them in the comment section.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You can also connect with me on &lt;a href="https://linkedin.com/in/adi-ray" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>learning</category>
    </item>
    <item>
      <title>Introduction to APIs via Postman</title>
      <dc:creator>adi-ray</dc:creator>
      <pubDate>Sun, 12 Mar 2023 13:42:37 +0000</pubDate>
      <link>https://dev.to/adiray/introduction-to-apis-via-postman-3p8o</link>
      <guid>https://dev.to/adiray/introduction-to-apis-via-postman-3p8o</guid>
      <description>&lt;p&gt;Recently, I had the pleasure of attending an &lt;strong&gt;&lt;em&gt;"API 101 with Postman"&lt;/em&gt;&lt;/strong&gt; session. As a newcomer to the world of APIs, I was eager to learn about Postman's capabilities and how it can streamline the API testing and development process. In this blog post, I'll share my experience attending the session and provide a comprehensive overview of Postman API.&lt;/p&gt;

&lt;p&gt;&lt;u&gt;About the speaker:&lt;/u&gt;&lt;br&gt;
The session was conducted by &lt;a href="https://www.linkedin.com/in/pratap-divyansh" rel="noopener noreferrer"&gt;Divyansh Pratap Singh&lt;/a&gt;, who has an extensive experience in API testing and automation. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3fvmxefzi90vp1n6w7ib.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3fvmxefzi90vp1n6w7ib.png" alt="Speaker information" width="800" height="354"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Agenda of the session:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Intro to APIs and Postman .&lt;/li&gt;
&lt;li&gt;Requests and responses.&lt;/li&gt;
&lt;li&gt;Hands-on session.&lt;/li&gt;
&lt;li&gt;Follow-up resources.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  What's an API ?
&lt;/h4&gt;

&lt;p&gt;Software has become more complex and collaborative over the years. Developers no longer need to create every services from scratch.&lt;br&gt;
Application Programming Interfaces(APIs) allow developers to access data from a service (like Google or twitter) without any kowledge of how the codebase has been implemented.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;APIs allow services to communicate with each other.&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Types of APIs:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Hardware APIs&lt;/li&gt;
&lt;li&gt;Software Library APIs &lt;/li&gt;
&lt;li&gt;Web APIs&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Request-Response Pattern&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faqbxjq3y8h8owkj749gg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faqbxjq3y8h8owkj749gg.png" alt="A picture showing how client interacts with the server via network" width="740" height="308"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  What is Postman?
&lt;/h4&gt;

&lt;p&gt;Postman is a collaborative API development platform that simplifies creating, using and testing APIs with an interactive UI.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;More than 500,000 organizations &amp;amp; 13 million developers use Postman.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;One of the main reasons for the increased Popularity of the Postman is because of its interface :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgx9zbnm7auf6rd8l3kz2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgx9zbnm7auf6rd8l3kz2.png" alt="Working APIs: Then vs Now" width="800" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.postman.com/" rel="noopener noreferrer"&gt;Refer this link&lt;/a&gt; for simply creating your postman account.&lt;/p&gt;




&lt;h3&gt;
  
  
  Making Requests (Interact with the API) :
&lt;/h3&gt;

&lt;p&gt;We were then shown how to send requests to APIs using different HTTP methods, such as GET, POST, PUT, and DELETE.&lt;br&gt;
The 3 ingredients to make a request:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Methods (GET,POST,etc.)&lt;/li&gt;
&lt;li&gt;Address / Endpoint (URL)&lt;/li&gt;
&lt;li&gt;Path&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkp6dpm2ox6w7i2z1brlp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkp6dpm2ox6w7i2z1brlp.png" alt="Requests - Methods and Endpoints " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  The response elements for Receiving Requests are :
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;Status Codes (200 OK , 201 CREATED , 404 NOT FOUND)&lt;/li&gt;
&lt;li&gt;Headers&lt;/li&gt;
&lt;li&gt;Accessing body data&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://https://learning.postman.com/" rel="noopener noreferrer"&gt;Learning Center &lt;/a&gt;&lt;br&gt;
&lt;a href="https://https://explore.postman.com/" rel="noopener noreferrer"&gt;API Network&lt;/a&gt;&lt;br&gt;
&lt;a href="https://https://community.postman.com/" rel="noopener noreferrer"&gt;Forum &lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Attending the Introduction to Postman API session was a great learning experience. We learned about the basics of API with Postman and got hands-on experience with various features of the tool.&lt;/p&gt;

&lt;p&gt;Apart from this, we also got to know about the Postman Student Expert Certification which will help us take Postman skills to the next level and showcase our expertise to the world.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flu4ae712qyz1pee7clr9.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flu4ae712qyz1pee7clr9.jpeg" alt="Postman programs for Students" width="800" height="333"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.postman.com/student-program/" rel="noopener noreferrer"&gt;Click Here&lt;/a&gt; to explore more about Postman Student Programs.&lt;/p&gt;




&lt;p&gt;Feel free to share this article with your peers and do hit a ❤️ if you liked my blog. If you have any query about how to get started with Postman , feel free to ask them in the comment section.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You can also connect with me on &lt;a href="https://linkedin.com/in/adi-ray" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>postmanstudent</category>
      <category>postmanapi</category>
      <category>api</category>
      <category>postman</category>
    </item>
  </channel>
</rss>
