I want you to look at this screenshot for a moment from the GitHub Copilot app. It’s a small one, it’s got a lot of icons, and it tells the most glorious story that I’m really excited about.
This image is a set of stacked sessions. They’re a series of tasks in the same repository, where each session builds off each other!
More on those below, but first, why is this screenshot so magical? We need to go back more than a decade to start. I have this very old repo of mine for a personal app. I first made it ages ago (end of 2014-ish), and it’s done what I want it to do (it’s like a personal “life” dashboard of calendars and smart devices in my home and task management) for all those years. I occasionally do some updates, but those have gotten harder and harder to wrangle.
My dependencies had gotten old. Embarrassingly old. I was using React 15 (which was released in 2016), Less for CSS pre-processing, and a version of react-bootstrap from around that time. Yes, you read that right. Bootstrap. This was old.
Trying to untangle this absolute mess before AI would have taken me weeks. I had tried and given up before. It’s not the largest app in the world, but it’s juuuust big enough that it would be painful, and the juice was simply not worth the squeeze.
…but we do have AI now, and so I fired up the GitHub Copilot app, added the repo, and got started.
First step: Could I one-shot this?
No.
I tried though! This is the prompt that I used in Plan mode:
I want to modernize the frontend for this project. I first wrote a lot of this code more than 10 years ago and it should be cleaned up a lot. I'm thinking we start either using Tailwind or just vanilla CSS (please vet everything to help me decide), we remove all Less (etc), and clean everything up accessibility-wise and responsiveness-wise. Right now I really want to just focus on styles, and then slowly but surely organize and consolidate the React functionality. It might be worth modernizing dependencies, too. Let's come up with a plan around this before diving in.
1. Nothing is sacred, it's okay if we have to completely start over some parts
2. Links should change colors and add underlines on hover/focus
3. Input boxes should have a smaller border radius in general, and their labels should be cleaner
4. There should be good wrapping and a max-width on containers so that an input box doesn't span an entire wide monitor.
I passed this into Claude Opus 4.8 got a Rubber Duck review from GPT-5.5, and had to do quite a bit of back-and-forth to make decisions. Once I got to a place I was happy with, I hit “go” and let the app go to town on my project to see if it would work!
…it didn’t, and it was my fault.
Second step: Realizing I had tried this before
So, remember when I said I’d “tried and given up before?” Turns out, I actually had an old devbranch where I actually had modernized some parts, and didn’t realize the compatibility issues I’d run into.
But, that was a good thing!
When I ran the new version from this session, I realized that I was branching off main, but that my current deployment that I was using regularly was using my partially updated version on dev. So, some wanted features that I had made for myself needed to be included in this set of changes. But, the changes were just big enough that I actually had to apply those changes to the devbranch to save my sanity a bit, rather than pull in the devchanges to main.
Pre-AI… my word, this would have made me pull my hair out in frustration. I was admittedly frustrated here, too. I had spent time and tokens trying to get this running with what I thought was a decent plan. But! I was able to switch gears (and sessions) with a simple ask, which was way cooler than I expected it to be:
All was not wasted! Copilot made a new session for me, closed the pull request I had attempted, and ported my styling decisions to changes it was applying to the dev branch.
Third step: Findings after testing
Whew, okay, so I had a good branch going, and a pull request I was decently happy with. As I started testing, though, I couldn’t help but notice some old warnings in my console.
My heart filled with dread as I saw old references to findDOMNodeand componentWillReceiveProps, functions I personally hadn’t touched in years and years. Ugh.
Those references were not in my codebase as much anymore, but they were in react-bootstrap. I opened up Plan mode again, because I needed to figure out if an upgrade would work, or if I should remove the library entirely:
Do you think we should remove react-bootstrap entirely (and replace with a modern alternative), or just upgrade/migrate existing components?
Running this gave me a decent plan, talked through the options, and recommended replacing the library entirely.
Fourth step: Stacking a session on top of the other
I needed to make sure my changes were safe from the existing work, but the react-bootstrap replacement felt like a lot of scope creep for what I was currently doing.
I’ve found that in a lot of my “agentic” engineering work, it’s particularly hard to avoid that kind of scope creep. Because I don’t have to write all the code myself, it’s so tempting to make 10,000 line pull requests that take care of all of the things I want to do! Which is really just a new form of procrastination, ha.
So, instead of making this mega pull request for myself to test, I broke it up with a new session, and prompted:
Let's make a pull request for the existing work, and then start a new session for this react-bootstrap replacement work that will branch off this existing work here, and be a separate pull request to merge into dev after this one.
This is the part that felt magical enough to make me want to write this blog post. The GitHub Copilot app:
Made a pull request for all of my current changes off dev
Made a “stacked session” for react-bootstrap removal (it took the previous context, made a session to run after the existing session, created a plan, had me approve the plan, and ran)
THIS WAS SO COOL. Stacked sessions and stacked pull requests? Is this the future?
YES.
In case you don’t get what that means by name: A stack is a series of pull requests in the same repository where each pull request targets the branch of the pull request below it, forming an ordered chain that ultimately lands on your main branch.
In my case, not only did the sessions follow each other, but their changes did too!
Fifth step: Sailing off into the sunset with stacked pull requests
I know I’m being somewhat cheeky with my excitement, but my happiness is sincere. The ease of shipping these changes was a delightful experience after neglecting my old codebase for ages.
Let’s look at that first screenshot again: I’ll walk you through it.
At the top, you can see the repo I pulled in.
Next “Frontend modernization” is the initial session name.
That next layer nested in is the first attempt at a pull request, that we ultimately didn’t ship (hence the red icon).
The next layer nested at the same level is where we got a working pull request for the devbranch.
The nested session below that is the draft pull request in progress, with the react-bootstrap changes.
Software development has never been smooth. But this project was made a whole lot easier with these modern tools.
If you’re looking to modernize your own codebases, give this a try!
Check out pull request stacks anywhere you commit code on GitHub, and stacked sessions in the GitHub Copilot app >
This is the July round-up for the Azure Developer CLI (azd). Five releases shipped since the last post: 1.27.0, 1.27.1, 1.28.0, 1.28.1, and 1.29.0. Below is what’s new, what changed, and what we fixed, with links to the pull requests if you want to dig in.
A new azd tool uninstall command completes the tool install, upgrade, and uninstall lifecycle.
Extensions can install directly from a registry location with -s/--source, and skip dependency resolution with --no-dependencies.
Model Azure AI Foundry projects, agents, and related resources directly in azure.yaml.
Container deployment for Azure App Service lets you push an image and run Web App for Containers with host: appservice and language: docker.
azd automatically switches to non-interactive mode when it detects a CI/CD or AI-agent environment, so commands fail fast instead of hanging on a prompt.
Breaking change: the skill --host flag on azd tool commands is renamed to --agent.
Microsoft Foundry at the AI Engineer World’s Fair
In Pablo Castro’s (Microsoft) “On AI and Knowledge” session at the AI Engineer World’s Fair, the Microsoft Foundry team showed their command-line experience built on top of the azd extension platform. It’s a great example of what teams can deliver on the extension framework, and it’s the kind of CLI story the platform is designed to enable. Watch the demo segment on YouTube to see it in action. Thanks to the Microsoft Foundry team for building on azd!
New features
Extensions
We continued to smooth out the extension install and authoring experience across these releases.
azd extension install, azd extension upgrade, and azd extension list now accept a registry location directly with -s/--source (a URL or local path), so you no longer need to run azd extension source add first. Direct locations are validated and registered as persisted sources before resolution continues. [#8792]
Add a --no-dependencies flag to azd extension install that installs only the named extension without resolving or installing its declared dependencies. [#8927]
Expose expanded service-level env values from azure.yaml to the extension service configuration, so extensions can read the same environment values azd resolves. [#8936]
Tool management
Add the azd tool uninstall command to complete the tool install, upgrade, and uninstall lifecycle. It supports --all, --dry-run, interactive multi-select, per-agent skill removal, and --output json. [#8794]
Azure AI Foundry modeling
Add support for modeling Azure AI Foundry projects, agents, and related resources directly in azure.yaml, including $ref file includes, secure-by-default networking, and Bicep-less and Terraform-less init paths. [#8818]
Provisioning and deployment
These changes broaden what azd can deploy and let extensions participate in provisioning validation regardless of the provider.
Add container deployment support for Azure App Service. Services configured with host: appservice and language: docker (or docker.path) now push the container image to Azure Container Registry (ACR) and update the site’s container configuration, enabling Web App for Containers scenarios. [#8847]
Add a provider-agnostic provision validation check that runs before provisioning for every provider. Extensions with the validation-provider capability can now contribute client-side checks that run regardless of the provisioning provider (Bicep, Terraform, or an extension-provided provider), not just during Bicep local preflight. [#9019]
CI/CD and agent environments
Automatically enable non-interactive (no-prompt) mode when azd detects a continuous integration and delivery (CI/CD) or AI-agent environment, so commands fail fast with a clear error instead of hanging on a prompt. Set AZD_NON_INTERACTIVE=false to opt out. Confirmation prompts now also honor their default value when there is no more input on standard input. [#9125]
Breaking changes
The skill --host flag is now --agent. On azd tool install, azd tool upgrade, and azd tool uninstall, the --host flag is renamed to --agent. Installed skills in azd tool list --output json and azd tool check --output json now expand into one row per agent and include an agent field. Update any scripts or JSON consumers that pass --host or read the previous shape. [#9045]
Bugs fixed
Extensions and tools
Fix azd tool install azure-skills mistaking the Visual Studio Code Copilot Chat launcher stub for a working Copilot Command Line Interface (CLI) host. Host selection now uses a functional probe, so installs no longer silently no-op on macOS or get stuck on a PATH prompt on Linux. [#8805]
Fix azd tool uninstall failing for Visual Studio Code extensions that have dependents (for example, vscode-azure-tools) and for the GitHub Copilot CLI when installed via Homebrew cask on macOS and Linux. Uninstall now detects which package manager owns the install and removes it accordingly, with guidance when a self-managed install requires manual removal. [#8875]
Fix generated azd extension install completions to offer extension IDs and .zip file paths. [#8887]
Fix azd extension install intermittently failing on Windows with an “Access is denied” error when replacing an extension executable held by a transient file lock. [#9161]
Fix concurrent extension updates to azure.yaml losing service fields by serializing project configuration writes. [#9211]
Fix and improve automatic installation of project extension requirements so azd resolves every missing provider declared or inferred from azure.yaml before project commands run, instead of failing on the first unsupported one. [#9218]
Provisioning and configuration
Fix azd env refresh for projects using extension-provided service hosts or provisioning providers, and report success when no deployment exists yet. [#9017]
Fix azure.yaml serialization writing empty project and language fields for services using code-less resource hosts such as azure.ai.project, azure.ai.connection, and microsoft.foundry; these fields are now omitted when empty. [#8937]
Exclude deprecated models by default from the model catalog and quota prompts. [#8842]
Stop forwarding dynamic linker and loader control variables (such as LD_PRELOAD, LD_LIBRARY_PATH, LD_AUDIT, and DYLD_INSERT_LIBRARIES) defined in an environment’s .env file into tool subprocesses like docker, npm, and python. [#8949]
Fix azd deploy for container-based Azure App Service services overwriting unrelated site configuration; the container image is now updated through the dedicated App Service configuration endpoint. [#9281]
Continuous integration and updates
Fix azd down --no-prompt hanging in CI/CD for Terraform-based projects by auto-approving the destroy when running non-interactively, and fix azd down --force failing with a backend initialization error on a fresh agent. [#9143]
Fix the azd update follow-up command to use azd version. Thanks @rguptar for the contribution! [#9083]
Other changes
Expose a service’s uses (dependency) list on the extension Software Development Kit (SDK) ServiceConfig, so extensions can read service and resource dependencies directly instead of via SetServiceConfigValue. [#8838]
Add an extension SDK helper that validates provider declarations in extension.yaml against the providers registered by extension code. [#9033]
Send Azure Resource Manager (ARM) request correlation IDs as a canonical hyphenated globally unique identifier, derived losslessly from the OpenTelemetry trace ID, instead of an undecorated 32-character string. This covers both the x-ms-correlation-request-id header on azd‘s direct ARM calls and the ARM_CORRELATION_REQUEST_ID value passed to the Terraform AzureRM provider, aligning azd with the ARM spec and other Azure tooling. [#9141]
Stop showing the automatic azd tool first-run install prompt and periodic update notifications. Explicit azd tool commands are unchanged. [#9261]
Emit the infra.provider telemetry attribute on provision, up, and down so provisioning runs can be segmented by infrastructure provider. [#9091]
Recognize azd invocations from Microsoft Foundry Skill in the execution.environment telemetry field. [#9167]
Report the GitHub Copilot app separately from the GitHub Copilot CLI in the execution.environment telemetry field. [#9288]
Manage Azure development tools with azd tool (July 27) — Updated to reflect the 1.28.1 change that removes the automatic azd tool first-run install prompt and periodic update notifications, so the reference now matches the current on-demand behavior.
Configure a pipeline and push updates using Azure Pipelines (July 28) — Corrected the OpenID Connect (OIDC) and federated credential guidance for azd pipeline config with Azure DevOps, plus refreshed sample links for GitHub Actions and Azure DevOps.
azure.yaml schema reference (July 16) — Refreshed with the Azure AI Foundry azure.yaml unification changes, documenting the Microsoft Foundry hosts for modeling Foundry projects, agents, and related resources directly in azure.yaml.
New templates
Community templates help you get started faster, cover common scenarios, and show how to deploy real solutions with Azure Developer CLI.
Azure Functions Timer trigger quickstarts by Azure Functions Team, extending the Timer trigger pattern across five languages. Each sample deploys to Azure Functions Flex Consumption with azd, using managed identity and a virtual network to be secure by default:
Python: An Azure Functions Timer trigger quickstart written in Python.
JavaScript: An Azure Functions Timer trigger quickstart written in JavaScript.
TypeScript: An Azure Functions Timer trigger quickstart written in TypeScript.
Java: An Azure Functions Timer trigger quickstart written in Java.
PowerShell: An Azure Functions Timer trigger quickstart written in PowerShell.
Durable Functions fan-out/fan-in quickstarts by Azure Functions Team, demonstrating the fan-out/fan-in orchestration pattern in five languages, each deployed to Azure Functions Flex Consumption with azd, managed identity, and a virtual network:
Java: A Durable Functions fan-out/fan-in quickstart written in Java.
JavaScript: A Durable Functions fan-out/fan-in quickstart written in JavaScript.
TypeScript: A Durable Functions fan-out/fan-in quickstart written in TypeScript.
Python: A Durable Functions fan-out/fan-in quickstart written in Python.
PowerShell: A Durable Functions fan-out/fan-in quickstart written in PowerShell.
Remote Model Context Protocol (MCP) Functions samples by Azure Functions Team, showing how to build and deploy custom remote MCP servers on Azure Functions:
Remote MCP Functions with JavaScript: This scenario demonstrates how to build and deploy a custom remote MCP server to the cloud using Azure Functions and JavaScript, with built-in authentication using Microsoft Entra as the identity provider.
Long-running MCP tools using Durable Functions (.NET): A .NET isolated Azure Functions MCP server that runs long-running MCP tools by backing them with Durable Functions and a budgeted start-and-poll pattern, deployed with azd using the Durable Task Scheduler backend and managed identity.
Azure Functions C# HTTP trigger using Azure Developer CLI (Terraform) by Azure Functions Team: An Azure Functions HTTP trigger quickstart written in C# (isolated worker) and deployed to Azure Functions Flex Consumption with azd using Terraform as the infrastructure-as-code provider, with managed identity and a virtual network for secure-by-default deployment.
mTLS with Azure API Management and Application Gateway by Ronald Bosma: A demo of mutual Transport Layer Security (mTLS) with Azure API Management and Application Gateway. It shows how to validate client certificates when calling API Management directly and when it sits behind an Application Gateway, and how to secure connections from API Management to backend systems using mTLS. Thanks Ronald Bosma for the contribution!
The Azure Developer CLI template gallery keeps growing thanks to contributions from the community. Thank you!
New to azd?
If you’re new to the Azure Developer CLI, azd is an open-source command-line tool that helps you get your application from your local development environment to Azure faster. It provides developer-friendly commands that map to key stages in your workflow, whether you’re working in the terminal, your editor, or CI/CD.
Learn why traditional M2M security fails for AI infrastructure and how treating your AI Agent as a Principal unlocks secure, production-ready workflows.
A transcription model hears “account number 8-4-7-2” but returns “account number eighty-four seventy-two.” A single error can break a downstream automation workflow. Developers building voice applications need transcription models that can handle real-world audio conditions, natural speech patterns, and business-critical details, including codes, dates, addresses, account numbers, mixed-language conversations, specialized terminology, and quiet or low-volume speech.
GPT-transcribe and GPT-live-transcribe do just that and are available in Microsoft Foundry today. Two updates to the audio model family designed to improve automatic speech recognition across asynchronous transcription and live streaming scenarios.
Built for More Accurate Transcription in Real-World Audio
GPT-transcribe is the highest accuracy ASR model from Open AI, designed for asynchronous speech-to-text transcription of completed audio files and batch workloads. It accepts audio input and returns text output, making it a strong fit for workflows that process recorded, uploaded, or submitted audio, including meeting recordings, voicemails, and media files.
GPT-live-transcribe is designed for low-latency streaming transcription through the Realtime API. It supports real-time audio input and text output, helping developers build live experiences where speech needs to be transcribed continuously as audio arrives. This model also introduces “tunable latency” where developers can adjust the latency/accuracy trade-off for streaming. It is a strong fit for live captions, voice assistants, contact center workflows, accessibility experiences, field service applications, real-time intake, and monitoring systems.
Together, these models give developers transcription options in Microsoft Foundry for stored audio and live voice interactions. Their text output can support downstream workflows such as search, summarization, routing, analytics, automation, and quality review.
What’s New in Both Models
The features of the new transcription models focus on improving transcription quality in real-world audio environments where speech can be brief, noisy, accented, quiet, domain-specific, or mixed across languages. Key capabilities include:
Background noise: Helps isolate speech in noisy environments so transcription quality can remain more reliable when audio conditions are not controlled.
Short utterances: Improves recognition of brief commands, confirmations, interruptions, and clipped speech that can be difficult to capture accurately.
Alphanumeric perception: Strengthens transcription of IDs, codes, phone numbers, dates, addresses, account numbers, and mixed letter-number sequences.
Domain terminology understanding: Improves recognition of specialized vocabulary used in product, workflow, industry, and business-process contexts.
Codemix: Improves understanding when speakers switch between languages within a conversation or utterance.
Context awareness: Uses topic hints and past conversation context to improve transcription accuracy and help maintain consistency.
Accent robustness: Improves handling of regional accents, non-native accents, dialects, and varied speaking styles.
Whispering: Improves recognition of quiet or low-volume speech, including whispered commands and private dictation.
Live captioning and accessibility experiences: Generate real-time captions for meetings, events, media experiences, and assistive applications.
Contact center and voice workflows: Capture spoken details as conversations happen, supporting routing, quality review, summarization, and downstream automation.
Monitoring, analytics, and compliance workflows: Provide text visibility into ongoing spoken input so teams can analyze, review, and act on conversation data.
Also Available: GPT-realtime-2.1 and GPT-realtime-mini-2.1
gpt-realtime-2.1 and gpt-realtime-mini-2.1 are also available in Microsoft Foundry for developers building speech-to-speech applications. Unlike GPT-transcribe and GPT-live-transcribe, which return text, these models accept audio and generate audio for low-latency conversational experiences over the Realtime API. gpt-realtime-2.1 focuses on interaction quality and robustness, while gpt-realtime-mini-2.1 provides a smaller, faster, and more cost-efficient option for high-volume deployments.
Together with GPT-transcribe and GPT-live-transcribe, these realtime audio updates give developers more flexibility to build voice applications that need both accurate transcription and responsive spoken interaction, whether the experience is centered on capturing speech as text, responding with audio, or combining both patterns in a single workflow.
Use Cases by Model
GPT-transcribe
Use GPT-transcribe when the application needs accurate text transcripts from recorded, uploaded, or submitted audio. It is a strong fit for meeting and call transcription, media transcription, customer support intake, voicemail and message processing, quality review, compliance workflows, and domain-specific transcription where short utterances, structured alphanumeric details, specialized terminology, accents, background noise, code-mixed speech, or quiet audio can affect downstream accuracy.
GPT-live-transcribe
Use GPT-live-transcribe when the application needs live streaming transcription with low latency. It is designed for real-time captions, accessibility experiences, contact center transcription, voice-enabled workflows, live monitoring, operational dashboards, and agent-assist scenarios where spoken input needs to become text continuously as the interaction unfolds.
Pricing
The following pricing example shows Global Standard rates by model and modality. Rates for GPT-realtime-2.1 and GPT-realtime-mini-2.1 are listed per 1 million tokens. GPT-transcribe and GPT-live-transcribe are listed per audio hour.
Model
Deployment
Modality
Input
Cached Input
Output
GPT-realtime-2.1
Global Standard
Audio
$32.00
$0.40
$64.00
Text
$4.00
$0.40
$24.00
Image
$5.00
$0.50
--
GPT-realtime-mini-2.1
Global Standard
Audio
$10.00
$0.30
$20.00
Text
$0.60
$0.06
$2.40
Image
$0.80
$0.08
--
GPT-live-transcribe
Global Standard
Audio
--
--
$1.02/hour
GPT-transcribe
Global Standard
Audio
--
--
$0.27/hour
Getting Started
Choose GPT-transcribe when your application processes complete audio files asynchronously, or GPT-live-transcribe when it needs text continuously as speech arrives. Try the models in Microsoft Foundry, then use the resources below to explore the Realtime API, follow the audio quickstart, compare available models, and review Azure OpenAI in Foundry Models documentation.
For asynchronous transcription, submit a complete audio file to GPT-transcribe and process the returned transcript after the request completes. This pattern works well for recordings, voicemails, and uploaded media. For streaming transcription, open a Realtime API session with GPT-live-transcribe, send audio as it is captured, and handle incremental transcript events. This pattern supports live captioning and agent-assist experiences that need text during an active interaction. Refer to the linked quickstart and Realtime API documentation for current SDK setup, authentication, request schemas, and supported audio formats.
Explore Microsoft Learn documentation to learn more: