Access Denied You don’t have permission to access “http://zeenews.india.com/technology/wait-what-your-old-phone-number-was-given-to-a-stranger-they-may-already-be-receiving-your-bank-otps-here-s-how-to-stay-safe-3055055.html” on this server. Reference #18.eff43717.1781355218.99fcc161 https://errors.edgesuite.net/18.eff43717.1781355218.99fcc161
Access Denied
Access Denied You don’t have permission to access “http://zeenews.india.com/technology/that-free-app-asking-for-your-microphone-access-could-be-riskier-than-you-think-heres-what-it-s-doing-with-it-3054977.html” on this server. Reference #18.c4f43717.1781351569.b22647c2 https://errors.edgesuite.net/18.c4f43717.1781351569.b22647c2
Access Denied
Access Denied You don’t have permission to access “http://zeenews.india.com/technology/dropped-your-smartphone-in-water-here-s-what-to-do-immediately-and-what-not-to-3055027.html” on this server. Reference #18.eff43717.1781347911.993f0f33 https://errors.edgesuite.net/18.eff43717.1781347911.993f0f33
Multimodal Browser AI with Transformers.js for Images and Speech
<title>Multimodal Media Analyzer</title> * { box–sizing: border–box; margin: 0; padding: 0; } body { font–family: system–ui, sans–serif; max–width: 820px; margin: 0 auto; padding: 1.5rem 1rem; background: #f1f5f9; color: #1e293b; } header { margin–bottom: 1.5rem; } header h1 { font–size: 1.5rem; } header p { color: #64748b; font-size: 0.9rem; margin-top: 0.2rem; } /* Model status indicators */ .model–status–bar { display: flex; gap: 0.5rem; flex–wrap: wrap; margin–top: 0.75rem; } .model–badge { font–size: 0.78rem; padding: 0.2rem 0.6rem; border–radius: 12px; background: #fef3c7; color: #92400e; } .model–badge.ready { background: #dcfce7; color: #15803d; } /* Tab bar */ .tabs { display: flex; background: white; border–radius: 8px; padding: 0.25rem; gap: 0.25rem; margin–bottom: 1.25rem; border: 1px solid #e2e8f0; } .tab { flex: 1; padding: 0.5rem; text–align: center; border–radius: 6px; cursor: pointer; font–size: 0.9rem; color: #64748b; transition: all 0.15s; } .tab.active { background: #2563eb; color: white; font-weight: 600; } /* Input panels */ .panel { display: none; } .panel.active { display: block; } .upload–area { background: white; border: 2px dashed #cbd5e1; border–radius: 8px; padding: 2rem; text–align: center; cursor: pointer; } .upload–area input { display: none; } #img-preview { margin–top: 1rem; max–width: 100%; max–height: 320px; border–radius: 8px; display: none; object–fit: cover; } .mic–center { text–align: center; padding: 1rem 0; } #rec-btn { width: 72px; height: 72px; border–radius: 50%; border: none; background: #dc2626; color: white; font–size: 1.6rem; cursor: pointer; display: flex; align–items: center; justify–content: center; margin: 0 auto 0.5rem; } #rec-btn.recording { background: #374151; } #rec-btn:disabled { background: #94a3b8; cursor: not-allowed; } #rec-timer { font-weight: 600; color: #374151; margin-bottom: 0.25rem; } #rec-hint { font-size: 0.85rem; color: #64748b; } #wave-canvas { display: block; margin: 0.5rem auto; border-radius: 4px; } /* Results grid */ .results–grid { display: grid; grid–template–columns: repeat(auto–fit, minmax(220px, 1fr)); gap: 1rem; margin–top: 1.25rem; } .result–card { background: white; border: 1px solid #e2e8f0; border–radius: 8px; padding: 1rem; } .result–card h3 { font–size: 0.75rem; text–transform: uppercase; letter–spacing: 0.06em; color: #64748b; margin–bottom: 0.6rem; } .label–item { display: flex; justify–content: space–between; align–items: center; padding: 0.25rem 0; font–size: 0.875rem; border–bottom: 1px solid #f1f5f9; } .label–score { font–size: 0.8rem; color: #64748b; background: #f1f5f9; padding: 0.1rem 0.4rem; border–radius: 4px; } .caption–body { font–size: 0.95rem; line–height: 1.5; font–style: italic; color: #334155; } .transcript–body { font–size: 0.95rem; line–height: 1.6; color: #334155; white–space: pre–wrap; } .placeholder–text { color: #94a3b8; font-style: italic; font-size: 0.9rem; } #global-status { font–size: 0.85rem; color: #64748b; margin–bottom: 1rem; } @media (max–width: 500px) { .results–grid { grid–template–columns: 1fr; } } <header> <h1>Multimodal Media Analyzer</h1> <p>Image classification, captioning, and speech transcription — all in your browser.</p> <div class=“model-status-bar”> <span class=“model-badge” id=“badge-cls”>Classifier: loading…</span> <span class=“model-badge” id=“badge-cap”>Captioner: loading…</span> <span class=“model-badge” id=“badge-asr”>Whisper: loading…</span> </div> </header> <div id=“global-status”>Loading models in parallel — first run downloads ~400 MB total.</div> <div class=“tabs”> <div class=“tab active” data–tab=“image”>🖼 Image Analysis</div> <div class=“tab” data–tab=“speech”>🎙 Speech Transcription</div> </div> <!— Image panel —> <div class=“panel active” id=“panel-image”> <div class=“upload-area” id=“img-drop”> <p>Click or drag an image to analyze</p> <p style=“font-size:0.8rem;color:#94a3b8;margin-top:0.3rem”> JPG, PNG, WebP, GIF supported </p> </div> <img id=“img-preview” alt=“Preview” /> </div> <!— Speech panel —> <div class=“panel” id=“panel-speech”> <div class=“mic-center”> <button id=“rec-btn” disabled>🎙</button> <div id=“rec-timer”>0:00</div> <div id=“rec-hint”>Waiting for Whisper model…</div> </div> </div> <!— Results – shown for both modes —> <div class=“results-grid” id=“results-grid” style=“display:none”> <!— Image results (shown in image mode) —> <div class=“result-card” id=“card-cls” style=“display:none”> <h3>Classification</h3> <div id=“cls-content”> <p class=“placeholder-text”>No results yet.</p> </div> </div> <div class=“result-card” id=“card-cap” style=“display:none”> <h3>Caption</h3> <div id=“cap-content”> <p class=“placeholder-text”>No caption yet.</p> </div> </div> <!— Speech results (shown in speech mode) —> <div class=“result-card” id=“card-asr” style=“display:none”> <h3>Transcription</h3> <div id=“asr-content”> <p class=“placeholder-text”>Record audio to see the transcription.</p> </div> </div> </div> import { pipeline } from ‘https://cdn.jsdelivr.net/npm/@huggingface/transformers@3.0.2’; // ── Pipeline references ─────────────────────────────────────────────── let classifier, captioner, transcriber; let readyCount = 0; // Update a model badge to “ready” state function markReady(badgeId, label) { const badge = document.getElementById(badgeId); badge.textContent = `${label}: ready`; badge.classList.add(‘ready’); readyCount++; if (readyCount === 3) { globalStatus.textContent = ‘All models ready. Upload an image or record audio.’; recBtn.disabled = false; recHint.textContent = ‘Click to start recording.’; } } // Load all three pipelines simultaneously Promise.all([ pipeline(‘image-classification’, ‘Xenova/vit-base-patch16-224’, { dtype: ‘q8’, progress_callback: p => p.status === ‘done’ && markReady(‘badge-cls’, ‘Classifier’) }), pipeline(‘image-to-text’, ‘Xenova/vit-gpt2-image-captioning’, { dtype: ‘q8’, progress_callback: p => p.status === ‘done’ && markReady(‘badge-cap’, ‘Captioner’) }), pipeline(‘automatic-speech-recognition’, ‘Xenova/whisper-tiny.en’, { dtype: ‘q8’, progress_callback: p => p.status === ‘done’ && markReady(‘badge-asr’, ‘Whisper’) }) ]).then(([cls, cap, asr]) => { classifier = cls; captioner = cap; transcriber = asr; }).catch(err => { globalStatus.textContent = `Error loading models: ${err.message}`; }); // ── UI references ───────────────────────────────────────────────────── const globalStatus = document.getElementById(‘global-status’); const resultsGrid = document.getElementById(‘results-grid’); const recBtn = document.getElementById(‘rec-btn’); const recHint = document.getElementById(‘rec-hint’); const recTimer = document.getElementById(‘rec-timer’); const waveCanvas = document.getElementById(‘wave-canvas’); const waveCtx = waveCanvas.getContext(‘2d’); // ── Image analysis ──────────────────────────────────────────────────── async function analyzeImage(dataUrl) { if (!classifier || !captioner) { globalStatus.textContent = ‘Models still loading. Please wait.’; return; } globalStatus.textContent = ‘Running classification and captioning…’; // Show image result cards, hide speech card document.getElementById(‘card-cls’).style.display = ‘block’; document.getElementById(‘card-cap’).style.display = ‘block’; document.getElementById(‘card-asr’).style.display = ‘none’; resultsGrid.style.display = ‘grid’; document.getElementById(‘cls-content’).innerHTML = ‘<p class=”placeholder-text”>Classifying…</p>’; document.getElementById(‘cap-content’).innerHTML = ‘<p class=”placeholder-text”>Generating caption…</p>’; try { // Run classification and captioning in parallel const [classResults, captionResults] = await Promise.all([ classifier(dataUrl, { top_k: 4 }), captioner(dataUrl, { max_new_tokens: 60 }) ]); // Render classification labels document.getElementById(‘cls-content’).innerHTML = classResults.map(({ label, score }) => ` <div class=“label-item”> <span>${label}</span> <span class=“label-score”>${(score * 100).toFixed(1)}%</span> </div>`).join(”); // Render generated caption document.getElementById(‘cap-content’).innerHTML = `<p class=“caption-body”>“${captionResults[0]?.generated_text ?? ‘No caption.’}”</p>`; globalStatus.textContent = ‘Analysis complete.’; } catch (err) { globalStatus.textContent = `Error: ${err.message}`; } } // File upload handler for images const imgDrop = document.getElementById(‘img-drop’); const imgInput = document.getElementById(‘img-input’); const imgPrev = document.getElementById(‘img-preview’); function handleImageFile(file) { if (!file?.type.startsWith(‘image/’)) return; const reader = new FileReader(); reader.onload = e => { imgPrev.src = e.target.result; imgPrev.style.display = ‘block’; analyzeImage(e.target.result); }; reader.readAsDataURL(file); } imgDrop.addEventListener(‘click’, () => imgInput.click()); imgInput.addEventListener(‘change’, e => handleImageFile(e.target.files[0])); imgDrop.addEventListener(‘dragover’, e => e.preventDefault()); imgDrop.addEventListener(‘drop’, e => { e.preventDefault(); handleImageFile(e.dataTransfer.files[0]); }); // ── Audio decoding helper ───────────────────────────────────────────── async function decodeAudio(arrayBuffer) { const audioCtx = new AudioContext({ sampleRate: 16000 }); const audioBuffer = await audioCtx.decodeAudioData(arrayBuffer); return audioBuffer.getChannelData(0); // Mono Float32Array at 16kHz }
Access Denied
Access Denied You don’t have permission to access “http://zeenews.india.com/technology/why-does-googles-homepage-change-with-internets-mood-noticed-today-s-bat-and-ball-icon-here-s-the-hidden-story-behind-this-3054811.html” on this server. Reference #18.5cfdd417.1781311333.1f8c6038 https://errors.edgesuite.net/18.5cfdd417.1781311333.1f8c6038
Python Concepts Every AI Engineer Must Master
In this article, you will learn five essential Python concepts that every AI engineer must master to build scalable, production-grade AI systems. Topics we will cover include: How generators and lazy evaluation allow you to stream large datasets with constant memory overhead. How context managers, asynchronous programming, and Pydantic models help you manage hardware resources, scale API calls, and validate configurations safely. How Python magic methods enable you to build custom abstractions that integrate cleanly with deep learning frameworks like PyTorch. Python Concepts Every AI Engineer Must Master What AI Engineers Need To Know Transitioning from writing local experimental scripts to building scalable, production-grade AI systems requires a shift in how we write Python. While dynamic typing, basic loops, and list comprehensions are reasonable for prototyping models or exploring data, they fail to meet the performance, memory, and latency constraints of real-world AI applications. AI engineering isn’t just about training algorithms or loading pre-trained weights — it’s about handling huge datasets, managing expensive hardware resources like GPUs, connecting to external APIs concurrently, and building clean, type-safe software interfaces. To operate at this level, you must master the native language constructs that professional developers and deep learning frameworks rely on. In this article, we will explore five critical Python concepts that you, the AI engineer, must master: Generators & lazy evaluation: for streaming huge datasets with constant memory overhead Context managers: for managing precious hardware states and resource cleanup Asynchronous programming: for scaling LLM API queries and concurrent agent tool execution Dataclasses & Pydantic: for validating configurations and building structured schemas for tool calling Magic methods: for designing framework-compatible ML abstractions from scratch 1. Generators & Lazy Evaluation (Memory-Efficient Data Streaming) When training models or running batch inference on large-scale datasets, loading all data into memory at once is a recipe for out-of-memory errors. If your dataset contains millions of text documents, high-resolution images, or feature vectors, a standard list forces Python to allocate memory for all items at once. Generators solve this with lazy evaluation. By using the yield keyword, a generator returns an iterator that computes and yields elements on demand, one at a time. This keeps your RAM usage flat, whether you are streaming 100 samples or 100 million. In this naive approach, we read and preprocess a dataset of text payloads, loading all processed dictionaries into a single massive list in memory before we can iterate over them: import json import io # A mock JSONL file stream of raw text payloads def get_dataset_stream(): data = “\n”.join([json.dumps({“id”: i, “text”: f”User query raw text payload {i}”}) for i in range(50000)]) return io.StringIO(data) # Naive list function processing all records at once def load_all_records_naive(stream): records = [] for line in stream: payload = json.loads(line) # Process data immediately and append to a list processed = { “id”: payload[“id”], “text”: payload[“text”].lower(), “length”: len(payload[“text”]) } records.append(processed) return records # Running this requires loading all 50,000 processed dictionaries into RAM stream = get_dataset_stream() data = load_all_records_naive(stream) print(f”Loaded {len(data)} records naive-style.”) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 import json import io # A mock JSONL file stream of raw text payloads def get_dataset_stream(): data = “\n”.join([json.dumps({“id”: i, “text”: f“User query raw text payload {i}”}) for i in range(50000)]) return io.StringIO(data) # Naive list function processing all records at once def load_all_records_naive(stream): records = [] for line in stream: payload = json.loads(line) # Process data immediately and append to a list processed = { “id”: payload[“id”], “text”: payload[“text”].lower(), “length”: len(payload[“text”]) } records.append(processed) return records # Running this requires loading all 50,000 processed dictionaries into RAM stream = get_dataset_stream() data = load_all_records_naive(stream) print(f“Loaded {len(data)} records naive-style.”) By converting our reader into a generator, we stream the preprocessed payloads batch-by-batch on demand. Let’s see a script that uses Python’s tracemalloc library to measure the difference in peak memory usage: import json import io import tracemalloc # A mock JSONL file stream of raw text payloads def get_dataset_stream(): data = “\n”.join([json.dumps({“id”: i, “text”: f”User query raw text payload {i}”}) for i in range(50000)]) return io.StringIO(data) # Naive list function processing all records at once def load_all_records_naive(stream): records = [] for line in stream: payload = json.loads(line) # Process data immediately and append to a list processed = { “id”: payload[“id”], “text”: payload[“text”].lower(), “length”: len(payload[“text”]) } records.append(processed) return records # Generator function yielding preprocessed records one-by-one def stream_records_generator(stream): for line in stream: payload = json.loads(line) yield { “id”: payload[“id”], “text”: payload[“text”].lower(), “length”: len(payload[“text”]) } # Measure the naive implementation tracemalloc.start() stream_naive = get_dataset_stream() records_list = load_all_records_naive(stream_naive) for r in records_list: pass # Simulate a training loop step _, peak_naive = tracemalloc.get_traced_memory() tracemalloc.stop() # Measure the generator implementation tracemalloc.start() stream_gen = get_dataset_stream() records_generator = stream_records_generator(stream_gen) for r in records_generator: pass # Simulate a training loop step _, peak_gen = tracemalloc.get_traced_memory() tracemalloc.stop() # Output results print(f”Naive peak RAM: {peak_naive / 1024 / 1024:.4f} MB”) print(f”Generator peak RAM: {peak_gen / 1024 / 1024:.4f} MB”) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 import json import io import tracemalloc # A mock JSONL file stream of raw text payloads def get_dataset_stream(): data = “\n”.join([json.dumps({“id”: i, “text”: f“User query raw text payload {i}”}) for i in range(50000)]) return io.StringIO(data) # Naive list function processing all records at once def load_all_records_naive(stream): records = [] for line in stream: payload = json.loads(line) # Process data immediately and append to a list processed = { “id”: payload[“id”], “text”: payload[“text”].lower(), “length”: len(payload[“text”]) } records.append(processed) return records # Generator
Access Denied
Access Denied You don’t have permission to access “http://zeenews.india.com/technology/iphone-17e-vs-samsung-galaxy-s25-edge-which-smartphone-is-better-to-buy-in-2026-price-features-camera-resale-value-compared-3054858.html” on this server. Reference #18.c4f43717.1781282765.ae542c5e https://errors.edgesuite.net/18.c4f43717.1781282765.ae542c5e
Access Denied
Access Denied You don’t have permission to access “http://zeenews.india.com/technology/facebook-and-instagram-down-heres-whats-going-wrong-and-when-it-might-be-fixed-3054894.html” on this server. Reference #18.eff43717.1781278469.95a463a5 https://errors.edgesuite.net/18.eff43717.1781278469.95a463a5
How to Build a Multi-Agent Research Assistant in Python
In this article, you will learn how to build a multi-agent AI research assistant using the OpenAI Agents SDK, the GPT-5.4 mini model, and the Olostep Web API, including how to wire together a manager agent, specialist sub-agents, and live web tools to produce structured, source-grounded research reports. Topics we will cover include: How to define a manager agent that orchestrates a judge agent and an analyst agent to progressively gather and evaluate evidence. How to integrate Olostep’s Answer, Search, Search-with-Scrape, and Scrape APIs as callable tools inside the OpenAI Agents SDK workflow. How to expose the finished research assistant as an interactive web application built with Reflex, complete with PDF export. How to Build a Multi-Agent Research Assistant in Python Introduction I have been experimenting with the OpenAI Agents SDK, and it has quickly become one of my favorite ways to build agentic AI applications. What stood out to me is how simple it is to create a multi-agent workflow: you define a manager agent, connect it with specialist sub-agents and tools, and let it decide how to complete the task. The manager agent can delegate work to other agents, call tools directly, and coordinate the overall research process. This makes it possible to build AI applications that do more than generate text — they can search the web, gather information, organize findings, and produce grounded outputs. In this guide, we will build a multi-agent AI research assistant using the OpenAI Agents SDK, the GPT-5.4 mini model, and the Olostep Web API. The assistant will generate a structured research report that is grounded in web data, easy to read, and produced in just a few seconds. The guide also includes the full code, a web app, and a link to the deployed version so you can test the system yourself. By the end, you will understand how multiple agents can work together to create a practical research assistant from scratch. 1. Set Up the Environment Before building the multi-agent research assistant, we need to set up the Python environment and configure the required API keys. We will use four main packages: openai-agents for building and running the multi-agent workflow olostep for accessing live web data pydantic for defining structured outputs python-dotenv for loading API keys from a .env file Run the following command to install the required packages: pip install -q -U openai-agents olostep python-dotenv pydantic pip install –q –U openai–agents olostep python–dotenv pydantic Next, create a .env file in your project directory. This file will store your API keys securely, so you do not need to hardcode them inside your notebook or application. OPENAI_API_KEY=your_openai_api_key OLOSTEP_API_KEY=your_olostep_api_key OPENAI_API_KEY=your_openai_api_key OLOSTEP_API_KEY=your_olostep_api_key You can create your OpenAI API key from the OpenAI Platform. Sign in to your OpenAI account, go to the API keys section, and generate a new key for this project. Make sure your OpenAI API account has billing enabled and at least $5 in credits available before running the examples. You may also need to complete account verification to access the latest models. For Olostep, create a free account from the Olostep website and generate an API key from your dashboard. The free plan includes 500 successful requests with no credit card required, which is enough to test the research assistant in this guide. Once your keys are ready, we will start in a Jupyter Notebook by importing the required libraries and loading the environment variables. This setup prepares the notebook to work with OpenAI, Olostep, structured outputs, and tracing. import json import os from datetime import datetime from typing import Any from dotenv import load_dotenv from IPython.display import Markdown, display from olostep import Olostep from pydantic import BaseModel, Field from agents import ( Agent, Runner, custom_span, flush_traces, function_tool, gen_trace_id, trace, ) load_dotenv() OPENAI_API_KEY = os.getenv(“OPENAI_API_KEY”) OLOSTEP_API_KEY = os.getenv(“OLOSTEP_API_KEY”) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 import json import os from datetime import datetime from typing import Any from dotenv import load_dotenv from IPython.display import Markdown, display from olostep import Olostep from pydantic import BaseModel, Field from agents import ( Agent, Runner, custom_span, flush_traces, function_tool, gen_trace_id, trace, ) load_dotenv() OPENAI_API_KEY = os.getenv(“OPENAI_API_KEY”) OLOSTEP_API_KEY = os.getenv(“OLOSTEP_API_KEY”) 2. Test Olostep Search with Scraping Before building the full multi-agent workflow, it is useful to test whether Olostep can search the web and scrape the returned pages successfully. This step confirms that your API key is working and that the search results include enough page content for downstream analysis. The Olostep Search API is especially useful because it can return search results with a built-in scraping option. Instead of only receiving page titles, snippets, and links, you can ask Olostep to scrape the returned URLs and provide the extracted content in formats such as Markdown. This means the agent can work with high-quality page content directly, rather than relying only on search snippets. It also saves time because you do not need to build a separate search-and-scrape pipeline yourself. client = Olostep(api_key=OLOSTEP_API_KEY) search = client.searches.create( query=”What are the most important recent developments in AI agents for business research?”, limit=5, scrape_options={“formats”: [“markdown”], “timeout”: 25}, ) for link in search.links: print(link[“url”], “-“, len(link.get(“markdown_content”) or “”), “chars”) client = Olostep(api_key=OLOSTEP_API_KEY) search = client.searches.create( query=“What are the most important recent developments in AI agents for business research?”, limit=5, scrape_options={“formats”: [“markdown”], “timeout”: 25}, ) for link in search.links: print(link[“url”], “-“, len(link.get(“markdown_content”) or “”), “chars”) This tells Olostep to scrape each returned page and provide the extracted content in Markdown format. Markdown is useful because it keeps the content readable while removing unnecessary page clutter. The timeout value gives Olostep enough time to fetch and process each page. After the search is complete, we loop through the returned links and print each URL along with the number of characters extracted from the page. 3. Add Helper Functions Before creating the agents and tools, we need to add a few helper
Access Denied
Access Denied You don’t have permission to access “http://zeenews.india.com/technology/you-and-your-friend-googled-same-thing-cafes-near-me-but-google-gave-different-results-heres-exactly-why-it-happens-3054535.html” on this server. Reference #18.c4f43717.1781235991.aa4931fd https://errors.edgesuite.net/18.c4f43717.1781235991.aa4931fd