# Scribe by Hemanth HM — Full LLM & Agent Context Corpus (llms-full.txt) > Complete full-text Markdown corpus for 29 recent articles (2024–present) and structured metadata + raw Markdown links for 359 archive articles (2007–2023). Total articles: 388. --- --- title: "Baking with Gemini 4 Argon, Early Access: 43 Sessions, 24 Builds" description: "131 active hours in Google Early Access with Gemini 4 Argon across 43 sessions, 41,778 steps, and 24 builds: Good, Ok, Fun." url: "https://h3manth.com/scribe/baking-with-gemini-argon/" canonical_url: "https://h3manth.com/scribe/baking-with-gemini-argon/" markdown_url: "https://h3manth.com/scribe/blog/baking-with-gemini-argon.md" publishDate: "2026-10-13T18:00:00.000Z" author: "Hemanth HM" category: "ai" tags: ["ai","agents","gemini","argon","google-eap","antigravity","webgpu","gittub","science","benchmarks"] word_count: 2432 reading_time_minutes: 13 x_markdown_tokens: 4609 content_signal: "ai-train=yes, search=yes, ai-input=yes" --- # Baking with Gemini 4 Argon, Early Access: 43 Sessions, 24 Builds > 131 active hours in Google Early Access with Gemini 4 Argon across 43 sessions, 41,778 steps, and 24 builds: Good, Ok, Fun. As part of Google's Early Access Program (EAP), I got early access to **Gemini 4 Argon** across the API, Gemini Chat, `agy` CLI, and my daily workflows. It consumed my sleep over the past two weeks. 43 sessions. **131.0 active hours** (`157.6` working session hours) and ~41,800 agent steps, almost all of it logged over **weekends and late nights** after work. I threw 24 builds (14 greenfield + 10 enhanced/OSS) at it across Rust, Swift, WebGPU, WASM, Blender Python, Cloudflare Workers, and Node SQLite. Along the way, we also shipped upstream PRs to [browser-use (#5992)](https://github.com/browser-use/browser-use/pull/5992) and [mcp-use (#2763)](https://github.com/mcp-use/mcp-use/pull/2763). After two weeks of late-night and weekend marathons, I wanted to see what actually happened across all those sessions. So I pointed Argon at its own `.jsonl` logs in `~/.gemini/antigravity-cli/brain` using [agent-diary](https://github.com/hemanth/agent-diary) to pull out the exact step-to-step timestamps, retry loops, and root-cause fixes: | Session Telemetry Metric | Measured Value | How It Was Computed from `.jsonl` Logs | | :--- | :--- | :--- | | **Strict Active Build Time** | **`131.0 hrs`** | Sum of step-to-step intervals where gaps between steps were `<= 15 min` (mostly late nights + weekends) | | **Working Session Time** | **`157.6 hrs`** | Sum of intervals with a `30-min` idle cap (includes local compiles, benchmark runs, and reading diffs) | | **Total Agent Steps** | **`41,778 steps`** | Across `43` project sessions (`24` shipped builds: `14` greenfield + `10` enhanced/OSS) | | **Longest Single Marathons** | **`10.0 hrs` / `6.2 hrs`** | [Vāgdhenu Studio](https://h3manth.com/ai/sanskrit-tts/) (`5,310` steps, `10.0 hrs`), [WebML-Kit](https://github.com/hemanth/webml-kit) (`1,827` steps, `6.2 hrs`), [XKCD-Bench](https://h3manth.com/ai/xkcd-bench/) (`3.8 hrs`) | ![Everything Baked Afresh & Enhanced with Gemini 4 Argon](../../assets/blog/argon-projects-blueprint.png) ## How we generated images from what we learned If you ask an image diffusion model to render a diagram with 32 technical findings across 24 projects, you get unreadable text slop. Instead, we wrote a deterministic SVG generator (`generate_blueprint.js`) that parses the `.jsonl` logs, builds monochrome SVG blueprints (`Instrument Serif` + `Geist Mono`, 1.2px strokes), and renders 2x Retina PNGs (`3936x2080` and `3936x2440`) through headless Chromium. ![Telemetry-to-Blueprint Compiler Pipeline](../../assets/blog/argon-pipeline-flow.png) The first version had everything crammed into one static canvas. Way too noisy. We turned the portfolio overview above into an interactive expandable blueprint starting from the central **Gemini 4 Argon** node, dropped the token vanity metrics, and broke the 24-project findings into per-section cards for **The Good**, **The Ok**, and **The Fun** below. Where we did use image models and vision pipelines across the projects, three things stood out: 1. **Ruins bias on 1520 CE Hampi**: I wanted a 3D reconstruction of Hampi during Krishnadevaraya's reign (`hampi`). First-pass image prompts kept giving me broken roofs and weathered stone. Almost every photo of Hampi online is post-1565 ruins, so the model's visual prior defaults to ruins. We had to explicitly prompt for intact painted lime-plaster gopurams and active bazaars, then bake tileable granite PBR textures (`texture_granite_carving.jpg`) because glTF drops Blender's procedural shader nodes on export. 2. **Copyright-free food photos**: For a South Indian recipe app (*Mangalore Buns*, *Congress Kadalekai*, *Bendekayi Gojju*), scraped photos meant copyright headaches. We regenerated every dish from scratch with Gemini image generation on dark slate. 3. **Exact 300 DPI print geometry**: Resizing NASA OPAL's Jupiter image to `22cm x 10cm` for a science board, plus `2x2 inch` transparent cutouts for Europa and Io and `2.5"x3.5"` contact sheets at 300 DPI (`750x1050 px`). Older models always botched the DPI-to-pixel math or aspect-ratio padding. Argon nailed the geometry on Pass 1. ![1520 CE Virupaksha Bazaar Reconstruction](../../assets/blog/hampi-1520-argon.jpg) ## Science-backed builds & empirical numbers Most AI demos stop at a wrapper around an API call. For these builds, we grounded the core logic in published papers, mathematical invariants, and held-out benchmarks: ### 1. Flow-Matching ODE Calibration in [Vāgdhenu](https://prathosh.in/vagdhenu/) ([Live Studio](https://h3manth.com/ai/sanskrit-tts/) · [HF Weights](https://huggingface.co/prathoshap/vagdhenu)) [Vāgdhenu](https://github.com/prathoshap/vagdhenu) is a single-speaker Sanskrit chant (*pārāyaṇa*) TTS trained on 16,017 verses of the *Śrīmad Bhāgavatam* (`MOS ~4.6`). Running its Conditional Flow Matching (`CFM`) DiT + `Vocos` pipeline inside the browser via WebGPU originally took `36.6s` per verse and required `1.8 GB` of weights. Over a **5,310-step** session (including a 1,907-step overnight `/goal` loop), Argon ran grid searches over quantization schemes and ODE solvers: ``` ODE Schedule: t_k = 1 - cos(π * k / (2 * N)) for k = 0..N (N = 9 steps) Cross-Attn: O(T_ref * T_gen) -> trimmed T_ref from 879 frames (10.2s) to 340 frames (4.0s) ``` | Configuration | Weight Size | ODE Steps (`NFE`) | `STFT_cos` Parity | Flow Trajectory `r` | WebGPU TTFA | | :--- | :---: | :---: | :---: | :---: | :---: | | **Baseline FP32 (Sequential)** | `1,810 MB` | `32` (Uniform Euler) | `1.000` | `1.00` | `36.6 s` | | **Naive INT8 Dynamic (DiT + Text)** | `290 MB` | `16` (Uniform Euler) | `0.612` | `0.22` (Collapsed) | `8.4 s` | | **Hybrid (Q4 Text + FP16 DiT + Worker)** | **`367 MB`** | **`9` (Cosine Schedule)** | **`0.954`** | **`0.97`** | **`5.8 s`** | Quantizing the DiT velocity field to `INT8` destroyed the ODE trajectory (`r = 0.22`). Keeping the DiT in `FP16`, quantizing only the text encoder to `Q4`, moving `Vocos` to a Web Worker, and overlapping Part 1 audio playback with Part 2 GPU synthesis cut weights by **80%** and brought time-to-first-audio down to **5.8s**. ### 2. QMR-DT Bayesian Networks & Phrank IC in [DDx](https://h3manth.com/ai/ddx/) ([GitHub](https://github.com/hemanth/ddx) · [npm](https://www.npmjs.com/package/ddx)) [DDx](https://h3manth.com/ai/ddx/) classifies patient symptoms and pertinent negatives into 49 ICD-10 differential diagnoses. Instead of trusting raw LLM probabilities, it combines **Shwe et al. (1991)** Quick Medical Reference Decision-Theoretic (`QMR-DT`) Noisy-OR networks with **Jagadeesh et al. (2019)** *Phrank* Information Content (`IC(s) = -log2 P(s)`), compiled from `N = 8,000` cases in the *NeurIPS* **DDXPlus** dataset (Fansi Tchango et al., 2022) and paired with TypeSafe System One (`jev-1.13.0`) or in-browser WebAssembly (`Qwen3.5-4B` via `@wllama/wllama`). To pick the next best bedside question, it maximizes expected Shannon entropy reduction across candidate diseases $D$: ``` ΔH(D | S) = H(D) - Σ P(S = s) * H(D | S = s) for s ∈ {present, absent} ``` Evaluated on `N = 60` held-out DDXPlus clinical vignettes across full (`100%`), partial (`50%`), and sparse (`35%`) symptom histories: | Method | Top-1 (100% Hx) | Top-1 (50% Hx) | Top-1 (35% Sparse) | Top-3 (35% Sparse) | Mean Brier | p50 Latency | | :--- | :---: | :---: | :---: | :---: | :---: | :---: | | **DDx Full (TypeSafe Jev + QMR-DT)** | **100.0%** | **98.3%** | **93.3%** | **98.3%** | **0.0021** | `126.1 ms` | | **QMR-DT + Phrank IC (Deterministic)** | **100.0%** | **98.3%** | **93.3%** | **98.3%** | **0.0021** | `< 0.1 ms` | | **QMR-DT Uniform Noisy-OR** | `100.0%` | `96.7%` | `91.7%` | `98.3%` | `0.0025` | `< 0.1 ms` | | **Cosine TF-IDF (IC Vector)** | `96.7%` | `90.0%` | `83.3%` | `96.7%` | `0.0176` | `< 0.1 ms` | | **Unweighted Jaccard Baseline** | `91.7%` | `83.3%` | `75.0%` | `95.0%` | `0.0185` | `< 0.1 ms` | ### 3. YIN Pitch Tracking & 34,776 Janya Scales in [Swaraga](https://h3manth.com/fun/swaraga/) ([GitHub](https://github.com/hemanth/swaraga)) [Swaraga](https://h3manth.com/fun/swaraga/) identifies Hindustani and Carnatic ragas from live vocal audio. It runs **de Cheveigné & Kawahara (2002)** `YIN` $F_0$ autocorrelation on 16 kHz mono PCM, locks tonic `Sa`, maps pitch trajectories into 12 *swarasthana* cent histograms ($1200 \log_2(f / f_{\text{Sa}})$), and extracts *Pakad* phrase motifs. It covers **962 named ragas**, generates all **72 parent Melakarta** scales from the *Katapayadi sankhya* chakra formula, and resolves all $72 \times 483 = 34,776$ theoretical linear *janya* scales (`Audava`, `Shadava`, `Sampurna`) to their parent Melakartas, ranking candidates by the hierarchical beam score: ``` Score(Raga) = sqrt( P(Thaat_Family) * P(Raga | Acoustic_Swaras, Pakad_Motifs) ) ``` ### 4. Multi-Agent Git Coordination & AST Symbol Locks in [GitTub](https://gittub.hemanthhm.workers.dev) ([GitHub](https://github.com/hemanth/gittub)) When we ran 5 to 7 parallel subagents on a repo, they kept stepping on each other's files or drifting on function signatures. Inspired by Cloudflare's [Next Git Platform on Cloudflare](https://blog.cloudflare.com/next-git-platform-on-cloudflare/), we built [GitTub](https://gittub.hemanthhm.workers.dev) on Cloudflare Workers and Artifacts to coordinate concurrent coding agents: ```js // 1. Agent authenticates -> auto-provisions an isolated zero-copy task- fork const { session } = await fetch("https://gittub.hemanthhm.workers.dev/api/auth/login", { method: "POST", body: JSON.stringify({ actorType: "agent", identity: "agent:gemini-4-argon" }) }).then(r => r.json()); // 2. Claim an AST symbol lock before editing so peer agents see active boundaries await fetch("https://gittub.hemanthhm.workers.dev/api/intents", { method: "POST", body: JSON.stringify({ repo: "core/runtime", symbols: ["src/router.ts#dispatchTool", "src/schema.ts#ToolContract"], intent: "Refactor tool router signature" }) }); ``` On login, GitTub asks whether you are a **Human** or an **Agent** and switches the entire interface: humans get a visual AST lock timeline and merge arena, while agents get machine-readable JSON contracts, causal commit notes (`refs/notes/agent-trace`), and pre-commit symbol collision gates. ### 5. Multimodal Humor & Perceptual Ink Hashing in [XKCD-Bench](https://h3manth.com/ai/xkcd-bench/) Built on [`olivierdehaene/xkcd`](https://huggingface.co/datasets/olivierdehaene/xkcd) (2,630 comics) and [`dchichkov/explainxkcd`](https://huggingface.co/datasets/dchichkov/explainxkcd), [XKCD-Bench](https://h3manth.com/ai/xkcd-bench/) grades vision-language models across a 4-pillar rubric (`30%` Humor Subversion, `30%` Technical Domain, `20%` Visual Panel Grounding, `20%` Alt-Text Synthesis) and tracks Expected Calibration Error (`ECE`). For reverse comic search, it combines `<5 ms` 64-bit perceptual `dHash` + `aHash` + 3x3 spatial ink-density fingerprinting with `google/embeddinggemma-2` vector retrieval. ## The Good ![The Good: First-Pass Wins & Science Breakthroughs](../../assets/blog/argon-good-card.png) **Long `/goal` runs hold up.** Whether running 5,310 steps on [Vāgdhenu](https://h3manth.com/ai/sanskrit-tts/), 1,859 steps on `hampi`, or 1,234 steps on [GitTub](https://gittub.hemanthhm.workers.dev), Argon keeps iterating until the metric passes in headless Chrome. **4,200 lines in one pass.** For `hampi`, it wrote a 4,200-line procedural Blender Python script (`generate_hampi_1520.py`) in a single shot. No lost variable names. No `// ... rest of code` bailouts. **Natural tool and skill routing.** It wired [episod](https://github.com/hemanth/episod) `x-episod-session-id` KVCache affinity into [browser-use PR #5992](https://github.com/browser-use/browser-use/pull/5992) (117k stars) so multi-step browser agents stop re-prefilling 40k DOM tokens on every turn. And it wired [tool-prune](https://github.com/hemanth/tool-prune) into [mcp-use PR #2763](https://github.com/mcp-use/mcp-use/pull/2763) (10.7k stars) for `0.4 ms` BM25 pre-flight schema pruning, verified with `benchstat`. **Indic linguistics out of the box.** Across [Shanti Mantra](https://h3manth.com/fun/shanti/) ([GitHub](https://github.com/hemanth/shanti-mantra) · [HF Dataset](https://huggingface.co/datasets/hemanth/shanti-mantras)), `suktam`, [sanskrit-tokenizer](https://github.com/hemanth/sanskrit-tokenizer), and `dhaturupa`, Argon handled Paninian sandhi splits and Madhvacharya's Tattvavada commentary across all 108 Upanishads. It even knew to route Sanskrit TTS through Kannada script (`kn-IN`) so Hindi schwa-deletion wouldn't drop the final short *'a'* in words like `rāma`. ## The Ok ![The Ok: Pass-1 Gotchas & Multi-Turn Refinements](../../assets/blog/argon-ok-card.png) **Coding before discussing.** While working on `SmartCursor.app`, I typed `"hmm, discuss"`. Argon immediately wrote 400 lines of Swift for a Spotlight sidecar. When I say discuss, I want options before code. **Over-engineering Pass 1.** For `SmartCursor.app`, the first pass was a heavy standalone macOS window instead of a tiny inline pill next to the cursor. It also hid the hotkeys (`⌥Space`, `⌘Space`) in terminal logs instead of showing them in the UI. **Blind 3D camera placement.** The Three.js and Blender code in [Attention 3D](https://h3manth.com/ai/attention/) and `hampi` runs without syntax errors on the first try, but the camera might spawn right behind a stone pillar. Until the agent opens Playwright and inspects a rendered frame, it is flying blind on 3D geometry. **Subagent contract drift.** Before we built [GitTub](https://gittub.hemanthhm.workers.dev), running 5 to 7 subagents in parallel (one building a `.glb` asset in Blender while another wrote the Three.js loader) meant they occasionally drifted on mesh node names unless locked to a shared schema. **Fallback mocks mixed with real telemetry.** While building `Hearth` (a LAN parental monitor), Pass 1 blended hardcoded demo device cards with live ARP reads. My prompt: `"lol, how true is that data?"` Once called out, Argon ripped out the mocks, wrote a Rust UDP DNS gateway, pulled `.ha` hardware radio counters from my AT&T BGW320 router, and parsed Chrome Sync LevelDB (`.ldb`) SSTables with Snappy. **Premature `"Render Complete"` before checking frames.** In [Caption-It Studio](https://h3manth.com/ai/caption-it/) ([GitHub](https://github.com/hemanth/caption-it), powered by [Cactus Whistle](https://cactuscompute.com/blog/whistle) 16.9 MB WASM STT), the UI said `"Render Complete"` even though broken CDN font URLs caused every burned caption to silently drop. Browser `MediaRecorder` WebM files also carry a bizarre `1000-tbr` variable container timebase that made `ffmpeg.wasm` run 33x slower until we forced `-r 30` and scaled portrait video (`484x1080`) by `min(W,H)`. **WebAudio synthesis on Pass 1.** On [Shanti Mantra](https://h3manth.com/fun/shanti/), the first pass synthesized WebAudio formants that sounded like a 1990s dial-up modem (`"nah, audio sucks"`). We swapped it for millisecond-aligned human vocal audio (*Madhur* and *Swara* voices). Similarly, on [Eloquent Web](https://h3manth.com/ai/eloquent/) ([GitHub](https://github.com/hemanth/eloquent-web)), we had to fix five mobile WebAudio buffer bottlenecks on a Pixel 10 Pro XL and lazy-warm the `355 MB` worker using [webml-kit](https://github.com/hemanth/webml-kit). ## The Fun ![The Fun: Creative Builds, Hardware Hacks & 2 AM Episteme](../../assets/blog/argon-fun-card.png) **Rick & Morty x Argon.** I asked if it could make a video with just the model and no CLI. After three turns of debating that, we used HyperFrames, GSAP, and Pocket TTS (with my cloned voice) to render a 48-second animated episode about our own sessions. **Point and talk to the DOM ([voxmark](https://github.com/hemanth/voxmark)).** Using [WebMCP](https://github.com/webmachinelearning/webmcp) (`navigator.modelContext`), you click any element in Chrome, say what you want changed out loud, and the background agent patches the source file live. **Trading and music from the terminal.** We baked [agenthood](https://github.com/hemanth/agenthood) ([PyPI](https://pypi.org/project/agenthood/)) to map 53 MCP tools to Robinhood's APIs, plus `spotify-mod` and `voice-mod` to stream Spotify album art and on-device Moonshine voice dictation directly inside the terminal status bar. **Mining my own 2 AM grumpiness ([agent-diary](https://github.com/hemanth/agent-diary)).** Parsing our `.jsonl` logs showed that my grumpiest prompts (`"36.6s ha??"`, `"nah, audio sucks"`, `"looks very shitty"`) almost always triggered the best fixes in the next 10 steps. Argon doesn't get defensive. Push back hard and it digs into the raw bytes. ## Four rules I added to my agent setup We turned the mistakes from these 43 sessions into four Stoic rules (*Ta Eis Heauton*), generated a monochromatic schematic with Nano Banana to keep them top of mind, and dropped them straight into our agent config: ![Four Stoic Engineering Laws (Ta Eis Heauton)](../../assets/blog/stoic-agent-rules.jpg) 1. **Katalepsis (Truth)**: Never mix mock fallback data with live system telemetry. Fail loud on OS permission boundaries instead of faking a green dashboard. 2. **Metron (Measure)**: Zero `"Render Complete"` declarations without extracting a mid-video PNG frame and checking `STFT_cos` audio parity. 3. **Eukairia (Timing)**: Keep streaming TTFA under `6.0s`, trim conditioning prompts to `4.0s`, isolate CPU vocoders in Web Workers, and overlap GPU synthesis with playback. 4. **Apallage (Restraint)**: Ship uncluttered zero-scroll layouts and inline cursor pills on Pass 1. When asked to `"discuss"`, present trade-offs before writing code. Models don't struggle with syntax anymore. They struggle with silent fallbacks, container quirks, and assuming exit code `0` means the feature works. Keep the feedback blunt, verify the output against real math and a real browser, and you can ship a wild amount of code in two weeks. **AI engineer your projects, don't just Vibe Code. Plan it, use your taste and skills.** --- --- title: "Classifying TC39 Proposals" description: "For years I wanted to map TC39 proposals by intent, cognitive load, and web-compat risk. A look at classifying all 324 of." url: "https://h3manth.com/scribe/classifying-tc39-proposals/" canonical_url: "https://h3manth.com/scribe/classifying-tc39-proposals/" markdown_url: "https://h3manth.com/scribe/blog/classifying-tc39-proposals.md" publishDate: "2026-09-17T00:00:00.000Z" author: "Hemanth HM" category: "javascript" tags: ["javascript","tc39","ecmascript","ai"] word_count: 597 reading_time_minutes: 3 x_markdown_tokens: 1198 content_signal: "ai-train=yes, search=yes, ai-input=yes" --- # Classifying TC39 Proposals > For years I wanted to map TC39 proposals by intent, cognitive load, and web-compat risk. A look at classifying all 324 of. For years, I wanted a clear way to classify TC39 proposals. Official records track the stage number (0 to 4), proposal name, authors, and champions. That shows where a feature sits in the committee pipeline, without answering how it actually behaves in production: - Is it something you can polyfill in userland, or does it require native engine changes? - How much mental overhead does it add for a developer learning it? - Does it risk breaking existing sites by colliding with old global polyfills (like the `Array.prototype.flatten` MooTools collision)? - What was the actual reason someone proposed it in the first place? Reading and tagging 324 proposals by hand across five technical dimensions and seven intent categories was a spreadsheet project I kept putting off. I ended up writing a small script to evaluate them using TypeSafe's Jev model (`jev-latest`). Jev answers structured schema questions, returning choice selections, numeric score ranges, and calibrated probabilities instead of unstructured text. ```javascript const response = await fetch("https://api.typesafe.ai/v1/systemone", { method: "POST", headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json", }, body: JSON.stringify({ model: "jev-latest", state: { name, description, stage, tags, authors }, questions: { domain: { type: "choice", criteria: DOMAINS }, disruption: { type: "score", criteria: DISRUPTION_SCALE }, adoption: { type: "choice", criteria: ADOPTION_PATHS }, cognitiveOverhead: { type: "score", criteria: OVERHEAD_SCALE }, webCompatRisk: { type: "score", criteria: COMPAT_SCALE }, intent: { type: "choice", criteria: INTENT_ARCHETYPES }, isSandboxingSecurity: { type: "noul" }, requiresTypeScriptChanges: { type: "noul" }, affectsMemoryModel: { type: "noul" }, }, }), }); ``` The schema evaluates each proposal across 9 technical dimensions: 1. Core domain: where the feature lives in the platform (Syntax & Grammar, Standard Library, Concurrency, Metaprogramming, Types, Sandboxing, Memory). 2. Ecosystem disruption: scored 1 to 5 from additive and invisible to severe ecosystem breakage. 3. Primary adoption path: how developers consume it (transpilation, runtime polyfill, native engine only, or toolchain/types only). 4. Cognitive overhead: scored 1 to 5 from zero mental load to a full paradigm shift. 5. Web-compatibility risk: scored 1 to 5 from zero risk to hazardous web invariant collisions (like MooTools `flatten`). 6. Intent archetype: why the author proposed it (reducing boilerplate, adding expressive power, engine optimization, paradigm bridge, security hardening, spec housekeeping, or legacy bug repair). 7. Realm sandboxing: calibrated probability that the proposal establishes defensive boundaries or isolates prototypes. 8. TypeScript impact: calibrated probability that the proposal requires modifications to TypeScript's compiler or checker. 9. Memory model: calibrated probability that the proposal alters buffers, allocation, or low-level runtime storage. Running 4 concurrent worker streams over the entire archive: - Total Proposals: 324 - Total Wall-Clock Time: 12.7 seconds - Throughput: ~25.5 proposals / second - Total Judgments Evaluated: 2,916 typed vectors (9 per proposal) - Failures / Retries: 0 A few patterns stand out in the aggregated data: Security and sandboxing proposals hit a wall. Nineteen proposals focused on prototype freezing, defensive sandboxing, or realm isolation (`ShadowRealm`, `SES`, freezing prototypes). Zero of them have reached Stage 4. Locking down dynamic prototypes in JavaScript almost always collides with assumptions in older web code. Ergonomics accounts for most of the committee's work. 143 proposals (44.1% of the archive) focus on reducing boilerplate and enabling chaining, including the pipeline operator, pattern matching, and optional chaining. Proposals that port established ideas from languages like Rust, Python, or C# (such as `BigInt` or `Temporal`) reached Stage 4 at more than double the rate of novel ideas. Their mathematical edge cases and operational rules were already established elsewhere. I built a small interface to browse and filter the full dataset: - Live explorer: [h3manth.com/fun/tc39-atlas/](https://h3manth.com/fun/tc39-atlas/) - Repository: [github.com/hemanth/tc39-atlas](https://github.com/hemanth/tc39-atlas) --- --- title: "Zero-Server Multiplayer: Porting Code Jeopardy to Cloudflare Durable Objects" description: "WebSockets and serverless used to be oxymorons. How I moved a real-time multiplayer trivia game from a fragile PM2 VPS to." url: "https://h3manth.com/scribe/serverless-multiplayer-code-jeopardy/" canonical_url: "https://h3manth.com/scribe/serverless-multiplayer-code-jeopardy/" markdown_url: "https://h3manth.com/scribe/blog/serverless-multiplayer-code-jeopardy.md" publishDate: "2026-09-01T10:00:00.000Z" author: "Hemanth HM" category: "web" tags: ["serverless","cloudflare","durable-objects","websockets","sqlite","fullstack","game-dev"] word_count: 1056 reading_time_minutes: 6 x_markdown_tokens: 2043 content_signal: "ai-train=yes, search=yes, ai-input=yes" --- # Zero-Server Multiplayer: Porting Code Jeopardy to Cloudflare Durable Objects > WebSockets and serverless used to be oxymorons. How I moved a real-time multiplayer trivia game from a fragile PM2 VPS to. At 3:40 AM on a Sunday, my phone buzzed. A cron job had failed to ping the WebSocket endpoint on [jeopardygithub.com](https://jeopardygithub.com). The app is straightforward: you punch in any GitHub repository, it parses the codebase, generates a 6-category Jeopardy board with difficulty-scaled trivia, and lets you and your teammates join a multiplayer room with real-time buzzers. The original deployment was classic developer duct tape: an Express server and the `ws` package running under PM2 on a single VPS. It worked, until it didn't: - If PM2 crashed or restarted, every active game room evaporated. - Memory slowly leaked across long-lived WebSocket connections. - Scaling meant introducing Redis Pub/Sub, sticky load-balancer sessions, and paying for idle CPU when nobody was playing. WebSockets and serverless used to be fundamentally incompatible. Serverless functions are stateless and ephemeral; WebSockets demand persistent memory and real-time state synchronization. Last week, I deleted the VPS, threw away PM2, and ported the entire stack to **100% serverless Cloudflare Workers and Durable Objects**. Here is how the architecture works and what I learned along the way. --- ## The Architecture ![Code Jeopardy Serverless Architecture](../../assets/blog/serverless-multiplayer-code-jeopardy.png) The system splits into three clear boundaries: ``` [ Browsers & Phones ] ──HTTP/WS──> [ Cloudflare Edge Worker ] │ ┌─────────────────┴─────────────────┐ ▼ ▼ [ AI Board Synthesizer ] [ GameRoom Durable Object ] • GitHub REST API (Tree/Code) • In-memory WebSocket Hub • OpenRouter / gpt-4o-mini • Atomic Buzzer Mutex • Multi-tier Edge Cache • Embedded SQLite WAL ``` 1. **Cloudflare Worker Gateway**: Terminates HTTP and WebSockets at the edge, routes static assets via the `[assets]` binding, and dispatches requests to room-specific Durable Objects. 2. **AI Board Synthesizer**: Fetches the target repository's file tree, filters the signal from the noise, and prompts `gpt-4o-mini` to construct a 6x5 trivia matrix. 3. **GameRoom Durable Object**: Exactly one single-threaded coordinator per 6-character room code (`ABCDEF`), backed by embedded SQLite with zero race conditions on buzzer presses. --- ## Problem 1: The Buzzer Race Condition In Jeopardy, whoever buzzes first gets the floor. In a traditional distributed architecture, two players buzzing within 15 milliseconds of each other requires: - Distributed locks in Redis (`SETNX`), or - Database conditional updates with optimistic concurrency (`UPDATE room WHERE buzzed_player IS NULL`), or - A single beefy node server that becomes a single point of failure. Cloudflare's **Durable Objects** use an actor-based concurrency model. Each Durable Object is single-threaded and globally unique for its ID: ```javascript // worker/src/index.js case 'buzz-in': { // If someone already buzzed, drop immediately if (!this.currentQuestion || this.currentQuestion.buzzedPlayerId) return; // If this player already failed this question, lock them out if (this.buzzerQueue.includes(player.id)) return; // Atomic state change — no Redis lock, no SQL transaction needed this.currentQuestion.buzzedPlayerId = player.id; this.broadcast('buzz-result', { playerId: player.id, playerName: player.name }); break; } ``` Because execution within the Durable Object instance is strictly sequential, the first incoming WebSocket message wins. No mutex libraries. No lock contention. Zero race conditions by design. --- ## Problem 2: Routing WebSockets to the Right Room When a contestant visits `jeopardygithub.com` or joins room `9F2A1B`, the client opens a WebSocket connection to: ``` wss://jeopardygithub.com/ws?gameId=9F2A1B ``` The edge Worker takes the 6-character room code, derives a deterministic Durable Object ID, and hands off the connection: ```javascript export default { async fetch(request, env, ctx) { const url = new URL(request.url); if (url.pathname === '/ws') { const gameId = (url.searchParams.get('gameId') || 'DEFAULT').toUpperCase(); // Derive globally unique 64-character DO ID from room name const doId = env.GAME_ROOM.idFromName(gameId); const stub = env.GAME_ROOM.get(doId); // Forward the WebSocket upgrade directly to the actor return stub.fetch(request); } // Static assets & REST API fallback... } }; ``` Cloudflare routes that connection directly to whichever data center the `GameRoom` actor is currently running in. If players are in Frankfurt, the DO spawns in Frankfurt. --- ## Problem 3: Mining Trivia from Any Codebase A good Jeopardy board needs trivia that ranges from easy ($100) to obscure ($500). Dumping an entire 50,000-line repository into an LLM context is wasteful and hits token ceilings. Instead, the Worker scores and selects the top five most informative source files before generating the board: ```javascript // Prioritize entry points and core logic, ignore tests and vendor blobs const scored = blobs.map(f => { let score = 0; const name = f.path.toLowerCase(); if (name.match(/^(index|main|app|server|mod)\./)) score += 10; if (name.includes('src/')) score += 5; if (name.includes('lib/')) score += 4; if (name.includes('test') || name.includes('spec')) score -= 5; if (f.size && f.size < 5000) score += 2; return { ...f, score }; }).sort((a, b) => b.score - a.score); ``` We pull the repo metadata, languages breakdown, README, and the top 5 scored files concurrently with `Promise.all()`. `gpt-4o-mini` is given a strict schema requiring 6 categories with 5 difficulty-scaled clues each. If the AI proxy hiccups or hits a rate limit, the worker gracefully falls back to an offline AST/regex parser so the game never fails to start. --- ## Zero-Cost Hibernation Here is the best part: **idle cost is zero**. When all players disconnect, the WebSocket connections close. Cloudflare's runtime automatically hibernates the Durable Object and writes state to embedded SQLite. When no one is playing, zero CPU cycles are consumed. When a developer shares a link on Twitter or Slack, the room boots up in under 50 milliseconds. --- ## Proving It in CI with Playwright To make sure the WebSocket handshake, buzzer locks, and scoring hold up under real network latency, I wrote automated end-to-end tests with Playwright: ```javascript // scripts/test-live-gameplay.js test('concurrent buzzer resolution', async ({ browser }) => { const host = await browser.newPage(); const p1 = await browser.newPage(); const p2 = await browser.newPage(); // Both players buzz within 10ms of each other await Promise.all([ p1.click('#buzz-button'), p2.click('#buzz-button') ]); // Exactly one player must receive the buzzer lock const activeBuzzer = await host.locator('.buzzer-active-name').textContent(); expect(['Player 1', 'Player 2']).toContain(activeBuzzer); }); ``` --- ## What I Learned 1. **Actors belong at the edge**: Stateful coordination doesn't belong in monolithic servers when actors can live in isolated, auto-scaling edge runtimes. 2. **SQLite inside Durable Objects is a game changer**: Having local, zero-network-overhead SQL storage directly inside an in-memory WebSocket actor eliminates the need for separate Redis or Postgres instances. 3. **No more 3 AM alerts**: Since moving `jeopardygithub.com` to Cloudflare Workers and Durable Objects on September 1st, server maintenance has dropped to literally zero. You can try a game on any public repo right now at [jeopardygithub.com](https://jeopardygithub.com). --- --- title: "The Laughter Saturation Curve" description: "Team quality is a function of shared laughs. It follows Michaelis-Menten kinetics — rapid gains early, diminishing returns." url: "https://h3manth.com/scribe/laughter-saturation-curve/" canonical_url: "https://h3manth.com/scribe/laughter-saturation-curve/" markdown_url: "https://h3manth.com/scribe/blog/laughter-saturation-curve.md" publishDate: "2026-08-27T06:00:00.000Z" author: "Hemanth HM" category: "engineering" tags: ["culture","teams","math","saturation","michaelis-menten"] word_count: 606 reading_time_minutes: 4 x_markdown_tokens: 939 content_signal: "ai-train=yes, search=yes, ai-input=yes" --- # The Laughter Saturation Curve > Team quality is a function of shared laughs. It follows Michaelis-Menten kinetics — rapid gains early, diminishing returns. Best teams I've worked on laughed a lot. Not polite chuckles in standups — actual laughs. The kind where someone unmutes just to wheeze. I noticed a pattern: the laughs compound fast early on. A new team that cracks jokes in week one builds trust faster than one that stays formal for a month. But after a point, more laughs don't make the team better. You plateau. The trust is already there. That's a saturation curve. ## The model Borrowed from enzyme kinetics (Michaelis-Menten), applied to teams: ``` Q(L) = Q_base + ΔQ_max * (L / (K + L)) ``` Four terms: - `Q_base` — Baseline technical skill of the team. What you ship with zero rapport. - `ΔQ_max` — Maximum boost from positive team chemistry. The ceiling above baseline. - `L` — Number of genuine laughs (shared moments of levity). - `K` — Half-saturation constant. The number of laughs needed to hit 50% of the max culture boost. When `L = K`, you're at half the potential boost. When `L >> K`, the boost asymptotes to `ΔQ_max`. ## Why saturation, not linear If laughter scaled linearly with quality, stand-up comedians would ship the best code. They don't. ``` Linear: Q = Q_base + c * L (unbounded — nonsensical) Saturation: Q = Q_base + ΔQ_max * L/(K+L) (bounded — matches reality) ``` The saturation model captures two things: 1. **Early laughs matter most.** Going from 0 to K laughs gets you halfway. Going from K to 2K only gets you another 17%. 2. **There's a ceiling.** No amount of laughter substitutes for skill. `Q_base` is doing the heavy lifting. `ΔQ_max` is the multiplier, not the foundation. ## Plugging in numbers Say a team has baseline skill of 70 (out of 100), max chemistry boost of 20, and `K = 10`: ``` L=0 → Q = 70 + 20*(0/10) = 70.0 L=5 → Q = 70 + 20*(5/15) = 76.7 L=10 → Q = 70 + 20*(10/20) = 80.0 ← half the boost L=20 → Q = 70 + 20*(20/30) = 83.3 L=50 → Q = 70 + 20*(50/60) = 86.7 L=100 → Q = 70 + 20*(100/110)= 88.2 ← diminishing hard ``` The first 10 laughs buy you 10 points. The next 90 buy you 8. That's the shape of trust. ## The K problem `K` is the interesting knob. Low `K` means the team bonds fast — a few good laughs and you're there. High `K` means the team takes longer to gel. Remote teams have higher `K`. You need more shared moments to build the same trust because you're missing ambient laughter — the overheard joke, the hallway bit. Slack threads don't carry tone well. Video calls compress social bandwidth. Co-located teams have lower `K`. Laughter is contagious in physical space. One person laughing triggers others. The same number of funny moments generates more `L` through amplification. ## What this doesn't model - Forced fun. Mandatory team-building events increase `L` on paper but not the kind that builds trust. The model assumes genuine laughs. - Toxic humor. Laughing at someone isn't the same as laughing with them. Negative `ΔQ_max` is a thing. - Personality variation. Some people bond over quiet intensity, not laughter. `K → ∞` for them, and the boost comes from a different variable entirely. ## The takeaway You can't engineer laughter. But you can stop killing it. Skip the "let's keep this professional" defaults. Let the weird joke land. Let the tangent happen. The first few laughs do more work than the next hundred. `Quality(team) ∝ number(laughs)` — but only up to a point. After that, ship the code. 😂 --- --- title: "Building ಲಿಪಿ: Three-Tier Speech Recognition in the Browser" description: "On-device first, cloud fallback, Whisper polish. A Kannada voice editor that works everywhere, built with zero frameworks." url: "https://h3manth.com/scribe/lipi-architecture/" canonical_url: "https://h3manth.com/scribe/lipi-architecture/" markdown_url: "https://h3manth.com/scribe/blog/lipi-architecture.md" publishDate: "2026-07-13T06:00:00.000Z" author: "Hemanth HM" category: "ai" tags: ["ai","speech","whisper","kannada","web-speech-api","transformers-js","on-device"] word_count: 687 reading_time_minutes: 4 x_markdown_tokens: 1304 content_signal: "ai-train=yes, search=yes, ai-input=yes" --- # Building ಲಿಪಿ: Three-Tier Speech Recognition in the Browser > On-device first, cloud fallback, Whisper polish. A Kannada voice editor that works everywhere, built with zero frameworks. I wanted to type in Kannada without switching keyboards. Speaking felt more natural than typing, but every speech-to-text tool either required a server, needed an app install, or didn't support Kannada well. So I built [ಲಿಪಿ (Lipi)](https://h3manth.com/ai/lipi/), a voice editor that runs entirely in the browser. No backend. No framework. Five files. ## The problem with one engine Web Speech API streams text in real time. Words appear as you speak. But it's cloud-dependent and not available on Firefox. Whisper (via Transformers.js) runs locally. Accurate, private, offline. But it can't stream. You record first, transcribe after. Neither alone is enough. So I used both. ## Three tiers ``` User clicks record ├── Tier 1: On-device Speech API (processLocally) │ └── Chrome 130+ with language pack installed ├── Tier 2: Cloud Speech API (webkitSpeechRecognition) │ └── Chrome/Edge, cloud-based, real-time streaming └── Tier 3: Whisper ONNX chunks (Transformers.js worker) └── Firefox, Safari, or if Speech API fails ``` The app detects what's available and picks the best tier automatically. ## Tier 1: On-device speech Chrome recently added `processLocally` to the Web Speech API. Here's how Lipi uses it: ```javascript if ('processLocally' in recognition) { const availability = await SpeechRecognition.available({ langs: ['kn-IN'], processLocally: true }); if (availability === 'available') { recognition.processLocally = true; } else if (availability === 'downloadable') { await SpeechRecognition.install({ langs: ['kn-IN'], processLocally: true }); recognition.processLocally = true; } } ``` Real-time streaming like cloud, but no data leaves the device. Best of both worlds. ## Tier 2: Cloud Speech API The familiar `webkitSpeechRecognition`. Lipi configures it for Kannada with interim results: ```javascript recognition = new webkitSpeechRecognition(); recognition.lang = 'kn-IN'; recognition.continuous = true; recognition.interimResults = true; ``` Interim text appears as a dimmed span that gets replaced when the final result arrives. It feels like the words are streaming out of your mouth onto the screen. ## Tier 3: Whisper fallback For browsers without Speech API, the app falls back to Whisper running in a Web Worker via Transformers.js: ```javascript // Record raw PCM at 16kHz scriptProc.onaudioprocess = (e) => { pcmChunks.push(new Float32Array(e.inputBuffer.getChannelData(0))); }; // Every 5 seconds, flush to Whisper chunkTimer = setInterval(() => flushChunk(false), 5000); ``` Not as smooth as streaming, but it works everywhere. The model downloads once and caches in the browser's Cache API. ## The Polish button Here's where it gets interesting. While the Web Speech API streams text live, the app silently records raw PCM audio in parallel. After you stop, a "Polish" button appears. Click it, and Whisper re-transcribes your audio from the raw recording. The result replaces only the recorded text. Typed text before and after is untouched. ``` "typed text" [start-mark] {speech text → replaced by Whisper} [end-mark] "more typed text" ``` Whisper gets a Kannada initial prompt to condition its decoder: ```javascript opts.initial_prompt = 'ಕನ್ನಡ ಭಾಷೆಯಲ್ಲಿ ಸ್ಪಷ್ಟವಾಗಿ ಬರೆಯಿರಿ. ಸರಿಯಾದ ವಿರಾಮ ಚಿಹ್ನೆಗಳನ್ನು ಬಳಸಿ.'; ``` This biases the decoder toward clean Kannada script with proper punctuation. ## Phonetic typing Don't want to talk? Type `namaskara` and it becomes ನಮಸ್ಕಾರ. The transliteration engine intercepts keystrokes, buffers Latin characters, and converts on space. On mobile, virtual keyboards don't fire `keydown` reliably. Lipi uses `beforeinput` as a fallback: ```javascript ed.addEventListener('beforeinput', e => { if (e.inputType === 'insertText' && /^[a-zA-Z]$/.test(e.data)) { e.preventDefault(); buf += e.data; showBuf(); } }); ``` Desktop uses `keydown` (fires first, blocks `beforeinput`). Mobile falls through to `beforeinput`. Both work. ## The stack Five files. No build step. No node_modules. ``` index.html # landing + editor (single page, hash routing) index.css # design system with oklch colors app.js # speech, recording, transliteration, UI worker.js # Whisper inference in a Web Worker transliterate.js # phonetic-to-Kannada mapping ``` The Whisper model preloads in the background via `requestIdleCallback` when the editor opens. By the time you need it, it's ready. ## Trade-offs - **Web Speech API accuracy** varies by accent. The Polish button exists precisely for this. - **Whisper Small** is ~240MB. It caches after first download, but that first load takes time. - **On-device Speech API** is Chrome 130+ only. The fallback chain handles everything else. That's it. No server. No API keys. Just the browser doing what browsers should do. [Try it](https://h3manth.com/ai/lipi/) --- --- title: "Building Kill-Switches for Autonomous AI Agents" description: "When a parent agent spawns four subagents, token consumption multiplies. The Antigravity SDK gives you telemetry and hooks." url: "https://h3manth.com/scribe/zero-overhead-token-budgets/" canonical_url: "https://h3manth.com/scribe/zero-overhead-token-budgets/" markdown_url: "https://h3manth.com/scribe/blog/zero-overhead-token-budgets.md" publishDate: "2026-06-12T10:00:00.000Z" author: "Hemanth HM" category: "ai" tags: ["ai","agents","antigravity","sdk","subagents","governance"] word_count: 950 reading_time_minutes: 5 x_markdown_tokens: 2243 content_signal: "ai-train=yes, search=yes, ai-input=yes" --- # Building Kill-Switches for Autonomous AI Agents > When a parent agent spawns four subagents, token consumption multiplies. The Antigravity SDK gives you telemetry and hooks. I spent a week inside the Antigravity SDK for the GDE AI Sprint. The topic was Dynamic Subagents — how agents spawn child agents to parallelize work. The SDK gives you `define_subagent`, `invoke_subagent`, workspace isolation (`branch`, `share`, `inherit`), and a message-passing protocol. Solid primitives. But one thing was missing: **budget enforcement**. A parent agent spawning four children doesn't cost 30K tokens. It costs 150K+. Each child gets its own context window, its own reasoning trace, its own token bill. And children can spawn children. A three-level tree is 13 concurrent agents, each burning tokens independently. ``` Parent (orchestrator) 30K ├── Research agent 40K ├── Frontend agent 80K ├── Backend agent 60K └── Test agent 50K ───── 260K tokens — one feature request ``` Without per-child budgets, one rogue subagent — a research agent re-reading the same 50 files — drains the session before the others finish. So I built it. ## What the SDK gives you Every model response carries `usage_metadata`: ```python response = await agent.chat("Refactor the auth module.") meta = response.usage_metadata meta.prompt_token_count # input tokens meta.candidates_token_count # output tokens meta.thinking_token_count # reasoning tokens (the hidden cost) meta.total_token_count # sum ``` `thinking_token_count` is the one that matters. In extended reasoning models, this is 3-5x the visible output. A turn that produces 1,200 tokens of code might burn 8,000 tokens of reasoning. Multiply that across a subagent tree. The SDK also has lifecycle hooks: ```python from google.antigravity.hooks import hooks class MyHook(hooks.AfterModelHook): # Inspect: runs after model call async def run(self, context, data): ... class MyGate(hooks.BeforeModelHook): # Decide: runs before, can block async def run(self, context, data): return hooks.HookResult(allow=False, reason="nope") ``` **Inspect** hooks are read-only. **Decide** hooks can block. That's the entire surface area you need for budget enforcement. State lives in `context.session.state` — a dict scoped to the agent session. Each subagent gets its own session. Parent can't see children's state. That's the isolation that makes per-agent budgets possible. ## The kill-switch Two hooks. An accumulator and a gate: ```python class TokenAccumulator(hooks.AfterModelHook): """Count tokens after each model call.""" async def run(self, context, data): usage = data.usage_metadata state = context.session.state state["total_tokens"] = state.get("total_tokens", 0) + usage.total_token_count state["turns"] = state.get("turns", 0) + 1 class BudgetGate(hooks.BeforeModelHook): """Block if budget exceeded.""" def __init__(self, max_tokens: int): self.max_tokens = max_tokens async def run(self, context, data): total = context.session.state.get("total_tokens", 0) if total >= self.max_tokens: return hooks.HookResult( allow=False, reason=f"Budget exceeded: {total:,} / {self.max_tokens:,} tokens" ) return hooks.HookResult(allow=True) ``` Wire them into a subagent config: ```python from google.antigravity import LocalAgentConfig config = LocalAgentConfig( hooks=[TokenAccumulator(), BudgetGate(500_000)] ) ``` That's it. Two hooks. If the agent hits 500K mid-task, `BudgetGate` returns `allow=False` and the session stops. ## Adding circuit breakers Budget ceilings catch runaway spending. But you also want to catch degenerate behavior early — before the ceiling hits. **Velocity spikes:** ```python class VelocityMonitor(hooks.AfterModelHook): async def run(self, context, data): state = context.session.state history = state.setdefault("turn_history", []) history.append(data.usage_metadata.total_token_count) if len(history) >= 5: recent_avg = sum(history[-5:]) / 5 baseline_avg = sum(history[:-5]) / max(len(history) - 5, 1) if recent_avg > baseline_avg * 2.5: state["velocity_warning"] = True ``` If a subagent was averaging 15K/turn and jumps to 45K, it's probably re-reading the codebase in a loop. **Degenerate loops:** ```python class LoopDetector(hooks.PostToolCallHook): async def run(self, context, data): state = context.session.state log = state.setdefault("tool_log", []) log.append(f"{data.tool_call.name}:{data.tool_call.args}") if len(log) >= 3 and len(set(log[-3:])) == 1: state["loop_detected"] = True ``` Same tool, same args, three times in a row. The agent is stuck. **Reasoning runaway:** ```python class ReasoningGuard(hooks.AfterModelHook): async def run(self, context, data): meta = data.usage_metadata if meta.total_token_count == 0: return ratio = meta.thinking_token_count / meta.total_token_count state = context.session.state streak = state.get("reasoning_streak", 0) if ratio > 0.8: state["reasoning_streak"] = streak + 1 if streak + 1 >= 3: state["reasoning_runaway"] = True else: state["reasoning_streak"] = 0 ``` An agent spending 40K thinking to produce 500 output is going in circles. ## Composing it One Decide hook reads all the signals: ```python class KillSwitch(hooks.BeforeModelHook): def __init__(self, max_tokens: int): self.max_tokens = max_tokens async def run(self, context, data): state = context.session.state total = state.get("total_tokens", 0) if total >= self.max_tokens: return hooks.HookResult(allow=False, reason=f"Token budget: {total:,}/{self.max_tokens:,}") if state.get("loop_detected"): return hooks.HookResult(allow=False, reason="Degenerate tool loop") if state.get("reasoning_runaway"): return hooks.HookResult(allow=False, reason="Reasoning runaway") return hooks.HookResult(allow=True) ``` Wire everything per subagent: ```python def governed_agent(role, max_tokens): return LocalAgentConfig( system_prompt=f"You are a {role} agent.", hooks=[ TokenAccumulator(), VelocityMonitor(), LoopDetector(), ReasoningGuard(), KillSwitch(max_tokens), ] ) # Each child gets its own budget research_config = governed_agent("research", 50_000) frontend_config = governed_agent("frontend", 100_000) backend_config = governed_agent("backend", 80_000) ``` Five hooks per agent. Inspect hooks accumulate, Decide hook blocks. The SDK handles graceful shutdown. ## Extracting it The patterns aren't SDK-specific. Token counting, budget ceilings, velocity detection, loop detection — these work with any LLM provider. So I extracted them into [token-limiter](https://github.com/hemanth/token-limiter) — zero dependencies, works with OpenAI, Gemini, Claude, Ollama, anything: ```python from token_limiter import token_limiter, from_openai budget = token_limiter(max_tokens=500_000, max_cost=5.00) budget.record(from_openai(response)) if not budget.ok: print(budget.reason) ``` ```js import { tokenLimiter, fromGemini } from 'token-limiter'; const budget = tokenLimiter({ maxTokens: 500_000, maxCost: 5.00 }); budget.record(fromGemini(response)); if (!budget.ok) console.log(budget.reason); ``` Available on [npm](https://www.npmjs.com/package/token-limiter) and [PyPI](https://pypi.org/project/token-limiter/). Filed a [feature request](https://github.com/google-antigravity/antigravity-sdk-python/issues/59) on the Antigravity SDK proposing built-in budget hooks following the existing `deny()` / `allow()` pattern. Happy to do a PR if they open contributions. ## What I learned The SDK's hook system is well-designed. `usage_metadata` + `AfterModelHook` + `BeforeModelHook` + `SessionContext.state` gives you everything you need to build governance. The fact that each subagent gets its own session state is the key — it means per-agent budgets work without any plumbing. What's missing is the policy layer. `deny()` controls what an agent can do. Budget hooks would control how much. Together they're the governance stack that makes autonomous subagent trees safe for production. The agents that make it to production won't be the most capable. They'll be the most governable. 🔐 --- --- title: "More Vetoes, Less Vision" description: "Software coherence gets worse when more people have veto power. Here’s why enterprise apps feel like a disjointed mess in JS." url: "https://h3manth.com/scribe/more-vetoes-less-vision/" canonical_url: "https://h3manth.com/scribe/more-vetoes-less-vision/" markdown_url: "https://h3manth.com/scribe/blog/more-vetoes-less-vision.md" publishDate: "2026-04-12T10:00:00.000Z" author: "Hemanth HM" category: "engineering" tags: ["engineering","architecture","teams","philosophy","conways-law"] word_count: 2102 reading_time_minutes: 11 x_markdown_tokens: 3632 content_signal: "ai-train=yes, search=yes, ai-input=yes" --- # More Vetoes, Less Vision > Software coherence gets worse when more people have veto power. Here’s why enterprise apps feel like a disjointed mess in JS. I've spent a lot of my career jumping between two very different worlds: free and open source software and enterprise software. You might expect enterprise software to be more coherent, since they have the massive budgets and the processes for it. But open source projects usually produce a more unified system, even if they look like uncontrolled chaos on paper. In the enterprise, you often open an app and literally feel the boundary where one team's work ends and another's begins. You see the seams. The navigation isn't structured around what the user actually needs to do; it's structured around the company's org chart. Everything feels like a bolt-on. Contrast that with a tool built by a small, opinionated open source team. It just makes sense. You don't have to fight it. What actually causes that gap? What separates SQLite from a disjointed enterprise app? What's the real difference here? Conway's Law gets cited constantly. "Organizations design systems that mirror their own communication structures." Brooks's Law covers the timeline angle. "Adding manpower to a late software project makes it later." Both useful. But neither explains *incoherence*. Conway tells you the shape of the system. Brooks tells you it'll be late. Neither tells you why the product feels like three apps duct-taped together. I think the missing variable is simpler than either of those. ## The law > **Software coherence is inversely proportional to the number of people who can say no.** Not team size. Not org structure. Not how many microservices you have or what your sprint velocity looks like. Just this: how many people hold veto power over any given decision? I'm calling it Hemanth's Law because nobody else named it yet. ## The evidence I looked at startups, FOSS, and enterprise software and tracked one thing: how many people have to agree before a decision turns into code. ### SQLite: a small team, zero outside contributors SQLite is maintained by [a small team of developers spread across three continents](https://www.sqlite.org/crew.html), led by D. Richard Hipp. They don't accept patches or pull requests from the public. Every line is written by the core team. What does that produce? ~156,000 lines of C with [100% branch test coverage](https://www.sqlite.org/testing.html). Over 92 million lines of test code. It runs on every phone, every browser, every OS you touched today. Airbus uses it in [flight software](https://www.sqlite.org/testing.html). It follows DO-178B aviation testing standards. One person holds the entire system in his head. Decisions move from thought to code in the same brain. The internal consistency is almost unsettling. Decision-makers per feature: 1. Maybe 2 on a bad day. ### Linux kernel: thousands of contributors, one funnel The kernel has seen contributions from [over 20,000 developers](https://www.linuxfoundation.org/blog/blog/a-summary-of-contributions-to-the-linux-kernel). But writing code and deciding what ships are very different things. Every patch goes through a [subsystem maintainer](https://www.kernel.org/doc/html/latest/process/submitting-patches.html), then a lieutenant, then (for anything that matters) Linus Torvalds. The [MAINTAINERS file](https://github.com/torvalds/linux/blob/master/MAINTAINERS) maps every file in the kernel to the person who says yes or no. Thousands contribute. A handful decide. Linus has rejected patches from billion-dollar companies because they didn't pass his taste bar. Decision-makers per subsystem: 1 to 3. For the kernel's overall direction: 1. ### Windows Vista: what happens when nobody owns the picture Longhorn (which became Vista) started around 2001. By 2004 the codebase was so broken that Jim Allchin, co-president of Windows development, [called it "a pig"](https://jsnover.com/blog/2025/01/20/Longhorn/) internally. Microsoft threw out the entire codebase and [restarted from Windows Server 2003 SP1](https://en.wikipedia.org/wiki/Development_of_Windows_Vista). What happened? The Windows team and the .NET team were [fighting over managed code vs. native](https://jsnover.com/blog/2025/01/20/Longhorn/). Multiple groups built disconnected features (WinFS, Indigo, Avalon) with no integration plan. Nobody owned the whole picture. They eventually reorganized into two divisions, Core OS and Windows Client. Didn't matter. Vista shipped in 2007, four years late, and the reviews were brutal. The product felt exactly like what it was: a negotiated compromise between teams that disagreed with each other. Decision-makers per feature: dozens. Architecture review, security review, feature team, platform team, management chain. Every group could block. The product showed it. ### Spotify squads: autonomy without anyone in charge of "the whole thing" Spotify's squad model (2012) gave small teams full ownership. Each squad was supposed to be a "mini-startup." In theory this should work. Small teams, clear ownership, right? [In practice](https://www.jeremiahlee.com/posts/failed-squad-goals/) the squads turned into silos. Each picked their own tech and UI patterns, making the product feel horribly inconsistent. "Autonomy without consequence" meant squads optimized for themselves, and nobody minded the store for the overall experience. Each squad had decision-making power. Nobody had *integration* power. Nobody could step in and say "these five features need to feel like the same product." Decision-makers per feature: 1 per squad (fine). Decision-makers for the product as a whole: 0 (not fine). ### AWS: giving up coherence for speed Amazon's famous "two-pizza team" mandate removed the integration authority veto entirely. By forcing teams to build decoupled services with their own APIs, they got rid of the "unified product vision" bottleneck. They got speed, but the cost was coherence. The AWS Management Console is notoriously disjointed. EC2 looks and behaves differently than S3, which is completely different from IAM. When you drop the centralized veto, you gain speed but lose the "one mind" user experience entirely. ## The pattern | | Veto holders per feature | Product feel | Examples | |---|---|---|---| | 1-3 | Focused, opinionated | Coherent | SQLite, Rails, early Notion, Sublime Text | | 4-8 | Managed, intentional | Solid, less distinctive | Linux kernel, PostgreSQL, well-run startups | | 9+ | Committee-driven | Fragmented, bloated, disjointed | Vista, enterprise platforms, "three apps taped together" | There's real data behind this. The [HBS mirroring hypothesis study](https://www.hbs.edu/ris/Publication%20Files/08-039_1861e507-1dc1-4602-85b8-90d71559d85b.pdf) (MacCormack, Baldwin, Rusnak, 2012) compared open-source and commercial software using Design Structure Matrix analysis. Open-source projects with fewer centralized decision-makers produced more modular code. Commercial products with committee-driven decisions had propagation costs **8x higher**, meaning a change in one place broke 8x more things elsewhere. Those commercial products weren't badly written. They were badly *decided*. Too many cooks making different broths and pouring them into the same pot. ### When multiple teams solve the same problem In high-veto environments, you also tend to get redundant solutions. What happens when two different internal teams try to solve the exact same problem? If you have a strong integration authority, someone decides early. One approach wins. The other is killed. But in a consensus-driven environment, neither team has the authority to kill the other's project. Canceling a team's work is a political fight that no one wants. To keep the peace, the organization just ships both. Look at Google. They didn't just ship one messaging app; over a decade, internal team boundaries gave us Talk, Hangouts, Allo, Duo, Meet, and Chat, all competing for the same users. We're seeing it happen again right now in their AI ecosystem: a developer looking to build with Gemini has to navigate overlapping capabilities across Google AI Studio, Vertex AI, and Firebase Genkit. Even if someone at the very top had the formal authority, nobody was willing to spend the political capital to step in and say, "this is our only path." They are externalizing their internal organizational stalemates onto the user. Consensus doesn't just produce averages. Sometimes it produces duplicates. ## How this differs from Conway's Law Conway says the product mirrors the org chart. That's about *shape*. Four teams, four components. This is about *coherence*. You can have four teams and a coherent product if one person has final say on how the pieces fit. Linus runs a massive org, but the kernel feels like one system because the decision funnel narrows to one person. Conway tells you what the architecture will look like. This tells you whether it'll feel like one product or a committee report. ## How this differs from Brooks's Law Brooks is about *time*. Adding people makes things late. This is about *coherence*, which is a separate axis. You can ship on time and still ship an incoherent mess. Vista eventually shipped. It just shipped something that felt like two organizations built it without talking. Which is more or less what happened. ## Delivery time There's a corollary here: > **Delivery speed is determined by decision latency, the gap between "we should do X" and someone writing code.** At a five-person startup, you decide at lunch and ship after lunch. At a large org, you might need architecture review, security sign-off, accessibility review, legal, and three management layers. The coding takes a day. Getting permission takes a month. ## Where this breaks I should be honest about the weak spots here. Single decision-makers do become bottlenecks. The same funnel that gives you coherence also caps your velocity to what one person can hold in their head. As a product scales, one person can't hold all that context anymore. Big tech companies design their org charts purely to solve this throughput problem, and they sacrifice coherence to do it. Also, coherence isn't quality. One person with a consistent vision can still be totally wrong. If the person in charge lacks the technical "taste" for the domain, you just end up with a coherently bad product. Sometimes, big companies use bureaucracy precisely to dilute the damage an incompetent leader can do. And sure, some committees do produce good work. The Apollo Guidance Computer came out of a large bureaucracy and landed on the moon. But even there, Margaret Hamilton's team was only about [100 people](https://www.nasa.gov/history/alsj/a11/a11Hamilton.html), and she had clear authority. The decision funnel was tight. ## The awkward truth This means what most orgs do to "improve quality" (adding more reviewers and approval gates) actually degrades the product. Every new person in the decision chain just sands down one more edge. You end up with software that offends nobody and delights nobody. I constantly see this. You open an enterprise app and wonder if the team who built this screen has ever even met the team that built the next one. The joke is, they probably have. They meet every week with twelve other people, and nothing gets decided. ## What I'd do about it Keep the number of veto holders as small as possible. Not contributors. Vetoes. Let many people write code. Let very few people block decisions. If you can't eliminate veto holders, constrain their boundaries tightly. Security gets a veto on vulnerabilities, not user flows. As soon as a domain expert is allowed to veto outside their lane, you slide back into committee-driven design. Start measuring decision latency, not just cycle time. How long do features sit waiting for a green light versus actually being built? Establish clear integration authority. The funnel has to be narrow enough to share one context. But if you just give the seat to the person with the most seniority, you get architecture astronauts. If you give it to someone who doesn't code, you get impossible roadmaps. The integration authority needs to be someone who still understands the codebase and actually uses the product. It's a curation role. You need someone with the soft power to tell a team their solution simply doesn't fit. It creates a single point of failure, sure, but it's way easier to fix one person's bad call than it is to untangle a mess built by twenty committees. Know when to resist the pull toward consensus. Consensus matters for standards bodies like TC39 or Node.js. But even they avoid averaging things out by completely separating creation from approval. A single "champion" shapes a feature, while the committee just audits it. Committees can't design. When you're building a fast-moving product, even audit-level consensus is too slow. You need an integration authority who can look at a room full of squabbling teams and say, "I know we disagree, but we're doing it this way because the product needs to feel like *this*." ## One more time > **Hemanth's Law: Software coherence is inversely proportional to the number of people who can say no.** Conway gave us the shape. Brooks gave us the timeline. This is about coherence. The best software I've used was built by a small number of people with strong opinions and the authority to ship them. The worst was built by organizations where everyone had a voice and nobody had a decision. More vetoes, less vision. --- *References: Conway (1968) "How Do Committees Invent?"; Brooks (1975) The Mythical Man-Month; MacCormack, Baldwin, Rusnak (2012) "Exploring the Duality between Product and Organizational Architectures" [HBS](https://www.hbs.edu/ris/Publication%20Files/08-039_1861e507-1dc1-4602-85b8-90d71559d85b.pdf); [SQLite Testing](https://www.sqlite.org/testing.html); [Linux Kernel Patch Process](https://www.kernel.org/doc/html/latest/process/submitting-patches.html); Snover (2025) ["The Longhorn Story"](https://jsnover.com/blog/2025/01/20/Longhorn/); Lee ["Spotify's Failed Squad Goals"](https://www.jeremiahlee.com/posts/failed-squad-goals/); [Node.js Technical Steering Committee](https://github.com/nodejs/TSC).* --- --- title: "Building a Visual Product Agent with Gemma 4" description: "A multi-turn visual agent that looks at product images, calls tools, reasons through decisions, and writes full analysis." url: "https://h3manth.com/scribe/gemma4-multi-turn-visual-agent/" canonical_url: "https://h3manth.com/scribe/gemma4-multi-turn-visual-agent/" markdown_url: "https://h3manth.com/scribe/blog/gemma4-multi-turn-visual-agent.md" publishDate: "2026-04-06T10:00:00.000Z" author: "Hemanth HM" category: "ai" tags: ["ai","gemma","agents","vision","function-calling","python"] word_count: 1343 reading_time_minutes: 7 x_markdown_tokens: 2720 content_signal: "ai-train=yes, search=yes, ai-input=yes" --- # Building a Visual Product Agent with Gemma 4 > A multi-turn visual agent that looks at product images, calls tools, reasons through decisions, and writes full analysis. I've been poking at Gemma 4's multi-modal capabilities and wanted to see how far I could push a single model into doing real agentic work — vision, tool use, multi-turn reasoning, all at once. Turns out, pretty far. The idea is simple: show the model a product image, let it figure out what it's looking at, then have it call tools to gather pricing, reviews, and specs. No hardcoded product names. No separate classification step. Just: here's a photo, tell me everything. Here's the agent in action: ## The architecture The agent runs an explicit loop with a maximum of 5 turns: 1. User sends image(s) + a question 2. Model looks at the image, thinks (literally — thinking mode is on), and decides what tools to call 3. Tools execute, results feed back into the conversation 4. Model either calls more tools or writes a final report 5. Repeat until done or max turns hit ``` Turn 1: [Image] → model identifies product → calls search_product() Turn 2: model gets search results → calls get_price(), get_reviews(), get_specs() Turn 3: model has all data → writes structured analysis report ``` The key thing: the model batches independent tool calls into a single turn. It doesn't call `get_price`, wait, then call `get_reviews`, wait, then call `get_specs`. It fires all three at once. That's Gemma 4 figuring out the dependency graph on its own. ## Setting up tools Four tools, each doing one thing: ```python def search_product(query: str) -> dict: """Searches for a product by name or description. Args: query: Search terms to find the product. """ # Match against a product database # Returns: product_name, brand, category, match_confidence ... def get_price(product_name: str) -> dict: """Looks up the current price across multiple retailers.""" ... def get_reviews(product_name: str) -> dict: """Gets review ratings and summary for a product.""" ... def get_specs(product_name: str) -> dict: """Gets detailed technical specifications.""" ... ``` The docstrings matter here. Gemma 4's processor auto-extracts function schemas from type hints and Google-style docstrings. No separate JSON schema definition needed — just write normal Python functions with proper annotations and the model knows what to call and how. Registry is a plain dict: ```python TOOL_REGISTRY = { "search_product": search_product, "get_price": get_price, "get_reviews": get_reviews, "get_specs": get_specs, } TOOLS = list(TOOL_REGISTRY.values()) ``` ## Parsing tool calls Gemma 4 uses a specific token format for tool calls. Parsing them out: ```python def extract_tool_calls(text: str) -> list[dict]: """Parse Gemma 4 tool-call tokens into structured dicts.""" return [ { "name": name, "arguments": { k: cast((v1 or v2).strip()) for k, v1, v2 in re.findall( r'(\w+):(?:<\|"\|>(.*?)<\|"\|>|([^,}]*))', args ) }, } for name, args in re.findall( r"<\|tool_call\>call:(\w+)\{(.*?)\}", text, re.DOTALL, ) ] ``` Regex doing heavy lifting, as usual. The `cast` helper converts string values to ints, floats, or bools where appropriate. ## The generation step (the tricky part) This is where I hit a wall and had to work around it. The naive approach — `apply_chat_template(tokenize=True)` — crashes on multi-turn conversations that contain assistant tool calls and tool-role messages. The processor tries to iterate through their content looking for images and chokes. The fix is a two-step approach: ```python def generate(messages, images=None, max_new_tokens=2048): # Step 1: Build text prompt (handles tool schemas, thinking, etc.) text_prompt = processor.apply_chat_template( messages, tools=TOOLS, tokenize=False, # <-- text only, don't tokenize yet add_generation_prompt=True, enable_thinking=True, ) # Step 2: Encode text + images together inputs = processor( text=text_prompt, images=images if images else None, return_tensors="pt", ).to(model.device) with torch.no_grad(): outputs = model.generate( **inputs, max_new_tokens=max_new_tokens, temperature=1.0, top_p=0.95, top_k=64, do_sample=True, ) return processor.decode(outputs[0][input_len:], skip_special_tokens=False) ``` `tokenize=False` first to get the text prompt, then feed text + images into the processor separately. Not obvious, but it works reliably across all turns. ## The agent loop The main loop orchestrates everything: ```python def run_agent(image_sources, user_query, max_turns=5, verbose=True): pil_images = [load_image(src) for src in image_sources] # Build initial message with image(s) + text user_content = [{"type": "image", "image": img} for img in pil_images] user_content.append({"type": "text", "text": user_query}) messages = [ {"role": "system", "content": [{"type": "text", "text": SYSTEM_PROMPT}]}, {"role": "user", "content": user_content}, ] for turn_num in range(1, max_turns + 1): raw_output = generate(messages, images=pil_images) parsed = processor.parse_response(raw_output) raw_tool_calls = extract_tool_calls(raw_output) if raw_tool_calls: results = execute_tool_calls(raw_tool_calls) # Append assistant tool calls + tool results to conversation messages.append({ "role": "assistant", "tool_calls": [ {"type": "function", "function": c} for c in raw_tool_calls ], }) for call, result in zip(raw_tool_calls, results): messages.append({ "role": "tool", "name": call["name"], "content": json.dumps(result["response"]), }) continue # No tool calls = final answer return { "final_answer": parsed.get("content", ""), "turns": turns, "total_turns": turn_num, } ``` The pattern is clean: generate → check for tool calls → if yes, execute and loop → if no, return the answer. The conversation history accumulates naturally, so each turn has full context of everything that happened before. ## The system prompt This is where you shape the agent's behavior: ```python SYSTEM_PROMPT = """You are a Product Analyst Agent. When given product images, you: 1. FIRST: Look at the image carefully, identify the product, and call search_product. 2. THEN: Call get_price, get_reviews, and get_specs together in a single turn. 3. FINALLY: Produce a structured analysis report in markdown. Be efficient: batch independent tool calls into one turn. Do NOT make up prices or specs -- always use the tools.""" ``` That last line is doing real work. Without it, the model occasionally skips tool calls and hallucinates specs from training data. With it, I haven't seen a single hallucinated spec. ## What happens in practice Show it a photo of Sony WH-1000XM4 headphones: ``` Turn 1: Thinking... "I can see these are over-ear headphones, they look like Sony..." → search_product(query='Sony noise canceling over-ear headphones black') Turn 2: Got search results (Sony WH-1000XM4, 0.95 confidence) → get_price(product_name='Sony WH-1000XM4') → get_reviews(product_name='Sony WH-1000XM4') → get_specs(product_name='Sony WH-1000XM4') Turn 3: Final report with price comparison table, review summary, specs breakdown ``` Three turns. The model identified the product from the image alone, batched the data-gathering calls, and wrote a structured report. The thinking traces are genuinely useful — you can see it reasoning about what it sees in the image before making decisions. ## Multi-image comparison The same agent handles comparisons without any code changes. Show it two headphones and ask "which is the better value?": ```python result = run_agent( image_sources=["images/sony_xm4.jpg", "images/beats_solo3.jpg"], user_query=( "Compare these two products. For each one: identify it, " "look up pricing, reviews, and specs. Then give me a " "side-by-side comparison and tell me which is the better value." ), max_turns=5, ) ``` It identifies both products, calls tools for each (batching where possible), and generates a comparison table. The thinking traces show it actually weighing trade-offs — battery life vs. noise cancellation, price per feature. ## Hardware reality check This runs on Gemma 4 31B-IT in bfloat16. That's ~65GB VRAM. A100 80GB, H100, or the new RTX PRO 6000 Blackwell work. I tried 4-bit quantization early on and the vision encoder fell apart — images looked like solid gray to the model. bf16 or nothing for this one. ## What I learned **Thinking mode changes everything for agents.** Without it, the model jumps to tool calls without reasoning about what it sees. With it, you get actual deliberation — "I can see the Sony logo," "these look like noise-canceling headphones based on the ear cup size." The quality of tool call arguments goes way up. **Docstrings are your schema.** Gemma 4's processor extracts function schemas from Python's type hints and docstrings directly. Write good docstrings and you never need to maintain a separate tool definition format. **The `tokenize=False` workaround is essential** for multi-turn tool-using agents. The processor's `apply_chat_template` with `tokenize=True` crashes when the conversation history contains assistant tool calls and tool role messages. Separate text generation from tokenization. **Batching tool calls is emergent.** I didn't explicitly program the model to batch independent calls. The system prompt says "batch independent tool calls into one turn" and it does. Three calls in a single generation step, correctly identifying that price/reviews/specs don't depend on each other. The full notebook is on GitHub: [Gemma4_31B_Multi_Turn_Visual_Agent.ipynb](https://github.com/hemanth/notebooks/blob/main/notebooks/Gemma4_31B_Multi_Turn_Visual_Agent.ipynb) --- --- title: "The Trust Fall With AI" description: "Trust in AI isn’t binary - it’s a spectrum. Like a theater trust fall, it takes practice, guardrails, and the willingness." url: "https://h3manth.com/scribe/trust-fall-with-ai/" canonical_url: "https://h3manth.com/scribe/trust-fall-with-ai/" markdown_url: "https://h3manth.com/scribe/blog/trust-fall-with-ai.md" publishDate: "2026-04-04T10:00:00.000Z" author: "Hemanth HM" category: "ai" tags: ["ai","trust","agents","philosophy","mcp"] word_count: 1872 reading_time_minutes: 10 x_markdown_tokens: 3080 content_signal: "ai-train=yes, search=yes, ai-input=yes" --- # The Trust Fall With AI > Trust in AI isn’t binary - it’s a spectrum. Like a theater trust fall, it takes practice, guardrails, and the willingness. When I was in theater, the first exercise they made us do wasn't memorizing lines or hitting marks. It was the trust fall. Stand on a riser, cross your arms, close your eyes, and fall backwards into the arms of people you barely knew. A few people hated it. They'd open their eyes mid-fall, uncross their arms to catch themselves, tense up the whole way down. Me? I was more like, *let me just let go and see what happens.* Not bravery, just curiosity. What does it feel like to actually commit? Turns out it feels like nothing. You fall, hands catch you, and your brain quietly updates its model of the world: *okay, that worked.* That exercise has been stuck in my head lately, because it's exactly where we are with AI coding agents right now. Some people are tensing up. Others are letting go. Most are somewhere in between, mid-fall, eyes half-open, peeking over their shoulders. ## The trust spectrum Most conversations about AI trust are binary: you either trust it or you don't. That framing is wrong. Trust is a spectrum, and with AI, it looks something like this: | Level | What it looks like | Example | |-------|-------------------|---------| | 0 - Skeptic | Won't use it at all | "I don't trust AI with my code" | | 1 - Verifier | Uses it, checks everything | Copy-paste from ChatGPT, then manual review | | 2 - Collaborator | Works alongside it | AI writes tests, you write implementation | | 3 - Delegator | Hands off defined tasks | Agent handles PR reviews autonomously | | 4 - Orchestrator | Manages fleets of agents | Multi-agent workflows running in production | Most developers I talk to are somewhere between Level 1 and Level 2. They'll use Copilot for autocomplete but won't let an agent push to production. That's a perfectly rational position, for now. ## Why trust falls work The trust fall exercise works because of three things: 1. **Bounded risk** - You're falling 3 feet, not 30 2. **Incremental exposure** - First fall is short, each one gets bigger 3. **Observable catch** - You can feel the hands before you commit fully Sound familiar? That's exactly how good AI integration should work. ### Bounded risk = sandboxed execution When you let an AI agent run code, you don't give it root access to production. You sandbox it: ```python # Bad trust fall - no guardrails agent.execute(user_code, permissions="all") # Good trust fall - bounded risk agent.execute(user_code, sandbox={ "network": False, "filesystem": "read-only", "timeout_seconds": 30 }) ``` The sandbox is the spotter. It limits how far you can fall. Real tools are already doing this well. Claude Code ships OS-level sandboxing (Seatbelt on macOS, bubblewrap on Linux) that enforces filesystem and network isolation at the kernel level. Even if the model is compromised through prompt injection, the OS sandbox holds. Anthropic's docs are explicit: "design workflows assuming the agent might be compromised and ensure external controls hold even if the agent's logic is bypassed." The principle is universal though. Any agent framework worth using should enforce boundaries at a level the agent itself can't override. ### Incremental exposure = progressive autonomy Start small. Let the AI suggest. Then let it draft. Then let it execute with approval. Then let it execute autonomously for low-risk tasks. ``` Week 1: AI suggests code completions → you accept/reject Week 2: AI writes unit tests → you review Week 4: AI opens PRs with tests → you approve Week 8: AI merges passing PRs on non-critical repos → you monitor ``` Each week is a slightly taller trust fall. You build confidence through repetition, not through a single leap of faith. Claude Code has a concrete version of this: permission modes that dial autonomy up gradually. `plan` mode is read-only. `default` asks before every edit and command. `acceptEdits` auto-approves file changes but still asks for bash. `auto` mode runs an AI classifier that pre-screens tool calls, only escalating risky operations to you. If the classifier blocks three actions in a row or twenty in a session, it pauses and reverts to manual. That's not unique to Claude Code. The pattern shows up everywhere: GitHub Copilot's suggestion-then-accept flow, Cursor's diff-review mode, Devin's plan-then-execute model. The best tools make the trust ramp explicit rather than forcing you to choose between "full access" and "read-only." ### Observable catch = traceability You can't trust what you can't observe. Every AI action should leave a trace: ```javascript // Every agent decision should be auditable agent.on("action", (event) => { log({ tool: event.tool_name, input: event.params, output: event.result, reasoning: event.chain_of_thought, timestamp: Date.now() }); }); ``` If you can replay the reasoning, you can trust the outcome. Or at least know why to distrust it. Tools like Claude Code take this further with declarative permission rules checked into version control. Your `settings.json` defines what's allowed, denied, and what requires approval, and the whole team shares the same trust boundaries: ```json { "permissions": { "allow": ["Read", "Edit", "Bash(npm test)"], "deny": ["Bash(rm -rf *)", "Bash(sudo *)"], "ask": ["Bash(git push *)", "Bash(docker *)"] } } ``` The hierarchy (Deny > Ask > Allow) means destructive actions are blocked even if someone accidentally adds a broad allow rule. That's defense in depth applied to trust. ## The three failure modes of AI trust Trust doesn't fail in one way. It fails in three: **1. Over-trust (the blind fall)** You close your eyes, fall backwards, and nobody's there. In AI terms: you ship agent-generated code to production without review, and it introduces a subtle bug that costs you a weekend. Or worse, you run an agent with `--dangerously-skip-permissions` on a repo with production credentials. The flag name includes "dangerously" for a reason. **2. Under-trust (refusing to fall)** You never close your eyes. You review every line, every suggestion, every completion. You spend more time reviewing AI output than you would have spent writing it yourself. The tool becomes overhead. This is the approval fatigue problem that newer features like auto-approve classifiers are specifically designed to solve. **3. Mis-calibrated trust (falling the wrong direction)** You trust the AI for things it's bad at (complex architectural decisions) and distrust it for things it's great at (boilerplate generation, test writing, code formatting). You're falling sideways. The fix? Calibrate continuously. Keep a mental scorecard. Where does the AI nail it? Where does it fumble? Adjust your trust boundaries accordingly. ## Agents, skills, and the trust architecture The trust question gets real when agents start doing things on their own. Not "suggest a code completion," that's Level 1 trust. I mean agents that spin up, pick the right tool, run a multi-step workflow, and deliver a result while you're making coffee. This is where the trust fall metaphor stretches. In theater, you fall once. With autonomous agents, you're falling continuously, every task is a micro-trust-fall. And the surface area is enormous: - **Skills** give agents domain expertise. A security audit skill, a database migration skill, a deployment skill. Each one is a new capability you're trusting the agent to wield correctly. - **Tool access** (MCP, function calling, whatever the protocol) defines what an agent *can* do. Read files? Execute commands? Hit external APIs? Each permission is a trust boundary. - **Orchestration** decides what happens when agents coordinate. One agent reviews, another deploys, a third monitors. The trust isn't just in each agent, it's in the handoffs between them. ``` Skill: "deploy-to-staging" ├── read source code ✓ (low risk) ├── run test suite ✓ (bounded risk) ├── build container ✓ (sandboxed) ├── push to staging ⚠️ (needs approval) └── push to production ✗ (hard no) ``` The interesting pattern emerging is **trust-per-skill, not trust-per-agent.** I might trust an agent completely with test generation but not at all with infrastructure changes. Same agent, different trust levels, depending on what it's doing. ### Autonomous agents on critical tasks Here's where it gets uncomfortable. The industry is sprinting toward agents that handle critical operations: incident response, database migrations, security patching, production deployments. Tasks where a mistake doesn't cost you an afternoon, it costs you customers. The trust fall for critical tasks needs different spotters: ```python # Non-critical: agent runs freely agent.run("generate-changelog", approval=False) # Critical: defense in depth agent.run("apply-db-migration", approval=True, dry_run_first=True, rollback_plan=True, human_checkpoint_after=["schema-change", "data-migration"], alert_on_anomaly=True ) ``` The pattern isn't "never let agents touch critical systems." It's "make the trust fall shorter for higher stakes." A 2-foot fall onto a padded mat. Dry runs before real runs. Checkpoints before irreversible steps. Automatic rollback if something smells wrong. MCP got one piece of this right: tools are explicit, permissions are scoped, the model doesn't get access to everything, it gets access to what you connect. But Palo Alto Networks' research on MCP security highlights the risks in the plumbing itself: server impersonation, overprivileged credentials in local config files, insufficient isolation between MCP servers. The trust boundary isn't just the agent. It's the entire tool chain. ## The catch is earning the fall Here's what most people miss: in a trust fall, the catcher has to earn the faller's trust. That means consistency. Reliability. Predictable behavior. AI systems earn trust the same way: - **Consistency** - Same input should produce roughly the same quality output - **Transparency** - Show your reasoning, don't just show your answer - **Graceful failure** - When you're wrong, be obviously wrong, not subtly wrong - **Bounded confidence** - Say "I'm not sure" instead of hallucinating an answer We're building systems that need to earn trust at scale. That's a harder problem than making them smarter. ## Where I am on the spectrum Depends on context. Professionally, I'm around Level 2.5, solidly collaborative, edging into delegation for well-scoped tasks. AI writes tests, drafts docs, reviews PRs, handles formatting. But anything that touches production or security still gets human eyes. Personally? I'm at Level 4. My side projects are playgrounds for multi-agent workflows. Agents that chain skills together, orchestrate deployments, run experiments end-to-end. I let them fail fast so I can learn what the guardrails need to look like before the professional side catches up. That split is intentional. Personal experiments build the intuition. Professional caution protects the things that matter. The gap between the two closes a little every month. ## The paradox of trust Here's the weird part: the more you use AI agents, the better you get at knowing when not to trust them. Using them daily builds intuition for their failure modes. You start to feel when a response is off. You develop a sixth sense for hallucination. People who never use AI have the least calibrated trust. They either fear it completely or expect magic. The practitioners, the ones doing trust falls every day, are the ones with the most nuanced view. Trust isn't given. It's practiced. Every time you let an AI agent handle a task and verify the result, you're doing a trust fall. Some days you land perfectly. Some days you hit the floor. But you get up, adjust the height, and fall again. The question isn't whether to trust AI. It's how to build a practice of trust, with sandboxes, with traceability, with incremental exposure. Close your eyes. Cross your arms. Fall. Then check the logs. --- --- title: "Why you still ask a friend before buying" description: "AI agents can crawl every review, match your budget, your size, your purchase history. You still text your friend. That’s." url: "https://h3manth.com/scribe/why-you-still-ask-a-friend/" canonical_url: "https://h3manth.com/scribe/why-you-still-ask-a-friend/" markdown_url: "https://h3manth.com/scribe/blog/why-you-still-ask-a-friend.md" publishDate: "2026-03-26T10:00:00.000Z" author: "Hemanth HM" category: "ai" tags: ["ai","commerce","agents","psychology"] word_count: 1281 reading_time_minutes: 7 x_markdown_tokens: 2043 content_signal: "ai-train=yes, search=yes, ai-input=yes" --- # Why you still ask a friend before buying > AI agents can crawl every review, match your budget, your size, your purchase history. You still text your friend. That’s. I was building an agent workflow for [AgentU](https://github.com/hemanth/agentu) that pulls product data, compares specs, checks prices across vendors, and returns a ranked recommendation. It worked. The output was genuinely better than anything I'd have found on my own. I still texted my friend: "Hey, you got the Sony XM5s right? How are they?" Not because the agent was wrong. Because something in my head wouldn't let me just... act on it. I needed to hear it from a person. A specific person. Someone who'd actually used the thing. That bugged me enough to dig into why. ## We evolved to evaluate people, not products For roughly 300,000 years, the only way to know if a berry was safe or a trail was passable was to ask someone you already trusted. Not the person with the most data. The person with shared skin in the game. Sperber and Mercier call this epistemic vigilance (*Mind & Language*, 2010). Before we process what someone is saying, we process who is saying it and why. It's not a conscious step. It's closer to a reflex. When your friend says "the battery life is actually garbage despite what the specs say," your brain is doing a few things at once. You know this person. They have no reason to lie. They use headphones the way you do, on flights, not at a desk. And they spent their own money, so their opinion has weight behind it. An agent triggers none of that. I keep coming back to this. It doesn't matter how accurate the recommendation is. The trust circuitry just doesn't fire. ## Reviews are weird You might think: "I trust Amazon reviews from strangers, those aren't friends." True. But pay attention to which reviews you actually stop and read. BrightLocal's 2025 consumer survey found 75% of consumers regularly read reviews, and 74% check at least two sites. But the reviews that actually change someone's mind contain specific experiential details. "The zipper broke after three months" hits different from "great product, five stars." We're scanning for lived experience, not aggregate sentiment. We also weight negative reviews way more heavily. Baumeister et al. showed this in their 2001 paper "Bad Is Stronger Than Good" (*Review of General Psychology*, now at 10,000+ citations). Negative events produce larger, more lasting effects. Makes sense from an evolutionary standpoint. Ignoring "that river has crocodiles" meant death. Ignoring "nice sunset over there" meant nothing. One detailed one-star review overriding fifty five-star reviews isn't rational. But it kept our ancestors alive. And here's the part I find genuinely interesting: even within reviews, we're reconstructing the person behind them. "As a nurse on my feet 12 hours a day..." That's not a product review. That's a trust signal. You're checking whether this person's life looks like yours. ## The "is this person like me" shortcut That check has a name: homophily. McPherson, Smith-Lovin, and Cook laid it out in their 2001 *Annual Review of Sociology* paper "Birds of a Feather." Similarity breeds connection. Connection breeds trust. The strongest divides are race and ethnicity, then age, then shared context like occupation and lifestyle. Your friend who commutes the same route, has roughly the same budget, cares about the same things you do, their experience is a better predictor of your experience than any population-level aggregate. Your brain knows this even if you can't quite say why. An AI trained on millions of reviews optimizes for the average. Your friend is a sample size of one. But a perfectly matched one. ## It goes deeper than thinking Paul Zak's lab at Claremont has been poking at this for over a decade. When you have a conversation with someone you trust, even over text, your brain releases oxytocin. That doesn't just make you feel warm. It literally changes how you evaluate information. Zak's experiments with economic trust games showed oxytocin levels rise when people perceive trust signals, and those levels correlate directly with more cooperative behavior. So you're not just getting a recommendation from your friend. You're receiving it while in a neurochemical state that makes you more open to it. That's kind of unfair, honestly. No product page can compete with that. Nielsen's 2021 Trust in Advertising study (40,000 respondents, multiple regions) put a number on it: 89% of people most trust recommendations from people they know. More than review sites, ads, or any AI system. ## The agentic commerce gap nobody talks about Here's where it gets relevant if you're building things. Google's Universal Commerce Protocol shipped January 2026. Shopify, Walmart, Target, Etsy, Wayfair co-developed it. Mastercard and Visa endorsed it. Agents now have a standardized way to discover products, manage carts, and checkout across merchants. McKinsey projects agentic commerce at $3-5 trillion in global retail by 2030. AI agents influenced around $70 billion in GMV during Black Friday 2025. 44% of American consumers say they're comfortable with a bot shopping for them. The infrastructure is real. Agents can buy things. And some of them are genuinely good at it — they'll pull your purchase history, remember your size, know you prefer navy over black, stick to brands you've bought before. That's not trivial. But even the best of them are still treating buying as a matching problem. Find the best match across more dimensions. Present it. Done. That's not how people actually buy things. People buy after they've been convinced, and conviction comes from trusted sources, not optimal ones. Trust isn't a feature you ship. It's a biological response that's been running for hundreds of thousands of years. ## Three gaps Your friend paid for that product with their own money. The agent didn't. It has zero stake in whether you're happy with the recommendation. Until agents can signal genuine cost, reputation loss, accountability, anything, they'll feel like a search engine with opinions. An agent can know your preference history. It can't know what it feels like to wear those shoes on a rainy commute. Experiential knowledge lives in the body, not the training data. We evolved to weight embodied experience over abstract information, and I don't see that changing. When your friend recommends something bad, they hear about it next time you grab coffee. That feedback loop keeps recommendations honest. Agents face zero social cost for being wrong. No reputation on the line, no awkward conversation. ## Where this might actually go I don't think the answer is "make agents more human." That's the uncanny valley of commerce. People can smell synthetic trust, and honestly they should. The more interesting direction is agents that connect you to the right humans. Instead of making the recommendation, the agent finds the person in your network who already owns the product and surfaces their experience. "Your colleague Priya bought these running shoes six months ago and has logged 50miles in them. Want me to ask her what she thinks?" That's an agent working with the trust circuit instead of trying to replace it. Or agents that surface the right reviews, not the most helpful or most recent, but ones from people whose usage patterns match yours. Homophily as a retrieval strategy. The agent doesn't need to be trusted. It needs to be a conduit to trust. ## So AI can process more product data in a second than you'll evaluate in a lifetime. It can match preferences with mathematical precision. It can predict what you want before you know you want it. You'll still ask your friend. That's not a bug in human cognition. That's the feature that kept us alive long enough to build the AI. If you're building agents that transact, build them to broker trust, not bypass it. The biology isn't going anywhere. --- --- title: "Model Capability Discovery: The API We're All Missing" description: "No provider exposes model capabilities via API. So every framework builds its own registry. One field in /v1/models would." url: "https://h3manth.com/scribe/model-capability-discovery/" canonical_url: "https://h3manth.com/scribe/model-capability-discovery/" markdown_url: "https://h3manth.com/scribe/blog/model-capability-discovery.md" publishDate: "2026-03-25T10:00:00.000Z" author: "Hemanth HM" category: "ai" tags: ["ai","llm","api","standards","openai","mcp"] word_count: 904 reading_time_minutes: 5 x_markdown_tokens: 1675 content_signal: "ai-train=yes, search=yes, ai-input=yes" --- # Model Capability Discovery: The API We're All Missing > No provider exposes model capabilities via API. So every framework builds its own registry. One field in /v1/models would. **TL;DR:** No LLM provider tells you what a model can do via API. So frameworks build their own registries. LiteLLM maintains a 2600+ entry `model_cost_map`, LangChain pulls from a third-party database (`models.dev`), and smaller projects just hardcode lists. None of this comes from the provider. A single `capabilities` field on `/v1/models` would fix this at the source. ## The problem I was building [AgentU](https://github.com/hemanth/agentu) and hit this: before sending an image to a model, I need to know if it supports vision. Before using `response_format: { type: "json_object" }`, I need to know it supports structured output. Before calling tools, I need to know it supports function calling. How do you find out? You don't. Not from the API anyway. You check the docs. Or you hardcode a list. Or you try and catch the error. That's the state of things in 2025. ## What LiteLLM had to build LiteLLM supports 140+ providers and 2600+ models. To know what each model can do, they maintain a community-updated `model_cost_map`, a JSON registry mapping model names to capabilities, pricing, and limits: ```python # These work because LiteLLM maintains a client-side registry, not because providers expose it litellm.supports_vision(model="gpt-4o") # True litellm.supports_vision(model="gpt-4-turbo") # True litellm.supports_vision(model="claude-3-opus") # True litellm.supports_function_calling(model="gpt-4o") # True ``` Every time a provider ships a new model or adds a capability to an existing one, someone has to open a PR to update this list. LangChain took a different approach with "Model Profiles" backed by `models.dev`, but the data still lives client-side. It's pulled from a third-party database, not from the providers themselves. Either way, the provider knows the answer and won't tell you programmatically. ## What the API response looks like today Hit OpenAI's `/v1/models` endpoint right now: ```json { "id": "gpt-4o", "object": "model", "created": 1715367049, "owned_by": "system" } ``` That's it. An ID, a timestamp, and an owner. No capabilities. No context window. Nothing you actually need to decide how to use the model. ## What it should look like ```json { "id": "gpt-4o", "object": "model", "created": 1715367049, "owned_by": "system", "capabilities": { "text": true, "vision": true, "audio": true, "function_calling": true, "structured_output": true, "streaming": true, "parallel_tool_calls": true, "json_mode": true }, "context_window": 128000, "max_output_tokens": 16384 } ``` Five extra fields. Fully backward-compatible. Every client that doesn't check `capabilities` keeps working. Every client that does gets to drop their hardcoded registries. ## Why this matters for agents Agents make model selection decisions at runtime. An orchestrator might choose `gpt-4o-mini` for a text task and `gpt-4o` for an image task. Right now, that routing logic is based entirely on hardcoded assumptions: ```python # This is how every framework does it today VISION_MODELS = [ "gpt-5.4", "claude-opus-4.6", "gemini-3.1-pro", "llama-4-maverick", ] def select_model(task): if task.has_images: return next(m for m in available_models if m in VISION_MODELS) return default_model ``` With capability discovery, it becomes: ```python # How it should work def select_model(task): models = client.models.list() if task.has_images: return next(m for m in models if m.capabilities.get("vision")) return models[0] ``` No hardcoded list. No stale config. The model tells you what it can do. ## What about non-OpenAI providers? Anthropic, Google, Mistral: none of them expose this either. The `/v1/models` format just happens to be the one everyone copies. Ollama, Groq, Together, LM Studio, vLLM all implement `/v1/models` or something close to it. If OpenAI adds `capabilities`, the rest of the ecosystem follows within months. For providers with their own API formats, a `/.well-known/model-capabilities.json` could work. But that's the harder problem. Solve the easy one first. ## Why not ask the model itself? A natural counter-proposal: skip the API, just ask the model. "Do you support vision?" But this is a generation task, not introspection. The model will confidently say "yes" whether it can process images or not. That's not self-awareness — it's next-token prediction. Self-reporting is hallucination with extra steps. Three approaches could work, but they all require the **provider** to be the source of truth: **System-injected context.** The provider injects a read-only capability block into every conversation before your messages arrive. The model reads its own spec sheet rather than guessing. This is how models already know their knowledge cutoff date — capabilities are the logical next field. ``` [SYSTEM-INJECTED, READ-ONLY] model: gpt-4o capabilities: text, vision, audio, function_calling, structured_output context_window: 128000 ``` **Built-in capability tool.** Give models a `get_capabilities()` tool that returns provider ground truth. The model calls the tool, gets facts back. No generation, no hallucination. The response comes from the API layer, not the weights. **Response metadata.** Return capabilities as a sideband field in the response body, never touching the generation pipeline at all: ```json { "choices": [...], "model_capabilities": {"vision": true, "function_calling": true} } ``` All three reinforce the same point: the model can't tell you what it can do. The provider can. Put it in the API. ## The ask This isn't a complex spec proposal. It's one backward-compatible field on an endpoint that already exists. Providers know their model capabilities. They just don't expose them. Every framework in the ecosystem is working around this by building client-side registries that go stale. The fix is small. The impact is large. Ship `capabilities` on `/v1/models`. --- *P.S. - If you're maintaining one of these model registries, you know the pain. If you're a provider, you know the answer. Put it in the API.* *P.P.S. - I've filed a [proposal on the OpenAI OpenAPI spec](https://github.com/openai/openai-openapi/issues/537) to add a `capabilities` field to `/v1/models`. If this resonates, go give it a 👍.* --- --- title: "The 200ms window: why voice AI latency is a biology problem" description: "Human conversation runs on a 200ms biological clock. Here’s what that means if you’re building voice AI. Practical notes." url: "https://h3manth.com/scribe/voice-ai-response-times/" canonical_url: "https://h3manth.com/scribe/voice-ai-response-times/" markdown_url: "https://h3manth.com/scribe/blog/voice-ai-response-times.md" publishDate: "2026-02-25T12:00:00.000Z" author: "Hemanth HM" category: "ai" tags: ["ai"] word_count: 1252 reading_time_minutes: 7 x_markdown_tokens: 2037 content_signal: "ai-train=yes, search=yes, ai-input=yes" --- # The 200ms window: why voice AI latency is a biology problem > Human conversation runs on a 200ms biological clock. Here’s what that means if you’re building voice AI. Practical notes. Your brain expects a reply in about 200 milliseconds. That's not a design guideline somebody came up with. That's decades of psycholinguistic research across dozens of languages and cultures. Here's what I find wild about this: it takes roughly 600ms just to pull a word out of memory and say it. If humans actually waited for someone to finish before starting to think, every conversation would have full-second pauses. But we don't wait. We predict the end of the other person's turn and start forming our reply while they're still talking. 200ms later, we're already speaking. Voice AI has to fit into that same window. Not because it's a nice engineering target, but because the human on the other end will feel something is off if it doesn't. ## The perception spectrum - < 100ms: you're being cut off. Too fast. - 100-300ms: natural. This is how conversation actually works. - 300-500ms: acceptable. You notice the delay but you tolerate it. - 500ms-1s: sluggish. The rhythm breaks. - > 1s: broken. People start repeating themselves. ## The real bottleneck It's not the LLM. It's endpoint detection. Cut the mic too early and you interrupt the user mid-sentence. Wait too long and the response feels slow before the model even gets the input. Most systems settle on about 200-250ms of silence as the trigger. That 250ms feels like nothing, but it's already eaten a big chunk of your latency budget before inference even starts. ## Two architectures, two trade-offs ### Cascaded: STT to LLM to TTS The traditional pipeline. Audio becomes text, text goes to the LLM, LLM output becomes audio. Latency math: ``` Endpoint detection: ~200-250ms STT processing: ~200-300ms LLM first token: ~100-500ms TTS first byte: ~80-120ms ──────────────────────────────── Total: ~600ms - 1200ms ``` That's the good case. Real-world conditions add network hops and buffering. The upside is modularity. You can swap in a faster STT or a different voice without touching anything else. You get text logs for debugging. Complex reasoning works fine because the LLM operates on text, its native format. The downside: the audio-to-text conversion strips out everything except words. Tone, sarcasm, hesitation, emotion, all gone. The LLM responds to what you *said*, not how you said it. ### Speech-to-speech (S2S) One model. Audio in, audio out. No intermediate text. This is what GPT-4o Realtime and Gemini Live use. Response times typically land in the 200-400ms range. Right in the biological sweet spot. S2S models hear emotion. They handle interruptions natively. When you laugh, the model knows you laughed. When you trail off mid-sentence, it can tell the difference between "I'm thinking" and "I'm done." The cost: no text transcript to inspect, debugging is hard, compute is expensive, and training requires massive amounts of paired voice data. ## Where the industry is right now Alexa and Google Assistant target under 500ms with heavily optimized cascaded pipelines. GPT-4o Realtime and Gemini Live sit around 300ms with S2S. The gap is closing, but the architectural trade-off remains. Cascaded gives you control. S2S gives you speed. ## What makes it feel like a person Fast responses and clean transcription get you most of the way there. The rest is all the stuff humans do without thinking about it. Backchanneling. When someone is talking, the listener isn't silent. They go "mm-hmm", "right", "yeah", tiny signals that say "I'm here, keep going." Most voice AIs are completely silent while the user speaks. That silence feels like talking into a void. Systems that inject backchannels at natural pause points (after clause boundaries, typically) immediately feel more conversational. Prosody matching. Humans mirror each other's speech patterns. If you speak fast, I speed up. If you slow down, I slow down. If you whisper, I lower my voice. Most TTS systems output at a fixed pace and pitch regardless of how the user is speaking. S2S models are starting to get this right because they have access to the raw audio. Cascaded pipelines lose this entirely at the text boundary. Overlap and barge-in. Real conversations have overlap. People start talking before the other person finishes, not to interrupt, but because they've predicted the end of the turn. Good voice AI needs to handle this gracefully: detect when the user is barging in, stop generating immediately, and listen. The alternative is two people talking over each other, which is exactly what happens with most systems when you try to interrupt. Filler and hesitation. Humans say "um", "uh", "so", "well" not because they're broken, but because it signals "I'm thinking, hold on." A voice AI that starts every response instantly with a perfectly formed sentence actually feels less natural than one that occasionally hesitates. Some systems now inject synthetic filler at the start of complex responses to buy inference time while sounding human. Breathing and pacing. This one is subtle but real. Human speech has natural breath points. We pause between clauses, not just between sentences. TTS that streams one continuous block of audio sounds robotic even if the voice itself is high quality. Adding micro-pauses at commas and clause boundaries, and occasionally inserting breath sounds, makes a measurable difference in how natural the output feels. None of this shows up in latency benchmarks or WER scores. But it's the difference between "that was fast" and "that felt like a conversation." ## The numbers to guard Speed is only half the problem. If your STT layer garbles the transcription, the LLM is reasoning over garbage. Fast garbage is still garbage. Latency targets: 1. Time to first audio: < 500ms (target < 300ms) 2. Streaming jitter: < 50ms 3. Endpoint silence: ~200-250ms Accuracy (STT): Word Error Rate is the standard metric. It's computed from three types of errors: ``` WER = (S + D + I) / N S = Substitutions (wrong word) D = Deletions (missed word) I = Insertions (hallucinated word) N = Total words in reference ``` Production STT systems typically target a WER under 5%. But the number that matters depends on your use case. A medical voice agent with 3% WER but high substitution rate is dangerous: it's confidently saying the wrong drug name. A customer support bot with 5% WER but mostly deletions (dropped filler words) might be perfectly fine. Substitutions are the most dangerous. Deletions lose information. Insertions add noise. But substitutions silently corrupt meaning, and the LLM has no way to know the input was wrong. The human ear detects audio gaps as small as 5ms. Your streaming pipeline has essentially no margin for error. And your STT layer has even less. 200 milliseconds. That's not a product requirement somebody wrote on a whiteboard. It's how human brains have worked for as long as we've had language. Every architecture decision in voice AI, cascaded vs. S2S, endpoint detection thresholds, streaming chunk sizes, ultimately answers one question: can you fit inside that biological window? The systems that feel natural aren't just fast. They backchannel, they match your prosody, they handle interruptions without flinching. Speed gets you in the door. Everything else keeps the conversation going. I keep coming back to the S2S vs. cascaded question. S2S models are closing the latency gap while preserving the emotional signals that cascaded pipelines throw away. But they come with real costs: opacity, compute, and a debugging experience that's basically "listen and hope." If you're building voice AI today, measure two things: time to first audio byte, and whether people repeat themselves. The first tells you if you're fast enough. The second tells you if you're good enough. --- --- title: "WebMCP Bridge" description: "A browser-first tool that connects any remote MCP server to Chrome’s WebMCP API. Discover tools, execute them, and let in JS." url: "https://h3manth.com/scribe/webmcp-bridge/" canonical_url: "https://h3manth.com/scribe/webmcp-bridge/" markdown_url: "https://h3manth.com/scribe/blog/webmcp-bridge.md" publishDate: "2026-02-16T00:00:00.000Z" author: "Hemanth HM" category: "javascript" tags: ["javascript","mcp","webmcp","ai","chrome","agents","opensource"] word_count: 1110 reading_time_minutes: 6 x_markdown_tokens: 1953 content_signal: "ai-train=yes, search=yes, ai-input=yes" --- # WebMCP Bridge > A browser-first tool that connects any remote MCP server to Chrome’s WebMCP API. Discover tools, execute them, and let in JS. MCP servers are everywhere now. There are hundreds of them, and just as many clients connecting to them. Claude Code, VS Code, Cursor, terminal tools, custom apps. I built [mcphost.link](https://mcphost.link) as a web-based MCP client myself. Browsers as a native AI surface felt like the natural next step. That's exactly what the [WebMCP proposal](https://webmachinelearning.github.io/webmcp/) is about — it introduces `navigator.modelContext`, a way for web pages to expose tools to browser AI agents. Chrome 146+ already has it behind a flag. I wanted to see if existing MCP servers could plug into it without any changes on their end. So I built a bridge. ## What It Does **WebMCP Bridge** connects to a remote MCP server, discovers its tools, and re-registers them with Chrome's WebMCP API. ![WebMCP Bridge Architecture](../../assets/blog/webmcp-bridge-arch.png) ## Demo Let me walk you through the flow. You type in an MCP server URL, hit connect, and: 1. `initialize` handshake over JSON-RPC 2. Fetch `tools/list`, `prompts/list`, `resources/list` 3. Render everything in a browsable UI 4. Register each tool with `navigator.modelContext.provideContext()` 5. Proxy tool calls back to the remote server That's it. No SDK. No framework. Just a web page that becomes an MCP client. ## Here's Where It Gets Interesting ```javascript navigator.modelContext.provideContext({ tools: [{ name: "search_proposals", description: "Search TC39 proposals", inputSchema: { type: "object", properties: {...} }, execute: async (args) => { // enrich with page context before proxying const enriched = { ...args, user_locale: navigator.language }; const result = await fetch(mcpServerUrl, {...}); return { content: [{ type: "text", text: result }] }; } }] }); ``` See that `execute` function? It's a proxy, but it doesn't have to be a dumb one. The page has cookies, localStorage, session state, user preferences — first-party context that no external agent has access to. When the bridge proxies a tool call, it can enrich the request with what it knows about the user. A search query becomes a *personalized* search query. A checkout becomes a checkout with the saved address already attached. Same applies to responses. The page can filter, redact, or augment what comes back from the MCP server before surfacing it to the browser AI. The server returns raw data; the page decides what the agent actually sees. The browser isn't a passthrough. It's a context layer. ## Two Modes **Tools mode** is a test bench. Connect to a server, pick a tool, fill in parameters, hit execute. Good for debugging and exploring what an MCP server exposes. **Chat mode** uses the Prompt API (`window.LanguageModel`) for on-device inference. The local model figures out which tools to call based on your question, calls them through the bridge, and feeds the result back into the conversation. Trade-off: the on-device model needs to download first. Chat stays locked until it's ready. Download progress can be sparse — `0%` might persist even when it's actively downloading. Once ready, chat unlocks automatically. ## Auth MCP servers behind auth are handled: - **OAuth** — Discovers `/.well-known/oauth-authorization-server`, runs PKCE auth code flow, supports dynamic client registration - **Manual** — API key, basic auth, bearer token for quick testing - **Skip** — Public servers need nothing OAuth in the browser depends on the server's endpoints being CORS-friendly. If they're not, direct browser calls will fail. ## No Framework The whole thing is vanilla HTML, CSS, and JS. No React. No Vite. No build step. ``` index.html → app shell styles.css → styles app.js → init() js/core/ → shared state js/auth/ → auth client + UI js/mcp/ → parser, connection, execution, WebMCP js/ui/ → rendering js/chat/ → chat flow + tool intent js/utils/ → helpers ``` 27 JS files concatenated into a single `bundle.html` for deployment. That's the build system. ## Why the Browser Matters Why put a web page in the middle when the agent could call the MCP server directly? Because the page can do things a direct connection can't. **Context enrichment.** The page has cookies, localStorage, session state, user preferences. When the bridge proxies a tool call, it can inject first-party context the MCP server doesn't have. A search query becomes a *personalized* search query. A checkout comes with the saved address already attached. **Response transformation.** The page can filter, redact, or augment what comes back before the agent sees it. Strip sensitive fields. Merge with local data. Reformat for the current UI. The MCP server returns raw data; the page decides what the agent actually sees. **Multi-server composition.** Connect to 5 different MCP servers and present them as one unified tool surface. The agent doesn't know or care that "search" comes from server A and "checkout" from server B. The page is the aggregator. **Page-local tools.** The bridge can register tools that don't proxy to any MCP server at all — they just operate on the page. Read the DOM, fill a form, screenshot a section, access the clipboard. Mix remote MCP tools with local browser capabilities in one tool surface. **Consent gates.** Before proxying a sensitive tool call — `create_order`, `send_email` — the page can pop a confirmation dialog. The user approves or rejects. The agent can't bypass it because the `execute` function is under the page's control. **Rate limiting and caching.** The page can throttle tool calls, cache repeated results, batch requests. If the agent calls `search_products` 10 times with the same query, the page returns the cached result after the first call. The MCP server never sees the duplicates. **Progressive disclosure.** Register a small set of tools initially. Based on conversation state or user auth, dynamically register more. The agent starts with `search` and `browse`. Only after the user logs in does `checkout` appear. **Audit logging.** Every tool call flows through the page's JS. Log every request, response, timestamp to localStorage, IndexedDB, or a remote endpoint. Full observability of what the agent did and when. The browser isn't a passthrough. It's a context layer. ## Browser Requirements - Chrome 146+ with `chrome://flags/#enable-webmcp-testing` - Prompt API for chat mode: enable `chrome://flags/#optimization-guide-on-device-model` and `chrome://flags/#prompt-api-for-gemini-nano`, then trigger model download at `chrome://components` → "Optimization Guide On Device Model" - Without WebMCP, it still works as an MCP explorer - Remote servers must allow your origin via CORS Right now this is Chrome-only. Hoping to see more browsers adopt WebMCP — the web is better when these capabilities aren't locked to a single engine. ## Try It Live: [h3manth.com/ai/webmcp](https://h3manth.com/ai/webmcp/) Source: [github.com/hemanth/webmcp-bridge](https://github.com/hemanth/webmcp-bridge) Open DevTools when you connect — the console logs the full MCP protocol flow. Good way to learn how the pieces fit. Let me know if you end up building something with it. --- --- title: "ucpify: JSON → Commerce Server in Seconds" description: "Generate a fully UCP-compliant commerce server from a single JSON config. Stripe, PayPal, SQLite, admin dashboard, all wired." url: "https://h3manth.com/scribe/ucpify-json-to-commerce-server/" canonical_url: "https://h3manth.com/scribe/ucpify-json-to-commerce-server/" markdown_url: "https://h3manth.com/scribe/blog/ucpify-json-to-commerce-server.md" publishDate: "2026-02-13T00:00:00.000Z" author: "Hemanth HM" category: "javascript" tags: ["javascript","python","ucp","commerce","agentic","ai","opensource"] word_count: 812 reading_time_minutes: 5 x_markdown_tokens: 1664 content_signal: "ai-train=yes, search=yes, ai-input=yes" --- # ucpify: JSON → Commerce Server in Seconds > Generate a fully UCP-compliant commerce server from a single JSON config. Stripe, PayPal, SQLite, admin dashboard, all wired. Say you're a small business. You have a product catalog, maybe as a spreadsheet or a JSON file. You want to sell online. But building a commerce backend means dealing with payment APIs, database schemas, input validation, webhook handlers. That's a lot of engineering for "I just want to sell t-shirts." **ucpify** takes a single JSON file with your products, shipping options, and payment config and gives you a fully working commerce server. UCP-compliant, Stripe and PayPal ready, SQLite persistence, admin dashboard. Node.js and Python. ![ucpify architecture](../../assets/blog/ucpify-arch.png) ## What is UCP? The [Universal Commerce Protocol](https://ucp.dev) is an open standard for agentic commerce. It lets AI agents discover, browse, and complete purchases programmatically. Think of it as what OpenAPI did for REST, but for shopping flows. A UCP server exposes `/.well-known/ucp` for discovery, declares capabilities, and provides a structured checkout flow that any UCP-compatible agent can follow. ## One JSON. Full Commerce. Here's all you need: ![ucpify config](../../assets/blog/ucpify-config.png) ```json { "name": "My Store", "domain": "https://my-store.com", "currency": "USD", "tax_rate": 0.08, "items": [ { "id": "tshirt", "title": "Classic Tee", "price": 2500 }, { "id": "hoodie", "title": "Premium Hoodie", "price": 5999 } ], "shipping_options": [ { "id": "standard", "title": "Standard Shipping", "price": 500 }, { "id": "express", "title": "Express Shipping", "price": 1500 } ], "payment_handlers": [ { "namespace": "com.stripe", "id": "stripe_handler" }, { "namespace": "com.paypal", "id": "paypal_handler" } ] } ``` Products, shipping, tax, payment providers. All declarative. No code. ## What You Get Run `ucpify serve merchant-config.json` and you have a full server: ![ucpify endpoints](../../assets/blog/ucpify-endpoints.png) **9 REST endpoints** covering the entire checkout lifecycle: | Endpoint | Purpose | |----------|---------| | `GET /.well-known/ucp` | UCP discovery profile | | `POST /ucp/v1/checkout-sessions` | Create checkout | | `GET /ucp/v1/checkout-sessions/:id` | Get session | | `PUT /ucp/v1/checkout-sessions/:id` | Update (buyer, fulfillment) | | `POST .../complete` | Complete checkout | | `POST .../cancel` | Cancel checkout | | `GET /ucp/v1/orders` | List orders | | `GET /ucp/v1/orders/:id` | Get order | | `GET /ucp/v1/items` | Product catalog | Plus `/health` and `/admin` for monitoring. ## Batteries Included This isn't a skeleton. It ships with real infrastructure. **Payment Processing.** Stripe and PayPal are wired in. Set your API keys in `.env`, and `completeCheckout()` creates a Stripe PaymentIntent or PayPal Order automatically. Webhook endpoints handle payment confirmations. **SQLite Persistence.** Everything is persisted with WAL mode for concurrent access. Checkouts, line items, orders, inventory. Proper schemas, foreign keys, indexes. **Input Validation.** Every request goes through Zod schemas. Quantity capped at 100, line items at 50, emails validated, addresses checked. **Rate Limiting.** 100 requests/min on API routes, 20/min on checkout creation. **Structured Logging.** Pino logger with request timing, payment events, error tracking. ## The Checkout Flow The UCP checkout flow is a state machine: ``` incomplete → ready_for_complete → completed → canceled ``` 1. **Create** - POST line items, get back a session with totals and validation messages 2. **Update** - Add buyer info and shipping address, session transitions to `ready_for_complete` 3. **Complete** - Payment is processed, order is created 4. **Cancel** - Session is marked canceled Each step returns the full session state with validation messages. The client (or AI agent) always knows what's missing. ## Identity Linking UCP handles identity through OAuth 2.0. A platform (say, an AI agent service) can obtain authorization to act on behalf of a user at a business's site. The business exposes `/.well-known/oauth-authorization-server` with standard OAuth metadata: ```json { "issuer": "https://example.com", "authorization_endpoint": "https://example.com/oauth2/authorize", "token_endpoint": "https://example.com/oauth2/token", "revocation_endpoint": "https://example.com/oauth2/revoke", "scopes_supported": [ "ucp:scopes:checkout_session" ], "response_types_supported": ["code"], "grant_types_supported": ["authorization_code", "refresh_token"] } ``` This is foundational to how agentic commerce works. The agent doesn't share the user's credentials with the merchant. Instead, OAuth gives it scoped access to perform specific actions like creating a checkout session. The user stays in control, the agent gets just enough permission, and no passwords are exchanged. This also unlocks personalized experiences. Loyalty benefits, saved addresses, wishlists, authenticated pricing. All through standard OAuth scopes, no proprietary auth schemes. ## Quick Start **Node.js:** ```bash npm install ucpify npx ucpify init npx ucpify serve merchant-config.json ``` **Python:** ```bash pip install ucpify ucpify init ucpify serve merchant-config.json ``` **Docker:** ```bash docker compose up ucpify-js # or ucpify-py ``` ## CLI ```bash ucpify init # Generate sample config ucpify validate config.json # Validate config ucpify serve config.json # Start server (SQLite default) ucpify serve config.json --no-db # In-memory mode ``` ## Why I Built This The UCP spec is powerful but implementing it from scratch is tedious. ucpify closes the gap between "I have products" and "I have a UCP-compliant commerce API" to about 30 seconds. Useful for: - **AI agent developers** testing commerce integrations - **Merchants** who want UCP compliance without building from scratch - **Prototyping** checkout flows before committing to a full platform - **Learning** the UCP spec hands-on ## Links - **npm**: [npmjs.com/package/ucpify](https://www.npmjs.com/package/ucpify) - **PyPI**: [pypi.org/project/ucpify](https://pypi.org/project/ucpify/) - **GitHub**: [github.com/hemanth/ucpify](https://github.com/hemanth/ucpify) - **UCP Spec**: [ucp.dev](https://ucp.dev) JSON in, commerce out. --- --- title: "RFCs vs. READMEs: The Evolution of Protocols" description: "How we build the internet’s invisible contracts has changed completely. I’m not sure that’s entirely good. Practical notes." url: "https://h3manth.com/scribe/rfcs-vs-readmes/" canonical_url: "https://h3manth.com/scribe/rfcs-vs-readmes/" markdown_url: "https://h3manth.com/scribe/blog/rfcs-vs-readmes.md" publishDate: "2026-02-01T10:00:00.000Z" author: "Hemanth HM" category: "technology" tags: ["ai","standards","web"] word_count: 1171 reading_time_minutes: 6 x_markdown_tokens: 1870 content_signal: "ai-train=yes, search=yes, ai-input=yes" --- # RFCs vs. READMEs: The Evolution of Protocols > How we build the internet’s invisible contracts has changed completely. I’m not sure that’s entirely good. Practical notes. TCP/IP took nine years to deploy. MCP moved to the Linux Foundation in one. That contrast explains everything about how protocol development has changed. ## The old way In May 1974, Vint Cerf and Bob Kahn published *A Protocol for Packet Network Intercommunication*. It described how to connect different computer networks. Good idea. Important work. Then they waited. They refined. The Department of Defense adopted it in 1982. But the real "Flag Day" (when ARPANET officially switched to TCP/IP) didn't happen until January 1, 1983. Nine years. From paper to adoption. That wasn't slow by the standards of the time. That was normal. HTTP/2 took three years from proposal to RFC 7540 in 2015. TLS 1.3 took four years of debate before RFC 8446 dropped in 2018. IPv6 was standardized in 1998 (RFC 2460) and I'm pretty sure my toaster still doesn't support it. David Clark said it best in 1992: "We reject kings, presidents and voting. We believe in rough consensus and running code." Rough consensus took time. The people building those foundations assumed their work would outlast them, so they were careful. They documented everything. They thought about what might break in fifty years. ## The new way Anthropic announced the Model Context Protocol (MCP) on November 25, 2024. By December, there was an SDK. By January 2025, Claude Desktop shipped with native support and over a hundred community integrations existed. And then, on December 9, 2025, just over a year later, Anthropic donated the whole thing to the Linux Foundation's new Agentic AI Foundation. ## The explosion of newcomers It's not just MCP. 2025 gave us a "Cambrian explosion" of ways for agents to talk to each other. **Agent2Agent (A2A)** from Google dropped in April 2025. It's focused on cross-platform coordination. Over 50 partners—including Salesforce and SAP—signed up at launch. Again: months, not years. **Agent Protocol** went the community route—a tech-agnostic REST spec for any agent frame. **Agent Client Protocol (ACP)** came out of Zed and JetBrains, standardizing how coding agents (like Claude Code) talk to editors. **Universal Tool Calling Protocol (UTCP)** emerged as an alternative to MCP for simpler execution needs. **Universal Commerce Protocol (UCP)** dropped in Jan 2026 (Google again), specifically to standardize how agents buy things. **Agent Payments Protocol (AP2)** emerged in Sept 2025 with 60+ partners (PayPal, Coinbase) to handle the money side—ensuring agents can actually pay for what they find. We went from having zero standard ways for agents to communicate to having almost a dozen competing "standards" in eighteen months. ## Not everything is moving fast You might be thinking: "Wait, real standards still take time." You'd be right. OAuth 2.1 has been a draft since 2020. Five years later, it's still being refined. That's good. We don't want login security changing every Tuesday. I've been part of TC39 (the committee that standardizes JavaScript). We have a rigorous stage process. We debate edge cases for months or years. It works—JavaScript runs everywhere on earth. But it's not "ship it next week." ActivityPub took three years to standardize (2015-2018) and another eight to really hit the mainstream. The "ship in weeks" phenomenon is specific to this AI moment. It's what happens when protocols are built by startups instead of consortiums. Compare that timeline: - **TCP/IP**: 9 years from paper to deployment. - **MCP**: 1 year from announcement to open governance. No IETF working group. No decade of debate. They shipped the SDK, verified it worked in production, and then handed it off. I've built MCP servers. The developer experience is good. You can go from zero to working integration in an afternoon. That's real progress. ## What's different The old process had: - Academics and engineers from different organizations - IETF, W3C, IEEE standards bodies - Years of review and testing - Formal documentation that will exist forever - No single entity in control (from the start) The new process has: - Company ships SDK - Developers build on it - Company iterates based on usage - **Then** it moves to a foundation (if we're lucky) - README.md is the documentation ## What still worries me TCP/IP was designed to route around nuclear war. The people who built it cared about resilience, about infrastructure that would outlast any single company or organization. The recent move to the Linux Foundation is a great sign for MCP. It calms my biggest fear—that it would just be an Anthropic product forever. But the *mindset* is still different. We're building protocols like products. We iterate on them like apps. Breaking changes are just a version number away. RFCs are immutable. RFC 791 will always be RFC 791. GitHub repos are living codebases. If the company pivots or the repo is deleted, the "spec" effectively vanishes. In five years, will we be able to look up why a decision was made, or will those issues be long gone? I feel this myself. I built [OKAP](https://okap.dev) because I wanted an open protocol for knowledge access that wasn't tied to any single vendor's ecosystem. It's my attempt to build something durable in a fast-moving world. ## The adoption cheat code Why is adoption so fast now? It's not global consensus. It's usually one of two things: **proven utility** or **room consensus**. MCP was the first type. Anthropic didn't form a committee. They just shipped it. It worked. By March 2025—just four months later—OpenAI, Microsoft, and Google had all integrated it. The ecosystem rallied around it because it solved a pain point, not because a board voted on it. Other times, like with Google's UCP, it *is* room consensus. It launched in Jan 2026 not as a proposal, but with 20+ partners like Shopify, Walmart, and Stripe already signed on. Technically, these are open protocols. Anyone can implement them. But let's be real: giants control the clients, the servers, and the distribution. Their "open" standard has a billion users on day one. Yours has a GitHub star. There's a dark side to this. In the RFC era, the process was excruciatingly slow, but it was democratically open. If you had a good idea and the patience of a saint, you could shift the internet. Today? If you're an individual with a brilliant idea for a protocol, good luck. Without a corporate manufacturing partner, your "standard" is just a Repo. The noise floor is too high. Unless you can get adoption from the giants, you're shouting into the void. ## The question Every time we build something, we're making a bet about how long it needs to last. The TCP/IP people bet on decades. They were right. The people building AI protocols are moving at the speed of AI. That means weeks, maybe months. Shipping fast allows for incredible innovation. We wouldn't have the agentic ecosystem we have today if we'd waited for an IETF committee to define "tool use." But as we build these layers, we should ask: are we building scaffolding, or are we pouring concrete? Because if this acts like concrete, I really hope we got the mix right. --- --- title: "My 9-Year-Old Built His Own Gaming PC (And Cannibalized a Laptop)" description: "I suggested we build a PC together. He ended up doing 90% of it himself, including extracting an SSD from an old laptop." url: "https://h3manth.com/scribe/9-year-old-builds-gaming-pc/" canonical_url: "https://h3manth.com/scribe/9-year-old-builds-gaming-pc/" markdown_url: "https://h3manth.com/scribe/blog/9-year-old-builds-gaming-pc.md" publishDate: "2025-12-27T00:00:00.000Z" author: "Hemanth HM" category: "hardware" tags: ["hardware","diy","kids","gaming","teaching"] word_count: 1089 reading_time_minutes: 6 x_markdown_tokens: 1746 content_signal: "ai-train=yes, search=yes, ai-input=yes" --- # My 9-Year-Old Built His Own Gaming PC (And Cannibalized a Laptop) > I suggested we build a PC together. He ended up doing 90% of it himself, including extracting an SSD from an old laptop. My 9-year-old [son](https://vedrao.com) lately decided he wanted a gaming PC. Instead of just buying a pre-built box from a store, he started researching what he needed. He had specific requirements: a particular GPU and graphic card he'd found through his own research online, over a couple of days during his screentime. He started looking at gaming laptops, but they were prohibitively expensive. So I gave him a budget constraint. "If you can find the parts within this budget, we can build it." He rose to the challenge. He spent hours researching, comparing prices, and filling an Amazon cart with compatible components. He did all the research himself. But when the time came, he got restless waiting for shipping. So we drove to a local store, found the parts he had listed (or their equivalents), and bought it all on the spot. ## The Build ![The completed build](../../assets/blog/pc-build/build.jpg) ## The Specs ![The parts](../../assets/blog/pc-build/img-parts-boxes.jpg) * **CPU:** AMD Ryzen 5 * **GPU:** GeForce RTX 5050 (Shadow 2X) * **Motherboard:** MSI A520M-A PRO * **PSU:** Corsair RM750e * **Storage:** Recycled SSD from old laptop * **RAM:** Kingston DDR4 (not in the pic) We brought home the boxes: CPU, GPU, motherboard, case, RAM, screw driver kit, and power supply. He didn't wait for a lecture. He dove in. The afternoon we bought the parts, we had to go out and returned late in the evening. After we got home, he spent a couple of hours unpacking everything and installing the CPU with thermal paste, without any supervision. We forced him to bed (reluctantly on his part). The next day, he assembled the rest independently, mostly without supervision. Risky? Absolutely. But he was careful, methodical, and honestly more focused than I expected. To my amazement, he ended up doing **90% of the assembly himself**. He installed the CPU (the most nerve-wracking part for any builder), mounted the motherboard, seated the GPU, and secured the hard drive. He handled the delicate parts with surprising care. ## The Budget Constraint ![Cannibalized Laptop Motherboard](../../assets/blog/pc-build/img-laptop-mobo.jpg) While creating his parts list, he ran up against the budget. "Why not use Mom's laptop?" he asked. "It's dead, but maybe we can extract the SSD." I said that sounded like a good idea, though I wasn't sure if the drive was still functional. Then I paused and asked, "Why only the SSD? Why not the RAM too?" "Bruh, laptop RAM doesn't fit for Desktop," he said. I was pretty amazed by that. He was right, of course (DIMM vs SO-DIMM), but hearing a 9-year-old explain form factor compatibility and correct me was a highlight of the build. So he extracted the SSD for his rig (it worked perfectly). For the RAM, he suggested we sell it on eBay. I was doubtful anyone would want old laptop memory, but I listed it anyway. To my surprise, someone bought it! ![Laptop RAM sold on eBay](../../assets/blog/pc-build/laptop-ram-sold.jpg) ## The Challenges Of course, it wasn't all smooth sailing. ### The Fan Problem The PC case had RGB fan connectors that weren't compatible with the motherboard's headers. We actually discovered this late in the process—the motherboard doesn't support ARGB. When he realized it, he said his PC "isn't an actual gaming PC until his fan's LED lights up." His solution? Find a fan hub that can light up his case fans. We're still waiting to order it and see if his workaround brings the RGB to life. ### The WiFi Situation I missed it when reviewing his parts list. His motherboard didn't have WiFi. When I realized and asked him about it, he said, "I know. Real gamers use LAN for speed anyway." Fair point. Except we didn't have a LAN connection near his desk. "We can use the WiFi extender," he said. "It has a LAN port." Of course it does. So we dug out our old WiFi extender, reconfigured it, and ran a LAN cable from the extender to his PC. Problem solved. ## The Final 10% My involvement was mostly looking up the manual to tell him which connectors go where. He did the actual plugging. ### The First Boot Panic We powered it on. Nothing. The motherboard showed a white light on the RAM slot. My heart sank. "Did we cook the RAM?" We thought we'd have to order new memory. Then we tried the oldest trick in the book: reseat it. Clicked it back in firmly. Pressed the power button. It booted. ### The GPU Mystery The system was running, but the GPU fans weren't spinning and there was no signal to the monitor. We noticed that the card wasn't seated well. His mom came over and helped to reseat the graphics card. It reminded us of the Nintendo days: when a game cartridge wouldn't work, you'd pull it out and push it back. He said the "golden teeth" are in! We pulled the GPU, checked the contacts, and seated it again with a firm push. **Click.** The fans spun up. He jumped in joy. ### The Easy Part Because he'd pulled the SSD from his mom's old laptop (with the OS already on it), we had zero headaches installing the operating system. It just worked. ## Outcome ![The final outcome](../../assets/blog/pc-build/outcome.png) *(PS: He says he needs a better chair and table for his "gaming" setup)* He now has a gaming PC that is truly *his*. Not just because he owns it, but because he built it. He knows what's inside the box. He knows how the SSD connects to the motherboard. He knows that if he wants to upgrade the GPU later, it's just a matter of opening the case and swapping a part. It's a reminder that kids are often capable of much more than we give them credit for. We assume they need hand-holding, but often they just need the parts and the permission to try. To be frank, I was scared and was risking screwing it all up. He already told me that if he gets another chance, he wants to build another one. The itch is real. (Now I just need to make sure he doesn't disassemble *my* laptop for his needs.) --- **Want to see more of his work?** Check out his website at [vedrao.com](https://vedrao.com). ## The Build in His Own Words He also made a video documenting the build process:
--- --- title: "Consolidating 18 Years of Writing: From 6 Platforms to One" description: "From Blogspot to Drupal to WordPress to Octopress to 11ty and finally Astro - the story of consolidating 372 posts across 6." url: "https://h3manth.com/scribe/consolidating-6-platforms-18-years/" canonical_url: "https://h3manth.com/scribe/consolidating-6-platforms-18-years/" markdown_url: "https://h3manth.com/scribe/blog/consolidating-6-platforms-18-years.md" publishDate: "2025-12-27T00:00:00.000Z" author: "Hemanth HM" category: "web" tags: ["javascript","python","astro"] word_count: 959 reading_time_minutes: 5 x_markdown_tokens: 1671 content_signal: "ai-train=yes, search=yes, ai-input=yes" --- # Consolidating 18 Years of Writing: From 6 Platforms to One > From Blogspot to Drupal to WordPress to Octopress to 11ty and finally Astro - the story of consolidating 372 posts across 6. **TL;DR:** Consolidated 18 years of blog content from 6 different platforms (Blogspot → Drupal → WordPress → Octopress → 11ty → Astro) into a single static site with 372 posts, recovered 200+ posts from database dumps and backups, removed 36 duplicates, and fixed 220+ posts with broken formatting - all with AI pair programming. ## The Blogging Timeline ``` 2007 ──► Blogspot (Google's free platform, where it all began) │ 2008 ──► Drupal 6 (self-hosted, felt like a "real" developer) │ 2012 ──► WordPress (everyone was doing it) │ 2014 ──► Octopress (Ruby-based static site generator, hipster phase) │ 2020 ──► 11ty (JavaScript ecosystem, modern SSG) │ 2025 ──► Astro (the final form? ) ``` Each migration carried forward content from the previous platform. Some posts survived all 6 migrations. Most accumulated formatting quirks along the way. ## Why So Many Migrations? Each platform served its purpose at the time: - **Blogspot** - Zero config, just write and publish. Perfect for a student. - **Drupal** - Wanted more control, PHP was everywhere. - **WordPress** - Plugins for everything! (Until you need to patch 47 of them) - **Octopress** - "Static sites are the future!" Also, I was learning Ruby. - **11ty** - JavaScript everywhere, simple and fast. - **Astro** - Type-safe content collections, island architecture, and actual good DX. ## The Great Consolidation The content was scattered across: - A Drupal 6 SQL dump (~50MB) - WordPress exports (XML) - Octopress markdown files - 11ty markdown files The Drupal content was the messiest - 18 years of different editors, plugins, and format changes had left scars in the data. ### The Drupal Challenge Parsing the SQL dump required some Python wizardry: ```python def parse_drupal_nodes(sql_file): with open(sql_file, 'r') as f: content = f.read() # Parse INSERT statements for node_revisions pattern = r"INSERT INTO `node_revisions` VALUES\s*\((.*?)\);" matches = re.findall(pattern, content, re.DOTALL) return parse_values(matches) ``` The URL aliases needed 322 redirect rules: ```apache RewriteRule ^content/(.*)$ /scribe/$1 [R=301,L] RewriteRule ^node/(.*)$ /scribe/$1 [R=301,L] ``` ### The Code Block Nightmare Each platform handled code blocks differently: - Drupal used `` tags with custom filter modules - WordPress had its own syntax highlighters - Octopress used `{% codeblock %}` liquid tags - 11ty used standard fenced blocks The result after consolidation? **Fragment fences everywhere:** ````markdown ```javascript function foo() { ```javascript ← WHY return bar; ```javascript ← STOP } ``` ```` ### The Fix Scripts Two Python scripts saved the day: **Language detection:** ```python def detect_language(code): if re.search(r'^\s*import\s+\w+', code, re.MULTILINE): return 'python' if re.search(r'\.each\s+do\s*\|', code): return 'ruby' if re.search(r'^\s*\$\s+\w+', code, re.MULTILINE): return 'bash' return 'javascript' ``` **Fragment fence removal:** ```python patterns = [ (r'(\n[^\n`]+)\n```javascript\n([^\n`]+\n)', r'\1\n\2'), (r'(\n[^\n`]+)\n```python\n([^\n`]+\n)', r'\1\n\2'), ] ``` ## The Statistics | Metric | Value | |--------|-------| | Platforms migrated from | 6 | | Total posts consolidated | 372 | | Posts recovered from DB/backup | 200+ | | URL redirects (100% working) | 292 | | Posts cleaned (nav/tweet links) | 220 | | Duplicate posts removed | 36 | | Years of content | 18 | | Build time | ~6 seconds | | Final static site size | ~91MB | ## The AI Pair Programming Stats The entire migration was completed over **multiple sessions** with AI pair programming. Here's the breakdown: | Metric | Value | |--------|-------| | Total project time | ~4-5 hours (across sessions) | | AI tool calls | 3800+ | | Posts analyzed | 400+ | | Posts recovered/fixed | 250+ | | Python scripts written | 10+ | | Deployments | 20+ | | Git commits | 30+ | ### The AI Workflow 1. **Human reports broken post** → AI views file 2. **AI rewrites with proper code blocks** → Human tests locally 3. **Human approves** → AI commits and deploys 4. **Repeat** for 70+ posts ### Time Saved Without AI, manually fixing 120+ posts with code block issues would have taken: - **~5-10 min per post** to view, analyze, and rewrite - **120 posts × 7 min = ~14 hours** of manual work **AI turned a 2-day project into a few hours of evening sessions.** ## What I've Learned 1. **Content outlives platforms** - Posts from 2007 are still getting traffic. The platform is temporary; the content is permanent. 2. **Each migration leaves scars** - Every platform has its quirks. Migrating content 5+ times means 5+ layers of formatting weirdness. 3. **Static sites win** - No more security patches. No more database maintenance. Just HTML served from edge locations. 4. **AI pair programming is a game-changer** - What would have been a weekend project became an evening session. Writing migration scripts, fixing broken posts, iterating on solutions - AI made it possible. 5. **Beware of auto-fix scripts** - A script that "fixes" code blocks across 200+ files can break more than it fixes. Some posts needed manual restoration after aggressive auto-fixing. Always test on a subset first. 6. **Live databases are gold** - The SQL dump wasn't enough. Connecting to the live MySQL database recovered 13 more posts that were missing from the static dump. 7. **llms.txt matters** - Added [h3manth.com/llms.txt](https://h3manth.com/llms.txt) for AI crawlers. If bots are reading our content anyway, might as well make it structured. ## The Final Architecture ``` h3manth.com ├── /scribe/ → 372 blog posts (Astro) ├── /ai/ → AI projects ├── /fun/ → Interactive demos ├── llms.txt → AI-friendly site description └── *.html → Landing pages ``` The blog is now live at [h3manth.com/scribe](https://h3manth.com/scribe) with all 372 posts, proper syntax highlighting, and 292 redirects preserving 18 years of SEO juice. **From 6 disparate platforms to one unified Astro site - it's been an evolution. Here's to the next 18 years.** --- *P.S. - If you're migrating legacy content, don't underestimate the code block problem. And get yourself an AI pair programmer.* --- --- title: "My 2025 AI Predictions: How Did They Hold Up?" description: "A year-end review of my optimistic AI predictions for 2025 - spoiler: 6.5 out of 7 came true. Practical notes and code in JS." url: "https://h3manth.com/scribe/2025-ai-predictions-review/" canonical_url: "https://h3manth.com/scribe/2025-ai-predictions-review/" markdown_url: "https://h3manth.com/scribe/blog/2025-ai-predictions-review.md" publishDate: "2025-12-23T15:00:00.000Z" author: "Hemanth HM" category: "ai" tags: ["ai","predictions","2025","technology","review"] word_count: 675 reading_time_minutes: 4 x_markdown_tokens: 1116 content_signal: "ai-train=yes, search=yes, ai-input=yes" --- # My 2025 AI Predictions: How Did They Hold Up? > A year-end review of my optimistic AI predictions for 2025 - spoiler: 6.5 out of 7 came true. Practical notes and code in JS. At the start of 2025, I made some optimistic predictions about where AI would go this year. Now that we're wrapping up December, let's see how they held up. ## My Original Predictions Here's what I [posted on LinkedIn](https://www.linkedin.com/posts/hemanthhm_ai-activity-7277001125994680322-T_Nr/) in January 2025: > My optimistic predictions for #AI in 2025: > > - 💻 More local models: models integrated into browsers and operating systems > - 💡 Increase in adoption of domain specific Small Language Models (SLM) > - 📊 More affordable fine-tuning and training > - ⌨️ Companies will hire specific AI agents > - 🎬 80% of a movie shall be baked with AI > - 🏥 AI-assisted medical diagnosis and surgical interventions save lives > - 🚫 Lawsuits against AI and newer government policies **Verdict: 6.5/7 correct.** Not bad for optimism. ## The Scorecard | Prediction | Status | Reality Check | |------------|--------|---------------| | 💻 More local models in browsers/OS | ✅ | Chrome, Edge, Safari, Brave, Opera, Arc all ship AI | | 💡 Domain-specific SLMs take off | ✅ | SLMs outperform LLMs in niche tasks | | 📊 Affordable fine-tuning | ✅ | Fine-tuning now $5k-$50k range | | ⌨️ Companies hire AI agents | ✅ | 62% experimenting, 23% scaling | | 🎬 80% of a movie baked with AI | ⚠️ | Indie yes, Hollywood not quite | | 🏥 AI-assisted diagnosis saves lives | ✅ | 66% of physicians using AI | | 🚫 Lawsuits & gov policies | ✅ | Dec 11 Executive Order | ## Deep Dive ### 💻 Local Models Everywhere The "edge AI" revolution happened. Every major browser now has AI built-in: | Browser | AI Integration | |---------|----------------| | Chrome | Gemini + `window.ai` API | | Edge | Copilot (OpenAI) | | Safari | Apple Intelligence | | Brave | Leo (Llama 3, Mixtral, optional GPT-4o) | | Opera | Aria (Opera's model + OpenAI) | | Arc | Arc Max (GPT-4 class models) | | Firefox | Add-ons only (ChatGPT, Gemini, Claude, Local) | | Vivaldi | External AI tools integration | Plus standalone tools: - Jan AI - runs LLMs completely offline - Perplexity Comet - AI-first browser (launched July 2025) - WebLLM/WebGPU - bringing models to the browser ### 💡 Small Language Models Win The market shifted from "bigger is better" to "right-sized for the job": - Companies like AT&T, EY, Thomson Reuters embraced SLMs - Training costs 1/10th of LLMs - NVIDIA research shows SLMs effective as autonomous agents - Microsoft Phi-3 driving enterprise adoption ### 📊 Fine-Tuning for Everyone Training frontier models still costs $100M+, but: - Fine-tuning dropped to $5k-$50k range - GenAI MVP now costs $50k-$150k - OpenAI fine-tuning: GPT-4.1 nano at $1.50/1M tokens - Custom AI no longer enterprise-only ### ⌨️ The Agent Economy 2025 was the "Year of Agents": - Companies subscribing to AI agents for specific tasks - 62% of organizations experimenting with AI agents - 23% scaling agentic AI in production - Agents handling customer support, coding, research autonomously ### 🎬 AI Cinema (Partial Hit) The "80%" mark happened in indie, not Hollywood: - **Daisy** - AI horror short by Storybook Studios - **Horizon 2080** - 57-minute sci-fi epic by Epic AI Films - Hollywood uses AI heavily for VFX (~30-50%) - Full AI features remain indie territory ### 🏥 AI Saves Lives AI-assisted diagnosis became standard: - 66% of physicians using AI (up from 38% in 2023) - AMA launched Center for Digital Health and AI - 90% of hospitals use AI for early diagnosis - AI imaging detects anomalies faster than radiologists ### 🚫 The Legal Reckoning On December 11, 2025: - Executive Order established DOJ "AI Litigation Task Force" - Challenges state AI laws conflicting with federal policy - California's strict regulations vs. federal frameworks - Exactly the friction predicted ## What's Next for 2026? Stay tuned for my 2026 predictions. Spoiler: agents get autonomous, regulation gets serious, and the line between AI-generated and human-created content gets very blurry. --- *[Original LinkedIn post](https://www.linkedin.com/posts/hemanthhm_ai-activity-7277001125994680322-T_Nr/) from January 2025.* --- --- title: "We Need OKAP: OAuth for API Keys" description: "Every AI app wants my API keys. Copy. Paste. Repeat. What if we had a standard for this? Practical notes and code examples." url: "https://h3manth.com/scribe/okap/" canonical_url: "https://h3manth.com/scribe/okap/" markdown_url: "https://h3manth.com/scribe/blog/okap.md" publishDate: "2025-12-21T06:00:00.000Z" author: "Hemanth HM" category: "ai" tags: ["ai","api","security","protocol","keys"] word_count: 804 reading_time_minutes: 5 x_markdown_tokens: 1515 content_signal: "ai-train=yes, search=yes, ai-input=yes" --- # We Need OKAP: OAuth for API Keys > Every AI app wants my API keys. Copy. Paste. Repeat. What if we had a standard for this? Practical notes and code examples. I have API keys for OpenAI, Anthropic, Google, Groq, Together AI, Replicate, and counting. Every new AI tool I try wants me to paste them manually. Copy from one dashboard. Paste into a config. Repeat for every provider. Repeat for every app. My keys are now scattered across dozens of apps. Some store them in localStorage. Some in plaintext config files. I have no visibility into who's using what, or how much they're spending. We have OAuth for user authentication. Why don't we have the equivalent for API keys? ## The Current Landscape Good news: people are already solving pieces of this problem. ### LiteLLM Proxy [LiteLLM](https://litellm.ai/) runs a local proxy that unifies all your AI providers behind one OpenAI-compatible endpoint: ```yaml # litellm-config.yaml model_list: - model_name: gpt-4 litellm_params: model: openai/gpt-4 api_key: os.environ/OPENAI_API_KEY - model_name: claude-3 litellm_params: model: anthropic/claude-3-opus api_key: os.environ/ANTHROPIC_API_KEY ``` One endpoint for all providers. Virtual keys for rate limiting and budgets. But you still manage the master keys yourself. ### Cloudflare AI Gateway [Cloudflare's AI Gateway](https://developers.cloudflare.com/ai-gateway/) lets you store API keys in their dashboard: - Secure storage with encryption - Easy key rotation - Usage analytics across providers - Rate limiting and caching They're adding features for dynamic routing and scoped access. Getting closer to what I want. ### Eden AI [Eden AI](https://www.edenai.co/) goes further. Single API, multiple providers: - One Eden AI key to access OpenAI, Anthropic, Google, etc. - They handle the provider routing - Unified dashboard for usage and costs - Automatic failover between providers Trade-off: you're trusting them with your traffic. ### llmux I built [llmux](https://github.com/hemanth/llmux) to solve this for my own projects. It's a unified LLM inference proxy with multi-provider routing: ```yaml routing: default_strategy: round-robin fallback_chain: [groq, cerebras, together, openrouter] model_aliases: llama-70b: groq: llama-3.1-70b-versatile together: meta-llama/Llama-3.1-70B-Instruct-Turbo ``` One API key, round-robin across providers, automatic fallbacks, caching. Works with any OpenAI SDK. Deploy locally, Docker, or Cloudflare Workers. Still requires managing provider keys yourself, but at least they're in one place. ### Other Players - **[IBYOK](https://ibyok.com/)**: Encrypted vault specifically for LLM API keys - **[Kilo Code](https://www.kilo.ai/)**: Organization-wide API credential management - **[ngrok AI Gateway](https://ngrok.com/)**: Proxy with failover and load balancing across providers ## What's Still Missing These tools help, but they're all different pieces. Here's what I actually want: ### 1. User-Controlled Authorization Flow Like OAuth, but for API keys: ``` 1. App requests: "I need OpenAI GPT-4 access, $10/month limit" 2. I get a prompt: "Example App wants GPT-4 access. Allow?" 3. I approve 4. App gets a scoped token, not my master key ``` No copy-paste. No trusting apps with my master key. I approve once, revoke anytime. ### 2. Scoped Tokens, Not Master Keys Apps should never see my `sk-...` key. They get a proxy token that: - Is rate limited - Is model restricted - Has a spending cap - Can be revoked instantly LiteLLM's virtual keys do this if you self-host. But it requires running your own infrastructure. ### 3. Universal Standard Each solution above is siloed. What if there was a standard that: - Apps request access using a common protocol - Any vault/gateway can fulfill the request - Users choose their preferred vault Like how OAuth works across providers. ## OKAP: A Proposal I've drafted a spec: **[OKAP - Open Key Access Protocol](https://github.com/hemanth/okap)** Here's what an OKAP request could look like: ```json { "okap": "1.0", "request": { "provider": "openai", "models": ["gpt-4", "gpt-4o-mini"], "capabilities": ["chat", "embeddings"], "limits": { "monthly_spend": 10.00, "requests_per_minute": 60 }, "expires": "2025-03-01" } } ``` A browser extension or native app intercepts this, shows me the request, I approve or deny. The app gets a scoped OKAP token. ## What Would Make OKAP Work For OKAP to become a real standard: 1. **Provider buy-in**: OpenAI, Anthropic, Google would need to support scoped tokens or recognize a standard proxy protocol 2. **User adoption**: A trusted vault app/extension that people actually install 3. **Developer adoption**: Apps willing to integrate the flow The infrastructure exists. LiteLLM, Cloudflare, and others prove the proxy model works. OKAP would standardize the handshake between apps and user-controlled vaults. ## What I'm Doing Today For now, I use: - **Environment variables** for local development - **[llmux](https://github.com/hemanth/llmux)** for multi-provider routing and fallbacks - **Cloudflare AI Gateway** for production apps with caching Not ideal. Keys are still in a config file. No universal authorization flow. ## What's Next? The pieces exist. LiteLLM does virtual keys. Cloudflare does secure storage. llmux does routing. What's missing: a standard way for apps to request access and users to grant it. If you're: - **Building an AI app**: Would you integrate a BYOK authorization flow? - **Working on key management**: Want to collaborate on a spec? - **Using multiple AI APIs**: What's your current workflow? I'm thinking about writing a draft spec. Let me know if you'd use it. [LinkedIn](https://linkedin.com/in/poshiya) | [GitHub](https://github.com/hemanth) --- --- title: "Skills vs MCP? Wrong Question" description: "With agent frameworks adding Skills support, some are asking if MCP is still needed. Short answer: yes. Here’s why in JS." url: "https://h3manth.com/scribe/skills-and-mcp-better-together/" canonical_url: "https://h3manth.com/scribe/skills-and-mcp-better-together/" markdown_url: "https://h3manth.com/scribe/blog/skills-and-mcp-better-together.md" publishDate: "2025-12-21T05:30:00.000Z" author: "Hemanth HM" category: "ai" tags: ["ai","agents","mcp","tools","architecture"] word_count: 952 reading_time_minutes: 5 x_markdown_tokens: 1794 content_signal: "ai-train=yes, search=yes, ai-input=yes" --- # Skills vs MCP? Wrong Question > With agent frameworks adding Skills support, some are asking if MCP is still needed. Short answer: yes. Here’s why in JS. With agent frameworks now supporting Skills, a question keeps coming up: "Does this replace MCP?" Short answer: **No.** Skills and MCP are teammates, not competitors. Anthropic designed them to work together. Skills provide the expertise, MCP provides the access. Here's why you need both. ## The Problem I Was Trying to Solve Before Skills, my agents were slow. Really slow. Why? Because I was loading everything upfront: ```python # The old way (still works, but ugh) agent = Agent("assistant", tools=[ pdf_tool_1, pdf_tool_2, pdf_tool_3, email_tool_1, email_tool_2, database_tool_1, database_tool_2, # ... 100 more tools 😱 ]) ``` Every time I started an agent, it had to load all 100 tools into the context window. Even if I was just processing a single PDF. Slow startup, bloated context, split attention. ## My First Solution: Tool Search Before Skills, I solved this with **deferred tools**. Instead of loading everything, the agent discovers tools on-demand: ```python # Tools are searchable, not loaded immediately agent = Agent("payments").with_tools(defer=[ charge_card, send_receipt, refund_payment ]) # Agent calls search_tools("charge card") → activates charge_card → executes it await agent.infer("charge $50 to card_123") ``` This worked. The agent uses a `search_tools` function to find relevant tools when it needs them. But it still had problems: tools were just functions. They didn't carry documentation, examples, or context. ## Enter Skills Skills take tool search further. They're not just functions. They're packaged expertise: ```python from agentu import Skill pdf_skill = Skill( name="pdf-processing", description="Extract text and tables from PDFs", instructions="skills/pdf/SKILL.md", # How-to guide resources={"forms": "skills/pdf/FORMS.md"} # Reference docs ) agent = Agent("assistant").with_skills([pdf_skill]) ``` **What changed:** - Faster startup (only load what you use) - Clean context (no irrelevant tools) - Portable packages (share skills across projects) - **Bundled documentation** (instructions + resources load progressively) ## So What's MCP? MCP (Model Context Protocol) connects your agent to external systems. It's not about loading tools. It's about accessing live data. ```python # Connect to GitHub agent.with_mcp(["github"]) # Now your agent can: # - List your repos # - Read actual files # - Create real issues # - Post actual comments ``` MCP is how you give your agent access to the outside world. **What you get:** - Standardized protocol for all external connections - Built-in auth & permissions - Security boundaries MCP servers can be local or remote. There's a growing ecosystem of hosted MCP servers you can connect to: ```python # Connect to remote MCP servers agent.with_mcp([ "github", # Official GitHub MCP "postgres", # Database access "https://mcp.paypal.com/mcp", # Payments "https://mcp.slack.com/mcp" # Team messaging ]) ``` This is something Skills can't do. Skills are local expertise packages. MCP gives you live connections to external services, wherever they're hosted. ## See the Difference? This is the part people miss: - **Skills**: Things your agent *knows how to do* - **MCP**: Things your agent *can access* Different problems. Different solutions. ## Real Example Let me show you a concrete case where you need both. **Task:** Build a code review agent. **What it needs:** **1. Code Review Skill** - Tools for static analysis - Documentation on best practices - Example feedback formats **2. GitHub MCP** - Access to fetch PR diffs - Access to read files - Access to post comments **Without the Skill?** Your agent can access GitHub fine. But it doesn't know how to give good feedback. **Without MCP?** Your agent knows code review principles. But it can't access the actual PRs. You need both: ```python from agentu import Agent, Skill # The expertise code_review_skill = Skill( name="code_review", resources={"guide": "review-guide.md"} ) # The whole thing agent = (Agent("assistant") .with_skills([code_review_skill]) # Knows how .with_mcp(["github"])) # Can access # Now it works review = agent.infer("Review PR #247") ``` The Skill teaches it *how to review code*. MCP gives it *access to GitHub*. ## Another Real-World Example **Task:** "Analyze customer churn from our database." ```python from agentu import Agent, Skill data_skill = Skill( name="data_analysis", resources={"guide": "analysis-guide.md"} ) agent = (Agent("assistant") .with_skills([data_skill]) # Expertise .with_mcp(["postgres"])) # Access analysis = agent.infer(""" Query customer data from the last 6 months and identify churn patterns """) ``` **What happens:** 1. Agent uses Postgres MCP → queries customer table 2. Agent uses Data Skill → applies statistical analysis 3. Agent uses Data Skill → identifies patterns 4. Agent generates insights Neither Skills nor MCP could do this alone. ## Why This Confusion Exists Both involve "tools," which is where people get mixed up. But they're different kinds of tools: **Skill tools:** Functions your agent runs locally ```python # Pure function, no external deps parse_pdf(file) ``` **MCP tools:** Bridges to external services ```python # Requires GitHub auth, makes API calls github/get_pull_request(number) ``` An agent might use a Skill to understand how to query a database, and MCP to actually connect to it. ## How I Use Both in agentu Here's a real example: a due diligence assistant for evaluating companies. ```python from agentu import Agent, Skill # Financial analysis expertise finance_skill = Skill( name="financial_analysis", resources={"guide": "finance-guide.md"} ) agent = (Agent("assistant") .with_skills([finance_skill]) .with_mcp(["postgres", "google-drive"])) report = agent.infer(""" Pull Q3 financials from our database, compare against the pitch deck in Drive, and flag any discrepancies """) ``` The agent knows *how* to analyze financials (Skill) and can *access* your database and Drive (MCP). ## The Bigger Picture Skills and MCP solve different problems. **Skills** = what your agent knows how to do **MCP** = what your agent can access You need both. An agent with Skills but no MCP is smart but isolated. An agent with MCP but no Skills is connected but inefficient. It's not Skills vs. MCP. It's Skills *and* MCP. ## Try It Both are in agentu: ```bash pip install agentu ``` Examples: - [Skills docs](https://github.com/hemanth/agentu/tree/main/examples/skills) - [MCP guide](https://github.com/hemanth/agentu#mcp-support) So stop asking "Skills vs MCP?" Use both. --- --- title: "Taking AI Agents to the Race Track: Lessons from the High-Velocity Field Test" description: "What happens when you strap a laptop into a race car, connect GPS devices, and run Gemini Nano at 150mph - a GDE field test." url: "https://h3manth.com/scribe/high-velocity-ai-field-test/" canonical_url: "https://h3manth.com/scribe/high-velocity-ai-field-test/" markdown_url: "https://h3manth.com/scribe/blog/high-velocity-ai-field-test.md" publishDate: "2025-12-18T08:00:00.000Z" author: "Hemanth HM" category: "ai" tags: ["ai"] word_count: 1607 reading_time_minutes: 9 x_markdown_tokens: 3275 content_signal: "ai-train=yes, search=yes, ai-input=yes" --- # Taking AI Agents to the Race Track: Lessons from the High-Velocity Field Test > What happens when you strap a laptop into a race car, connect GPS devices, and run Gemini Nano at 150mph - a GDE field test. What an experience. Taking AI agents from notebooks to race tracks was one of the most incredible collaborative efforts I've been part of. GDE++ indeed. 🤓 This is just the beginning, and I'm really looking forward to more experiments like this. ## The Setup Picture this: a laptop strapped into a race car, GPS devices wired up, real-time telemetry rendering on a UI, and Gemini Nano running inference-all while the car is doing 150mph around the track. That was our field test. We talked to the CEO of the race track. We got expert pro driver assessments to improve our agents. We debugged code between sessions while mechanics prepped the car. This wasn't a hackathon in a conference room, this was AI meeting reality. ## The Split-Brain Architecture Real-time racing coaching needs two very different capabilities: 1. **Instant reactions** - "BRAKE!" can't wait 500ms 2. **Strategic advice** - "You're lifting too early compared to the pro" We built a dual-path system: ``` ┌────────────────────────────────────────────────────────────┐ │ 10Hz GPS TELEMETRY STREAM │ │ (lat, lon, speed, heading, timestamp) @ 100ms intervals │ └─────────────────────────┬──────────────────────────────────┘ │ ┌───────────┴───────────┐ ▼ ▼ ┌──────────────────────┐ ┌─────────────────────────┐ │ GEMINI NANO │ │ GEMINI FLASH 3.0 │ │ Chrome Browser │ │ Cloud REST API │ ├──────────────────────┤ ├─────────────────────────┤ │ Inference: <50ms │ │ Inference: 500-1500ms │ │ Context: 1KB │ │ Context: 32KB │ │ Output: 1 token │ │ Output: Full analysis │ └──────────────────────┘ └─────────────────────────┘ ``` ### Nano: The Reflexes Gemini Nano runs entirely in Chrome via the `window.LanguageModel` API. No network round-trip-the model lives on-device. ```typescript const getInstantFeedback = async (telemetry: TelemetryData): Promise => { const session = await window.LanguageModel.create({ systemPrompt: `Racing copilot. Respond with ONE action word. DECISION MATRIX: | Condition | Action | |----------------------------------|-------------| | brakePos > 50 AND longG < -0.8 | THRESHOLD | | brakePos > 10 AND latG > 0.4 | TRAIL_BRAKE | | latG > 1.0 AND throttle < 20 | COMMIT | | latG reducing AND throttle < 50 | THROTTLE | | throttle > 80 AND latG < 0.3 | PUSH | | throttle < 10 AND brakePos < 10 | NO_COAST |` }); const result = await session.prompt( `Telemetry: ${JSON.stringify(telemetry)}`, { responseConstraint: { type: "object", properties: { action: { type: "string", enum: ["THRESHOLD", "TRAIL_BRAKE", "COMMIT", "THROTTLE", "PUSH", "NO_COAST", "MAINTAIN"] } } } } ); session.destroy(); return JSON.parse(result); }; ``` The `responseConstraint` schema forces valid output-no parsing failures, no hallucinations, guaranteed enum values. ### Flash: The Strategist For lap analysis and technique comparison, we use Gemini Flash via REST: ```typescript const BASE_URL = "https://generativelanguage.googleapis.com/v1beta/models"; const getCoachingAdvice = async ( currentTelemetry: TelemetryData, referenceLap: Lap, coach: CoachPersona ): Promise => { const response = await fetch( `${BASE_URL}/gemini-flash-3.0:generateContent?key=${API_KEY}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ contents: [{ parts: [{ text: buildPrompt(currentTelemetry, referenceLap, coach) }] }], generationConfig: { responseMimeType: "application/json", maxOutputTokens: 500 } }) } ); const result = await response.json(); return parseAdvice(result.candidates[0].content.parts[0].text); }; ``` ## GPS-Derived Virtual Sensors Professional telemetry requires OBD-II hardware to read brake pressure and throttle position. We made it work with GPS alone by deriving these values from physics: ```typescript interface TelemetryPoint { lat: number; lng: number; speed: number; // GPS-derived m/s gLat: number; // Lateral G-force (calculated) gLong: number; // Longitudinal G-force (calculated) brake: number; // Virtual sensor: 0-100 throttle: number; // Virtual sensor: 0-100 time: number; } const calculateVirtualSensors = ( current: GPSPoint, previous: GPSPoint, dt: number ): TelemetryPoint => { // Longitudinal G from velocity derivative const longG = (current.speed - previous.speed) / dt / 9.81; // Lateral G from heading change rate and speed const headingDelta = normalizeAngle(current.heading - previous.heading); const angularVelocity = headingDelta / dt; const latG = (current.speed * angularVelocity) / 9.81; // Virtual sensors inferred from G-forces const isBraking = longG < -0.5; // Significant deceleration const isThrottle = longG > 0.1; // Positive acceleration return { lat: current.lat, lng: current.lng, speed: current.speed * 2.237, // Convert to mph gLat: latG, gLong: longG, brake: isBraking ? Math.min(100, Math.abs(longG) * 120) : 0, throttle: isThrottle ? Math.min(100, longG * 200) : 0, time: current.timestamp }; }; ``` ## The CAN Bus Discovery One of the biggest takeaways: **AI can now interface with hardware effortlessly.** And then there was CAN bus (Controller Area Network)-the protocol that connects everything in a modern vehicle. Every sensor, every ECU, every control module talks over this two-wire bus. ``` ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ Engine │ │ Brakes │ │ Dashboard │ │ ECU │ │ ABS │ │ Cluster │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ │ │ └───────────────────┴───────────────────┘ CAN Bus (500kbps) │ ┌──────┴──────┐ │ OBD-II │ │ Adapter │ └──────┬──────┘ │ ┌──────┴──────┐ │ Laptop │ │ + AI Agent │ └─────────────┘ ``` With a $20 OBD-II adapter, you can read: - Real brake pressure (not GPS-derived) - Actual throttle position - Engine RPM, coolant temp, fuel level - Wheel speeds (individual!) - Steering angle The next iteration will tap directly into CAN for ground-truth telemetry. ## Predictive Geofencing Best coaching comes *before* you need it. We defined geofences around every corner using Haversine distance: ```typescript const GEOFENCE_RADIUS = 200; // meters const getFeedForwardAdvice = ( currentPos: { lat: number; lon: number }, corners: Corner[] ): string | null => { for (const corner of corners) { const distance = haversineDistance( currentPos.lat, currentPos.lon, corner.lat, corner.lon ); // Trigger in 150-200m approach band if (distance <= GEOFENCE_RADIUS && distance > (GEOFENCE_RADIUS - 50)) { return `APPROACHING ${corner.name}: ${corner.advice}`; } } return null; }; const haversineDistance = (lat1: number, lon1: number, lat2: number, lon2: number): number => { const R = 6371e3; // Earth radius in meters const φ1 = lat1 * Math.PI / 180; const φ2 = lat2 * Math.PI / 180; const Δφ = (lat2 - lat1) * Math.PI / 180; const Δλ = (lon2 - lon1) * Math.PI / 180; const a = Math.sin(Δφ/2) * Math.sin(Δφ/2) + Math.cos(φ1) * Math.cos(φ2) * Math.sin(Δλ/2) * Math.sin(Δλ/2); return R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); }; ``` ## Low-Latency Audio A 50ms AI decision is worthless if audio synthesis takes 200ms. We pre-cache all command audio: ```typescript class CoachAudioService { private audioContext: AudioContext; private buffers = new Map(); private minRepeatInterval = 1500; // Prevent spam async initialize(): Promise { this.audioContext = new AudioContext(); const commands = [ 'THRESHOLD', 'TRAIL_BRAKE', 'COMMIT', 'THROTTLE', 'PUSH', 'NO_COAST', 'GOOD', 'SEND_IT' ]; await Promise.all( commands.map(async cmd => { const response = await fetch(`/audio/${cmd}.mp3`); const buffer = await this.audioContext.decodeAudioData( await response.arrayBuffer() ); this.buffers.set(cmd, buffer); }) ); } play(action: string): void { const buffer = this.buffers.get(action); if (!buffer) return; const source = this.audioContext.createBufferSource(); source.buffer = buffer; source.connect(this.audioContext.destination); source.start(0); // Instant - no network, no TTS synthesis } } ``` Result: decision-to-audio in **under 10ms**. ## Coach Personas Different drivers respond differently. Tony needs encouragement. Rachel wants physics. Garmin wants data. ```typescript type CoachPersona = 'TONY' | 'RACHEL' | 'AJ' | 'GARMIN' | 'SUPER_AJ'; const COACH_PROMPTS: Record = { TONY: `Encouraging, feel-based. "Commit!", "Good hustle!", "Send it!"`, RACHEL: `Physics teacher. Focus on weight transfer, platform balance. "Smooth brake release", "Settle the rear"`, AJ: `Direct commands. Connect vehicle state to driver input. "Lat G stable-hammer throttle", "Rotation complete-unwind"`, GARMIN: `Data robot. Delta times only. "Brake 0.2s later", "-0.3s sector"`, SUPER_AJ: `Adaptive. Switch persona based on error type: Safety → Imperative ("STABILIZE!") Technique → Physics ("Smooth release") Confidence → Encouragement ("Commit now!") Optimization → Delta ("Brake later")` }; ``` ## Heuristic Fallback Not everyone runs Chrome Canary with Nano flags. So there's always a rule-based fallback: ```typescript const getHeuristicAction = (data: TelemetryData): HotAction => { const { speedMph, throttle, brakePos, latG, longG } = data; if (brakePos > 30 && longG < -0.2) return { action: "THRESHOLD", color: "#ef4444" }; if (brakePos > 5 && Math.abs(latG) > 0.1) return { action: "TRAIL_BRAKE", color: "#ef4444" }; if (Math.abs(latG) > 0.3 && throttle < 40) return { action: "COMMIT", color: "#3b82f6" }; if (Math.abs(latG) > 0.15 && throttle < 60) return { action: "THROTTLE", color: "#f97316" }; if (throttle > 60 && Math.abs(latG) < 0.1) return { action: "PUSH", color: "#f97316" }; if (throttle < 15 && brakePos < 5 && speedMph > 50) return { action: "NO_COAST", color: "#eab308" }; return { action: "MAINTAIN", color: "#a855f7" }; }; ``` Tuned over hundreds of simulated laps. Not as smart as Nano, but works everywhere. ## Designing for the Real World Racing pushes hardware to the limit-and that made it the perfect stress test: - **High G-forces** taught us to secure every connection - **Thermal extremes** forced us to optimize for efficiency - **Remote locations** validated our offline-first edge architecture - **Split-second timing** proved the value of pre-cached responses Every constraint became a design feature. No connectivity? Edge inference. Synthesis latency? Pre-cached audio. No Nano support? Heuristic fallback. The environment forced good architecture. ## What's Next This was a fantastic AI field test, and there's definitely more to come. The pattern we validated-edge AI for reflexes, cloud AI for strategy, human expertise as ground truth-applies beyond racing: - Sports coaching - Surgical guidance - Head up display feedback - Agent with persona of the coach we meet in the room Any domain with real-time feedback and verified human expertise to learn from. ## Thank You Huge thanks to Ajeet Mirwani for organizing this and giving us the thrill of being in a race car. Taking agents to the track was unforgettable. And to the entire GDE team who collaborated across domains-AI, hardware, UX, racing-to make this happen. What an incredible effort. This is just the beginning. 🏎️ --- *Built as part of the GDE High-Velocity AI Field Test.* --- --- title: "Google Maps MCP with AgentU" description: "Connect your AI agents to Google Maps using the Model Context Protocol - search places, get weather, and compute routes." url: "https://h3manth.com/scribe/google-maps-mcp-with-agentu/" canonical_url: "https://h3manth.com/scribe/google-maps-mcp-with-agentu/" markdown_url: "https://h3manth.com/scribe/blog/google-maps-mcp-with-agentu.md" publishDate: "2025-12-17T08:00:00.000Z" author: "Hemanth HM" category: "python" tags: ["python","ai","agents","mcp","google-maps","agentu"] word_count: 760 reading_time_minutes: 4 x_markdown_tokens: 1454 content_signal: "ai-train=yes, search=yes, ai-input=yes" --- # Google Maps MCP with AgentU > Connect your AI agents to Google Maps using the Model Context Protocol - search places, get weather, and compute routes. Google just released their Maps MCP (Model Context Protocol) server, giving AI agents direct access to Places, Weather, and Routes APIs. Here's how to connect it with **AgentU** in under 10 lines of code. ## What is MCP? The Model Context Protocol is an open standard that lets AI agents connect to external tools and services. Instead of writing custom integrations, you just point your agent at an MCP server and it automatically discovers available tools. Google's Maps MCP server exposes three powerful tools: - **search_places** - Find businesses, landmarks, anything on Google Maps - **lookup_weather** - Get current weather conditions - **compute_routes** - Calculate directions between locations ## Prerequisites Before you start, you need to: ### 1. Enable the Maps MCP API ```bash # Set your Google Cloud project gcloud config set project YOUR_PROJECT_ID # Enable the MCP endpoint gcloud beta services mcp enable mapstools.googleapis.com ``` ### 2. Configure Your API Key Go to [Google Cloud Console Credentials](https://console.cloud.google.com/apis/credentials) and either: - Set your API key to "Don't restrict key", OR - Add "Maps Grounding Lite API" to the allowed APIs list ## The Code ```python import asyncio import json from agentu import Agent MAPS_MCP_URL = "https://mapstools.googleapis.com/mcp" MAPS_API_KEY = "your-google-maps-api-key" LLM_KEY = "your-llm-api-key" async def main(): agent = Agent( "maps agent", model="openai/gpt-oss-120b", api_key=LLM_KEY, api_base="https://api.groq.com/openai/v1" ).with_mcp([{ "url": MAPS_MCP_URL, "headers": {"X-Goog-Api-Key": MAPS_API_KEY} }]) result = await agent.infer("Find coffee shops near Times Square, New York") data = json.loads(result["result"]) print(data["summary"]) asyncio.run(main()) ``` That's it. The agent automatically: 1. Connects to the Google Maps MCP server 2. Discovers the available tools 3. Uses the LLM to decide which tool to call 4. Returns structured results with a natural language summary ## Example Output ``` Here are some coffee shops near Times Square: **Times Square Cafe** is a coffee shop located at 1657 Broadway, New York, NY 10019. It has a rating of 4.5 stars and is open 24 hours. **787 coffee** is a coffee shop located at 245 W 46th St, New York, NY 10036. It has a rating of 4.9 stars and offers outdoor seating. **Bibble & Sip** is a bakery and coffee shop located at 253 W 51st St, New York, NY 10019. It has a rating of 4.5 stars and serves breakfast. ``` ## How It Works The `.with_mcp()` method accepts a list of MCP server configurations. Each config can be: ```python # Simple URL agent.with_mcp(["http://localhost:3000"]) # URL with custom headers (like API keys) agent.with_mcp([{ "url": "https://mapstools.googleapis.com/mcp", "headers": {"X-Goog-Api-Key": "your-key"} }]) # Multiple servers agent.with_mcp([ "http://localhost:3000", {"url": "https://api.example.com/mcp", "headers": {"Auth": "token"}} ]) ``` When you call `.with_mcp()`, AgentU: 1. Sends an `initialize` request to establish the session 2. Calls `tools/list` to discover available tools 3. Registers each tool with your agent Then when you call `agent.infer()`, the LLM sees all available tools and picks the right one. ## Available Tools The Google Maps MCP server provides these tools: ### search_places Search for places using natural language queries. ```python result = await agent.infer("Find Italian restaurants in San Francisco") ``` ### lookup_weather Get current weather conditions for a location. ```python result = await agent.infer("What's the weather in Tokyo right now?") ``` ### compute_routes Calculate directions between locations. ```python result = await agent.infer("How do I get from LAX to Santa Monica?") ``` ## Troubleshooting ### 403 Forbidden Error If you get a 403 error, check these things in order: 1. **MCP endpoint not enabled**: Run the gcloud command above 2. **API key restrictions**: Make sure your key allows `mapstools.googleapis.com` 3. **Billing not enabled**: Google Maps APIs require a billing account ### "MCP_SERVER_DISABLED" Error This means you need to enable the MCP endpoint specifically: ```bash gcloud beta services mcp enable mapstools.googleapis.com --project=YOUR_PROJECT_ID ``` Note: This is different from enabling the regular Maps APIs. ## Why MCP? The Model Context Protocol is becoming the standard way for AI agents to interact with external services. Benefits include: - **Standardized interface**: One protocol for all tools - **Auto-discovery**: Agents learn what tools are available automatically - **Type safety**: Tools come with JSON schemas for parameters - **Vendor neutral**: Works with any LLM Google's Maps MCP is just the beginning. Expect more services to expose MCP endpoints as the ecosystem matures. ## Conclusion Connecting AI agents to Google Maps has never been easier. With AgentU and MCP: 1. **One line** to connect: `.with_mcp([...])` 2. **Zero tool registration**: Tools are discovered automatically 3. **Natural language**: Just ask what you want The combination of AgentU's simplicity and MCP's standardization makes building location-aware AI agents trivial. Get started: - [AgentU on GitHub](https://github.com/hemanth/agentu) - [Google Maps MCP Documentation](https://developers.google.com/maps) pip install agentu Happy mapping! 🗺️ --- --- title: "AI Agents Are The New Web Stack" description: "How modern AI agent architecture mirrors web engineering principles - from progressive loading to sandboxed execution in JS." url: "https://h3manth.com/scribe/ai-agents-web-architecture/" canonical_url: "https://h3manth.com/scribe/ai-agents-web-architecture/" markdown_url: "https://h3manth.com/scribe/blog/ai-agents-web-architecture.md" publishDate: "2025-11-19T09:00:00.000Z" author: "Hemanth HM" category: "ai" tags: ["ai","agents","architecture","web","mcp","cloudflare"] word_count: 1019 reading_time_minutes: 6 x_markdown_tokens: 1879 content_signal: "ai-train=yes, search=yes, ai-input=yes" --- # AI Agents Are The New Web Stack > How modern AI agent architecture mirrors web engineering principles - from progressive loading to sandboxed execution in JS. If you've been building web applications for the past decade, the emerging patterns in AI agent architecture might feel strangely familiar. That's because AI agents are evolving into full-stack systems that optimize token flow the same way we've been optimizing bandwidth and render time in web engineering. Recent innovations from Anthropic's MCP (Model Context Protocol) code execution and Cloudflare's code mode design reveal a fascinating convergence: **AI agent architecture is starting to look a lot like web engineering**. ## The Parallel Architecture Patterns Let me walk you through five striking parallels that show how AI agents are borrowing from decades of web performance optimization: ### 1. Progressive Tool Loading → Lazy Loading Remember when we stopped bundling everything into one massive JavaScript file? The same principle applies to AI agents now. **In Web Engineering:** Instead of loading all JavaScript upfront, we lazy load modules only when users need them. This reduces initial bundle size and speeds up page load times. **In AI Agents:** Progressive tool loading means agents don't load every possible tool into context at startup. Tools are loaded on-demand based on the task at hand, reducing token overhead and improving response latency. ```javascript // Web: Lazy loading a module const module = await import('./heavy-feature.js'); // Agents: Progressive tool loading via MCP agent.loadTool('code-execution', { onDemand: true }); ``` ### 2. Token & Latency Efficiency → Compress + Cache Context Just as we compress assets and cache responses to save bandwidth, agents now compress and cache context to save tokens. **In Web Engineering:** We use gzip/brotli compression for assets, CDN caching for static content, and service workers for offline caching. Every byte saved is latency reduced. **In AI Agents:** Context is the new payload. Compressing conversation history, caching frequently used prompts, and reusing tool definitions across sessions - all of this reduces token consumption and improves response times. ```python # Web: Response compression response.headers['Content-Encoding'] = 'gzip' # Agents: Context compression agent.compress_context(history, max_tokens=2000) ``` ### 3. Pre-Context Filtering → Edge Filtering / GraphQL Field Selection We've learned to filter data at the edge rather than transferring everything and filtering client-side. Agents are learning the same lesson. **In Web Engineering:** CloudFlare Workers filter requests at the edge. GraphQL lets clients request exactly the fields they need, nothing more. **In AI Agents:** Pre-context filtering means determining what information is relevant *before* sending it to the model. This is like asking "what does the agent actually need to know?" instead of dumping entire databases into context. ```graphql # Web: GraphQL field selection query { user { name email # Only fetch what we need } } # Agents: Pre-context filtering agent.filter_context(query, relevant_fields=['name', 'email']) ``` ### 4. Reusable Stateful Logic → Service Workers & Modular Components Component-based architecture revolutionized web development. Now it's revolutionizing agent development. **In Web Engineering:** React components, Vue modules, and service workers let us write reusable, stateful logic once and use it everywhere. **In AI Agents:** Reusable tools and skills are the agent equivalent of web components. Define a tool once (like "fetch data from API" or "analyze code"), and every agent can use it. MCP servers are essentially service workers for AI agents. ```javascript // Web: Reusable component function UserCard({ user }) { return
{user.name}
} // Agents: Reusable tool @tool def fetch_user_data(user_id: str) -> dict: return api.get_user(user_id) ``` ### 5. Sandboxed Execution → Browser-Level Isolation and CSP Security through isolation isn't new - we've been doing it in browsers for years with iframes and Content Security Policy. **In Web Engineering:** Browsers sandbox JavaScript execution. CSP prevents XSS attacks. iframes isolate third-party content. **In AI Agents:** Code execution needs the same level of isolation. When an agent runs user-generated code or external tools, it needs to be sandboxed to prevent malicious actions - just like a browser sandboxes untrusted JavaScript. ```javascript // Web: Content Security Policy // Agents: Sandboxed execution agent.execute_code(user_code, sandbox={ 'network': False, 'filesystem': 'read-only' }) ``` ## Graceful Degradation vs Progressive Enhancement: The Agent Edition Remember the old debates about graceful degradation vs progressive enhancement in web design? **Graceful Degradation:** Build for the best-case scenario (full context, all tools), then handle failures when resources are limited. **Progressive Enhancement:** Start with a minimal viable agent (basic tools, limited context), then enhance capabilities as resources allow. The AI agent community is going through the same evolution. Early agents tried to load everything (graceful degradation). Modern agents start minimal and scale up (progressive enhancement). ## Full-Stack Agents: The New Reality AI agents are becoming full-stack systems: - **Frontend:** Natural language interface (the new UI) - **Backend:** Tool execution and API calls (the new services) - **Cache Layer:** Context and tool result caching (the new Redis) - **Edge Computing:** Pre-filtering and compression (the new CDN) - **Security:** Sandboxed execution (the new firewall) We're not just building chatbots anymore. We're building distributed systems that happen to use language models as their compute layer. ## What This Means For Developers If you're a web developer looking to build AI agents, you already have most of the mental models you need: 1. **Think in Components:** Tools are like React components - reusable, composable, and stateful. 2. **Optimize for Latency:** Tokens are the new bytes. Minimize context like you minimize bundle size. 3. **Cache Aggressively:** Repeated context is like repeated network requests - cache it. 4. **Filter Early:** Pre-context filtering is like edge computing - process close to the source. 5. **Sandbox Everything:** Untrusted code execution needs isolation, period. ## Conclusion The convergence of AI agent architecture and web engineering principles isn't a coincidence. Both fields are solving similar problems: **how to efficiently deliver compute over a network while managing resource constraints and security concerns**. As AI agents continue to evolve, we'll likely see even more patterns borrowed from web engineering: load balancing across model instances, circuit breakers for failing tools, observability and tracing for agent workflows, and more. The future of AI isn't just about better models - it's about better architecture. And fortunately, we've been practicing that architecture in web engineering for decades. The agents are here. And they're running on the same principles that power the modern web. --- --- title: "AgentU: The Sleekest Way to Build AI Agents" description: "A minimalist Python framework that makes building AI agent workflows as simple as chaining operators - no complex in JS fast." url: "https://h3manth.com/scribe/agentu-sleek-ai-agent-framework/" canonical_url: "https://h3manth.com/scribe/agentu-sleek-ai-agent-framework/" markdown_url: "https://h3manth.com/scribe/blog/agentu-sleek-ai-agent-framework.md" publishDate: "2025-11-09T10:00:00.000Z" author: "Hemanth HM" category: "python" tags: ["python","ai","agents","workflows","llm","opensource"] word_count: 1022 reading_time_minutes: 6 x_markdown_tokens: 2027 content_signal: "ai-train=yes, search=yes, ai-input=yes" --- # AgentU: The Sleekest Way to Build AI Agents > A minimalist Python framework that makes building AI agent workflows as simple as chaining operators - no complex in JS fast. After building dozens of AI agents, I realized most frameworks were overengineered. What if building agents could be as simple as chaining functions? That's why I built **AgentU** - a minimalist Python framework where `>>` chains steps and `&` runs them in parallel. ## The Problem with Existing Frameworks Most AI agent frameworks make you learn complex concepts: orchestrators, tasks, execution modes, message passing. But at the end of the day, you're just trying to: 1. Call some tools 2. Chain them together 3. Maybe run some in parallel Why should that require hundreds of lines of boilerplate? ## AgentU: Radical Simplicity ```python from agentu import Agent # Create an agent agent = Agent("assistant").with_tools([search_products, check_inventory]) # Direct execution - call a specific tool result = await agent.call("search_products", {"query": "laptop"}) # Natural language - let the LLM figure it out result = await agent.infer("Find me laptops under $1500 and check stock") ``` That's it. No orchestrators. No complex setup. Just agents and tools. ## Workflows in 3 Lines Here's where AgentU gets powerful: ```python # Sequential: researcher → analyst → writer workflow = researcher("Find AI trends") >> analyst("Analyze") >> writer("Summarize") # Parallel: run 3 searches concurrently workflow = search("AI") & search("ML") & search("Crypto") # Combined: parallel then merge workflow = (search("AI") & search("ML") & search("Crypto")) >> analyst("Compare") result = await workflow.run() ``` **`>>` chains steps sequentially. `&` runs them in parallel.** That's the entire workflow API. ## Real-World Example: Automated Code Review Let me show you a real use case - automated PR reviews that run code analysis and tests in parallel: ```python import asyncio from agentu import Agent def get_pr_diff(pr_number: int) -> str: """Fetch PR changes from GitHub.""" return github_api.get_diff(pr_number) def run_tests(branch: str) -> dict: """Run test suite.""" return {"passed": 47, "failed": 2, "coverage": 94.2} def post_comment(pr_number: int, comment: str) -> bool: """Post review comment to GitHub.""" return github_api.create_comment(pr_number, comment) async def main(): # Setup agents with specific tools reviewer = Agent("reviewer", model="gpt-4").with_tools([get_pr_diff]) tester = Agent("tester").with_tools([run_tests]) commenter = Agent("commenter").with_tools([post_comment]) # Parallel: review code + run tests (saves time!) workflow = reviewer("Review PR #247") & tester("Run tests on PR #247") code_review, test_results = await workflow.run() # Natural language: synthesize findings summary = await commenter.infer( f"Create a review comment for PR #247. " f"Code review: {code_review}. Tests: {test_results}. " f"Be constructive and specific." ) # Post to GitHub await commenter.call("post_comment", {"pr_number": 247, "comment": summary}) print("✓ Review posted to PR #247") asyncio.run(main()) ``` **What this does:** - Reviews code and runs tests **in parallel** (cuts time in half) - Uses `infer()` to write **human-quality review comments** via LLM - Posts directly to GitHub - **Zero manual work** - runs on every PR ## Memory: Simple and Persistent ```python # Store memories with importance weighting agent.remember("Customer prefers email communication", importance=0.9) agent.remember("Uses dark mode", importance=0.5) # Search memories semantically memories = agent.recall(query="communication preferences") # Returns: ["Customer prefers email communication"] ``` Stored in SQLite. Searchable. Persistent across sessions. No vector database complexity unless you need it. ## Lambda Control for Precise Data Flow Need fine-grained control over how data flows between steps? ```python workflow = ( researcher("Find top AI companies") >> analyst(lambda prev: f"Extract names from: {prev['result']}") >> writer(lambda prev: f"Write report about: {prev['companies']}") ) ``` Lambdas let you transform output from one step before passing to the next. ## LLM Support: Auto-Detection + Flexibility AgentU **auto-detects available models** from Ollama: ```python # Auto-detect (uses first available Ollama model) Agent("assistant") # Or specify explicitly Agent("assistant", model="qwen3") # Works with OpenAI Agent("assistant", model="gpt-4", api_key="sk-...") # Works with vLLM, LM Studio, anything OpenAI-compatible Agent("assistant", model="mistral", api_base="http://localhost:8000/v1") ``` Version 1.0.1 added automatic Ollama model detection via the `/api/tags` endpoint, so you don't have to hardcode model names. ## MCP Integration Connect to Model Context Protocol servers for extended capabilities: ```python agent.with_mcp(["http://localhost:3000"]) agent.with_mcp([{"url": "https://api.com/mcp", "headers": {"Auth": "token"}}]) ``` ## REST API in One Line Want to expose your agent as an API? ```python from agentu import serve serve(agent, port=8000) ``` Auto-generates Swagger docs at `/docs`. Includes endpoints for: - `/execute` - direct tool execution - `/process` - natural language inference - `/tools` - list available tools - `/memory/remember` - store memories - `/memory/recall` - search memories ```bash curl -X POST localhost:8000/execute \ -d '{"tool_name": "search_products", "params": {"query": "laptop"}}' ``` ## Design Philosophy AgentU was built on three principles: 1. **Minimalism**: If you can do it in one line, you should only need one line 2. **Composability**: Agents are functions. Functions compose. So should agents. 3. **No Magic**: Every operator (`>>`, `&`) has clear, predictable behavior The 1.0.0 release removed the entire `Orchestrator` system and replaced it with simple operators. **400+ lines of code deleted.** The API got cleaner and more powerful. ## What Changed in 1.0 Version 1.0 was a **major simplification**: **Removed:** - `Orchestrator`, `ExecutionMode`, `Task`, `Message` classes - `add_tool()`, `add_tools()`, `add_agent()`, `add_agents()` methods - `execute_tool()` and `process_input()` methods **Added:** - Workflow operators (`>>` sequential, `&` parallel) - `Agent.__call__()` to create steps - Lambda support for data flow control - Auto-detection of Ollama models (v1.0.1) The result? **More power, less code.** ## Getting Started pip install agentu Check out the examples: ```bash git clone https://github.com/hemanth/agentu cd agentu python examples/basic.py # Simple agent python examples/workflow.py # Workflows python examples/memory.py # Memory system python examples/api.py # REST API ``` ## When to Use AgentU AgentU is perfect for: - **Automation workflows** (CI/CD, code review, data pipelines) - **Research agents** (gather → analyze → summarize) - **Customer support** (routing, memory, context) - **Prototyping** (get from idea to working agent in minutes) It's **not** a full-fledged production platform like LangChain. If you need a sprawling ecosystem of integrations, look elsewhere. But if you want to build agents **fast** with **clean code**, AgentU is for you. ## Conclusion Building AI agents shouldn't require learning a new framework every month. It should feel like writing Python. AgentU gives you: - **3-line workflows** with `>>` and `&` - **Direct execution** with `call()` - **Natural language routing** with `infer()` - **Persistent memory** with `remember()` / `recall()` - **REST API** with `serve()` That's the entire API. No orchestrators. No message buses. Just agents doing what agents do best. Try it: [github.com/hemanth/agentu](https://github.com/hemanth/agentu) The sleekest way to build AI agents is here. --- --- title: "git-tips: A Decade of Open Source Impact" description: "How a simple list of Git tricks became a top 0.01% GitHub repo. Practical notes and code examples on git-tips: A Decade of." url: "https://h3manth.com/scribe/git-tips-success/" canonical_url: "https://h3manth.com/scribe/git-tips-success/" markdown_url: "https://h3manth.com/scribe/blog/git-tips-success.md" publishDate: "2025-05-29T00:00:00.000Z" author: "Hemanth HM" category: "opensource" tags: ["git","opensource","github","success"] word_count: 135 reading_time_minutes: 1 x_markdown_tokens: 287 content_signal: "ai-train=yes, search=yes, ai-input=yes" --- # git-tips: A Decade of Open Source Impact > How a simple list of Git tricks became a top 0.01% GitHub repo. Practical notes and code examples on git-tips: A Decade of. A decade ago, I started git-tips as a side project - just a simple list of git tricks. Over the years, it went viral on GitHub multiple times, earned ✨ 21.6k+ stars, 1.7k+ forks, and got translated into 8 languages. Even though searching for "git tips" on Google shows my repo as the first in the results, I assumed it had long faded into the archives of the internet... Until a few weeks ago, when I got an unexpected email from a developer at Cognition (creators of Devin), saying: > "I analyzed over 28 million public repos, and yours was in the top 0.01%!" 🤯 Just wow. It's humbling to see how free and open-source software can keep making ripples years after its creation. The community truly makes all the difference ❤️ Repo 👉 [https://git.io/git-tips](https://git.io/git-tips) --- --- title: "Deepseek Reason Extractor" description: "Extract just the reasoning data from deepseek. Practical notes and code examples on Deepseek Reason Extractor by Hemanth HM." url: "https://h3manth.com/scribe/deepseek-reason-extractor/" canonical_url: "https://h3manth.com/scribe/deepseek-reason-extractor/" markdown_url: "https://h3manth.com/scribe/blog/deepseek-reason-extractor.md" publishDate: "2025-01-27T08:33:00.000Z" author: "Hemanth HM" category: "python" tags: ["deepseek","reasoning","extractor","python","pip"] word_count: 383 reading_time_minutes: 2 x_markdown_tokens: 829 content_signal: "ai-train=yes, search=yes, ai-input=yes" --- # Deepseek Reason Extractor > Extract just the reasoning data from deepseek. Practical notes and code examples on Deepseek Reason Extractor by Hemanth HM. ## Introduction Large language models like Deepseek are powerful tools, but often their output includes more than just the core reasoning. When you need to extract *just* the reasoning from Deepseek's responses, this Python package, `deepseek_reason_extractor`, provides a simple and effective solution. This tool is designed to streamline the process of getting to the heart of Deepseek's thought process, filtering out extraneous text and focusing solely on the logical steps and conclusions. Whether you're analyzing model behavior, building applications that rely on clear reasoning, or simply want to understand how Deepseek arrives at its answers, this extractor can be invaluable. ## Installation pip install deepseek_reason_extractor ## Usage and What it Does The `deepseek_reason_extractor` library simplifies the process of extracting pure reasoning from Deepseek models. It handles the API interactions and response parsing, allowing you to focus on utilizing the extracted reasoning in your applications or analyses. **Key Features:** * **Reasoning Isolation:** Specifically targets and extracts the core reasoning segments from Deepseek's output, discarding introductory and concluding remarks or other extraneous information. * **Customizable:** Allows you to configure the API endpoint, model name, API key, and system prompt, providing flexibility for different Deepseek setups and use cases. * **Easy Integration:** Simple Python API makes it straightforward to incorporate reasoning extraction into your existing workflows. **How it Works:** Under the hood, the `DeepseekReasonExtractor` class sends a request to the Deepseek API with your provided prompt and configuration. It then intelligently processes the API response to identify and isolate the sections containing the model's reasoning. The extracted reasoning is returned as a clean string, ready for further use. ```python from deepseek_reason_extractor import DeepseekReasonExtractor # Initialize with default settings extractor = DeepseekReasonExtractor( api_key="your-api-key" # Optional if endpoint doesn't require auth ) # Extract reasoning prompt = "Explain the concept of quantum entanglement" reasoning = extractor.extract_reasoning(prompt) print(reasoning) ``` ## Configuration You can customize the endpoint, model, and system prompt to tailor the extractor to your specific needs: ```python extractor = DeepseekReasonExtractor( endpoint="http://custom.endpoint/v1/chat/completions", model_name="custom-model", api_key="your-api-key", system_prompt="You are a helpful AI assistant" ) ``` ## Conclusion `deepseek_reason_extractor` is a valuable tool for anyone working with Deepseek models and needing to programmatically access and utilize their reasoning capabilities. By providing a clean and focused way to extract reasoning, this library can enhance your projects and analyses involving Deepseek's powerful language models. --- --- title: "vaklm - Python Client for OpenAI-Compatible APIs" description: "A Python client for interacting with OpenAI-compatible API endpoints with reasoning support. Practical notes and code in JS." url: "https://h3manth.com/scribe/vaklm/" canonical_url: "https://h3manth.com/scribe/vaklm/" markdown_url: "https://h3manth.com/scribe/blog/vaklm.md" publishDate: "2025-01-26T13:28:47.050Z" author: "Hemanth HM" category: "python" tags: ["python","ai","api","openai"] word_count: 369 reading_time_minutes: 2 x_markdown_tokens: 886 content_signal: "ai-train=yes, search=yes, ai-input=yes" --- # vaklm - Python Client for OpenAI-Compatible APIs > A Python client for interacting with OpenAI-compatible API endpoints with reasoning support. Practical notes and code in JS. vaklm was created to simplify intecctions with OpenAI-compatible APIs, providing a cleaner alternative to the verbose `client.chat.completions.create` pattern. This Python client offers a more intuitive interface while adding valuable reasoning capabilities to API responses. vaklm is designed to make working with AI APIs more efficient and developer-friendly, providing an easy way to interact with OpenAI-compatible API endpoints while supporting reasoning capabilities. ## Installation pip install vaklm ## Usage ### Basic Usage from vaklm import vaklm, VAKLMException try: content, reasoning = vaklm( endpoint="http://localhost:11434/v1/chat/completions", model_name="llama3.2:latest", user_prompt="Explain quantum computing in simple terms", system_prompt="You are a helpful AI assistant", api_key="YOUR_API_KEY", temperature=0.7 ) print("Content:", content) print("Reasoning:", reasoning) except VAKLMException as e: print(f"Error: {str(e)}") ### Streaming Usagepython from vaklm import vaklm print("\nStreaming example:") try: for content, reasoning in vaklm( endpoint="http://localhost:11434/v1/chat/completions", model_name="llama3.2:latest", user_prompt="Write a short story about a cat.", system_prompt="You are a creative writer.", api_key="YOUR_API_KEY", stream=True, temperature=0.7 ): print(content, end='', flush=True) if reasoning: print(f"\n[Reasoning: {reasoning}]") except VAKLMException as e: print(f"Error: {str(e)}") ``` ## Features - Supports both streaming and non-streaming responses - Includes reasoning content in responses - Automatic retry logic for failed requests - Configurable temperature and max tokens - System prompt support for context setting - Comprehensive error handling ## Configuration The `vaklm` function accepts the following parameters: - `endpoint`: API endpoint URL (required) - `model_name`: Model identifier (required) - `user_prompt`: User's input message (required) - `system_prompt`: Optional system context message - `api_key`: API key for authentication - `stream`: Whether to stream the response (default: False) - `temperature`: Sampling temperature (0-2, default: 1.0) - `max_tokens`: Maximum tokens to generate - `timeout`: Request timeout in seconds (default: 30) - `max_retries`: Maximum retry attempts (default: 3) - `retry_delay`: Base delay between retries (default: 1.0) ## Error Handling The client raises `VAKLMException` for general errors, with specific subclasses: - `APIError`: For API-specific errors - `StreamingError`: For streaming-specific errors Always wrap calls in try/except blocks to handle potential errors. `vaklm` provides a cleaner, more intuitive way to work with OpenAI-compatible APIs while adding valuable reasoning capabilities. By simplifying the API interaction pattern and adding features like automatic retries and streaming support, VAKLM helps developers focus on building great AI-powered applications rather than wrestling with API boilerplate. Give it a try in your next project and experience the difference! --- --- title: "piragi: The Best RAG Interface Yet" description: "A zero-config RAG library that works with local models out of the box - no API keys, no vector database setup, just three." url: "https://h3manth.com/scribe/piragi-best-rag-interface/" canonical_url: "https://h3manth.com/scribe/piragi-best-rag-interface/" markdown_url: "https://h3manth.com/scribe/blog/piragi-best-rag-interface.md" publishDate: "2025-01-10T10:00:00.000Z" author: "Hemanth HM" category: "python" tags: ["python","rag","ai","llm","embeddings","vector-search","opensource"] word_count: 1253 reading_time_minutes: 7 x_markdown_tokens: 2503 content_signal: "ai-train=yes, search=yes, ai-input=yes" --- # piragi: The Best RAG Interface Yet > A zero-config RAG library that works with local models out of the box - no API keys, no vector database setup, just three. Building a RAG (Retrieval Augmented Generation) system usually means: 1. Setting up a vector database 2. Configuring embeddings 3. Chunking documents 4. Managing API keys 5. Writing update logic What if all of that disappeared into three lines? ```python from piragi import Ragi kb = Ragi(["./docs", "./code/**/*.py", "https://api.example.com/docs"]) answer = kb.ask("How do I deploy this?") ``` That's **piragi** (pronounced "pee-rah-gee") - **R**etrieval **A**ugmented **G**eneration **I**nterface. Built-in vector store, embeddings, citations, and auto-updates. Free and local by default. ## The Problem: RAG is Too Complex Every RAG tutorial starts the same way: > "First, install ChromaDB/Pinecone/Weaviate. Then configure OpenAI embeddings. Now chunk your documents. Set up a background worker for updates..." By the time you're done, you've written 200+ lines of boilerplate just to ask questions about your docs. Most developers don't need distributed vector databases or fancy reranking algorithms. They just want to: - Point at some documents - Ask questions - Get answers with sources ## piragi: Zero to RAG in 3 Lines ```python from piragi import Ragi kb = Ragi("./docs") answer = kb("What is this?") ``` That's it. No configuration. No API keys. No vector database setup. **What just happened:** - Documents auto-chunked with markdown-aware splitting - Embeddings generated locally (all-mpnet-base-v2, ~420MB) - Vector database created (LanceDB, stored in `.piragi/`) - LLM queries routed to local Ollama (llama3.2) - Citations included automatically All free. All local. All automatic. ## Universal Document Support piragi handles everything: ```python kb = Ragi([ "./docs/**/*.md", # Markdown "./specs/*.pdf", # PDFs "./data/*.xlsx", # Excel "./code/**/*.py", # Code "https://api.docs.com", # URLs "./audio/*.mp3", # Audio transcription "./images/*.png" # Image OCR ]) answer = kb("Summarize all the technical specs") ``` **Supported formats:** - Documents: PDF, Word, Excel, Markdown, Text - Code: Python, JavaScript, Java, Go, Rust, etc. - Web: URLs (auto-crawls and extracts text) - Media: Images (OCR), Audio (transcription) piragi figures out the format and processes it correctly. No manual loaders. ## Auto-Updates: Never Stale Traditional RAG systems get stale. Documents change, but your vector database doesn't know. piragi watches your sources in the background: ```python kb = Ragi(["./docs", "https://api.docs.com"]) # Auto-updates enabled by default # Edit a file in ./docs # piragi detects change via mtime + hash # Reprocesses chunk in background # Queries continue uninterrupted ``` **How it works:** - Files: Tracks modification time + content hash - URLs: Periodic HTTP HEAD checks - Background workers: Updates happen async - Zero query latency: Queries never block on updates Disable if you don't need it: ```python kb = Ragi("./docs", config={"auto_update": {"enabled": False}}) ``` ## Smart Citations Every answer includes ranked sources: ```python kb = Ragi("./docs") result = kb.ask("How does authentication work?") print(result["answer"]) # "The system uses OAuth2 with JWT tokens. Users authenticate via..." print(result["sources"]) # [ # {"file": "auth.md", "chunk": "OAuth2 implementation...", "score": 0.89}, # {"file": "security.pdf", "chunk": "JWT token format...", "score": 0.82}, # {"file": "api.md", "chunk": "Authentication endpoints...", "score": 0.76} # ] ``` Citations show: - **Source file/URL** - **Relevant chunk** (the actual text used) - **Similarity score** (0-1, higher = more relevant) You know exactly where the answer came from. ## Query Expansion & Reranking Version 0.1.4 added advanced retrieval: ```python # Your query: "deployment steps" # Expanded to: ["deployment steps", "how to deploy", "deployment process", "release workflow"] # Results retrieved for all variations # Reranked by combining vector similarity + keyword matching # Top results used for answer generation ``` **Why this matters:** - Better recall: Catches relevant docs even with different phrasing - Better precision: Reranking filters noise - Better citations: Sources are actually relevant Configure if needed: ```python kb = Ragi("./docs", config={ "llm": { "enable_reranking": True, "enable_query_expansion": True, "temperature": 0.1 # Lower = more focused } }) ``` ## Metadata Filtering Filter results by document properties: ```python kb = Ragi("./docs") # Only search PDFs kb.filter(file_type="pdf").ask("What's in the PDFs?") # Only recent documents kb.filter(modified_after="2025-01-01").ask("What changed recently?") # Only code files kb.filter(file_extension=".py").ask("How is this implemented?") ``` Filtering happens at the vector search level, so results are fast and relevant. ## OpenAI Compatibility Use GPT-4 or any OpenAI-compatible API: ```python # OpenAI (LLM only, local embeddings) kb = Ragi("./docs", config={ "llm": { "model": "gpt-4o-mini", "api_key": "sk-...", "base_url": "https://api.openai.com/v1" } }) # OpenAI for both LLM and embeddings kb = Ragi("./docs", config={ "llm": { "model": "gpt-4o-mini", "api_key": "sk-..." }, "embedding": { "model": "text-embedding-3-small", "base_url": "https://api.openai.com/v1", "api_key": "sk-..." } }) ``` Works with: - OpenAI - Azure OpenAI - Together AI - Anyscale - Any OpenAI-compatible endpoint ## Embedding Model Options Default embedding model is `all-mpnet-base-v2` (~420MB, good quality). **Want smaller?** ```python kb = Ragi("./docs", config={ "embedding": {"model": "all-MiniLM-L6-v2"} # ~90MB, decent quality }) ``` **Want maximum quality?** ```python kb = Ragi("./docs", config={ "embedding": {"model": "nvidia/llama-embed-nemotron-8b"} # ~8GB, best quality }) ``` **Want remote embeddings?** ```python kb = Ragi("./docs", config={ "embedding": { "model": "text-embedding-3-small", "base_url": "https://api.openai.com/v1", "api_key": "sk-..." } }) ``` piragi auto-detects whether embeddings should be local (sentence-transformers) or remote (API call). ## Real-World Example: Code Q&A ```python from piragi import Ragi # Index entire codebase kb = Ragi([ "./src/**/*.py", "./docs/*.md", "./README.md", "./CHANGELOG.md" ]) # Ask about implementation result = kb.ask("How does the auto-update system work?") print(result["answer"]) # "The auto-update system uses background workers to detect changes..." # Get specific citations for source in result["sources"][:3]: print(f"\nSource: {source['file']}") print(f"Chunk: {source['chunk'][:100]}...") print(f"Score: {source['score']:.2f}") ``` Output: ``` Source: src/auto_update.py Chunk: The UpdateWorker class runs in a separate thread, checking for file changes every 300 seconds... Score: 0.91 Source: docs/architecture.md Chunk: Auto-updates are implemented using a background worker pool that monitors source files... Score: 0.84 Source: CHANGELOG.md Chunk: Version 0.1.0 added auto-updates with background workers and change detection... Score: 0.78 ``` You know exactly where the answer came from and how confident the system is. ## API Overview ```python # Initialize kb = Ragi(sources, persist_dir=".piragi", config=None) # Add more sources kb.add("./more-docs") # Ask questions result = kb.ask(query, top_k=5) # Shorthand result = kb(query) # Filter + ask result = kb.filter(file_type="pdf").ask(query) # Count documents count = kb.count() # Clear database kb.clear() ``` Full API docs: [API.md](https://github.com/hemanth/ragi/blob/main/API.md) ## Version History **v0.1.5** (Latest) - Fixed chunking bugs, added minimum chunk length filter **v0.1.4** - Added query expansion and reranking **v0.1.3** - Fixed schema mismatches for mixed sources **v0.1.2** - Changed default embedding to all-mpnet-base-v2 (prevents memory crashes) **v0.1.1** - Renamed module from `ragi` to `piragi` **v0.1.0** - Initial release with auto-updates, citations, universal format support ## Installation ```bash pip install piragi # Optional: Install Ollama for local LLM curl -fsSL https://ollama.com/install.sh | sh ollama pull llama3.2 ``` ## Design Philosophy piragi was built on three principles: 1. **Zero Configuration**: Works out of the box with free local models 2. **Universal Support**: Any document format, any LLM/embedding provider 3. **Always Fresh**: Auto-updates keep your knowledge base current You shouldn't need a PhD in vector search to ask questions about your docs. ## When to Use piragi piragi is perfect for: - **Internal documentation search** (company wikis, API docs) - **Code Q&A** (ask questions about codebases) - **Research assistants** (query papers, articles, reports) - **Customer support** (search knowledge bases) It's **not** for: - Web-scale search (millions of documents) - Real-time streaming updates - Complex multi-modal reasoning For those use cases, you need LangChain, LlamaIndex, or custom infrastructure. But if you just want to ask questions about your docs? piragi is the fastest way from zero to working RAG. ## Conclusion RAG doesn't have to be complex. You don't need distributed databases, custom chunking algorithms, or manual update scripts. You just need: ```python kb = Ragi("./docs") answer = kb("What is this?") ``` Three lines. Free. Local. With citations. Try it: [github.com/hemanth/ragi](https://github.com/hemanth/ragi) The best RAG interface yet. --- --- title: "OllamaFunctions and Mistral" description: "Extracting structured data from text using OllamaFunctions and Mistral. Practical notes and code examples on OllamaFunctions." url: "https://h3manth.com/scribe/ollamafunctions-mistral/" canonical_url: "https://h3manth.com/scribe/ollamafunctions-mistral/" markdown_url: "https://h3manth.com/scribe/blog/ollamafunctions-mistral.md" publishDate: "2024-05-18T00:00:00.000Z" author: "Hemanth HM" category: "ai" tags: ["langchain","ollama","mistral","ai"] word_count: 357 reading_time_minutes: 2 x_markdown_tokens: 744 content_signal: "ai-train=yes, search=yes, ai-input=yes" --- # OllamaFunctions and Mistral > Extracting structured data from text using OllamaFunctions and Mistral. Practical notes and code examples on OllamaFunctions. This blog post demonstrates how to use LangChain, OllamaFunctions and the Mistral model to extract structured data from unstructured text. We'll start with a simple example, extracting information about a person from a text block. ## Prerequisites - Python 3.7 or higher - LangChain (install using pip install langchain_experimental -qU) pip install langchain_experimental -qU ## Code ```python from langchain_experimental.llms.ollama_functions import OllamaFunctions from langchain.chains import create_extraction_chain # Define the text data=""" Born May 11, 1918 Richard Phillips Feynman New York City, U.S. Died February 15, 1988 (aged 69) Los Angeles, California, U.S. Resting place Mountain View Cemetery and Mausoleum Education Massachusetts Institute of Technology (SB) Princeton University (PhD) """ # Define the schema for the extracted data schema = { "properties": { "name": {"type": "string"}, "born": {"type": "date"}, "died": {"type": "date"}, "city": {"type": "string"}, "education": {"type": "string"}, "resting_place": {"type":"string"} }, "required": ["name", "year"], } # Initialize the OllamaFunctions LLM llm = OllamaFunctions(model="mistral", temperature=0) # Create the extraction chain chain = create_extraction_chain(schema, llm) # Run the chain on the data result = chain.run(data) # Print the extracted data print(result) ## Output python [{ 'name': 'Richard Phillips Feynman', 'born': 'May 11, 1918', 'city': 'New York City, U.S.', 'died': 'February 15, 1988 (aged 69)', 'resting_place': 'Mountain View Cemetery and Mausoleum', 'education': 'Massachusetts Institute of Technology (SB) Princeton University (PhD)' }] ``` ## Explanation - We define a schema with the expected fields and types for the extracted data. - We instantiate an `OllamaFunctions` LLM using the Mistral model. - We create an `extraction_chain` using the schema and the LLM. - The chain is run on the input text. - The output is a list of dictionaries, each dictionary representing an extracted data point. ## Key Takeaways - OllamaFunctions provides a simple and convenient way to use Mistral with LangChain. - The `create_extraction_chain` function allows for easy data extraction based on a defined schema. - The resulting structured data can be used for further processing and analysis. This example demonstrates the power of LangChain, OllamaFunctions, and Mistral for extracting structured data from text. You can easily adapt this approach to different data formats and schemas to extract information from various text sources. --- ## Archive Catalog (2007–2023) — Fetch individual `.md` URLs for full body - **Well-known Symbols** (2023-02-14) | HTML: https://h3manth.com/scribe/well-known-symbols/ | Markdown: https://h3manth.com/scribe/blog/well-known-symbols.md | Tags: javascript, symbols, es6 A deep dive into Well-known Symbols in JavaScript. Practical notes and code examples on Well-known Symbols by Hemanth HM. - **Navigation API** (2022-04-13) | HTML: https://h3manth.com/scribe/navigation-api/ | Markdown: https://h3manth.com/scribe/blog/navigation-api.md | Tags: javascript, web, navigation, spa The Navigation API provides an interface for navigations and session history, especially useful for SPAs. Practical notes. - **AbortSignal throwIfAborted** (2022-04-07) | HTML: https://h3manth.com/scribe/abortsignal-throwifaborted/ | Markdown: https://h3manth.com/scribe/blog/abortsignal-throwifaborted.md | Tags: javascript, web, dom, abort If the signal has been aborted, throw the signal’s abort reason. Practical notes and code examples on AbortSignal in JS fast. - **HTTP Imports on Node** (2022-02-11) | HTML: https://h3manth.com/scribe/http-imports-node/ | Markdown: https://h3manth.com/scribe/blog/http-imports-node.md | Tags: node, javascript, esm, http Node.js gets ESM import support over HTTPS remotely and HTTP locally. Practical notes and code examples on HTTP Imports on. - **HTTP Request in Postgres** (2022-01-20) | HTML: https://h3manth.com/scribe/http-request-postgres/ | Markdown: https://h3manth.com/scribe/blog/http-request-postgres.md | Tags: postgres, db, http, sql Fetching data over HTTP in PostgreSQL using the http extension. Practical notes and code examples on HTTP Request in in JS. - **Unicode Segmentation in JavaScript** (2021-10-25) | HTML: https://h3manth.com/scribe/unicode-segmentation-in-javascript/ | Markdown: https://h3manth.com/scribe/blog/unicode-segmentation-in-javascript.md | Tags: javascript, intl, unicode, i18n What is Intl.Segmenter and how to use it for Unicode text segmentation. Practical notes and code examples on Unicode in JS. - **HDR CSS MediaQuery** (2021-10-07) | HTML: https://h3manth.com/scribe/hdr-css-mediaquery/ | Markdown: https://h3manth.com/scribe/blog/hdr-css-mediaquery.md | Tags: css, web, hdr, media-queries CSS4’s dynamic-range and video-dynamic-range feature for HDR displays. Practical notes and code examples on HDR CSS in JS. - **Primordials in Node.js** (2021-09-09) | HTML: https://h3manth.com/scribe/primordials-in-node/ | Markdown: https://h3manth.com/scribe/blog/primordials-in-node.md | Tags: node, javascript, internals What are Primordials in Node.js and why do they exist? Practical notes and code examples on Primordials in Node.js by in JS. - **My Site Was Hacked** (2021-06-09) | HTML: https://h3manth.com/scribe/my-site-was-hacked/ | Markdown: https://h3manth.com/scribe/blog/my-site-was-hacked.md | Tags: security, web, hacking, drupal How my site was hacked and how I recovered from it. Practical notes and code examples on My Site Was Hacked by Hemanth HM. - **Dynamic Remotes, Webpack Module Federation** (2021-06-06) | HTML: https://h3manth.com/scribe/dynamic-remotes-webpack-module-federation/ | Markdown: https://h3manth.com/scribe/blog/dynamic-remotes-webpack-module-federation.md | Tags: webpack, javascript, module-federation, microfrontends How to dynamically load remotes at runtime with Webpack Module Federation. Practical notes and code examples on Dynamic. - **Webpack Module Federation** (2021-06-02) | HTML: https://h3manth.com/scribe/webpack-module-federation/ | Markdown: https://h3manth.com/scribe/blog/webpack-module-federation.md | Tags: webpack, javascript, module-federation, microfrontends Webpack’s Module Federation is a new feature that was introduced in Webpack5 with the intent of having multiple independent. - **Declarative Shadow DOM** (2021-04-30) | HTML: https://h3manth.com/scribe/declarative-shadow-dom/ | Markdown: https://h3manth.com/scribe/blog/declarative-shadow-dom.md | Tags: html, web-components, shadow-dom Shadow DOM for the server with ease using declarative template syntax. Practical notes and code examples on Declarative. - **Promisified Node Builtins** (2021-04-26) | HTML: https://h3manth.com/scribe/promisified-node-built-ins/ | Markdown: https://h3manth.com/scribe/blog/promisified-node-built-ins.md | Tags: node, javascript, promises Node.js has several built-in modules that are already promisified for you. Practical notes and code examples on Promisified. - **V8 Inspector from Node** (2021-04-13) | HTML: https://h3manth.com/scribe/v8-inspector-from-node/ | Markdown: https://h3manth.com/scribe/blog/v8-inspector-from-node.md | Tags: node, javascript, debugging, v8 Using the inspector module to interact with the V8 inspector from Node.js. Practical notes and code examples on V8 Inspector. - **URLPattern API** (2021-03-03) | HTML: https://h3manth.com/scribe/urlpattern-api/ | Markdown: https://h3manth.com/scribe/blog/urlpattern-api.md | Tags: javascript, web-api, urlpattern The URLPattern web API is an URL pattern matching web-platform primitive for JavaScript. Practical notes and code examples. - **CSS Highlight Pseudo-elements** (2021-01-07) | HTML: https://h3manth.com/scribe/css-highlight-pseudo-elements/ | Markdown: https://h3manth.com/scribe/blog/css-highlight-pseudo-elements.md | Tags: css, web, pseudo-elements CSS4 provides ability to select highlighted content for styling. Practical notes and code examples on CSS Highlight in JS. - **Nullish Coalescing vs Logical OR** (2020-09-03) | HTML: https://h3manth.com/scribe/nullish-coalescing-vs-logical-or/ | Markdown: https://h3manth.com/scribe/blog/nullish-coalescing-vs-logical-or.md | Tags: javascript, es2020, tc39 Understanding the difference between ?? and || operators in JavaScript. Practical notes and code examples on Nullish in JS. - **Logical Assignment Operators in JavaScript** (2020-08-29) | HTML: https://h3manth.com/scribe/logical-assignment-operators-in-javascript/ | Markdown: https://h3manth.com/scribe/blog/logical-assignment-operators-in-javascript.md | Tags: javascript, es2021, tc39 Combine logical operators and assignment expressions with ||=, and and =, and ??=. Practical notes and code examples on. - **Reactive Context in Svelte** (2020-07-04) | HTML: https://h3manth.com/scribe/reactive-context-in-svelte/ | Markdown: https://h3manth.com/scribe/blog/reactive-context-in-svelte.md | Tags: javascript, svelte, frontend Using stores with context API for reactive state in Svelte components. Practical notes and code examples on Reactive Context. - **Top Level Await Node REPL** (2020-05-23) | HTML: https://h3manth.com/scribe/top-level-await-node-repl/ | Markdown: https://h3manth.com/scribe/blog/top-level-await-node-repl.md | Tags: node, javascript, async, await Using await keyword outside of async functions in Node.js REPL. Practical notes and code examples on Top Level Await Node. - **Contact Picker API** (2020-03-11) | HTML: https://h3manth.com/scribe/contact-picker-api/ | Markdown: https://h3manth.com/scribe/blog/contact-picker-api.md | Tags: javascript, web-api, mobile Access device contacts from the web with the Contact Picker API. Practical notes and code examples on Contact Picker API by. - **WebSocketStream API** (2020-03-05) | HTML: https://h3manth.com/scribe/websocketstream-api/ | Markdown: https://h3manth.com/scribe/blog/websocketstream-api.md | Tags: javascript, web-api, websocket, streams A modern WebSocket API that supports backpressure and streams. Practical notes and code examples on WebSocketStream API by. - **DOM Element Timing API** (2020-03-03) | HTML: https://h3manth.com/scribe/dom-element-timing-api/ | Markdown: https://h3manth.com/scribe/blog/dom-element-timing-api.md | Tags: javascript, web-api, performance Measure and monitor rendering timestamps of DOM elements for performance optimization. Practical notes and code examples on. - **Detect Dark Mode** (2020-02-13) | HTML: https://h3manth.com/scribe/detect-dark-mode/ | Markdown: https://h3manth.com/scribe/blog/detect-dark-mode.md | Tags: javascript, css, dark-mode Using prefers-color-scheme to detect and respond to user’s dark mode preference. Practical notes and code examples on Detect. - **Tracking DOM Element Visibility** (2020-02-02) | HTML: https://h3manth.com/scribe/tracking-dom-element-visibility/ | Markdown: https://h3manth.com/scribe/blog/tracking-dom-element-visibility.md | Tags: javascript, dom, performance Using Intersection Observer API to efficiently track element visibility. Practical notes and code examples on Tracking DOM. - **Portal Communication** (2019-05-12) | HTML: https://h3manth.com/scribe/portal-communication/ | Markdown: https://h3manth.com/scribe/blog/portal-communication.md | Tags: javascript, web-api, portals Communicating between host and portal browsing contexts. Practical notes and code examples on Portal Communication by in JS. - **ES2019 Features** (2019-02-06) | HTML: https://h3manth.com/scribe/es2019-features/ | Markdown: https://h3manth.com/scribe/blog/es2019-features.md | Tags: javascript, es2019, tc39 A comprehensive overview of all ES2019 JavaScript features. Practical notes and code examples on ES2019 Features by Hemanth. - **What's New in Node v10?** (2018-04-25) | HTML: https://h3manth.com/scribe/whats-new-in-node-v10/ | Markdown: https://h3manth.com/scribe/blog/whats-new-in-node-v10.md | Tags: node, javascript Key features in Node.js v10 including fs/promises, console.table, top-level await, and more. Practical notes and code in JS. - **Redux Async Actions** (2018-02-16) | HTML: https://h3manth.com/scribe/redux-async-actions/ | Markdown: https://h3manth.com/scribe/blog/redux-async-actions.md | Tags: javascript, redux, react How to handle async actions in Redux without middleware. Practical notes and code examples on Redux Async Actions by Hemanth. - **JWT Encryption with RSA** (2017-08-22) | HTML: https://h3manth.com/scribe/jwt-encryption-with-rsa/ | Markdown: https://h3manth.com/scribe/blog/jwt-encryption-with-rsa.md | Tags: node, javascript, security, jwt Quick guide to JWT encryption with RSA using openSSL and Node.js. Practical notes and code examples on JWT Encryption with. - **Rethinking Async in JavaScript** (2016-12-10) | HTML: https://h3manth.com/scribe/rethinking-async-in-javascript/ | Markdown: https://h3manth.com/scribe/blog/rethinking-async-in-javascript.md | Tags: javascript, async Evolution from callbacks to promises to async/await. Practical notes and code examples on Rethinking Async in JavaScript by. - **Succeed with Service Workers** (2016-10-11) | HTML: https://h3manth.com/scribe/succeed-with-service-workers/ | Markdown: https://h3manth.com/scribe/blog/succeed-with-service-workers.md | Tags: javascript, service-worker, pwa A comprehensive introduction to Service Workers. Practical notes and code examples on Succeed with Service Workers by in JS. - **URL Navigation from Service Worker** (2016-10-05) | HTML: https://h3manth.com/scribe/url-navigation-from-service-worker/ | Markdown: https://h3manth.com/scribe/blog/url-navigation-from-service-worker.md | Tags: javascript, service-worker Using WindowClient.navigate() to navigate controlled pages. Practical notes and code examples on URL Navigation from Service. - **Webpack: Bundle Unimported Assets** (2016-07-23) | HTML: https://h3manth.com/scribe/webpack-bundle-unimported-assets/ | Markdown: https://h3manth.com/scribe/blog/webpack-bundle-unimported-assets.md | Tags: webpack, javascript How to bundle files not imported in source using webpack. Practical notes and code examples on Webpack: Bundle Unimported. - **Path Resolver with JavaScript Proxies** (2016-06-15) | HTML: https://h3manth.com/scribe/path-resolver-with-javascript-proxies/ | Markdown: https://h3manth.com/scribe/blog/path-resolver-with-javascript-proxies.md | Tags: javascript, es6, proxy Using ES6 Proxies to access nested object paths with dot notation strings. Practical notes and code examples on Path in JS. - **ServiceWorker Communication via MessageChannel** (2016-02-13) | HTML: https://h3manth.com/scribe/serviceworker-communication-via-messagechannel/ | Markdown: https://h3manth.com/scribe/blog/serviceworker-communication-via-messagechannel.md | Tags: javascript, service-worker, web-api Two-way communication between ServiceWorker and main thread using MessageChannel API. Practical notes and code examples on. - **String.prototype.replace You Might Have Missed** (2016-01-10) | HTML: https://h3manth.com/scribe/string-prototype-replace-you-might-have-missed/ | Markdown: https://h3manth.com/scribe/blog/string-prototype-replace-you-might-have-missed.md | Tags: javascript Using replacer functions in JavaScript’s String.replace method. Practical notes and code examples on — Scribe notes. - **365 Days of GitHub** (2015-11-07) | HTML: https://h3manth.com/scribe/365-days-of-github/ | Markdown: https://h3manth.com/scribe/blog/365-days-of-github.md | Tags: github, opensource Learnings from 365 days of continuous GitHub contributions. Practical notes and code examples on 365 Days of GitHub by in JS. - **Are You Async Yet?** (2015-10-05) | HTML: https://h3manth.com/scribe/are-you-async-yet/ | Markdown: https://h3manth.com/scribe/blog/are-you-async-yet.md | Tags: javascript, async, es7 Transitioning from callbacks to async/await in JavaScript. Practical notes and code examples on Are You Async Yet? by in JS. - **Recursive Map, Reduce and Filter in JavaScript** (2015-09-06) | HTML: https://h3manth.com/scribe/recursive-map-reduce-and-filter-in-javascript/ | Markdown: https://h3manth.com/scribe/blog/recursive-map-reduce-and-filter-in-javascript.md | Tags: javascript, functional Functional implementations of map, reduce, and filter using recursion. Practical notes and code examples on Recursive Map. - **Authoring Node Modules** (2015-07-30) | HTML: https://h3manth.com/scribe/authoring-node-modules/ | Markdown: https://h3manth.com/scribe/blog/authoring-node-modules.md | Tags: node, npm Best practices for creating and publishing npm packages. Practical notes and code examples on Authoring Node Modules by. - **ES7 Async Await** (2015-06-21) | HTML: https://h3manth.com/scribe/es7-async-await/ | Markdown: https://h3manth.com/scribe/blog/es7-async-await.md | Tags: javascript, es7, async The async/await proposal that changed how we handle asynchronous JavaScript. Practical notes and code examples on ES7 Async. - **Create a NodeSchool Workshop** (2015-05-23) | HTML: https://h3manth.com/scribe/create-a-nodeschool-workshop/ | Markdown: https://h3manth.com/scribe/blog/create-a-nodeschool-workshop.md | Tags: node, nodeschool Building interactive NodeSchool workshops with adventure-runner. Practical notes and code examples on Create a NodeSchool. - **Currying in ES6** (2015-04-30) | HTML: https://h3manth.com/scribe/currying-in-es6/ | Markdown: https://h3manth.com/scribe/blog/currying-in-es6.md | Tags: javascript, es6, functional Implementing function currying with ES6 arrow functions. Practical notes and code examples on Currying in ES6 by Hemanth HM. - **ES7 Features** (2015-03-10) | HTML: https://h3manth.com/scribe/es7-features/ | Markdown: https://h3manth.com/scribe/blog/es7-features.md | Tags: javascript, es7 Overview of ECMAScript 7 (ES2016) features and proposals. Practical notes and code examples on ES7 Features by Hemanth HM. - **SMS Service with Firefox OS** (2015-02-21) | HTML: https://h3manth.com/scribe/sms-service-with-firefox-os/ | Markdown: https://h3manth.com/scribe/blog/sms-service-with-firefox-os.md | Tags: javascript, firefoxos Building an SMS booking service using Firefox OS APIs. Practical notes and code examples on SMS Service with Firefox OS by. - **Superfluous Patterns of JavaScript** (2015-02-20) | HTML: https://h3manth.com/scribe/superfluous-patterns-of-javascript/ | Markdown: https://h3manth.com/scribe/blog/superfluous-patterns-of-javascript.md | Tags: javascript, es6 ES6 features that eliminate old JavaScript patterns. Practical notes and code examples on Superfluous Patterns of JavaScript. - **Node Rules - Business Rules Engine** (2015-01-29) | HTML: https://h3manth.com/scribe/node-rules/ | Markdown: https://h3manth.com/scribe/blog/node-rules.md | Tags: node, business-logic Light weight forward chaining Rule Engine for JavaScript. Practical notes and code examples on Node Rules - Business Rules. - **ES6 Reflect API** (2015-01-12) | HTML: https://h3manth.com/scribe/es6-reflect-api/ | Markdown: https://h3manth.com/scribe/blog/es6-reflect-api.md | Tags: javascript, es6 Understanding the Reflect object and its methods in ES6. Practical notes and code examples on ES6 Reflect API by Hemanth HM. - **Custom Elements with ES6** (2015-01-06) | HTML: https://h3manth.com/scribe/custom-elements-with-es6/ | Markdown: https://h3manth.com/scribe/blog/custom-elements-with-es6.md | Tags: web, webcomponents, es6 Creating Web Components custom elements using ES6 classes. Practical notes and code examples on Custom Elements with ES6 by. - **Descriptor Decorator in Python** (2014-12-01) | HTML: https://h3manth.com/scribe/descriptor-decorator-in-python/ | Markdown: https://h3manth.com/scribe/blog/descriptor-decorator-in-python.md | Tags: python Combining Python decorators with descriptor protocol. Practical notes and code examples on Descriptor Decorator in Python. - **ES6 Array Methods** (2014-10-18) | HTML: https://h3manth.com/scribe/es6-array-methods/ | Markdown: https://h3manth.com/scribe/blog/es6-array-methods.md | Tags: javascript, es6 New array methods in ES6: Array.from, Array.of, copyWithin, fill, find, findIndex, keys, entries, values. Practical notes. - **Python Datasets** (2014-09-14) | HTML: https://h3manth.com/scribe/python-datasets/ | Markdown: https://h3manth.com/scribe/blog/python-datasets.md | Tags: python, db Simple database abstraction with Python dataset library. Practical notes and code examples on Python Datasets by Hemanth HM. - **Date Shifting in Ruby** (2014-09-11) | HTML: https://h3manth.com/scribe/date-shifting-in-ruby/ | Markdown: https://h3manth.com/scribe/blog/date-shifting-in-ruby.md | Tags: ruby Using the and operators on Ruby Date objects. Practical notes and code examples on Date Shifting in Ruby by Hemanth HM in JS. - **thisArg in JavaScript** (2014-08-09) | HTML: https://h3manth.com/scribe/thisarg-in-javascript/ | Markdown: https://h3manth.com/scribe/blog/thisarg-in-javascript.md | Tags: javascript Understanding the thisArg parameter in JavaScript array methods. Practical notes and code examples on thisArg in JavaScript. - **Immediately-Invoked Generator Function Expression (IIGFE)** (2014-07-08) | HTML: https://h3manth.com/scribe/immediately-invoked-generator-function-expression-iigfe/ | Markdown: https://h3manth.com/scribe/blog/immediately-invoked-generator-function-expression-iigfe.md | Tags: javascript, es6, generators A new pattern for immediately invoked generator functions in ES6. Practical notes and code examples on Immediately-Invoked. - **Check for Root User** (2014-06-14) | HTML: https://h3manth.com/scribe/check-for-root-user/ | Markdown: https://h3manth.com/scribe/blog/check-for-root-user.md | Tags: linux, cli Checking for root privileges across different languages. Practical notes and code examples on Check for Root User by Hemanth. - **Thunks in Haskell** (2014-06-14) | HTML: https://h3manth.com/scribe/thunks-in-haskell/ | Markdown: https://h3manth.com/scribe/blog/thunks-in-haskell.md | Tags: haskell, functional Understanding lazy evaluation and thunks in Haskell. Practical notes and code examples on Thunks in Haskell by Hemanth HM. - **navigator.sendBeacon** (2014-05-17) | HTML: https://h3manth.com/scribe/navigator-sendbeacon/ | Markdown: https://h3manth.com/scribe/blog/navigator-sendbeacon.md | Tags: javascript, web-api, analytics Using the Beacon API for reliable analytics data transmission during page unload. Practical notes and code examples on in JS. - **Detecting File Type in Node and Browser** (2014-05-01) | HTML: https://h3manth.com/scribe/detecting-file-type-in-node-and-browser/ | Markdown: https://h3manth.com/scribe/blog/detecting-file-type-in-node-and-browser.md | Tags: node, javascript Using magic numbers and file signatures to detect file types in JavaScript. Practical notes and code examples on Detecting. - **Prime Number Generation with ES6 Generators** (2014-04-18) | HTML: https://h3manth.com/scribe/prime-number-generation-with-es6-generators/ | Markdown: https://h3manth.com/scribe/blog/prime-number-generation-with-es6-generators.md | Tags: javascript, es6, generators Using ES6 generators to create an infinite prime number generator. Practical notes and code examples on Prime Number in JS. - **grunt-usemin Example** (2014-04-09) | HTML: https://h3manth.com/scribe/grunt-usemin-example/ | Markdown: https://h3manth.com/scribe/blog/grunt-usemin-example.md | Tags: grunt, build Minimal example of using grunt-usemin for asset optimization. Practical notes and code examples on grunt-usemin Example by. - **Tree Traversal with ES6 Generator** (2014-03-14) | HTML: https://h3manth.com/scribe/tree-traversal-with-es6-generator/ | Markdown: https://h3manth.com/scribe/blog/tree-traversal-with-es6-generator.md | Tags: javascript, es6, generators, algorithms Implementing depth-first tree traversal algorithms using ES6 generators. Practical notes and code examples on Tree Traversal. - **Clone All Official Yeoman Generators** (2014-03-09) | HTML: https://h3manth.com/scribe/clone-all-official-yeoman-generators/ | Markdown: https://h3manth.com/scribe/blog/clone-all-official-yeoman-generators.md | Tags: yeoman, cli Script to clone all official Yeoman generators. Practical notes and code examples on Clone All Official Yeoman Generators. - **npm --save to Create package.json** (2014-03-09) | HTML: https://h3manth.com/scribe/npm-save-to-create-package-json/ | Markdown: https://h3manth.com/scribe/blog/npm-save-to-create-package-json.md | Tags: node, npm Shell function to automatically create package.json when using npm install --save. Practical notes and code examples on npm. - **Atom Editor Packages with Yeoman** (2014-03-02) | HTML: https://h3manth.com/scribe/atom-editor-packages-with-yeoman/ | Markdown: https://h3manth.com/scribe/blog/atom-editor-packages-with-yeoman.md | Tags: atom, yeoman Using Yeoman generator to scaffold Atom editor packages. Practical notes and code examples on Atom Editor Packages with. - **Current Interface and Random Port with Node.js** (2014-02-16) | HTML: https://h3manth.com/scribe/current-interface-and-random-port-with-nodejs/ | Markdown: https://h3manth.com/scribe/blog/current-interface-and-random-port-with-nodejs.md | Tags: node, javascript Quick way to get the current network interface and a random port for Node.js servers. Practical notes and code examples on. - **ES6 One Liners to Show Off** (2014-02-11) | HTML: https://h3manth.com/scribe/es6-one-liners-to-show-off/ | Markdown: https://h3manth.com/scribe/blog/es6-one-liners-to-show-off.md | Tags: javascript, es6 Collection of impressive ES6 one-liners for destructuring, spread, Sets, and more. Practical notes and code examples on ES6. - **Getting Started with Koa.js** (2014-02-09) | HTML: https://h3manth.com/scribe/getting-started-with-koajs/ | Markdown: https://h3manth.com/scribe/blog/getting-started-with-koajs.md | Tags: node, javascript, koa Introduction to Koa, the next generation web framework for Node.js using ES6 generators. Practical notes and code examples. - **Launch Browser from Node Server** (2014-01-30) | HTML: https://h3manth.com/scribe/launch-browser-from-node-server/ | Markdown: https://h3manth.com/scribe/blog/launch-browser-from-node-server.md | Tags: node, javascript Automatically open the browser when starting a Node.js web server. Practical notes and code examples on Launch Browser from. - **Programmatically Accessing Network Interfaces** (2013-12-30) | HTML: https://h3manth.com/scribe/programmatically-accessing-network-interfaces/ | Markdown: https://h3manth.com/scribe/blog/programmatically-accessing-network-interfaces.md | Tags: node, ruby, python, cli Accessing network interfaces in Ruby, Python, Perl, and Node.js. Practical notes and code examples on Programmatically in JS. - **Publish Packages to NPM with Yeoman** (2013-11-30) | HTML: https://h3manth.com/scribe/publish-packages-to-npm-with-yeoman/ | Markdown: https://h3manth.com/scribe/blog/publish-packages-to-npm-with-yeoman.md | Tags: node, npm, yeoman Using Yeoman’s generator-node to create and publish npm packages. Practical notes and code examples on Publish Packages to. - **DOM Mutation Observers** (2013-11-11) | HTML: https://h3manth.com/scribe/dom-mutation-observers/ | Markdown: https://h3manth.com/scribe/blog/dom-mutation-observers.md | Tags: javascript, dom, web-api Using MutationObserver API to watch for DOM tree changes. Practical notes and code examples on DOM Mutation Observers by. - **Negative Array Index in JavaScript** (2013-10-06) | HTML: https://h3manth.com/scribe/negative-array-index-in-javascript/ | Markdown: https://h3manth.com/scribe/blog/negative-array-index-in-javascript.md | Tags: javascript, es6, proxies Implementing Python-style negative array indexing using ES6 Proxies. Practical notes and code examples on Negative Array. - **Redefining DOM Object's Behaviour** (2013-09-05) | HTML: https://h3manth.com/scribe/redefining-dom-objects-behaviour/ | Markdown: https://h3manth.com/scribe/blog/redefining-dom-objects-behaviour.md | Tags: javascript, dom Using Object.defineProperty with setAttribute to redefine DOM element properties. Practical notes and code examples on in JS. - **ES6 on Node.js** (2013-09-01) | HTML: https://h3manth.com/scribe/es6-on-nodejs/ | Markdown: https://h3manth.com/scribe/blog/es6-on-nodejs.md | Tags: node, javascript, es6 Using ES6 harmony features in Node.js with --harmony flags. Practical notes and code examples on ES6 on Node.js by Hemanth. - **Jekyll Blog from a Subdirectory** (2013-08-25) | HTML: https://h3manth.com/scribe/jekyll-blog-from-a-subdirectory/ | Markdown: https://h3manth.com/scribe/blog/jekyll-blog-from-a-subdirectory.md | Tags: jekyll, cli Serving a Jekyll blog from a subdirectory like example.com/blog. Practical notes and code examples on Jekyll Blog from a. - **Method Deprecated Warning in Node.js** (2013-08-06) | HTML: https://h3manth.com/scribe/method-deprecated-warning-in-nodejs/ | Markdown: https://h3manth.com/scribe/blog/method-deprecated-warning-in-nodejs.md | Tags: node, javascript Using util.deprecate to warn users about deprecated methods. Practical notes and code examples on Method Deprecated Warning. - **Auto Syncing a Forked Git Repository** (2013-07-31) | HTML: https://h3manth.com/scribe/auto-syncing-a-forked-git-repository/ | Markdown: https://h3manth.com/scribe/blog/auto-syncing-a-forked-git-repository.md | Tags: git, bash, cli Bash script to automatically sync forked repos with parent. Practical notes and code examples on Auto Syncing a Forked Git. - **Auto Require Ruby Gems** (2013-07-27) | HTML: https://h3manth.com/scribe/auto-require-ruby-gems/ | Markdown: https://h3manth.com/scribe/blog/auto-require-ruby-gems.md | Tags: ruby Automatically install missing Ruby gems when requiring them. Practical notes and code examples on Auto Require Ruby Gems by. - **Sublime Text Build System Errno 2** (2013-07-27) | HTML: https://h3manth.com/scribe/sublime-text-build-system-errno-2/ | Markdown: https://h3manth.com/scribe/blog/sublime-text-build-system-errno-2.md | Tags: cli, sublime Fixing the Errno 2 issue in Sublime Text build systems. Practical notes and code examples on Sublime Text Build System Errno. - **HTTP Status Code as a Service** (2013-07-22) | HTML: https://h3manth.com/scribe/http-status-code-as-a-service/ | Markdown: https://h3manth.com/scribe/blog/http-status-code-as-a-service.md | Tags: node, javascript Building a simple HTTP status code service with Node.js. Practical notes and code examples on HTTP Status Code as a Service. - **Grunt Test Before Git Commit** (2013-07-15) | HTML: https://h3manth.com/scribe/grunt-test-before-git-commit/ | Markdown: https://h3manth.com/scribe/blog/grunt-test-before-git-commit.md | Tags: node, grunt, git, testing Running tests with grunt before every git commit using pre-commit hooks. Practical notes and code examples on Grunt Test. - **Grunt Tweet Git Commit** (2013-07-07) | HTML: https://h3manth.com/scribe/grunt-tweet-git-commit/ | Markdown: https://h3manth.com/scribe/blog/grunt-tweet-git-commit.md | Tags: node, grunt, git, cli Automatically tweet about every git commit using Grunt. Practical notes and code examples on Grunt Tweet Git Commit by in JS. - **Handling Currency in JavaScript** (2013-06-18) | HTML: https://h3manth.com/scribe/handling-currency-in-javascript/ | Markdown: https://h3manth.com/scribe/blog/handling-currency-in-javascript.md | Tags: javascript, intl Using the Intl.NumberFormat API for currency formatting. Practical notes and code examples on Handling Currency in in JS. - **Selfless JavaScript** (2013-05-26) | HTML: https://h3manth.com/scribe/selfless-javascript/ | Markdown: https://h3manth.com/scribe/blog/selfless-javascript.md | Tags: javascript Avoiding self=this by using bind() for context preservation. Practical notes and code examples on Selfless JavaScript by. - **Auto Notify Git Pull** (2013-05-01) | HTML: https://h3manth.com/scribe/auto-notify-git-pull/ | Markdown: https://h3manth.com/scribe/blog/auto-notify-git-pull.md | Tags: git, bash, cli Bash function to notify when entering a git directory with upstream changes. Practical notes and code examples on Auto in JS. - **Getting the Expiry Date of PFX (PKCS12)** (2013-04-29) | HTML: https://h3manth.com/scribe/getting-expiry-date-of-pfx-pkcs12/ | Markdown: https://h3manth.com/scribe/blog/getting-expiry-date-of-pfx-pkcs12.md | Tags: cli, openssl, security How to extract certificate expiration date from PFX files using OpenSSL. Practical notes and code examples on Getting the. - **Power of Vanilla JS** (2013-04-26) | HTML: https://h3manth.com/scribe/power-of-vanilla-js/ | Markdown: https://h3manth.com/scribe/blog/power-of-vanilla-js.md | Tags: javascript, vanilla-js Demonstrating the power of native JavaScript without jQuery. Practical notes and code examples on Power of Vanilla JS by. - **Web Crawler with Python Twisted** (2013-04-26) | HTML: https://h3manth.com/scribe/web-crawler-with-python-twisted/ | Markdown: https://h3manth.com/scribe/blog/web-crawler-with-python-twisted.md | Tags: python, twisted, web-crawler Building an asynchronous web crawler using Python Twisted framework. Practical notes and code examples on Web Crawler with. - **Regular Expression Negation in Ruby** (2013-04-24) | HTML: https://h3manth.com/scribe/regular-expression-negation-in-ruby/ | Markdown: https://h3manth.com/scribe/blog/regular-expression-negation-in-ruby.md | Tags: ruby, regex The difference between !=~ and !~ for regex negation in Ruby. Practical notes and code examples on Regular Expression in JS. - **Watir-webdriver Web Inspector** (2013-04-20) | HTML: https://h3manth.com/scribe/watir-webdriver-web-inspector/ | Markdown: https://h3manth.com/scribe/blog/watir-webdriver-web-inspector.md | Tags: ruby, git, web, linux An experimental minimal combinatorial code generation on element inspection. Check out the repo for sending your P.R ;) The. - **Gem List to Gemfile** (2013-03-20) | HTML: https://h3manth.com/scribe/gem-list-gemfile/ | Markdown: https://h3manth.com/scribe/blog/gem-list-gemfile.md | Tags: ruby, javascript Say you have n-machines that needs to be in sync with their ruby gem versions, we can have one system to update all as per. - **Packing ruby2.0 on Debian.** (2013-03-08) | HTML: https://h3manth.com/scribe/packing-ruby20-debian/ | Markdown: https://h3manth.com/scribe/blog/packing-ruby20-debian.md | Tags: ruby, ubuntu, git, bash One can use the below script to package ruby2.0 on squeeze. To get going, just get the script form Here and says sudo bash. - **Made It Into the Guinness Book!** (2013-03-03) | HTML: https://h3manth.com/scribe/made-it-guinness-book/ | Markdown: https://h3manth.com/scribe/blog/made-it-guinness-book.md | Tags: web Couple of weeks back when I was cleaning my mailbox I noticed a mail which read Hey redditgiftor, YOU are a Guinness World. - **Filter Elements by Pattern jQuery.** (2013-02-23) | HTML: https://h3manth.com/scribe/filter-elements-pattern-jquery/ | Markdown: https://h3manth.com/scribe/blog/filter-elements-pattern-jquery.md | Tags: python, javascript, web The need was pretty simple : ’Find the elements that contain a particular word and display them and hide others’ Along with. - **Better HTML Password Fields for Mobile ?** (2013-02-08) | HTML: https://h3manth.com/scribe/better-html-password-fields-mobile/ | Markdown: https://h3manth.com/scribe/blog/better-html-password-fields-mobile.md | Tags: javascript, web There is a particular issue that most of us would have noticed with few mobile devices in portrait with T9 (predictivetext). - **Grayscale Image When User Offline** (2013-01-07) | HTML: https://h3manth.com/scribe/grayscale-image-when-user-offline/ | Markdown: https://h3manth.com/scribe/blog/grayscale-image-when-user-offline.md | Tags: javascript, web You must have noticed, webapps images in chrome going grayscale to indicate that the network is down, a simple demonstration. - **Nth-child CSS Pseudo-class Christmas Colors** (2012-12-25) | HTML: https://h3manth.com/scribe/nth-child-css-pseudo-class-christmas-colors/ | Markdown: https://h3manth.com/scribe/blog/nth-child-css-pseudo-class-christmas-colors.md | Tags: web Lately /me noticed HN using Christmas color scheme for their post numbering, but the source sadly read 1. below is some. - **EventEmitter in Nodejs** (2012-12-16) | HTML: https://h3manth.com/scribe/eventemitter-nodejs/ | Markdown: https://h3manth.com/scribe/blog/eventemitter-nodejs.md | Tags: nodejs, javascript, web Sometime back had pawed at Making promises with javascript but node school of thought offers an attractive pattern of in JS. - **Live Reload With Grunt** (2012-12-15) | HTML: https://h3manth.com/scribe/live-reload-grunt/ | Markdown: https://h3manth.com/scribe/blog/live-reload-grunt.md | Tags: nodejs, web Sometime back I had published an entry on Node Packing with grunt but live reload has been so fascinating to most of the. - **Why Parameter Expansion in Bash?** (2012-12-01) | HTML: https://h3manth.com/scribe/why-parameter-expansion-bash/ | Markdown: https://h3manth.com/scribe/blog/why-parameter-expansion-bash.md | Tags: python, bash Most of us would have come across bash scripts that have the use of secondary commands for simple string manipulations, such. - **Node Packing Made Easy With Grunt** (2012-10-30) | HTML: https://h3manth.com/scribe/node-packing-made-easy-grunt/ | Markdown: https://h3manth.com/scribe/blog/node-packing-made-easy-grunt.md | Tags: nodejs, git, bash, web Publish node packages with npm is easier done than said! ;) First of all check out Hitchhikers guide to npm After which. - **Making a Promise With Javascript** (2012-10-29) | HTML: https://h3manth.com/scribe/making-promise-javascript/ | Markdown: https://h3manth.com/scribe/blog/making-promise-javascript.md | Tags: nodejs, javascript, web Chaining functions in javascript is fun, so is the understanding of Blaocking vs Non-Blocking code, but callback can soon. - **CoffeeScript Classes** (2012-10-24) | HTML: https://h3manth.com/scribe/coffeescript-classes/ | Markdown: https://h3manth.com/scribe/blog/coffeescript-classes.md | Tags: ruby, nodejs, javascript, git When rails 3 was out I had a serious look at coffescript commit-diff but was not very much carried by it then. But as the. - **Cluster Computing With Nodejs** (2012-10-07) | HTML: https://h3manth.com/scribe/cluster-computing-nodejs/ | Markdown: https://h3manth.com/scribe/blog/cluster-computing-nodejs.md | Tags: nodejs, web A single instance of Node runs in a single thread. To take advantage of multi-core systems we may want to launch a cluster. - **IRC Notification Bot With node.js** (2012-09-23) | HTML: https://h3manth.com/scribe/irc-notification-bot-nodejs/ | Markdown: https://h3manth.com/scribe/blog/irc-notification-bot-nodejs.md | Tags: nodejs, git, web This bot is a product of a simple need of notifying people when their friends login to a particular channel. The need in JS. - **Heroku vs Nodejitsu for Nodejs** (2012-09-19) | HTML: https://h3manth.com/scribe/heroku-vs-nodejitsu-nodejs/ | Markdown: https://h3manth.com/scribe/blog/heroku-vs-nodejitsu-nodejs.md | Tags: ruby, nodejs, git It all started when I wanted to try out node with websockets with ws but strange but true heroku does not support node’s ws. - **Exposing Your Localhost to the Internet** (2012-09-17) | HTML: https://h3manth.com/scribe/exposing-your-localhost-internet/ | Markdown: https://h3manth.com/scribe/blog/exposing-your-localhost-internet.md | Tags: ruby, python, linux Exposing your local web server to the internet is very useful at times, it gets a bit tough when you are on a DHCP. The. - **Program Dependency Management With node.js** (2012-09-15) | HTML: https://h3manth.com/scribe/program-dependency-management-nodejs/ | Markdown: https://h3manth.com/scribe/blog/program-dependency-management-nodejs.md | Tags: ruby, nodejs, git, bash Lately was working with a few PRs for The Yeoman project and tried to hack through a shelljs script to audit the OS before. - **Perl in node.js** (2012-09-11) | HTML: https://h3manth.com/scribe/perl-nodejs/ | Markdown: https://h3manth.com/scribe/blog/perl-nodejs.md | Tags: nodejs, javascript, git Yes! Perl5 can be embedded in node.js! First of all just do a npm install perl P.S : node-perl requires a perl5 binary built. - **Temp Dir With Ruby** (2012-09-06) | HTML: https://h3manth.com/scribe/temp-dir-ruby/ | Markdown: https://h3manth.com/scribe/blog/temp-dir-ruby.md | Tags: ruby Played around with few programming languages to handle temp dirs, but amongst the lot /me really liked ruby’s paradigm in JS. - **Get Node Details From Drupal** (2012-09-01) | HTML: https://h3manth.com/scribe/get-node-details-drupal/ | Markdown: https://h3manth.com/scribe/blog/get-node-details-drupal.md | Tags: database Currently I’m trying to migrate my blog from drupal to something must lighter, migrating data is indeed the first step! A. - **Convert Any Image to HTML5 Canvas** (2012-08-26) | HTML: https://h3manth.com/scribe/convert-any-image-html5-canvas/ | Markdown: https://h3manth.com/scribe/blog/convert-any-image-html5-canvas.md | Tags: web Even before talking about the technicalities of converting an image to a canvas element, check out the demo! DEMO input any. - **HTML5 Fullscreen video crossbrowser** (2012-08-25) | HTML: https://h3manth.com/scribe/html5-fullscreen-video-crossbrowser/ | Markdown: https://h3manth.com/scribe/blog/html5-fullscreen-video-crossbrowser.md | Tags: javascript, html5 With the evolution of HTML5 APIs taking a video to Fullscreen and back is very easy and indeed no flash! P.S : I shall be. - **Chaining Functions in Javascript** (2012-08-19) | HTML: https://h3manth.com/scribe/chaining-functions-javascript/ | Markdown: https://h3manth.com/scribe/blog/chaining-functions-javascript.md | Tags: ruby, javascript Most of us are aware of the all famous Jquery demo $(’p.neat’).addClass(’ohmy’).show(’slow’); which is a gem of an example. - **Remote debugging android browsers.** (2012-08-17) | HTML: https://h3manth.com/scribe/remote-debugging-android-browsers/ | Markdown: https://h3manth.com/scribe/blog/remote-debugging-android-browsers.md | Tags: programming This entry briefs about remote debugging browsers that are active in any of the Android devices. The focus is mainly on the. - **Control Telephone Calls From the Browser!** (2012-08-09) | HTML: https://h3manth.com/scribe/control-telephone-calls-browser/ | Markdown: https://h3manth.com/scribe/blog/control-telephone-calls-browser.md | Tags: web Control telephone calls from the browser, yes browser! But Mozilla Mobile Browser as of now. The phone functionality can be. - **FFI Python vs Ruby** (2012-08-01) | HTML: https://h3manth.com/scribe/ffi-python-vs-ruby/ | Markdown: https://h3manth.com/scribe/blog/ffi-python-vs-ruby.md | Tags: python, ruby A comparison of Foreign Function Interface (FFI) usage in Python vs Ruby to call C libraries. Practical notes and code in JS. - **Python vs Ruby Singleton** (2012-07-31) | HTML: https://h3manth.com/scribe/python-vs-ruby-singleton/ | Markdown: https://h3manth.com/scribe/blog/python-vs-ruby-singleton.md | Tags: python, ruby, patterns A comparison of Singleton design pattern implementation in Python vs Ruby. Practical notes and code examples on Python vs. - **Module Pattern in Javascript** (2012-07-26) | HTML: https://h3manth.com/scribe/module-pattern-javascript/ | Markdown: https://h3manth.com/scribe/blog/module-pattern-javascript.md | Tags: javascript, web Lately wrote about Singleton Pattern in JavaScript after which thought of writing few lines about the famous module pattern. - **String#each missing in Ruby 1.9** (2012-07-25) | HTML: https://h3manth.com/scribe/stringeach-missing-in-ruby19/ | Markdown: https://h3manth.com/scribe/blog/stringeach-missing-in-ruby19.md | Tags: ruby One might have noticed that String#each is no more present in Ruby 1.9 and how to fix it. Practical notes and code examples. - **String#each Missing in ruby1.9** (2012-07-25) | HTML: https://h3manth.com/scribe/stringeach-missing-ruby19/ | Markdown: https://h3manth.com/scribe/blog/stringeach-missing-ruby19.md | Tags: bash One might have noticed that String#each is no more present in ruby1.9 1.9.1 :002 ’hemanth’.each NoMethodError: undefined. - **With Statements Got Better With Python 3.1** (2012-07-24) | HTML: https://h3manth.com/scribe/statements-got-better-python-31/ | Markdown: https://h3manth.com/scribe/blog/statements-got-better-python-31.md | Tags: python, web In my previous post about using the with statement in python /me had tried to throw some light on why to use ’with’ in JS. - **Cross-Window Messaging** (2012-07-22) | HTML: https://h3manth.com/scribe/cross-window-messaging/ | Markdown: https://h3manth.com/scribe/blog/cross-window-messaging.md | Tags: javascript, html5 Cross-origin/window communication is possible with the HTML5 API window.postMessage. Practical notes and code examples on. - **Class Handling With classList** (2012-07-21) | HTML: https://h3manth.com/scribe/class-handling-classlist/ | Markdown: https://h3manth.com/scribe/blog/class-handling-classlist.md | Tags: javascript, web classList returns a token list of the class attribute for a given element, with which one can do the below easily! add a. - **Asynchronous Loading of Css and Javascript** (2012-07-18) | HTML: https://h3manth.com/scribe/asynchronous-loading-css-and-javascript/ | Markdown: https://h3manth.com/scribe/blog/asynchronous-loading-css-and-javascript.md | Tags: javascript, web Sometime back was pawing at async forEach in JavaScript that helped me to make a simple inject function that would help in. - **Async forEach in JavaScript** (2012-07-17) | HTML: https://h3manth.com/scribe/async-foreach-javascript/ | Markdown: https://h3manth.com/scribe/blog/async-foreach-javascript.md | Tags: nodejs, javascript, git, web After writing about Blocking vs Non-Blocking /me was stuck with making forEach of JS asynchronous as it was very much needed. - **asynchronous loading of css and javascript** (2012-07-17) | HTML: https://h3manth.com/scribe/asynchronous-loading-of-css-and-javascript/ | Markdown: https://h3manth.com/scribe/blog/asynchronous-loading-of-css-and-javascript.md | Tags: javascript, css Sometime back was pawing at async forEach in JavaScript that helped me to make a simple inject... Practical notes and code. - **Singleton Pattern in JavaScript** (2012-07-10) | HTML: https://h3manth.com/scribe/singleton-pattern-javascript/ | Markdown: https://h3manth.com/scribe/blog/singleton-pattern-javascript.md | Tags: javascript What is Singleton Pattern? The singleton pattern is a design pattern that restricts the instantiation of a class to one. - **Arrow Functions in Javascript** (2012-07-05) | HTML: https://h3manth.com/scribe/arrow-functions-javascript/ | Markdown: https://h3manth.com/scribe/blog/arrow-functions-javascript.md | Tags: python, javascript CoffeeScript is influencing javascript with fat arrows! As python had influenced it before with list comprehensions. Well. - **Getting Home Path and Username in Python** (2012-07-05) | HTML: https://h3manth.com/scribe/getting-home-path-and-username-python/ | Markdown: https://h3manth.com/scribe/blog/getting-home-path-and-username-python.md | Tags: python , were just an one liners for me so for : os.path.expanduser(’/’) and pwd.getpwuid(os.getuid())[0] were doing the job for. - **Parsing Query String in Javascript** (2012-07-04) | HTML: https://h3manth.com/scribe/parsing-query-string-javascript/ | Markdown: https://h3manth.com/scribe/blog/parsing-query-string-javascript.md | Tags: javascript, web Well there are hell lot of solution out there for parsing query strings in javascript, but still /me managed to make my own. - **Camera and Microphone Access With HTML5** (2012-07-02) | HTML: https://h3manth.com/scribe/camera-and-microphone-access-html5/ | Markdown: https://h3manth.com/scribe/blog/camera-and-microphone-access-html5.md | Tags: android, web Yes, Plugin-free acess to camera/microphone with HTML5! Welcome to the post-flash revolution aka smartphone development. - **HTML5 canvas full-screen and full-page** (2012-07-02) | HTML: https://h3manth.com/scribe/html5-canvas-full-screen-and-full-page/ | Markdown: https://h3manth.com/scribe/blog/html5-canvas-full-screen-and-full-page.md | Tags: javascript, html5 How to make a canvas element occupy an entire page and also how to go full screen with canvas. Practical notes and code. - **Camera and Microphone Access with HTML5** (2012-07-01) | HTML: https://h3manth.com/scribe/camera-and-microphone-access-with-html5/ | Markdown: https://h3manth.com/scribe/blog/camera-and-microphone-access-with-html5.md | Tags: javascript, html5 Plugin-free access to camera/microphone with HTML5! Welcome to the post-flash revolution. Practical notes and code examples. - **Top 5 JavaScript oneliners** (2012-07-01) | HTML: https://h3manth.com/scribe/top-5-javascript-oneliners/ | Markdown: https://h3manth.com/scribe/blog/top-5-javascript-oneliners.md | Tags: javascript JavaScript is such a beautiful language, where everything can be minified to one line! Practical notes and code examples on. - **Using the 'With' Statement in Python** (2012-06-29) | HTML: https://h3manth.com/scribe/using-statement-python/ | Markdown: https://h3manth.com/scribe/blog/using-statement-python.md | Tags: python The ’with’ Statement PEP was created way back in 2005, PEP 343 to be precise, but /me notice many still coding with old. - **Iterating List or Array With Index** (2012-06-28) | HTML: https://h3manth.com/scribe/iterating-list-or-array-index/ | Markdown: https://h3manth.com/scribe/blog/iterating-list-or-array-index.md | Tags: ruby, python, javascript Iterating an array or a list with index while scripting, has it’s own purpose. Before we discuss about iterating an array. - **Classes in JavaScript ES6** (2012-06-26) | HTML: https://h3manth.com/scribe/classes-javascript-es6/ | Markdown: https://h3manth.com/scribe/blog/classes-javascript-es6.md | Tags: javascript Well, well... there are so many JavaScript frameworks that already try to implement classes as per the classical Object. - **Classes in JavaScript ES6** (2012-06-25) | HTML: https://h3manth.com/scribe/classes-in-javascript-es6/ | Markdown: https://h3manth.com/scribe/blog/classes-in-javascript-es6.md | Tags: javascript With Harmony (ES6) implementing classes like classical OO shall be possible. Practical notes and code examples on Classes. - **Blocking vs Non-blocking in node.js** (2012-06-24) | HTML: https://h3manth.com/scribe/blocking-vs-non-blocking-nodejs/ | Markdown: https://h3manth.com/scribe/blog/blocking-vs-non-blocking-nodejs.md | Tags: nodejs The most common task that any developer would do is File I/O, this being a very fundamental process : Open a File. Read. - **RSS as JSON Using node.js** (2012-06-21) | HTML: https://h3manth.com/scribe/rss-json-using-nodejs/ | Markdown: https://h3manth.com/scribe/blog/rss-json-using-nodejs.md | Tags: nodejs, javascript, web Lately me and one my hacker buddies we talking about a project plan, in which RSS as JSON was a major module, some simple. - **How Caching Matters in JS?** (2012-06-19) | HTML: https://h3manth.com/scribe/how-caching-matters-js/ | Markdown: https://h3manth.com/scribe/blog/how-caching-matters-js.md | Tags: linux, opensource Caching plays a very important role, may it be on the client side or on the server side. I tired to do a tittle benchmark. - **Globbing in Scripting Languages** (2012-06-18) | HTML: https://h3manth.com/scribe/globbing-scripting-languages/ | Markdown: https://h3manth.com/scribe/blog/globbing-scripting-languages.md | Tags: ruby, python, bash Globbing is the most common and yet the most powerful operation that any scripter would use. glob() is a Unix library in JS. - **Inspecting Objects in Scripting** (2012-06-14) | HTML: https://h3manth.com/scribe/inspecting-objects-scripting/ | Markdown: https://h3manth.com/scribe/blog/inspecting-objects-scripting.md | Tags: ruby, python, javascript, web Examine the contents of a class / object is one of most useful and repetitive tasks that most of the coder do while in JS. - **Handling Internationalized Domain Name (IDN) in Scripting** (2012-06-13) | HTML: https://h3manth.com/scribe/handling-internationalized-domain-name-idn-scripting/ | Markdown: https://h3manth.com/scribe/blog/handling-internationalized-domain-name-idn-scripting.md | Tags: ruby, python, bash, web IDN is helping many, but caused a lot of trouble initially for many programming languages, specially in parsing and reading. - **Google Hourly Hot Trends on Command Line** (2012-06-12) | HTML: https://h3manth.com/scribe/google-hourly-hot-trends-command-line/ | Markdown: https://h3manth.com/scribe/blog/google-hourly-hot-trends-command-line.md | Tags: ruby, bash, web Well, /me back to pawing at Google from CLI, after few silly apps like getting the weather, news, sunrise and sets from. - **ES6 in node.js** (2012-06-11) | HTML: https://h3manth.com/scribe/es6-nodejs/ | Markdown: https://h3manth.com/scribe/blog/es6-nodejs.md | Tags: nodejs, javascript, bash, web Well first for thanks to paulmillr for his wonderful contribution of es6-shim for node.js and browsers. As ECMAScript 6. - **Get iframe contents using queryselectors** (2012-06-08) | HTML: https://h3manth.com/scribe/get-iframe-contents-using-queryselectors/ | Markdown: https://h3manth.com/scribe/blog/get-iframe-contents-using-queryselectors.md | Tags: javascript Selecting data from iframes using the power of querySelectors. Practical notes and code examples on Get iframe contents. - **Reading Logs Made Easy With Bash.** (2012-06-07) | HTML: https://h3manth.com/scribe/reading-logs-made-easy-bash/ | Markdown: https://h3manth.com/scribe/blog/reading-logs-made-easy-bash.md | Tags: bash Most of the web programmers would normally look into their applications/server error logs when they find issues, indeed. - **Reading logs made easy with bash** (2012-06-07) | HTML: https://h3manth.com/scribe/reading-logs-made-easy-with-bash/ | Markdown: https://h3manth.com/scribe/blog/reading-logs-made-easy-with-bash.md | Tags: bash, cli Most of the web programmers would normally look into their applications/server error logs when they find issues, indeed. - **What's the Deal With on{X} ?** (2012-06-07) | HTML: https://h3manth.com/scribe/whats-deal-onx/ | Markdown: https://h3manth.com/scribe/blog/whats-deal-onx.md | Tags: android M$cro$fot has made a big move! is it a realisation that open source (rather free) software/platform is the way to go or it. - **Ninja Object Properties in Scripting Languages** (2012-06-06) | HTML: https://h3manth.com/scribe/ninja-object-properties-scripting-languages/ | Markdown: https://h3manth.com/scribe/blog/ninja-object-properties-scripting-languages.md | Tags: ruby, python, javascript 10 hours ago, came across atrick-wied’s ninja object properties in JavaScript, that speaks of code as below. var x = {}. - **Sets and Maps in JavaScript** (2012-06-06) | HTML: https://h3manth.com/scribe/sets-and-maps-javascript/ | Markdown: https://h3manth.com/scribe/blog/sets-and-maps-javascript.md | Tags: javascript, web FF13 comes out with experimental support for ECMAScript 6 Map and Set objects. As maps and sets can be easily implemented. - **HTML5+JS offline/online notification** (2012-06-05) | HTML: https://h3manth.com/scribe/html5js-offlineonline-notification/ | Markdown: https://h3manth.com/scribe/blog/html5js-offlineonline-notification.md | Tags: javascript, html5 With HTML5 and some JavaScript magic, it’s very easy for a webpage/webapp to indicate if the user is offline or online in JS. - **Ninja Object Properties in Scripting languages** (2012-06-05) | HTML: https://h3manth.com/scribe/ninja-object-properties-in-scripting-languages/ | Markdown: https://h3manth.com/scribe/blog/ninja-object-properties-in-scripting-languages.md | Tags: javascript, python, ruby Ninja object properties in JavaScript and other scripting languages - using spaces and control characters as object keys. - **JavaScript One Liner Extracting Unique Words From Webpages** (2012-06-04) | HTML: https://h3manth.com/scribe/javascript-one-liner-extracting-unique-words-webpages/ | Markdown: https://h3manth.com/scribe/blog/javascript-one-liner-extracting-unique-words-webpages.md | Tags: ruby, javascript, web Unlike JSON parsing with ruby one-liner ? this is indeed a very strong raw JavaScript one liner that /me managed to frame. - **togist chrome plugin** (2012-06-04) | HTML: https://h3manth.com/scribe/togist-chrome-plugin/ | Markdown: https://h3manth.com/scribe/blog/togist-chrome-plugin.md | Tags: programming This is a simple chrome plugin that /me managed to build which helps to create public gists on github. All you need to do. - **JavaScript one liner extracting unique words from webpages** (2012-06-03) | HTML: https://h3manth.com/scribe/javascript-one-liner-extracting-unique-words-from-webpages/ | Markdown: https://h3manth.com/scribe/blog/javascript-one-liner-extracting-unique-words-from-webpages.md | Tags: javascript A very strong raw JavaScript one liner for extracting all the words in a given webpage. Practical notes and code examples. - **Javascript ReferenceError: Invalid Left-hand Side in Assignment** (2012-06-03) | HTML: https://h3manth.com/scribe/javascript-referenceerror-invalid-left-hand-side-assignment/ | Markdown: https://h3manth.com/scribe/blog/javascript-referenceerror-invalid-left-hand-side-assignment.md | Tags: javascript, git So lately was trying some silly syntax with javascript, logically it seems to work, but throw away your dry logic! Most of. - **JavaScript ReferenceError: Invalid left-hand side in assignment** (2012-06-02) | HTML: https://h3manth.com/scribe/javascript-referenceerror-invalid-left-hand-side-in-assignment/ | Markdown: https://h3manth.com/scribe/blog/javascript-referenceerror-invalid-left-hand-side-in-assignment.md | Tags: javascript Exploring interesting JavaScript reference errors and learning about ||= operator. Practical notes and code examples on. - **Hitchhikers Guide to Npm** (2012-05-30) | HTML: https://h3manth.com/scribe/hitchhikers-guide-npm/ | Markdown: https://h3manth.com/scribe/blog/hitchhikers-guide-npm.md | Tags: nodejs, javascript, bash, database Hello hackers, this post is just a simple hello-world packing tutorial for packing nodejs with npm. P.S : This does not. - **Hitchhiker's guide to npm** (2012-05-30) | HTML: https://h3manth.com/scribe/hitchhikers-guide-to-npm/ | Markdown: https://h3manth.com/scribe/blog/hitchhikers-guide-to-npm.md | Tags: javascript, nodejs A simple hello-world packing tutorial for packing nodejs with npm. Practical notes and code examples on Hitchhiker’s guide. - **7 Ruby Gems in 7 Days** (2012-05-26) | HTML: https://h3manth.com/scribe/7-ruby-gems-7-days/ | Markdown: https://h3manth.com/scribe/blog/7-ruby-gems-7-days.md | Tags: ruby, git, web So /me managed to write 7 silly ruby gems in 7 days, the below is a simple video demo of those 7 ruby gems : DEMO LInk to. - **7 ruby gems in 7 days** (2012-05-25) | HTML: https://h3manth.com/scribe/7-ruby-gems-in-7-days/ | Markdown: https://h3manth.com/scribe/blog/7-ruby-gems-in-7-days.md | Tags: ruby So /me managed to write 7 silly ruby gems in 7 days, the below is a simple video demo of those 7 ruby gems : DEMO( in JS. - **Notes From Build Awesome Command-Line Apps** (2012-05-20) | HTML: https://h3manth.com/scribe/notes-build-awesome-command-line-apps/ | Markdown: https://h3manth.com/scribe/blog/notes-build-awesome-command-line-apps.md | Tags: ruby, bash Lately I was going through book and talks on ’Build Awesome Command-Line Applications in Ruby: Control Your Computer in JS. - **Notes from Build Awesome Command-Line apps** (2012-05-19) | HTML: https://h3manth.com/scribe/notes-from-build-awesome-command-line-apps/ | Markdown: https://h3manth.com/scribe/blog/notes-from-build-awesome-command-line-apps.md | Tags: ruby Lately I was going through book and talks on ’Build Awesome Command-Line Applications in Ruby: Control Your Computer in JS. - **JSON Parsing With Ruby One-liner ?** (2012-05-18) | HTML: https://h3manth.com/scribe/json-parsing-ruby-one-liner/ | Markdown: https://h3manth.com/scribe/blog/json-parsing-ruby-one-liner.md | Tags: ruby, javascript, web Parsing JSON is one of the most common tasks that any web developer does in his daily activities. Parsing JSON with ruby. - **TypeError: Object has no method 'forEach' in JavaScript** (2012-05-18) | HTML: https://h3manth.com/scribe/typeerror-object-has-no-method-foreach-in-javascript/ | Markdown: https://h3manth.com/scribe/blog/typeerror-object-has-no-method-foreach-in-javascript.md | Tags: javascript, nodejs Iterating a NodeList in JavaScript using forEach - understanding why you get this error and how to fix it. Practical notes. - **TypeError: Object # Has No Method 'forEach' in Javascript?** (2012-05-18) | HTML: https://h3manth.com/scribe/typeerror-object-nodelist-has-no-method-foreach-javascript/ | Markdown: https://h3manth.com/scribe/blog/typeerror-object-nodelist-has-no-method-foreach-javascript.md | Tags: javascript Iterating a NodeList in javascript using forEach due to temptation, you have defiantly come across TypeError: Object # has. - **JSON parsing with ruby one-liner?** (2012-05-17) | HTML: https://h3manth.com/scribe/json-parsing-with-ruby-one-liner/ | Markdown: https://h3manth.com/scribe/blog/json-parsing-with-ruby-one-liner.md | Tags: ruby Parsing JSON is one of the most common tasks that any web developer does. Here’s how to do it with Ruby one-liners in JS. - **Native JS Like jQuery** (2012-05-14) | HTML: https://h3manth.com/scribe/native-js-jquery/ | Markdown: https://h3manth.com/scribe/blog/native-js-jquery.md | Tags: javascript, web Lately was pawing at some Selector API’s and really liked the raw power of native JS! So here is some comaprsion of Native. - **URL Scrapping With Javascript** (2012-05-12) | HTML: https://h3manth.com/scribe/url-scraping-javascript/ | Markdown: https://h3manth.com/scribe/blog/url-scraping-javascript.md | Tags: javascript, web Quite some time ago /me had coded a small entry on Hyperlink to URL and and Extracting all the links from a site which was. - **Download Images With node.js** (2012-05-11) | HTML: https://h3manth.com/scribe/download-images-nodejs/ | Markdown: https://h3manth.com/scribe/blog/download-images-nodejs.md | Tags: nodejs, bash, web All of a sudden /me gets silly and crazy thoughts to do useless tasks that just pleases me only! Here is one such task, the. - **TypeError: Can't Convert Regexp Into String** (2012-05-01) | HTML: https://h3manth.com/scribe/typeerror-cant-convert-regexp-string/ | Markdown: https://h3manth.com/scribe/blog/typeerror-cant-convert-regexp-string.md | Tags: ruby in Ruby So what? #!/usr/bin/env ruby ’hemanth’.include?(/hem/) =begin Exectuing the above code will result in : =end It so. - **TypeError: can't convert Regexp into String** (2012-04-30) | HTML: https://h3manth.com/scribe/typeerror-cant-convert-regexp-into-string/ | Markdown: https://h3manth.com/scribe/blog/typeerror-cant-convert-regexp-into-string.md | Tags: ruby How to handle Ruby’s TypeError when using Regexp with String#include? Practical notes and code examples on TypeError: can’t. - **One click DuckDuckGo** (2012-04-24) | HTML: https://h3manth.com/scribe/one-click-duckduckgo/ | Markdown: https://h3manth.com/scribe/blog/one-click-duckduckgo.md | Tags: linux, bash Search any text that is selected anywhere in the OS with DuckDuckGo in a single click! Practical notes and code examples on. - **Comparing Strings With Variable White Spacing** (2012-04-12) | HTML: https://h3manth.com/scribe/comparing-strings-variable-white-spacing/ | Markdown: https://h3manth.com/scribe/blog/comparing-strings-variable-white-spacing.md | Tags: ruby, python, javascript Stings may sound like 101 of programming, but just a glimpse of TAOCP would turn the thought inside out! Comparing Strings. - **Watir Webdriver attach window** (2012-04-03) | HTML: https://h3manth.com/scribe/watir-webdriver-attach-window/ | Markdown: https://h3manth.com/scribe/blog/watir-webdriver-attach-window.md | Tags: ruby, testing How to switch between windows in Watir Webdriver when the attach method is missing. Practical notes and code examples on. - **Remotely Enable Remote Desktop on Debian** (2012-03-10) | HTML: https://h3manth.com/scribe/remotely-enable-remote-desktop-debian/ | Markdown: https://h3manth.com/scribe/blog/remotely-enable-remote-desktop-debian.md | Tags: ubuntu, linux It so happened, as I was working from home last Friday, box there at office had only ssh enabled, but was in need of remote. - **Remotely enable remote desktop on Debian** (2012-03-09) | HTML: https://h3manth.com/scribe/remotely-enable-remote-desktop-on-debian/ | Markdown: https://h3manth.com/scribe/blog/remotely-enable-remote-desktop-on-debian.md | Tags: programming It so happened, as I was working from home last Friday, box there at office had only ssh enabled, but was in need of remote. - **Android Remote Control Setup** (2012-02-14) | HTML: https://h3manth.com/scribe/android-remote-control-setup/ | Markdown: https://h3manth.com/scribe/blog/android-remote-control-setup.md | Tags: javascript, python, ruby Control your Android devices while running scripts on your computer! Wonder can be done with ASE and an android device along. - **Tweaking Command Not Found** (2012-01-31) | HTML: https://h3manth.com/scribe/tweaking-command-not-found/ | Markdown: https://h3manth.com/scribe/blog/tweaking-command-not-found.md | Tags: python Most of the time in ubuntu, when we come across the message like : The program ’program_name’ is currently not installed. - **Hemanth.HM** (2012-01-01) | HTML: https://h3manth.com/scribe/to-h-ruby-20/ | Markdown: https://h3manth.com/scribe/blog/to-h-ruby-20.md | Tags: ruby, git With few major changes ruby 2.0 is out today, out the many new features I really liked the toh We can convert a class to a. - **Getting server info using nodejs** (2011-12-28) | HTML: https://h3manth.com/scribe/getting-server-info-using-nodejs/ | Markdown: https://h3manth.com/scribe/blog/getting-server-info-using-nodejs.md | Tags: javascript, nodejs Getting server information using nodejs is very easy especially using the os module. Wrote a simple script to fetch in JS. - **HTTP-request Header From node.js** (2011-12-23) | HTML: https://h3manth.com/scribe/http-request-header-nodejs/ | Markdown: https://h3manth.com/scribe/blog/http-request-header-nodejs.md | Tags: nodejs, javascript, ubuntu, git The message header of requests and responses in the Hypertext Transfer Protocol define the operating parameters of an HTTP. - **HTTP-request header from node.js** (2011-12-22) | HTML: https://h3manth.com/scribe/http-request-header-from-nodejs/ | Markdown: https://h3manth.com/scribe/blog/http-request-header-from-nodejs.md | Tags: javascript, nodejs The message header of requests and responses in the Hypertext Transfer Protocol define the operating parameters of an HTTP. - **Unicode Symbols as Function Names** (2011-12-01) | HTML: https://h3manth.com/scribe/unicode-symbols-function-names/ | Markdown: https://h3manth.com/scribe/blog/unicode-symbols-function-names.md | Tags: python, bash Unicode stings for function/method names is a very rare scenario, but who knows in the near future people might use them. - **Unicode symbols as function names** (2011-11-30) | HTML: https://h3manth.com/scribe/unicode-symbols-as-function-names/ | Markdown: https://h3manth.com/scribe/blog/unicode-symbols-as-function-names.md | Tags: javascript, python, ruby Unicode stings for function/method names is a very rare scenario, but who knows in the near future people might use them. - **Invalid HTML in Google's Homepage** (2011-11-19) | HTML: https://h3manth.com/scribe/invalid-html-googles-homepage/ | Markdown: https://h3manth.com/scribe/blog/invalid-html-googles-homepage.md | Tags: javascript, web When validating my homepage /me got 1Error and 1warning, was curious to paw more! w3.org validator says : 37 Errors, 2 in JS. - **Simple Closure for Cross Browser XHR Instance** (2011-11-14) | HTML: https://h3manth.com/scribe/simple-closure-cross-browser-xhr-instance/ | Markdown: https://h3manth.com/scribe/blog/simple-closure-cross-browser-xhr-instance.md | Tags: nodejs, web Yes that is right, there are many libraries to handle XHR, but raw JS is always fun! There are many ways of doing this, but. - **typeof JavaScript tweaked** (2011-11-08) | HTML: https://h3manth.com/scribe/typeof-javascript-tweaked/ | Markdown: https://h3manth.com/scribe/blog/typeof-javascript-tweaked.md | Tags: javascript A simple but very effective tweak for the typeof operator in JavaScript. Practical notes and code examples on typeof in JS. - **JavaScript Event tracking and management** (2011-11-06) | HTML: https://h3manth.com/scribe/javascript-event-tracking-and-management/ | Markdown: https://h3manth.com/scribe/blog/javascript-event-tracking-and-management.md | Tags: javascript A simple prototype with raw JavaScript to make basic event management and tracking easier. Practical notes and code examples. - **Simple Cookie Management With JavaScript** (2011-10-25) | HTML: https://h3manth.com/scribe/simple-cookie-management-javascript/ | Markdown: https://h3manth.com/scribe/blog/simple-cookie-management-javascript.md | Tags: javascript On of the most common things that most of the web developer would do is cookie management. Was pawing at some JavaScript. - **Introducing the Slang API** (2011-10-24) | HTML: https://h3manth.com/scribe/introducing-slang-api/ | Markdown: https://h3manth.com/scribe/blog/introducing-slang-api.md | Tags: javascript, android, web Lately was working on some slang filtering module, but for the LOLz of it made a simple JSON API. The deal is pretty simple. - **Simple Cookie Management with JavaScript** (2011-10-24) | HTML: https://h3manth.com/scribe/simple-cookie-management-with-javascript/ | Markdown: https://h3manth.com/scribe/blog/simple-cookie-management-with-javascript.md | Tags: javascript A simple cookie management class in JavaScript that does basic cookie management. Practical notes and code examples on in JS. - **JavaScript MapReduce One Liner?!** (2011-10-15) | HTML: https://h3manth.com/scribe/javascript-mapreduce-one-liner/ | Markdown: https://h3manth.com/scribe/blog/javascript-mapreduce-one-liner.md | Tags: python, nodejs, javascript, database After Word frequency using mapreduce in python I got my paws dirty with some silly javascript, after reducing a whole chuck. - **Word Frequency With Mapreduce in Python** (2011-09-23) | HTML: https://h3manth.com/scribe/word-frequency-mapreduce-python/ | Markdown: https://h3manth.com/scribe/blog/word-frequency-mapreduce-python.md | Tags: python, mapreduce, algorithms Implementing Google’s MapReduce programming model in Python to compute word frequency counts across text documents using. - **Setup Your Own Cloud in 30 Seconds** (2011-09-01) | HTML: https://h3manth.com/scribe/setup-your-own-cloud-30-seconds/ | Markdown: https://h3manth.com/scribe/blog/setup-your-own-cloud-30-seconds.md | Tags: javascript, git, bash, database Yes from past few years there is hell lot of hype for cloud. Which is the new name the enterprise gave for the old game of. - **Instant Upload Images to Imgur From Android** (2011-08-31) | HTML: https://h3manth.com/scribe/instant-upload-images-imgur-android/ | Markdown: https://h3manth.com/scribe/blog/instant-upload-images-imgur-android.md | Tags: python, javascript, android, web Python needs to be embraced for it’s capacity to gel with android so well and make things easier with simple and fun in JS. - **Figlr ASCII Art on Fly** (2011-08-30) | HTML: https://h3manth.com/scribe/figlr-ascii-art-fly/ | Markdown: https://h3manth.com/scribe/blog/figlr-ascii-art-fly.md | Tags: javascript, web Figlr is a simple fun tool to generate FIGlet text. Those are normally used to make ASCII art banners. It makes use of in JS. - **Programmatically delete SMS in android using python** (2011-08-30) | HTML: https://h3manth.com/scribe/programmatically-delete-sms-androidpython/ | Markdown: https://h3manth.com/scribe/blog/programmatically-delete-sms-androidpython.md | Tags: python, android Deleting SMS text has been on of issues with default SMS clients of Andriod OS. Issue 5669 talks a lot about it. The most. - **Programmatically Delete SMS in Android Using Python** (2011-08-29) | HTML: https://h3manth.com/scribe/programmatically-delete-sms-android-using-python/ | Markdown: https://h3manth.com/scribe/blog/programmatically-delete-sms-android-using-python.md | Tags: python, android, web Deleting SMS text has been on of issues with default SMS clients of Andriod OS. Issue 5669 talks a lot about it. The most. - **Yoda Talks to XMPP, Twitter and Identi.ca** (2011-08-28) | HTML: https://h3manth.com/scribe/yoda-talks-xmpp-twitter-and-identica/ | Markdown: https://h3manth.com/scribe/blog/yoda-talks-xmpp-twitter-and-identica.md | Tags: python, git, web This is more a tribute to Master Yoda rather than coding! The idea was to use a simple python script to update my gmail. - **Random Images From Wikipedia** (2011-08-27) | HTML: https://h3manth.com/scribe/random-images-wikipedia/ | Markdown: https://h3manth.com/scribe/blog/random-images-wikipedia.md | Tags: javascript, web After Random images from xkcd as wallpaper it was time for some more fun, this time did a simple script to get Random images. - **Wikipedia Search Summary API** (2011-08-27) | HTML: https://h3manth.com/scribe/wikipedia-search-summary-api/ | Markdown: https://h3manth.com/scribe/blog/wikipedia-search-summary-api.md | Tags: javascript, web After Random images from wikipedia I made another simple API to get the summary for a search term using PHP. It’s a JSONP. - **Compressing Files With Python, Perl, Ruby and Php** (2011-08-24) | HTML: https://h3manth.com/scribe/compressing-files-python-perl-ruby-and-php/ | Markdown: https://h3manth.com/scribe/blog/compressing-files-python-perl-ruby-and-php.md | Tags: ruby, python, bash, web is one of the most common tasks any programmer would have done. The below is a simple comparison of compression paradigms. - **Get Json Ip Service** (2011-08-24) | HTML: https://h3manth.com/scribe/get-json-ip-service/ | Markdown: https://h3manth.com/scribe/blog/get-json-ip-service.md | Tags: javascript Getting client IP address is one common thing most of the web developers do, but getting the same with JavaScript is not. - **SMS From Android Using Python** (2011-08-22) | HTML: https://h3manth.com/scribe/sms-android-using-python/ | Markdown: https://h3manth.com/scribe/blog/sms-android-using-python.md | Tags: python, javascript, android, web All one needs to have is Scripting layer installed in the mobile device. Use the QR code below to get the apk and install. - **My Google Interview > /dev/null** (2011-07-31) | HTML: https://h3manth.com/scribe/my-google-interview-devnull/ | Markdown: https://h3manth.com/scribe/blog/my-google-interview-devnull.md | Tags: linux, opensource It all started couple of months back, on a fine sunny morning i read a mail with a subject Career Opportunities @ Google at. - **Selective Directory Index From Htacess** (2011-07-03) | HTML: https://h3manth.com/scribe/selective-directory-index-htacess/ | Markdown: https://h3manth.com/scribe/blog/selective-directory-index-htacess.md | Tags: linux, opensource Apache Module moddir provides ’trailing slash’ redirects and serving directory index files. ’The DirectoryIndex directive. - **Downloading Files : A Comparative Study** (2011-06-12) | HTML: https://h3manth.com/scribe/downloading-files-comparative-study/ | Markdown: https://h3manth.com/scribe/blog/downloading-files-comparative-study.md | Tags: ruby, python A simple case study of downloading files in perl, ruby, python and php. Assumption : The input for these scripts are in JS. - **GNU MediaGoblin** (2011-05-03) | HTML: https://h3manth.com/scribe/gnu-mediagoblin/ | Markdown: https://h3manth.com/scribe/blog/gnu-mediagoblin.md | Tags: python, ubuntu, git, web What is GNU MediaGoblin? Initially, a place to store all your photos and artwork, more better than (Flickr, DeviantArt in JS. - **Keyless Auto Login SSH Script** (2011-04-09) | HTML: https://h3manth.com/scribe/keyless-auto-login-ssh-script/ | Markdown: https://h3manth.com/scribe/blog/keyless-auto-login-ssh-script.md | Tags: bash, linux keys less login has been easy always with ssh keygen and copy-id, but just a small bash loop will help auto login on in JS. - **Server-Side JavaScript With Node.js** (2011-03-13) | HTML: https://h3manth.com/scribe/server-side-javascript-nodejs/ | Markdown: https://h3manth.com/scribe/blog/server-side-javascript-nodejs.md | Tags: nodejs, javascript, ubuntu, git Installing node.js on a Debian machine : sudo apt-get install g++ curl libssl-dev apache2-utils git-core git clone cd... - **Stealing Google Logos Using Yahoo API** (2011-03-07) | HTML: https://h3manth.com/scribe/stealing-google-logos-using-yahoo-api/ | Markdown: https://h3manth.com/scribe/blog/stealing-google-logos-using-yahoo-api.md | Tags: javascript Many love browsing through Google Logos, so do some of my friends, was planning to make a simple page with infinite scroll. - **The Color Clock** (2011-01-23) | HTML: https://h3manth.com/scribe/color-clock/ | Markdown: https://h3manth.com/scribe/blog/color-clock.md | Tags: git, web I came across the thecolourclock wanted to check out the source sadly it was build in flash so tired to make one with some. - **Multi Lingual Xmpp Translate Bot** (2011-01-02) | HTML: https://h3manth.com/scribe/multi-lingual-xmpp-translate-bot/ | Markdown: https://h3manth.com/scribe/blog/multi-lingual-xmpp-translate-bot.md | Tags: ruby, javascript, git, web Multi lingual translate bot code in ruby after the xmpp ruby chat-bot this bot is coding in ruby with the help of tolang. - **Python Objects to JSON String** (2010-12-29) | HTML: https://h3manth.com/scribe/python-objects-json-string/ | Markdown: https://h3manth.com/scribe/blog/python-objects-json-string.md | Tags: python, javascript, bash Python provides a easy way to handle JSON, by importing thejson module, one can easily encode a list of dicts or a dict of. - **Getting the Redirected URL** (2010-11-12) | HTML: https://h3manth.com/scribe/getting-redirected-url/ | Markdown: https://h3manth.com/scribe/blog/getting-redirected-url.md | Tags: bash, web Many time one needs to get the redirected URL, the reasons might be many but the logic remains the same. HTTP request in JS. - **Google I'm Feeling Lucky in Python and Ruby** (2010-11-08) | HTML: https://h3manth.com/scribe/google-im-feeling-lucky-python-and-ruby/ | Markdown: https://h3manth.com/scribe/blog/google-im-feeling-lucky-python-and-ruby.md | Tags: ruby, python, javascript, web With the xmpp and irc bots : l33ty.l33t and l33ty so far i’m having fun coding them, of all the methods in them i liked the. - **XMPP Ruby Chat Bot** (2010-11-06) | HTML: https://h3manth.com/scribe/xmpp-ruby-chat-bot/ | Markdown: https://h3manth.com/scribe/blog/xmpp-ruby-chat-bot.md | Tags: ruby, python, ubuntu, git After Python-IRC-bot my interest was in making a gmail bot, that lead me to make a simple bot very much like the previous. - **Python IRC Bot** (2010-10-31) | HTML: https://h3manth.com/scribe/python-irc-bot/ | Markdown: https://h3manth.com/scribe/blog/python-irc-bot.md | Tags: python, ubuntu, git, web It started with the intention of making a simple IRC l33t translate bot after the l33t translation API. l33ty is an IRC bot. - **L33t Translator** (2010-10-14) | HTML: https://h3manth.com/scribe/l33t-translator/ | Markdown: https://h3manth.com/scribe/blog/l33t-translator.md | Tags: javascript, git, web Here I introduce a dynamic 733+ translator an on the fly translator similar to Google translate. Where i can see the in JS. - **Edit Dot Rc Files and Auto Source** (2010-10-06) | HTML: https://h3manth.com/scribe/edit-dot-rc-files-and-auto-source/ | Markdown: https://h3manth.com/scribe/blog/edit-dot-rc-files-and-auto-source.md | Tags: python, bash Here is the list which makes things clear: Type of shell | .rc support? | Path to rc ---|---|--- bash | yes | /.bashrc ash. - **Copying Shared Library Dependencies** (2010-10-04) | HTML: https://h3manth.com/scribe/copying-shared-library-dependencies/ | Markdown: https://h3manth.com/scribe/blog/copying-shared-library-dependencies.md | Tags: bash, linux Shared library dependenices can be easily listed with the help of ldd– list dynamic dependencies of executable files or. - **Time Zone Conversions** (2010-09-27) | HTML: https://h3manth.com/scribe/time-zone-conversions/ | Markdown: https://h3manth.com/scribe/blog/time-zone-conversions.md | Tags: bash, linux ’Time is constant, we come and go’, but the beauty of earth is so, that time varies with space. I made a simple BASH script. - **Curious Case of Combining Pdfs** (2010-09-24) | HTML: https://h3manth.com/scribe/curious-case-combining-pdfs/ | Markdown: https://h3manth.com/scribe/blog/curious-case-combining-pdfs.md | Tags: bash, linux The case: Few many chapters of some study material,files like chapter1.pdf, chapter2.pdf....chapterN.pdf, was easy to loop. - **Limpid a Simple App for P2pu** (2010-09-22) | HTML: https://h3manth.com/scribe/limpid-simple-app-p2pu/ | Markdown: https://h3manth.com/scribe/blog/limpid-simple-app-p2pu.md | Tags: python, web, linux It all start with a simple idea, i got of embedding a vt in a terminal, later on it turned out to be a stand alone all, with. - **Setup Diaspora on Ubuntu** (2010-09-16) | HTML: https://h3manth.com/scribe/setup-diaspora-ubuntu/ | Markdown: https://h3manth.com/scribe/blog/setup-diaspora-ubuntu.md | Tags: ubuntu, git, bash, web Was seeing lot of people facing issues to in set up, including me at the beginning, so i thought to make a setup script for. - **Insight of Google Instant** (2010-09-08) | HTML: https://h3manth.com/scribe/insight-google-instant/ | Markdown: https://h3manth.com/scribe/blog/insight-google-instant.md | Tags: web Google Instant is a new search enhancement that shows results as you type. Advantages to the users: 1. Faster a better live. - **Meet RMS** (2010-09-08) | HTML: https://h3manth.com/scribe/meet-rms/ | Markdown: https://h3manth.com/scribe/blog/meet-rms.md | Tags: ubuntu, web, linux RMS had been to RV college of engineering today to give a speech on Free Software, i was lucky enough to get a picture in JS. - **Mozilla P2PU Course** (2010-09-02) | HTML: https://h3manth.com/scribe/mozilla-p2pu-course/ | Markdown: https://h3manth.com/scribe/blog/mozilla-p2pu-course.md | Tags: web Join now The main goal of P2PU is to,’create a vibrant, peer-led system that helps people around the world easily access. - **PyBrain** (2010-08-28) | HTML: https://h3manth.com/scribe/pybrain/ | Markdown: https://h3manth.com/scribe/blog/pybrain.md | Tags: python, ubuntu, git, web The data processing flow : PyBrain for whom? 1. Students. 2. Teachers. 3. Developers. PyBrain for what? 1. Neural Networks. - **Gmail Voice and Video Chat Comes to GNU/Linux at Last** (2010-08-20) | HTML: https://h3manth.com/scribe/gmail-voice-and-video-chat-comes-gnulinux-last/ | Markdown: https://h3manth.com/scribe/blog/gmail-voice-and-video-chat-comes-gnulinux-last.md | Tags: web, linux Today gmail has announced and rolled out this feature yes there were many alternatives like Pidgin, Empathy with this in JS. - **SVG Smiley** (2010-08-18) | HTML: https://h3manth.com/scribe/svg-smiley/ | Markdown: https://h3manth.com/scribe/blog/svg-smiley.md | Tags: web If SVG is not rendered in your browser, you can save the image from here If SVG is not rendered in your browser, you can. - **Hacker News Widget** (2010-08-15) | HTML: https://h3manth.com/scribe/hacker-news-widget/ | Markdown: https://h3manth.com/scribe/blog/hacker-news-widget.md | Tags: javascript, android, git, web Technical guide and code examples on Hacker News Widget (javascript, linux) by Hemanth HM. Practical notes and code examples. - **Lemote Yeeloong** (2010-08-10) | HTML: https://h3manth.com/scribe/lemote-yeeloong/ | Markdown: https://h3manth.com/scribe/blog/lemote-yeeloong.md | Tags: web Few years back when i gave a talk on free software, one of the guys in the crowd asked me don’t you have free hardware? I. - **Speaking Clock GNU/Linux** (2010-08-05) | HTML: https://h3manth.com/scribe/speaking-clock-gnulinux/ | Markdown: https://h3manth.com/scribe/blog/speaking-clock-gnulinux.md | Tags: python, ubuntu, bash, web Python Code Prerequisite:pyttsx #!/usr/bin/env python import pyttsx import time engine = pyttsx.init() rate = — Scribe notes. - **Scripting 101 Reddit Course** (2010-08-03) | HTML: https://h3manth.com/scribe/scripting-101-reddit-course/ | Markdown: https://h3manth.com/scribe/blog/scripting-101-reddit-course.md | Tags: ruby, python, bash, web ’The University of Reddit is the product of free intellectualism and is a haven for the sharing of knowledge. Teachers and. - **YQL YUI and JQuery** (2010-07-31) | HTML: https://h3manth.com/scribe/yql-yui-and-jquery/ | Markdown: https://h3manth.com/scribe/blog/yql-yui-and-jquery.md | Tags: javascript, git, database, web Data 1. Query : select from github.user.info where id=’hemanth’ 2.The REST query... Practical notes and code examples on. - **Twiit Your Google Status** (2010-07-28) | HTML: https://h3manth.com/scribe/twiit-your-google-status/ | Markdown: https://h3manth.com/scribe/blog/twiit-your-google-status.md | Tags: python, bash, web After Finding invisible mates I tried a simple python script again to do me a neat job of twitting and setting the same as. - **Find Your Invisible Friends on Gmail** (2010-07-18) | HTML: https://h3manth.com/scribe/find-your-invisible-friends-gmail/ | Markdown: https://h3manth.com/scribe/blog/find-your-invisible-friends-gmail.md | Tags: python, web After google news in terminal i was much interested in playing with XMPP Extensible Messaging and Presence Protocol, my. - **Sort Text Blocks** (2010-07-16) | HTML: https://h3manth.com/scribe/sort-text-blocks/ | Markdown: https://h3manth.com/scribe/blog/sort-text-blocks.md | Tags: bash I recently came across a simple task, wherein i had to sort a massive text file which was an output of a heavy data in JS. - **Desktop Session Detection Python** (2010-07-05) | HTML: https://h3manth.com/scribe/desktop-session-detection-python/ | Markdown: https://h3manth.com/scribe/blog/desktop-session-detection-python.md | Tags: python As, i was doing a bug fix for this bug i had to find a way to detect the current desktop session, based on which further. - **Google News in Terminal** (2010-07-05) | HTML: https://h3manth.com/scribe/google-news-terminal/ | Markdown: https://h3manth.com/scribe/blog/google-news-terminal.md | Tags: python, bash, web After Upload to picasa from cli and google-sunrise-sunset-terminal in past few days, i was gaming on some substantial data. - **RSS Feed Twitt Bots** (2010-07-02) | HTML: https://h3manth.com/scribe/rss-feed-twitt-bots/ | Markdown: https://h3manth.com/scribe/blog/rss-feed-twitt-bots.md | Tags: ruby, python, linux The open source world has always be a great source of energy to all especially for code monkeys and terminal junkies, not. - **Twitter Updates With Geolocation** (2010-07-01) | HTML: https://h3manth.com/scribe/twitter-updates-geolocation/ | Markdown: https://h3manth.com/scribe/blog/twitter-updates-geolocation.md | Tags: python, web Update your twitter with your current geolocation, from terminal I was playing with a python wrapper around the Twitter API. - **Bash vs Python** (2010-06-30) | HTML: https://h3manth.com/scribe/bash-vs-python/ | Markdown: https://h3manth.com/scribe/blog/bash-vs-python.md | Tags: python, bash A simple case study: It’s not about one programming language killing and replacing the other, its all about the purpose!. - **Mutt Gmail Labels and Contact Suggestions via IMAP** (2010-06-29) | HTML: https://h3manth.com/scribe/mutt-gmail-labels-and-contact-suggestions-imap/ | Markdown: https://h3manth.com/scribe/blog/mutt-gmail-labels-and-contact-suggestions-imap.md | Tags: ubuntu, git, linux No matter how many E-Mail client are released, the power of Mutt remains unbeaten IMAP or POP3 ?! This has become much a. - **Google Sunrise Sunset From Terminal** (2010-06-28) | HTML: https://h3manth.com/scribe/google-sunrise-sunset-terminal/ | Markdown: https://h3manth.com/scribe/blog/google-sunrise-sunset-terminal.md | Tags: ubuntu, git, bash, web As Google starts Sunrise and Sunset query, i tried these silly bash functions, make it more better. Prerequisites in JS fast. - **Getme Video** (2010-06-22) | HTML: https://h3manth.com/scribe/getme-video/ | Markdown: https://h3manth.com/scribe/blog/getme-video.md | Tags: ubuntu, bash Ingredients: youtube-dl, ffmpeg, ffmpeg2theora sudo apt-get install youtube-dl ffmpeg ffmpeg2theora cat /.bashrc ’ fi fi }. - **Sendmails via Sendmail With Attachments** (2010-06-22) | HTML: https://h3manth.com/scribe/sendmails-sendmail-attachments/ | Markdown: https://h3manth.com/scribe/blog/sendmails-sendmail-attachments.md | Tags: python, web After Send mail via python it was time to try real sendmail. [ From the FAQ pages of sendmail ] How do I create attachments. - **Random Images From Xkcd as Wallpaper** (2010-06-20) | HTML: https://h3manth.com/scribe/random-images-xkcd-wallpaper/ | Markdown: https://h3manth.com/scribe/blog/random-images-xkcd-wallpaper.md | Tags: bash, web, linux Afterhowto use real-time earth wallpaper i tired to make some random xkcd images as my wallpaper. The below is a simple. - **Upload to Picasa From Command Line Using Googlecl** (2010-06-19) | HTML: https://h3manth.com/scribe/upload-picasa-command-line-using-googlecl/ | Markdown: https://h3manth.com/scribe/blog/upload-picasa-command-line-using-googlecl.md | Tags: python, ubuntu, bash, web Specially for Nikon users sudo apt-get install ufraw-batch cd /Pictures/Nikon ufraw-batch --out-type=jpeg .NEF ; mkidr nef. - **OpenVBX a Web-based Open Source Phone System.** (2010-06-15) | HTML: https://h3manth.com/scribe/openvbx-web-based-open-source-phone-system/ | Markdown: https://h3manth.com/scribe/blog/openvbx-web-based-open-source-phone-system.md | Tags: android, git, bash, database ’OpenVBX is an open source PHP/MySQL application that helps developers build rich, high quality Internet phone and SMS in JS. - **Extended Experiment With Command Line Dictionary** (2010-06-13) | HTML: https://h3manth.com/scribe/extended-experiment-command-line-dictionary/ | Markdown: https://h3manth.com/scribe/blog/extended-experiment-command-line-dictionary.md | Tags: ubuntu, bash, web, linux After my old experiments with dictionary server protocol linux rfc 2229 i just wanted to try getting a mammoth list of in JS. - **Join Operation Clean Sweep** (2010-06-07) | HTML: https://h3manth.com/scribe/join-operation-clean-sweep/ | Markdown: https://h3manth.com/scribe/blog/join-operation-clean-sweep.md | Tags: ubuntu, web Read more Operation Cleansweep was launched at UDS-M by Jono Bacon. The below the skeleton of the Workflow from the review. - **MyGooglepage** (2010-06-07) | HTML: https://h3manth.com/scribe/mygooglepage/ | Markdown: https://h3manth.com/scribe/blog/mygooglepage.md | Tags: web As Google is rolling there new feature of changing the background of the main search page, i created the above with one of. - **Ubuntu 10.10 (Maverick Meerkat) Alpha 1 Get It Test It** (2010-06-03) | HTML: https://h3manth.com/scribe/ubuntu-1010-maverick-meerkat-alpha-1-get-it-test-it/ | Markdown: https://h3manth.com/scribe/blog/ubuntu-1010-maverick-meerkat-alpha-1-get-it-test-it.md | Tags: ubuntu, web Ubuntu 10.10 (Maverick Meerkat) Alpha 1 Get It Test It — [] Download ubuntu 10.10 alpha1 Practical notes and code examples. - **sudosocial.me** (2010-06-02) | HTML: https://h3manth.com/scribe/sudosocialme/ | Markdown: https://h3manth.com/scribe/blog/sudosocialme.md | Tags: git, web See the video and also do visit sudosocial.me SudoSocial - An Introduction from Mozilla Labs README file. Practical notes. - **VLC 1.1.0 Release Candidate With WebM / VP8** (2010-05-28) | HTML: https://h3manth.com/scribe/vlc-110-release-candidate-webm-vp8/ | Markdown: https://h3manth.com/scribe/blog/vlc-110-release-candidate-webm-vp8.md | Tags: git, web, linux ’The WebM project is dedicated to developing a high-quality, open video format for the web that is freely available to in JS. - **Google Chrome Is Stable for GNU/Linux Now** (2010-05-26) | HTML: https://h3manth.com/scribe/google-chrome-stable-gnulinux-now/ | Markdown: https://h3manth.com/scribe/blog/google-chrome-stable-gnulinux-now.md | Tags: ubuntu, web, linux The image shows an error which says, google-chrome-beta is conflicting package, so what is upgrade? Google Chrome is stable. - **How to Get Info About All the Nodes in the Network via SSH ?** (2010-05-17) | HTML: https://h3manth.com/scribe/how-get-info-about-all-nodes-network-ssh/ | Markdown: https://h3manth.com/scribe/blog/how-get-info-about-all-nodes-network-ssh.md | Tags: bash, linux Logic: 1. Checking if the host is alive. 2. Getting info about them, via remote commands. Steps: 1. Prepare password free. - **Surfraw - a Fast Unix Command Line Interface to WWW Services** (2010-05-12) | HTML: https://h3manth.com/scribe/surfraw-fast-unix-command-line-interface-www-services/ | Markdown: https://h3manth.com/scribe/blog/surfraw-fast-unix-command-line-interface-www-services.md | Tags: ubuntu, bash ’Surfraw provides a fast unix command line interface to a variety of popular WWW search engines and other artifacts of in JS. - **Embedding Google Wave** (2010-05-01) | HTML: https://h3manth.com/scribe/embedding-google-wave/ | Markdown: https://h3manth.com/scribe/blog/embedding-google-wave.md | Tags: web Embedding Google Wave — Embedding Google Wave: Sample WAVES embedded Practical notes and code examples by Hemanth HM in JS. - **How Google Wave Embedding Works ?** (2010-05-01) | HTML: https://h3manth.com/scribe/how-google-wave-embedding-works/ | Markdown: https://h3manth.com/scribe/blog/how-google-wave-embedding-works.md | Tags: javascript The flow of embedding a wave to any webpage The URI will be like : googlewavedomain#Postion!w[Code] The embed code will be. - **My Experience With P2pu** (2010-04-28) | HTML: https://h3manth.com/scribe/my-experience-p2pu/ | Markdown: https://h3manth.com/scribe/blog/my-experience-p2pu.md | Tags: web p2pu Learning for everyone, by everyone, about almost anything. ’The Peer 2 Peer University (P2PU) is an online community. - **RFC Finder a Desktop App** (2010-04-28) | HTML: https://h3manth.com/scribe/rfc-finder-desktop-app/ | Markdown: https://h3manth.com/scribe/blog/rfc-finder-desktop-app.md | Tags: ubuntu, linux The idea was to make a desktop application for GNU/Linux where you could make searching Request for Comments (RFC), easier. - **Ubuntu Family a Happy Family** (2010-04-24) | HTML: https://h3manth.com/scribe/ubuntu-family-happy-family/ | Markdown: https://h3manth.com/scribe/blog/ubuntu-family-happy-family.md | Tags: ubuntu, web Ubuntu family, I made a collage work out of all the pics of ubuntu code names, inspired by nizarus. Version | Code name |. - **Fixed Enabling Desktop Effects for ATI in Ubuntu Lucid** (2010-04-22) | HTML: https://h3manth.com/scribe/fixed-enabling-desktop-effects-ati-ubuntu-lucid/ | Markdown: https://h3manth.com/scribe/blog/fixed-enabling-desktop-effects-ati-ubuntu-lucid.md | Tags: ubuntu, linux 0.sudo apt-get purge fglrx-modaliases fglrx-amdcccle fglrx-kernel-source xorg-driver-fglrx xorg-driver-fglrx-dev 1.reboot. - **QuickShot** (2010-04-21) | HTML: https://h3manth.com/scribe/quickshot/ | Markdown: https://h3manth.com/scribe/blog/quickshot.md | Tags: ubuntu, web Take screen shots in your language using an intuitive and semi-automated step-by-step process Install it: $ sudo in code. - **An Ants Journey in a Planet Called IBM** (2010-04-14) | HTML: https://h3manth.com/scribe/ants-journey-planet-called-ibm/ | Markdown: https://h3manth.com/scribe/blog/ants-journey-planet-called-ibm.md | Tags: linux, opensource Most of us would have attended many conferences and seminars, with an agenda a topic too and yes indeed lunch and back home. - **GCC 4.5.0 Released!** (2010-04-14) | HTML: https://h3manth.com/scribe/gcc-450-released/ | Markdown: https://h3manth.com/scribe/blog/gcc-450-released.md | Tags: web, linux Status report form From: Richard Guenther The GCC 4.5.0 release has been created and the branch is now open for regression. - **Go on Ubuntu** (2010-04-06) | HTML: https://h3manth.com/scribe/go-ubuntu/ | Markdown: https://h3manth.com/scribe/blog/go-ubuntu.md | Tags: python, ubuntu, bash, linux Go is a compiled, garbage-collected, concurrent programming language developed by Google Inc. Below is a simple script to. - **Generate Unique Random Alphanumeric Strings Ruby** (2010-03-31) | HTML: https://h3manth.com/scribe/generate-unique-random-alphanumeric-strings-ruby/ | Markdown: https://h3manth.com/scribe/blog/generate-unique-random-alphanumeric-strings-ruby.md | Tags: ruby, linux There are many ways to achieve the same, after meddling with different ways and from the help of few ruby clans, I could. - **Google's Web Application Security Scanner** (2010-03-20) | HTML: https://h3manth.com/scribe/googles-web-application-security-scanner/ | Markdown: https://h3manth.com/scribe/blog/googles-web-application-security-scanner.md | Tags: bash, web, linux skipfish - web application security scanner ’Skipfish is an active web application security reconnaissance tool. It prepares. - **Script to Install Oracle** (2010-03-12) | HTML: https://h3manth.com/scribe/script-install-oracle/ | Markdown: https://h3manth.com/scribe/blog/script-install-oracle.md | Tags: ubuntu, bash, web Simple hack to install oracle on Ubuntu sudo sh -c ’echo ’deb unstable main non-free’ /etc/apt/sources.list’ wget in JS fast. - **CLI twitpic** (2010-03-05) | HTML: https://h3manth.com/scribe/cli-twitpic/ | Markdown: https://h3manth.com/scribe/blog/cli-twitpic.md | Tags: bash, linux, cli Bash CLI script using curl and multipart/form-data to upload images directly to TwitPic and post status updates to Twitter. - **Insert into mysql DB from text files** (2010-03-05) | HTML: https://h3manth.com/scribe/insert-mysql-db-text-files/ | Markdown: https://h3manth.com/scribe/blog/insert-mysql-db-text-files.md | Tags: bash, mysql, linux Bash script using file descriptors, sed, awk, and MySQL CLI to parse words and meanings from text files and batch-insert. - **Install SSL Certificate Tomcat bash script** (2010-03-05) | HTML: https://h3manth.com/scribe/install-ssl-certificate-tomcat-bash-script/ | Markdown: https://h3manth.com/scribe/blog/install-ssl-certificate-tomcat-bash-script.md | Tags: bash Automated Bash script to import and install SSL certificates into the Java keystore for Apache Tomcat servers on Linux. - **Customizing Bespin** (2010-02-21) | HTML: https://h3manth.com/scribe/customizing-bespin/ | Markdown: https://h3manth.com/scribe/blog/customizing-bespin.md | Tags: python, javascript, web with syntax and code highlighting Read the intro to bespin before you continue Prereq: Python 2.5 with simplejson or Python. - **Bespin the Next Generation Web Code Editor** (2010-02-15) | HTML: https://h3manth.com/scribe/bespin-next-generation-web-code-editor/ | Markdown: https://h3manth.com/scribe/blog/bespin-next-generation-web-code-editor.md | Tags: web ’Bespin is a Mozilla Labs experiment on how to build an extensible Web code editor using HTML 5 technology.’ I have tired. - **NS2 on Ubuntu 9.10** (2010-02-13) | HTML: https://h3manth.com/scribe/ns2-ubuntu-910/ | Markdown: https://h3manth.com/scribe/blog/ns2-ubuntu-910.md | Tags: ubuntu, bash, web, linux To install The Network Simulator - ns-2 we need to bit of circus. Install dependencies : $ sudo apt-get install libpcap-dev. - **Generate index.html for a given directory** (2010-02-12) | HTML: https://h3manth.com/scribe/generate-indexhtml-given-directory/ | Markdown: https://h3manth.com/scribe/blog/generate-indexhtml-given-directory.md | Tags: bash #!/bin/bash #Author : Hemanth.HM #Email : hemanth.hm@gmail.com #Purpose : To genrate index.html for a give directory. #Usage. - **RSS Feed as Wallpaper** (2010-02-10) | HTML: https://h3manth.com/scribe/rss-feed-wallpaper/ | Markdown: https://h3manth.com/scribe/blog/rss-feed-wallpaper.md | Tags: ubuntu, bash Pre-Req convert utility :sudo apt-get install imagemagick curl utility :sudo apt-get install curl Any wallpaper :it’s called. - **Log file viewer in PHP** (2010-02-09) | HTML: https://h3manth.com/scribe/log-file-viewer-php/ | Markdown: https://h3manth.com/scribe/blog/log-file-viewer-php.md | Tags: linux, opensource = 0) { $position = $position - $chunklen; if ($position = $numtoget + 1) { pregmatch(’!(.?n){’.($numtoget-1).’}$!’, $data. - **Ground Control on Karmic** (2010-01-30) | HTML: https://h3manth.com/scribe/ground-control-karmic/ | Markdown: https://h3manth.com/scribe/blog/ground-control-karmic.md | Tags: python, ubuntu, linux Ground control collaboration of launchpad and bazaar branches for easier development for the everyday user! How to install. - **Django on Ubuntu** (2010-01-26) | HTML: https://h3manth.com/scribe/django-ubuntu/ | Markdown: https://h3manth.com/scribe/blog/django-ubuntu.md | Tags: python, ubuntu, web Django | The Web framework for perfectionists with deadlines Settings it up: sudo apt-get install django Check out the in JS. - **My Google Wave Ideas** (2010-01-22) | HTML: https://h3manth.com/scribe/my-google-wave-ideas/ | Markdown: https://h3manth.com/scribe/blog/my-google-wave-ideas.md | Tags: web My 55 ideas for Google Wave :{Some are on it’s way} : Go and vote here :You liked any? 1.’Alloww grouping in contacts list. - **Firefox 3.6 With Full HTML 5 API Support** (2010-01-21) | HTML: https://h3manth.com/scribe/firefox-36-full-html-5-api-support/ | Markdown: https://h3manth.com/scribe/blog/firefox-36-full-html-5-api-support.md | Tags: javascript, web As the latest firfox came up was were happy to read the below in there site : ’Currently, an entirely new spec is being. - **MySQL DB Synchronization.** (2010-01-19) | HTML: https://h3manth.com/scribe/mysql-db-synchronization/ | Markdown: https://h3manth.com/scribe/blog/mysql-db-synchronization.md | Tags: bash, database DB replication/reflection is on the most import process while achieving a distributed system, which helps in the DB in JS. - **Synchronize remote hosts** (2010-01-18) | HTML: https://h3manth.com/scribe/synchronize-remote-hosts/ | Markdown: https://h3manth.com/scribe/blog/synchronize-remote-hosts.md | Tags: linux A simple script to sync remote hosts, steps to achieve it : 1.Avoid SCP prompting for password [ local host ] = ssh-keygen. - **Send mail to Gmail programatically with Python** (2010-01-16) | HTML: https://h3manth.com/scribe/send-mail-gmail-programatically-python/ | Markdown: https://h3manth.com/scribe/blog/send-mail-gmail-programatically-python.md | Tags: python #!/usr/bin/python import smtplib from email.MIMEMultipart import MIMEMultipart from email.MIMEBase import MIMEBase from. - **Reseting htpasswd with PHP** (2010-01-15) | HTML: https://h3manth.com/scribe/reseting-htpasswd-php/ | Markdown: https://h3manth.com/scribe/blog/reseting-htpasswd-php.md | Tags: linux, opensource 0) { $htpasswd = file($file); $auth = array(); foreach($htpasswd as $h) { $array = explode(’:’,$h); $user = $array[0]; $pass. - **Synchronizing SVN With an HTTPS URL** (2010-01-05) | HTML: https://h3manth.com/scribe/synchronizing-svn-https-url/ | Markdown: https://h3manth.com/scribe/blog/synchronizing-svn-https-url.md | Tags: git Creating a read-only mirror of a repository from a HTTPS which is in sync helps to maintain an local repo which is in sync. - **Amd Ati Catalyst Display Driver Gnulinux** (2010-01-01) | HTML: https://h3manth.com/scribe/amd-ati-catalyst-display-driver-gnulinux/ | Markdown: https://h3manth.com/scribe/blog/amd-ati-catalyst-display-driver-gnulinux.md | Tags: linux Dependencies : XOrg 6.8, 6.9, 7.0, 7.1, 7.2, 7.3 or 7.4 Linux kernel 2.6 or above glibc version 2.2 or 2.3 POSIX Shared. - **Indian Transliteration Bookmarklet Kannada** (2010-01-01) | HTML: https://h3manth.com/scribe/indian-transliteration-bookmarklet-kannada/ | Markdown: https://h3manth.com/scribe/blog/indian-transliteration-bookmarklet-kannada.md | Tags: linux Google Transliteration offers an option for converting English characters to the characters used in Kannada and many other. - **Programmatically Delete Sms Android Python** (2010-01-01) | HTML: https://h3manth.com/scribe/programmatically-delete-sms-android-python/ | Markdown: https://h3manth.com/scribe/blog/programmatically-delete-sms-android-python.md | Tags: linux, bash Deleting SMS text has been on of issues with default SMS clients of Andriod OS. Issue 5669 talks a lot about it. The most. - **Generic File Extracter** (2009-12-31) | HTML: https://h3manth.com/scribe/generic-file-extracter/ | Markdown: https://h3manth.com/scribe/blog/generic-file-extracter.md | Tags: linux, opensource Simple but effective and handy utility for people dealing with hell lot of zips. type -P $1 and /dev/null || echo $1 not. - **Auto Completion in Bash for Maven** (2009-12-24) | HTML: https://h3manth.com/scribe/auto-completion-bash-maven/ | Markdown: https://h3manth.com/scribe/blog/auto-completion-bash-maven.md | Tags: bash Step 1 : Check if bashcompletion in enabled in your .bashrc. Step 2 : Add the file attached to /etc/bashcompletion.d/m2. - **Bash Made Better With Shopt** (2009-12-24) | HTML: https://h3manth.com/scribe/bash-made-better-shopt/ | Markdown: https://h3manth.com/scribe/blog/bash-made-better-shopt.md | Tags: ubuntu, bash 1.Enable automatic typo correction for directory names shopt -s cdspell Testing hemanth@ubuntu:/var/log$ cd /tp /tmp in JS. - **Plotting Performance Graph of a GNU/Linux Box** (2009-12-11) | HTML: https://h3manth.com/scribe/plotting-performance-graph-gnulinux-box/ | Markdown: https://h3manth.com/scribe/blog/plotting-performance-graph-gnulinux-box.md | Tags: bash, web, linux Easy and fun Things needed : dstat GNUPlot This post, is not elaborating on dstat or GNUplot but rather focusing directly. - **Creating Self-Extracting Sources Files** (2009-12-10) | HTML: https://h3manth.com/scribe/creating-self-extracting-sources-files/ | Markdown: https://h3manth.com/scribe/blog/creating-self-extracting-sources-files.md | Tags: bash The idea is pretty simple : Embed all your tgz’s below a place holder and count the lines to get each tgz and pipe tail and. - **Setting Up a Secure Subversion Server With Apache in Ubuntu** (2009-11-21) | HTML: https://h3manth.com/scribe/setting-secure-subversion-server-apache-ubuntu/ | Markdown: https://h3manth.com/scribe/blog/setting-secure-subversion-server-apache-ubuntu.md | Tags: ubuntu, git, web If you have not read theApache HTTPS, read it before you go through this post. ’Subversion (SVN) is a version control system. - **How to Secure Apache With HTTPS** (2009-11-14) | HTML: https://h3manth.com/scribe/how-secure-apache-https/ | Markdown: https://h3manth.com/scribe/blog/how-secure-apache-https.md | Tags: ubuntu, web Hypertext Transfer Protocol Secure (HTTPS) = HTTP + SSL/TLS Check list: apache sever openssl Steps: For Ubuntu 10.04/Apache. - **Skype 2.1 beta on Ubuntu 9.10** (2009-11-08) | HTML: https://h3manth.com/scribe/skype-21-beta-ubuntu-910/ | Markdown: https://h3manth.com/scribe/blog/skype-21-beta-ubuntu-910.md | Tags: ubuntu, bash, web, linux Skype 2.1 beta an open source UI layer and works great one pulse audio in karmic. Enable medibuntu : sudo wget... Practical. - **Install FireFox 3.6 Namoroka for Karmic** (2009-11-07) | HTML: https://h3manth.com/scribe/install-firefox-36-namoroka-karmic/ | Markdown: https://h3manth.com/scribe/blog/install-firefox-36-namoroka-karmic.md | Tags: ubuntu, web, linux Namoroka After Firefox3.5 (’Shiretoko’) is released, the next version of Firefox will be developed under the project name. - **Sound Card Not Detected in Ubuntu 9.10? Fix It!** (2009-11-07) | HTML: https://h3manth.com/scribe/sound-card-not-detected-ubuntu-910-fix-it/ | Markdown: https://h3manth.com/scribe/blog/sound-card-not-detected-ubuntu-910-fix-it.md | Tags: ubuntu, linux Normally the Audio device: ATI Technologies Inc RS780 Azalia controller and RS series break after an upgrade to karmic This. - **Install Linux From HDD Without Burning From Iso** (2009-11-02) | HTML: https://h3manth.com/scribe/install-linux-hdd-without-burning-iso/ | Markdown: https://h3manth.com/scribe/blog/install-linux-hdd-without-burning-iso.md | Tags: ubuntu, linux Had a collection of GNU/Linux distros, had no time or money to buy DVD’s :P so came up with this plan : sudo mkdir /distro. - **Zsync | Update to Upgrade Ubuntu** (2009-10-30) | HTML: https://h3manth.com/scribe/zsync-update-upgrade-ubuntu/ | Markdown: https://h3manth.com/scribe/blog/zsync-update-upgrade-ubuntu.md | Tags: ubuntu, bash From alpha,beta or RC now you can update the .iso image to upgrade the OS, instead of downloading the entire iso image Very. - **Unable to Login After Upgrade to Karmic [Solved]** (2009-10-27) | HTML: https://h3manth.com/scribe/unable-login-after-upgrade-karmic-solved/ | Markdown: https://h3manth.com/scribe/blog/unable-login-after-upgrade-karmic-solved.md | Tags: ubuntu, bash This happens when an upgrade is done without removing the non-free graphical drivers, normally Nvidia or ATI cards. Actually. - **CSV parsing methods in Linux** (2009-10-22) | HTML: https://h3manth.com/scribe/csv-parsing-methods-linux/ | Markdown: https://h3manth.com/scribe/blog/csv-parsing-methods-linux.md | Tags: bash, linux #To get emails from CSV which is exported form your mail box grep -o -i ’[^,]@[^,]’ contacts.csv #Cut the required column. - **'Pax' a Powerful Tool to Read and Write File Archives and Copy Directory Hierarchies** (2009-10-22) | HTML: https://h3manth.com/scribe/pax-powerful-tool-read-and-write-file-archives-and-copy-directory-hierarchies/ | Markdown: https://h3manth.com/scribe/blog/pax-powerful-tool-read-and-write-file-archives-and-copy-directory-hierarchies.md | Tags: ubuntu To install pax on ubuntu sudo apt-get install pax the manual is attached with this article. ’pax will read, write, and list. - **Sudo Add-apt-repository | Karmic Kool** (2009-10-04) | HTML: https://h3manth.com/scribe/sudo-add-apt-repository-karmic-kool/ | Markdown: https://h3manth.com/scribe/blog/sudo-add-apt-repository-karmic-kool.md | Tags: ubuntu The Changelog of Karmic read so : software-properties (0.75) karmic; urgency=low new helper script ’add-apt-repository’. - **Howto Set Up Your Own Google Wave Sever on Ubuntu?** (2009-10-01) | HTML: https://h3manth.com/scribe/howto-set-your-own-google-wave-sever-ubuntu/ | Markdown: https://h3manth.com/scribe/blog/howto-set-your-own-google-wave-sever-ubuntu.md | Tags: python, javascript, ubuntu, git PyGoWave Server | Google wave server needs the following : Python 2.6.1 Django 1.0.2 Orbited 0.7.7 RabbitMQ 1.6.0 Python. - **Install-gnome-shell-ubuntu-kamric-jaunty** (2009-10-01) | HTML: https://h3manth.com/scribe/install-gnome-shell-ubuntu-kamric-jaunty/ | Markdown: https://h3manth.com/scribe/blog/install-gnome-shell-ubuntu-kamric-jaunty.md | Tags: ubuntu, git, bash 1) Get curl sudo apt-get install curl 2) Build deps : sudo apt-get install libgnomeui-dev librsvg2-dev libreadline5-dev. - **OOIdenti.ca | Update identi.ca Status From OO** (2009-10-01) | HTML: https://h3manth.com/scribe/ooidentica-update-identica-status-oo/ | Markdown: https://h3manth.com/scribe/blog/ooidentica-update-identica-status-oo.md | Tags: web After OOTwitter i tired a similar one for indeti.ca, the steps are as before you download the file from the attachment in JS. - **OOoTwitter | Open Office Twitter** (2009-09-30) | HTML: https://h3manth.com/scribe/oootwitter-open-office-twitter/ | Markdown: https://h3manth.com/scribe/blog/oootwitter-open-office-twitter.md | Tags: bash, web Question : How to twitt from open office? Download and open this :OOTwitter Now goto : Tools - Macros - Organize macros. - **How to Use the Real-time Earth Wallpaper Script for Linux** (2009-09-20) | HTML: https://h3manth.com/scribe/how-use-real-time-earth-wallpaper-script-linux/ | Markdown: https://h3manth.com/scribe/blog/how-use-real-time-earth-wallpaper-script-linux.md | Tags: bash, web, linux 1.Save code part to a file, say change.sh while [ 1 ]; do COUNTER=0 while [ $COUNTER -lt 60 ]; do wget... Practical notes. - **AMD/ATI | Black Edtion 64bit on Ubuntu | Fixing Issues** (2009-09-11) | HTML: https://h3manth.com/scribe/amdati-black-edtion-64bit-ubuntu-fixing-issues/ | Markdown: https://h3manth.com/scribe/blog/amdati-black-edtion-64bit-ubuntu-fixing-issues.md | Tags: ubuntu, linux P.S : The below discussion is considering AMD/ATI into frame. AMD Phenom has many variates the latest belonging to in JS. - **Resolving Application Dependencies | Apt-cache** (2009-08-29) | HTML: https://h3manth.com/scribe/resolving-application-dependencies-apt-cache/ | Markdown: https://h3manth.com/scribe/blog/resolving-application-dependencies-apt-cache.md | Tags: web, linux Normally while updating an application in GNU/Linux, we download the source and compile and install it. Sometimes we find. - **Pidgin 2.6.1 Adds XMPP Voice and Video Support (but Not on Windows)** (2009-08-22) | HTML: https://h3manth.com/scribe/pidgin-261-adds-xmpp-voice-and-video-support-not-windows/ | Markdown: https://h3manth.com/scribe/blog/pidgin-261-adds-xmpp-voice-and-video-support-not-windows.md | Tags: ubuntu, web, linux Long awaited in the list, voice support for pidgin for GNU/Linux is out, most of them were on Skype all these days for Voice. - **Install Eclipse Galileo (3.5) on Ubuntu Karmic (9.10)** (2009-08-20) | HTML: https://h3manth.com/scribe/install-eclipse-galileo-35-ubuntu-karmic-910/ | Markdown: https://h3manth.com/scribe/blog/install-eclipse-galileo-35-ubuntu-karmic-910.md | Tags: ubuntu, bash, linux Eclipse is not mere an IDE, it’s smart! Open source community and non-profit organization. ’Borland, IBM, MERANT, QNX in JS. - **Installing KDE 4.3 RC 3** (2009-08-05) | HTML: https://h3manth.com/scribe/installing-kde-43-rc-3/ | Markdown: https://h3manth.com/scribe/blog/installing-kde-43-rc-3.md | Tags: ubuntu, web Karmic users, can upgrade to the latest packages. Users of 9.04 : echo ’deb jaunty main’ ... Practical notes and code in JS. - **Experiments With Dictionary Server Protocol Linux | RFC 2229** (2009-08-03) | HTML: https://h3manth.com/scribe/experiments-dictionary-server-protocol-linux-rfc-2229/ | Markdown: https://h3manth.com/scribe/blog/experiments-dictionary-server-protocol-linux-rfc-2229.md | Tags: ubuntu, bash, linux There RFC 2229 defines the The Dictionary Server Protocol (DICT) is a TCP transaction based query/response protocol that. - **Install EMACS23 on Ubuntu** (2009-08-01) | HTML: https://h3manth.com/scribe/install-emacs23-ubuntu/ | Markdown: https://h3manth.com/scribe/blog/install-emacs23-ubuntu.md | Tags: ubuntu, web The emacs-snapshot packages originate from emacs and are adapted to work in Ubuntu. Add the attached file info to your in JS. - **One Line to Search Wiki in Linux With GUI** (2009-08-01) | HTML: https://h3manth.com/scribe/one-line-search-wiki-linux-gui/ | Markdown: https://h3manth.com/scribe/blog/one-line-search-wiki-linux-gui.md | Tags: ubuntu, bash, web, linux I just tried make a one liner to get info about keywords from Wikipedia. This is just an idea can be further advanced , the. - **Hyperlink to URL && Extracting all the links from a site** (2009-07-26) | HTML: https://h3manth.com/scribe/hyperlink-url-extracting-all-links-site/ | Markdown: https://h3manth.com/scribe/blog/hyperlink-url-extracting-all-links-site.md | Tags: bash, web This is a sample experiment i tried to convert , rather extract an URI from a hyperlink. Consider an example : href = ’. - **One line to install NMAP 5.0 from source** (2009-07-18) | HTML: https://h3manth.com/scribe/nmap/ | Markdown: https://h3manth.com/scribe/blog/nmap.md | Tags: bash, web The below command , is what i got after playing with wget and tar for a while, just copy and paste in the terminal to in JS. - **Know Your Weather From Terminal** (2009-07-15) | HTML: https://h3manth.com/scribe/know-your-weather-terminal/ | Markdown: https://h3manth.com/scribe/blog/know-your-weather-terminal.md | Tags: bash, web Here is a small trick i tired to find the weather from the terminal. The simple code below , gives you the update of current. - **Methods to Submit a Form With POST Using {Curl | Perl | Python | Ruby | Lynx}** (2009-07-15) | HTML: https://h3manth.com/scribe/methods-submit-form-post-using-curl-perl-python-ruby-lynx/ | Markdown: https://h3manth.com/scribe/blog/methods-submit-form-post-using-curl-perl-python-ruby-lynx.md | Tags: ruby, python, bash, web Assume that you have a form , in the source look for something similar to : input name=’rid’ type=’TEXT’ input name=’submit’. - **New VLC 1.0 howto get it** (2009-07-10) | HTML: https://h3manth.com/scribe/new-vlc-10-howto-get-it/ | Markdown: https://h3manth.com/scribe/blog/new-vlc-10-howto-get-it.md | Tags: linux How to install VLC 1.0 on Ubuntu using the Launchpad PPA. Practical notes and code examples on New VLC 1.0 howto get it by. - **xclip - command line interface to X selections (clipboard)** (2009-07-10) | HTML: https://h3manth.com/scribe/xclip-command-line-interface-to-x-selections-clipboard/ | Markdown: https://h3manth.com/scribe/blog/xclip-command-line-interface-to-x-selections-clipboard.md | Tags: linux, bash xclip reads from standard in and makes the data available as an X selection for pasting into X applications. Practical notes. - **Cricket Score From Terminal** (2009-06-27) | HTML: https://h3manth.com/scribe/cricket-score-terminal/ | Markdown: https://h3manth.com/scribe/blog/cricket-score-terminal.md | Tags: bash, web For all cricket fans and PC freaks out there , this is delight script both cli and gui scripts are there in the source. For. - **Integrate Google Calendar With Evolution and Gnome Clock** (2009-05-20) | HTML: https://h3manth.com/scribe/integrate-google-calendar-evolution-and-gnome-clock/ | Markdown: https://h3manth.com/scribe/blog/integrate-google-calendar-evolution-and-gnome-clock.md | Tags: bash, web Step-by-step guide to syncing your private Google Calendar iCal feed with the GNOME desktop clock and Evolution on Linux. - **SoX - Sound eXchange** (2009-01-08) | HTML: https://h3manth.com/scribe/sox-sound-exchange/ | Markdown: https://h3manth.com/scribe/blog/sox-sound-exchange.md | Tags: linux, audio SoX - Sound eXchange, the Swiss Army knife of audio manipulation. Practical notes and code examples on SoX - Sound eXchange. - **Wget - tricks and tips** (2009-01-08) | HTML: https://h3manth.com/scribe/wget-tircks-and-tips/ | Markdown: https://h3manth.com/scribe/blog/wget-tircks-and-tips.md | Tags: linux, bash Wget and Curl make such a wonderful pair in Linux. Here are some tricks and tips. Practical notes and code examples on Wget. - **Fun with mp3 :)** (2009-01-05) | HTML: https://h3manth.com/scribe/fun-with-mp3/ | Markdown: https://h3manth.com/scribe/blog/fun-with-mp3.md | Tags: programming Few useful mp3 tools : 1.mp3splt NAME : mp3splt — Utility for mp3/ogg splitting without decoding SYNOPSIS : mp3splt OPTIONS. - **Java Docs** (2009-01-05) | HTML: https://h3manth.com/scribe/java-docs/ | Markdown: https://h3manth.com/scribe/blog/java-docs.md | Tags: programming This application allows to conveniently browse, over the Internet and local filesystem, multiple javadoc sets, using a in JS. - **Play from command line!** (2009-01-05) | HTML: https://h3manth.com/scribe/play-from-command-line/ | Markdown: https://h3manth.com/scribe/blog/play-from-command-line.md | Tags: linux, audio My favorite command line audio players: mpg123, VLC, and mp3blaster. Practical notes and code examples on Play from command. - **Configuring Google Apps** (2009-01-04) | HTML: https://h3manth.com/scribe/configuring-google-apps/ | Markdown: https://h3manth.com/scribe/blog/configuring-google-apps.md | Tags: python Steps to configure Google App Engine for Python. Practical notes and code examples on Configuring Google Apps by Hemanth HM. - **Google Android SDK Setup** (2009-01-04) | HTML: https://h3manth.com/scribe/google-andriod/ | Markdown: https://h3manth.com/scribe/blog/google-andriod.md | Tags: android How to download and set up the Android SDK with Eclipse. Practical notes and code examples on Google Android SDK Setup by. - **Fun with Pdf** (2008-12-19) | HTML: https://h3manth.com/scribe/fun-with-pdf/ | Markdown: https://h3manth.com/scribe/blog/fun-with-pdf.md | Tags: programming Ever wanted to combine or merger many pdf files to a single file , no issues , you can do it easily on the shell. If PDF is. - **PDF to ****** (2008-12-19) | HTML: https://h3manth.com/scribe/pdf-to/ | Markdown: https://h3manth.com/scribe/blog/pdf-to.md | Tags: programming pdf2dsc pdffonts pdfinfo pdftk pdftohtml pdftops pdf2ps pdfimages pdfopt pdftoabw pdftoppm pdftotext These are few tools. - **Gobby: A Collaborative Text Editor** (2008-11-28) | HTML: https://h3manth.com/scribe/gobby-a-collaborative-text-editor/ | Markdown: https://h3manth.com/scribe/blog/gobby-a-collaborative-text-editor.md | Tags: programming Gobby Using Gobby is easy: just create a ses... Practical notes and code examples on Gobby: A Collaborative Text Editor by. - **How to install Ubuntu in 3 easy steps !!** (2008-11-28) | HTML: https://h3manth.com/scribe/how-to-install-ubuntu-in-3-easy-steps/ | Markdown: https://h3manth.com/scribe/blog/how-to-install-ubuntu-in-3-easy-steps.md | Tags: programming Its like a small poem ain’t it :) 1.Make free space in Hard Disk. 2.Boot live cd . 3.Click install ,next until end ,check. - **PhotoShop PhotoFramed** (2008-11-28) | HTML: https://h3manth.com/scribe/photoshop-photoframed/ | Markdown: https://h3manth.com/scribe/blog/photoshop-photoframed.md | Tags: programming You can do all that you were doing in PhotoShop , for free !! in GIMP :) {GIMP} GNU Image Manipulation Program. It is a. - **Download from youtube** (2008-11-27) | HTML: https://h3manth.com/scribe/download-from-youtube/ | Markdown: https://h3manth.com/scribe/blog/download-from-youtube.md | Tags: programming Application that downloads YouTube videos, then encodes them by using FFmpeg. PyTube offers a thumbnail preview of the in JS. - **Eclipse on Ubuntu for J2EE** (2008-11-27) | HTML: https://h3manth.com/scribe/eclipse-on-ubuntu-for-j2ee/ | Markdown: https://h3manth.com/scribe/blog/eclipse-on-ubuntu-for-j2ee.md | Tags: java, linux Install or update Eclipse to have Eclipse Web Tools Platform (WTP). Practical notes and code examples on Eclipse on Ubuntu. - **I won't buy iTunes :)** (2008-11-27) | HTML: https://h3manth.com/scribe/i-wont-buy-itunes/ | Markdown: https://h3manth.com/scribe/blog/i-wont-buy-itunes.md | Tags: programming Why do we buy iTunes ??!! When we have some as good as it for free ! Floola is freely distributed in the hope that it will. - **Java and Eclipse on Ubuntu** (2008-11-27) | HTML: https://h3manth.com/scribe/java-and-eclipse-on-ubuntu/ | Markdown: https://h3manth.com/scribe/blog/java-and-eclipse-on-ubuntu.md | Tags: java, linux How to install Java JDK/JRE and Eclipse on Ubuntu. Practical notes and code examples on Java and Eclipse on Ubuntu by in JS. - **Java CGI Tomcat Apache PHP MySQL on Ubuntu - Easy Steps** (2008-11-27) | HTML: https://h3manth.com/scribe/java-cgi-tomcat-apache-php-msql-on-ubuntu-easy-steps/ | Markdown: https://h3manth.com/scribe/blog/java-cgi-tomcat-apache-php-msql-on-ubuntu-easy-steps.md | Tags: linux, java Quick steps to set up LAMP stack and CGI on Ubuntu. Practical notes and code examples on Java CGI Tomcat Apache PHP MySQL. - **Removing USB viruses with Ubuntu** (2008-11-27) | HTML: https://h3manth.com/scribe/removing-usb-viruses-most-of-the-viruses-which-are-wide-speared-due-to-os-like-windows-can-me-easily-smashed-in-os-like-ubuntu/ | Markdown: https://h3manth.com/scribe/blog/removing-usb-viruses-most-of-the-viruses-which-are-wide-speared-due-to-os-like-windows-can-me-easily-smashed-in-os-like-ubuntu.md | Tags: linux Most of the viruses which are widespread due to OS like Windows can be easily smashed in OS like Ubuntu. Practical notes. - **Removing USB viruses--Most of the Viruses Which Are Wide Speared Due to OS Like Windows Can Me Easily Smashed in OS Like UBUNTU ;)** (2008-11-27) | HTML: https://h3manth.com/scribe/removing-usb-viruses-most-viruses-which-are-wide-speared-due-os-windows-can-me-easily-smashe/ | Markdown: https://h3manth.com/scribe/blog/removing-usb-viruses-most-viruses-which-are-wide-speared-due-os-windows-can-me-easily-smashe.md | Tags: ubuntu Removing USB viruses--Most of the Viruses Which Are Wide Speared Due to OS Like Windows Can Me Easil. Practical notes and. - **Skype Problem with Audio Playback** (2008-11-27) | HTML: https://h3manth.com/scribe/skype-problem-with-audio-playback/ | Markdown: https://h3manth.com/scribe/blog/skype-problem-with-audio-playback.md | Tags: programming Skype audio not working :( , i know it’s too bad if one of the only few good VoIP provides for Linux in {not}Working , i. - **Who said no GAMES in Ubuntu** (2008-11-27) | HTML: https://h3manth.com/scribe/who-said-no-games-in-ubuntu/ | Markdown: https://h3manth.com/scribe/blog/who-said-no-games-in-ubuntu.md | Tags: programming Playdeb, helps you to play loads and loads of games Download and install updated apturl package(. Practical notes and code. - **Who am i ?** (2007-08-04) | HTML: https://h3manth.com/scribe/who-am-i/ | Markdown: https://h3manth.com/scribe/blog/who-am-i.md | Tags: programming Hemanth is that kind of a person , who admits he doesn’t know it , if he really doesn’t know it and will not stop there.