Sr. Content Developer at Microsoft, working remotely in PA, TechBash conference organizer, former Microsoft MVP, Husband, Dad and Geek.
150521 stories
·
33 followers

Prevent agentic identity theft

1 Share
Ryan is joined by Nancy Wang, CTO of 1Password, to discuss the security challenges local agents present, how enterprises can create robust governance of credentials through zero-knowledge architecture, and the implications of agent intent and misuse in a world where AI agents are becoming more and more integrated into everyday applications.
Read the whole story
alvinashcraft
18 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Invoke SSIS Package Activity in Microsoft Fabric (Preview)

1 Share

SQL Server Integration Services (SSIS) has been a cornerstone of enterprise data integration for decades, powering mission-critical ETL workloads across thousands of organizations worldwide. Now Invoke SSIS Package activity (Preview) in Data Factory in Microsoft Fabric, brings the power of your existing SSIS investments directly into Fabric's unified SaaS analytics platform.

Many enterprises have significant investments in SSIS packages that orchestrate complex ETL workflows across on-premises databases, file systems, and cloud services. Until now, running these packages required either an on-premises SQL Server or the Azure-SSIS Integration Runtime in Azure Data Factory. Both options meant managing additional infrastructure and staying outside the Fabric ecosystem.

But the Invoke SSIS Package pipeline activity in Microsoft Fabric Data Factory changes this. It allows you to execute your existing SSIS packages directly from a Fabric pipeline, enabling true lift-and-shift of legacy ETL workloads into Fabric — no package rewrite required. No integration runtime management, no stop/starting IRs— just add it to your pipeline!

Key benefits include:

  • Zero rewrite migration: Run your existing SSIS packages as-is inside Fabric pipelines. Protect years of ETL investment while moving to a modern platform.
  • Unified orchestration: Combine SSIS package execution with Fabric-native activities — Copy activity, Dataflow Gen2, Notebook, Stored Procedure, and more — in a single pipeline.
  • OneLake integration: SSIS packages running in Fabric can leverage OneLake as package store and write package execution logs into OneLake.
  • Simplified management: No need to provision or manage separate integration runtimes. Fabric handles the compute for executing your SSIS packages.

Getting started

Getting started with the Invoke SSIS Package activity takes just a few steps:

  1. Upload packages to OneLake — Move your .dtsx (and optional .dtsConfig) files into a Lakehouse via OneLake file explorer or the Fabric portal.
  2. Add the activity to a pipeline — Create or open a new pipeline, then add the Invoke SSIS Package activity from the Activities pane.

 

Figure: Add an Invoke SSIS Package activity.

  1. Configure package settings — Browse to select your package and configuration files from OneLake and optionally enable logging to capture execution logs in OneLake.

Figure: Invoke SSIS package activity configuration.

  1. Set runtime values — Override connection manager properties or package properties (such as connection strings and credentials) using the Connection Managers and Property Overrides tabs. You can use expressions, pipeline parameters, or system variables for dynamic values.
  2. Run or schedule — Save the pipeline and run it immediately or set up a recurring schedule.
  3. Monitor execution — Track progress in the pipeline Output tab or the workspace Monitor hub. When logging is enabled, detailed execution logs are written to OneLake.

For full configuration details, refer to the Invoke SSIS Package activity documentation.

Get started

The Invoke SSIS Package activity (Preview) for all Fabric workspaces.

  1. Open Data Factory in Microsoft Fabric.
  2. Create a new Data Pipeline in your workspace.
  3. Add the Invoke SSIS Package activity and configure it to point to your packages in OneLake.
  4. Refer to the Invoke SSIS Package activity documentation for detailed configuration guidance.
  5. Refer to Tutorial: Integrate SSIS with SQL database in Microsoft Fabric for detailed configuration to connect with Fabric SQL database in SSIS package.

We want to hear from you! Share your experience, report issues, and request features.

What's next

This preview represents the first step in a broader set of capabilities we’re building. Today’s experience focuses on core scenarios, with additional investments already underway — including expanded package sources, on-premises and private network connectivity, and custom or third-party component support. We’ll continue to evolve the platform as we incorporate feedback and deliver these capabilities over time.

These upcoming features will roll out through a series of private previews. If you'd like early access to help shape the future of SSIS in Fabric, sign up to join our upcoming private previews. Your feedback is invaluable in driving this experience toward general availability.

Learn more

  1. SSIS activity in Fabric Pipelines demo video
  2. Invoke SSIS Package activity documentation
  3. Tutorial: Integrate SSIS with SQL database in Microsoft Fabric
  4. Data Factory in Microsoft Fabric overview
  5. The Evolution of SQL Server Integration Services (SSIS): SSIS 2025 (Generally Available)
Read the whole story
alvinashcraft
18 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Building an Offline AI Interview Coach with Foundry Local, RAG, and SQLite

1 Share

How to build a 100% offline, AI-powered interview preparation tool using Microsoft Foundry Local, Retrieval-Augmented Generation, and nothing but JavaScript.

Foundry Local 100% Offline RAG + TF-IDF JavaScript / Node.js

Introduction

Imagine preparing for a job interview with an AI assistant that knows your CV inside and out, understands the job you're applying for, and generates tailored questions, all without ever sending your data to the cloud. That's exactly what Interview Doctor does.

Interview Doctor - Landing Page

Interview Doctor's web UI, a polished, dark-themed interface running entirely on your local machine.

In this post, I'll walk you through how I built an interview prep tool as a fully offline JavaScript application using:

  • Foundry Local — Microsoft's on-device AI runtime
  • SQLite — for storing document chunks and TF-IDF vectors
  • RAG (Retrieval-Augmented Generation) — to ground the AI in your actual documents
  • Express.js — for the web server
  • Node.js built-in test runner — for testing with zero extra dependencies

No cloud. No API keys. No internet required. Everything runs on your machine.

What is RAG and Why Does It Matter?

Retrieval-Augmented Generation (RAG) is a pattern that makes AI models dramatically more useful for domain-specific tasks. Instead of relying solely on what a model learned during training (which can be outdated or generic), RAG:

  1. Retrieves relevant chunks from your own documents
  2. Augments the model's prompt with those chunks as context
  3. Generates a response grounded in your actual data

For Interview Doctor, this means the AI doesn't just ask generic interview questions, it asks questions specific to your CV, your experience, and the specific job you're applying for.

Why Offline RAG?

Privacy is the obvious benefit, your CV and job applications never leave your device. But there's more:

  • No API costs — run as many queries as you want
  • No rate limits — iterate rapidly during your prep
  • Works anywhere — on a plane, in a café with bad Wi-Fi, anywhere
  • Consistent performance — no cold starts, no API latency

Architecture Overview

Interview Doctor Architecture Diagram

Complete architecture showing all components and data flow.

The application has two interfaces (CLI and Web) that share the same core engine:

  1. Document Ingestion — PDFs and markdown files are chunked and indexed
  2. Vector Store — SQLite stores chunks with TF-IDF vectors
  3. Retrieval — queries are matched against stored chunks using cosine similarity
  4. Generation — relevant chunks are injected into the prompt sent to the local LLM

Step 1: Setting Up Foundry Local

First, install Foundry Local:

# Windows winget install Microsoft.FoundryLocal # macOS brew install microsoft/foundrylocal/foundrylocal The JavaScript SDK handles everything else — starting the service, downloading the model, and connecting: import { FoundryLocalManager } from "foundry-local-sdk"; import { OpenAI } from "openai"; const manager = new FoundryLocalManager(); const modelInfo = await manager.init("phi-3.5-mini"); // Foundry Local exposes an OpenAI-compatible API const openai = new OpenAI({ baseURL: manager.endpoint, // Dynamic port, discovered by SDK apiKey: manager.apiKey, });

 

⚠️ Key Insight

Foundry Local uses a dynamic port never hardcode localhost:5272. Always use manager.endpoint which is discovered by the SDK at runtime.

Step 2: Building the RAG Pipeline

Document Chunking

Documents are split into overlapping chunks of ~200 tokens. The overlap ensures important context isn't lost at chunk boundaries:

export function chunkText(text, maxTokens = 200, overlapTokens = 25) { const words = text.split(/\s+/).filter(Boolean); if (words.length <= maxTokens) return [text.trim()]; const chunks = []; let start = 0; while (start < words.length) { const end = Math.min(start + maxTokens, words.length); chunks.push(words.slice(start, end).join(" ")); if (end >= words.length) break; start = end - overlapTokens; } return chunks; }

Why 200 tokens with 25-token overlap? Small chunks keep retrieved context compact for the model's limited context window. Overlap prevents information loss at boundaries. And it's all pure string operations, no dependencies needed.

TF-IDF Vectors

Instead of using a separate embedding model (which would consume precious memory alongside the LLM), we use TF-IDF, a classic information retrieval technique:

 
export function termFrequency(text) { const tf = new Map(); const tokens = text .toLowerCase() .replace(/[^a-z0-9\-']/g, " ") .split(/\s+/) .filter((t) => t.length > 1); for (const t of tokens) { tf.set(t, (tf.get(t) || 0) + 1); } return tf; } export function cosineSimilarity(a, b) { let dot = 0, normA = 0, normB = 0; for (const [term, freq] of a) { normA += freq * freq; if (b.has(term)) dot += freq * b.get(term); } for (const [, freq] of b) normB += freq * freq; if (normA === 0 || normB === 0) return 0; return dot / (Math.sqrt(normA) * Math.sqrt(normB)); }
 

 

 

Each document chunk becomes a sparse vector of word frequencies. At query time, we compute cosine similarity between the query vector and all stored chunk vectors to find the most relevant matches.

SQLite as a Vector Store

Chunks and their TF-IDF vectors are stored in SQLite using sql.js (pure JavaScript — no native compilation needed):

export class VectorStore { // Created via: const store = await VectorStore.create(dbPath) insert(docId, title, category, chunkIndex, content) { const tf = termFrequency(content); const tfJson = JSON.stringify([...tf]); this.db.run( "INSERT INTO chunks (...) VALUES (?, ?, ?, ?, ?, ?)", [docId, title, category, chunkIndex, content, tfJson] ); this.save(); } search(query, topK = 5) { const queryTf = termFrequency(query); // Score each chunk by cosine similarity, return top-K } }

 

💡 Why SQLite for Vectors?

For a CV plus a few job descriptions (dozens of chunks), brute-force cosine similarity over SQLite rows is near-instant (~1ms). No need for Pinecone, Qdrant, or Chroma — just a single .db file on disk.

Step 3: The RAG Chat Engine

The chat engine ties retrieval and generation together:

async *queryStream(userMessage, history = []) { // 1. Retrieve relevant CV/JD chunks const chunks = this.retrieve(userMessage); const context = this._buildContext(chunks); // 2. Build the prompt with retrieved context const messages = [ { role: "system", content: SYSTEM_PROMPT }, { role: "system", content: `Retrieved context:\n\n${context}` }, ...history, { role: "user", content: userMessage }, ]; // 3. Stream from the local model const stream = await this.openai.chat.completions.create({ model: this.modelId, messages, temperature: 0.3, stream: true, }); // 4. Yield chunks as they arrive for await (const chunk of stream) { const content = chunk.choices[0]?.delta?.content; if (content) yield { type: "text", data: content }; } }

The flow is straightforward: vectorize the query, retrieve with cosine similarity, build a prompt with context, and stream from the local LLM. The temperature: 0.3 keeps responses focused — important for interview preparation where consistency matters.

Step 4: Dual Interfaces — Web & CLI

Web UI

The web frontend is a single HTML file with inline CSS and JavaScript — no build step, no framework, no React or Vue. It communicates with the Express backend via REST and SSE:

  • File upload via multipart/form-data
  • Streaming chat via Server-Sent Events (SSE)
  • Quick-action buttons for common follow-up queries (coaching tips, gap analysis, mock interview)
Interview Doctor - Form filled with job details

The setup form with job title, seniority level, and a pasted job description — ready to generate tailored interview questions.

CLI

The CLI provides the same experience in the terminal with ANSI-coloured output:

npm run cli

It walks you through uploading your CV, entering the job details, and then generates streaming questions. Follow-up questions work interactively. Both interfaces share the same ChatEngine class, they're thin layers over identical logic.

Edge Mode

For constrained devices, toggle Edge mode to use a compact system prompt that fits within smaller context windows:

Interview Doctor - Edge Mode enabled

Edge mode activated, uses a minimal prompt for devices with limited resources.

Step 5: Testing

Tests use the Node.js built-in test runner, no Jest, no Mocha, no extra dependencies:

import { describe, it } from "node:test"; import assert from "node:assert/strict"; describe("chunkText", () => { it("returns single chunk for short text", () => { const chunks = chunkText("short text", 200, 25); assert.equal(chunks.length, 1); }); it("maintains overlap between chunks", () => { // Verifies overlapping tokens between consecutive chunks }); }); npm test

Tests cover the chunker, vector store, config, prompts, and server API contract, all without needing Foundry Local running.

Adapting for Your Own Use Case

Interview Doctor is a pattern, not just a product. You can adapt it for any domain:

What to ChangeHow
Domain documentsReplace files in docs/ with your content
System promptEdit src/prompts.js
Chunk sizesAdjust config.chunkSize and config.chunkOverlap
ModelChange config.model — run foundry model list
UIModify public/index.html — it's a single file

Ideas for Adaptation

  • Customer support bot — ingest your product docs and FAQs
  • Code review assistant — ingest coding standards and best practices
  • Study guide — ingest textbooks and lecture notes
  • Compliance checker — ingest regulatory documents
  • Onboarding assistant — ingest company handbooks and processes

What I Learned

  1. Offline AI is production-ready. Foundry Local + small models like Phi-3.5 Mini are genuinely useful for focused tasks.
  2. You don't need vector databases for small collections. SQLite + TF-IDF is fast, simple, and has zero infrastructure overhead.
  3. RAG quality depends on chunking. Getting chunk sizes right for your use case is more impactful than the retrieval algorithm.
  4. The OpenAI-compatible API is a game-changer. Switching from cloud to local was mostly just changing the baseURL.
  5. Dual interfaces are easy when you share the engine. The CLI and Web UI are thin layers over the same ChatEngine class.

⚡ Performance Notes

On a typical laptop (no GPU): ingestion takes under 1 second for ~20 documents, retrieval is ~1ms, and the first LLM token arrives in 2-5 seconds. Foundry Local automatically selects the best model variant for your hardware (CUDA GPU, NPU, or CPU).

Getting Started

git clone https://github.com/leestott/interview-doctor-js.git cd interview-doctor-js npm install npm run ingest npm start # Web UI at http://127.0.0.1:3000 # or npm run cli # Interactive terminal

The full source code is on GitHub. Star it, fork it, adapt it — and good luck with your interviews!


Resources

 

Read the whole story
alvinashcraft
18 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Avalonia’s New Page Navigation APIs

1 Share


Read the whole story
alvinashcraft
18 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Why AI Needs Better Benchmarks

1 Share
From: AIDailyBrief
Duration: 16:24
Views: 732

ARC-AGI-3 from the ARC Prize measures intelligence by testing learning efficiency across 135 interactive visual games. Coverage examines benchmark saturation, benchmark maxing, and the shift from memorization-focused tests toward interactive, tool-enabled real-world evaluations. ARC-AGI-3 aims to expose gaps between human learning and current models and to refocus research on genuine general intelligence.

The AI Daily Brief helps you understand the most important news and discussions in AI.
Subscribe to the podcast version of The AI Daily Brief wherever you listen: https://pod.link/1680633614
Get it ad free at http://patreon.com/aidailybrief
Learn more about the show https://aidailybrief.ai/

Read the whole story
alvinashcraft
18 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Episode 565: Field Engineering is the YOLO team

1 Share

This week, we discuss big bets gone wrong, OpenAI buying the Python toolchain, and Claude's favorite tools. Plus, how fast should AI agents ship bug fixes?

Watch the YouTube Live Recording of Episode 565

Runner-up Titles

  • Product Management Slot Machine
  • We poisoned our own data
  • As the resident hater of SDT
  • I’m optimistic on this one
  • I’ll check back when you call it Siri
  • AI SEO
  • The Ryan Gosling of Podcasts

Rundown

Relevant to your Interests

Conferences

SDT News & Community

Recommendations





Download audio: https://aphid.fireside.fm/d/1437767933/9b74150b-3553-49dc-8332-f89bbbba9f92/2b3ae849-18f5-4840-bf50-ffa341970cfb.mp3
Read the whole story
alvinashcraft
19 minutes ago
reply
Pennsylvania, USA
Share this story
Delete
Next Page of Stories