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

GitLab cuts 14% of staff as it scales its platform to serve AI workloads

1 Share
The company is reducing its workforce as it exits 22 countries, reduces management layers, and invests in its infrastructure to scale its platform.
Read the whole story
alvinashcraft
46 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

How To Make Your Design System AI-Ready

1 Share

AI-generated prototypes often don't deliver consistently decent results because of tiny inconsistencies scattered all across a design system. I's decisions made but not documented, hard-coded values never cleaned up, or relying too much on AI making sense of mock-ups or design flows on its own.

Yesterday I stumbled upon a useful practical guide by Hardik Pandya from Atlassian — on how to reduce drifts, minimize mistakes, maintain context, and improve the quality of AI-generated prototypes. Let’s see how it works.

1. Design Decisions Are Infrastructure

Unsurprisingly, better AI prototypes come from better data — but also from better human guidance. We shouldn’t assume that AI knows how to choose the right component and how to design with accessibility in mind. It needs priorities, a clear path on how we make decisions, design principles, examples, do’s and don’ts.

In fact, we should treat design decisions as infrastructure. That means that every time we make a decision — not just a design decision, but even a decision on how to actually prioritize our work and how we make decisions around here — it must find a path into the spec file that is then consumed by AI.

2. Auditing: FigmaLint

One of the useful tools to audit the quality of the design system is FigmaLint. It’s a useful free Figma plugin for auditing tokens, states, accessibility, binding tokens, renaming layers, detecting detached instances, missing interactive states and hard-coded values — and preparing the design documentation.

If you often have to work with vendors and third parties who supply you with their design systems and component libraries, that’s a great helper to have by your side — especially if you want to improve the quality of prototypes, AI-generated code, and AI-written documentation.

3. Three Layers: Spec Files + Token Layer + Auditing

To ensure quality, we establish design principles, guidelines, and rules in the form of “spec files”. It’s structured Markdown files that include spacing rules, color choices, component usage guidelines, priorities, etc. AI is going to read and reuse that spec file every time it’s going to generate a prototype.

Because the spec files are text files, it’s much more cost-effective but also much more accurate, just because we don’t rely on AI recognizing or decoding patterns from mock-ups but get specific guidelines instead. In fact, extending code is often a more effective way than generating code from mock-ups.

The token layer lists and keeps updated all tokens used throughout the design system. AI always chooses from a closed set of named variables instead of inventing plausible values ad hoc.

An audit script catches what AI gets wrong. It scans the prototype and flags every hard-coded value and flags it if necessary. It can be a regular software doing that, with AI waiting for its feedback to come back.

Finally, when a design system ships updates, a sync routine flags which spec files need updating. The goal is to make sure that AI always reads up-to-date, current specs, not the ones written against an outdated version.

4. Examples of AI-Ready Design Systems Wrapping Up

Ultimately, AI cannot magically resolve technical debt or design debt without proper guidance. It relies heavily on clear decisions, established priorities, and well-defined principles.

The more deliberate and precise designers are in guiding AI, the better the overall outcomes will be. This requires not just cleaning up and improving design systems but also maintaining them over time as decisions need to trickle down into Markdown files. We’ll be busy for years to come.

Meet “Design Patterns For AI Interfaces”

Meet Design Patterns For AI Interfaces, Vitaly’s new video course with 100s of real-life examples and UX guidelines to design AI features that people actually use — with a live UX training later this year. Jump to a free preview.

Meet Design Patterns For AI Interfaces, Vitaly’s video course on interface design & UX.

Video + UX Training

$ 450.00 $ 799.00 Get Video + UX Training

30 video lessons (10h) + Live UX Training.
100 days money-back-guarantee.

Video only

$ 275.00$ 395.00
Get the video course

30 video lessons (10h). Updated yearly.
Also available as a UX Bundle with 3 video courses.

Useful Resources

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

Taking your AI to the edge with .NET MAUI | OD803

1 Share
From: Microsoft Developer
Duration: 46:30
Views: 35

AI is transforming both what we build and how we build it. Learn how .NET MAUI developers can bring AI to the edge using local models and on-device capabilities across mobile and desktop, while understanding the role of cloud AI. We’ll cover the impact on privacy, performance, and UX, explore .NET 10 features and what’s coming in .NET 11, and show how AI-powered tools and agentic workflows like DevFlow can accelerate app development.

To learn more, please check out these resources:
* https://aka.ms/build26-next-steps
* https://aka.ms/maui

𝗦𝗽𝗲𝗮𝗸𝗲𝗿𝘀:
* Gerald Versluis

𝗦𝗲𝘀𝘀𝗶𝗼𝗻 𝗜𝗻𝗳𝗼𝗿𝗺𝗮𝘁𝗶𝗼𝗻:
This is one of many sessions from the Microsoft Build 2026 event. View even more sessions on-demand and learn about Microsoft Build at https://build.microsoft.com

OD803 | English (US) | Developer tools & frameworks

Pre-recorded | (300) Advanced

#MSBuild

Chapters:
0:00 - Introduction to Taking AI to the Edge with .NET MAUI
00:00:34 - Overview of .NET MAUI and Blazor Hybrid Capabilities
00:04:21 - How .NET MAUI Team Uses Copilot for AI-Enhanced Development
00:08:01 - Community Involvement, MAUI Days, and MAUIverse Initiatives
00:13:00 - Partnerships with Syncfusion, Uno, and Avalonia Expanding MAUI
00:15:21 - Focus Areas in .NET MAUI 10: Stability, Performance, and XAML Enhancements
00:21:00 - .NET MAUI 10 New Features: SafeArea API, Android Material 3, and Service Releases
00:27:02 - Upcoming Enhancements in .NET 11: CoreCLR, Simplified CLI, and New Controls
00:34:31 - MAUI Labs: Integrating AI with Essentials.ai and DevFlow Tools
00:43:00 - MAUI Sherpa, Release Schedule, and Closing Remarks on AI-powered Cross-Platform Development

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

Why Nested ListView Breaks Down Faster Than You Expect in .NET MAUI

1 Share

TL;DR: Nested ListView in .NET MAUI is often introduced as layouts grow more complex. This article explores where that pattern creates challenges and examines the alternative list structuring approaches commonly used instead.

Using .NET MAUI ListView to build complex, data-heavy layouts often starts smoothly, especially when the UI structure closely mirrors the data model. The friction shows up later, usually when lists grow, layouts become interactive, and scrolling needs to stay fluid across devices.

This guide walks through what actually happens inside Syncfusion® .NET MAUI ListView when lists are nested, why those internal behaviors lead to gesture conflicts and layout thrashing, and how common replacement patterns, such as grouping, expand/collapse rows, and composite templates, change the performance profile of a page.

Along the way, it also looks at where nesting sometimes cannot be avoided, what trade-offs it introduces, and how tuning options like sizing strategy and incremental loading affect real-world scrolling behavior in Syncfusion ListView.

Why you should avoid nested ListView

1. Competing virtualization pipelines

Each List View maintains its own recycling, measurement, and layout lifecycle. When one ListView is nested inside another, both attempt to virtualize independently.

Any change in the inner list can force the outer list to remeasure, triggering cascading layout passes. As item counts grow, this directly impacts scroll smoothness.

2. Re-entrant layout and memory pressure

Expandable inner lists, dynamic item heights, or late data loading trigger repeated layout invalidations. On mobile hardware, that translates into extra CPU work and short-lived allocations, issues that surface as stutter or frame drops.

3. Gesture and scroll ownership conflicts

When both parent and child List View controls believe they own vertical scrolling, gesture arbitration becomes unpredictable. Users experience sticky scrolling, missed swipes, or inconsistent touch handling.

4. Accessibility and focus side effects

Keyboard navigation and accessibility tools struggle with nested scroll regions. Managing focus across multiple ListView instances often requires additional customization that offsets the original layout simplicity.

Designing hierarchy without Nesting Syncfusion ListView

The key architectural shift is this: hierarchy does not require nested ListView controls.

With Syncfusion’s ListView features, you can preserve structure while keeping a single, predictable virtualization and scrolling pipeline.

Grouping

Grouping is the most scalable alternative to nested lists. It is an organizational pattern that buckets items into labelled sections based on a shared key.

Instead of embedding ListViews, bind a single SfListView to a flat collection and group items using a shared key (for example, CategoryName). Group headers render inline, optionally as sticky headers, while all items scroll within a single virtualized surface.

Why grouping works well in Syncfusion ListView:

  • One virtualization pipeline.
  • Predictable measurement behavior.
  • Clear visual hierarchy without layout recursion.
  • Stable performance with large datasets.

This pattern fits catalogs, settings pages, and any screen where sectioning matters more than strict parent-child interaction.

Let’s implement the grouping feature in Syncfusion .NET MAUI ListView.

Step 1: Creating a data model

Start by creating a data model to bind to the ListView. Define a Product class with Name, Price, and CategoryName (used as the grouping key) in a Product.cs file, as shown in the code example below.

public sealed class Product
{
    public string Name { get; set; } = string.Empty;
    public decimal Price { get; set; }
    public string CategoryName { get; set; } = string.Empty;
    public bool IsHeader { get; set; }
}

public sealed partial class Category : BindableObject
{
    public string Name { get; set; } = string.Empty;

    private bool isExpanded;
    public bool IsExpanded
    {
        get => isExpanded;
        set
        {
            if (isExpanded == value) return;
            isExpanded = value;
            OnPropertyChanged();
        }
    }

    public ObservableCollection<Product> Products { get; } = new();
}

Step 2: Populate the model collection in the ViewModel

Next, create a view model to supply grouped data. Build Categories and flatten the data into GroupedProducts (ObservableCollection) in CatalogViewModel.cs, assigning CategoryName to each item so grouping can be resolved at the list level, as shown in the code example below.

public class CatalogViewModel
{
    public ObservableCollection<Category> Categories { get; }
    public ObservableCollection<Product> GroupedProducts { get; }

    public CatalogViewModel()
    {
        Categories = new ObservableCollection<Category>
        {
            new Category
            {
                Name = "Featured",
                Products = // Add products here
                {
                }
            }
        };

        var flat = new List<Product>();
        foreach (var cat in Categories)
        {
            flat.Add(new Product
            {
                CategoryName = cat.Name,
                IsHeader = true
            });
            foreach (var p in cat.Products)
            {
                flat.Add(new Product
                {
                    Name = p.Name,
                    Price = p.Price,
                    CategoryName = cat.Name
                });
            }
        }

        GroupedProducts = new ObservableCollection<Product>(flat);
    }
}

Step 3: Binding the ViewModel and defining the item template

Define the XAML that renders a single, grouped list. Bind Syncfusion .NET MAUI ListView to GroupedProducts, configure grouping using CategoryName through a GroupDescriptor, and provide templates for group headers and list items, including optional sticky headers, as shown in the code example below.

<!-- Grouped List View with sticky headers (details in GitHub demo) -->
<sfListView:SfListView ItemsSource="{Binding GroupedProducts}"
                       IsStickyGroupHeader="True"
                       SelectionMode="None">
    <!-- sfListView:SfListView.DataSource with sfData:GroupDescriptor -->
    <!-- GroupHeaderTemplate: shows {Binding Key} -->
    <!-- ItemTemplate: shows product fields -->
</sfListView:SfListView>

Here’s a quick demo of the feature in action:

Grouping .NET MAUI ListView
Grouping .NET MAUI ListView

Expand/Collapse items using a single SfListView

Expand and collapse is a disclosure pattern that works particularly well with Syncfusion .NET MAUI ListView.

Instead of pushing users into nested lists or secondary views, parent rows reveal or hide related content inline. The ListView remains continuous, and users never lose scroll context.

To implement this feature, bind Syncfusion .NET MAUI List View to the Categories collection through the page’s BindingContext. Then define an ItemTemplate that renders a tappable category header and conditionally displays its child items when IsExpanded is true, as shown in the code example below.

<!-- reuse the Model and ViewModel from the Grouping section. -->
<!-- Expandable rows (details in GitHub demo) -->
<sfListView:SfListView ItemsSource="{Binding Categories}"
                       SelectionMode="None">
    <!-- ItemTemplate:
        - Header row with tap gesture or command
        - Divider line
        - Child items in a BindableLayout shown when IsExpanded -->
</sfListView:SfListView>
Expand/Collapse items in .NET MAUI ListView
Expand/Collapse items in .NET MAUI ListView

Composite item template

Some screens are heterogeneous rather than hierarchical.

Using a DataTemplateSelector with Syncfusion ListView allows you to render different row types, headers, items, and dividers—inside a single ListView instance. The control still maintains one recycling and measurement path.

This pattern is ideal for:

  • Feed-style layouts.
  • Mixed content lists.
  • Scenarios where row structure varies by item state.

You gain flexibility without fragmenting virtualization across multiple controls.

Step 1: Defining the template selector

Create a template selector to render header and item rows differently within a single ListView. Define ProductTemplateSelector (e.g., ProductTemplateSelector.cs) that switches between HeaderTemplate and ItemTemplate based on the IsHeader property, as shown in the code example below.

public sealed class ProductTemplateSelector : DataTemplateSelector
{
    public DataTemplate? HeaderTemplate { get; set; }
    public DataTemplate? ItemTemplate { get; set; }

    protected override DataTemplate OnSelectTemplate(object? item, BindableObject container)
    {
        if (item is Product product && product.IsHeader)
        {
            return HeaderTemplate ?? ItemTemplate ?? new DataTemplate(() => new ContentView());
        }

        return ItemTemplate ?? HeaderTemplate ?? new DataTemplate(() => new ContentView());
    }
}

Step 2: Binding ViewModel and apply template selector

Next, declare HeaderTemplate and ItemTemplate in the page’s resources, register ProductTemplateSelector, and apply it to a Syncfusion .NET MAUI List View bound to Rows, as shown in the code example below.

<!-- Reuse the Model and ViewModel from the Grouping section -->
<ContentPage.Resources>
    <!-- ParentTemplate and ChildTemplate -->
    <!-- TemplateSelector with HeaderTemplate/ItemTemplate -->
</ContentPage.Resources>

<sfListView:SfListView ItemsSource="{Binding Categories}"
                       ItemTemplate="{StaticResource ProductTemplateSelector}"
                       SelectionMode="None" />
Output for Composite Item template
Output for Composite Item template

When a nested ListView is unavoidable

There are edge cases where nesting cannot be removed entirely. In those cases, the goal is containment, not elegance.

Horizontal ListView inside a vertical feed

A horizontal SfListView embedded in a vertical one can be acceptable when:

  • The inner list has a fixed height.
  • Item templates are lightweight.
  • The outer ListView remains the sole vertical scroll owner.

Because scroll direction differs, gesture ownership stays clear.

Try this in your code:

<!-- Vertical List View with a compact horizontal strip per section -->
<sfListView:SfListView ItemsSource="{Binding Categories}">
    <sfListView:SfListView.ItemTemplate>
        <DataTemplate>
            <VerticalStackLayout>
                <Label Text="{Binding Name}"
                       FontAttributes="Bold" />
                <!-- Inner horizontal strip: fixed HeightRequest, simple item template -->
                <sfListView:SfListView ItemsSource="{Binding Products}"
                                       Orientation="Horizontal"
                                       HeightRequest="120">
                    <!-- Simple item template -->
                </sfListView:SfListView>
            </VerticalStackLayout>
        </DataTemplate>
    </sfListView:SfListView.ItemTemplate>
</sfListView:SfListView>
Horizontal Nested List View
Horizontal Nested List View

Vertical List inside another vertical feed

If you must nest vertically:

  • Disable scrolling on the inner SfListView.
  • Assign an explicit height.
  • Keep item counts tightly bounded.

At this point, you are deliberately opting out of inner virtualization so that the outer ListView controls scrolling and layout.

Here’s how you can do it in code:

<!-- Vertical inside vertical: fix inner height; outer list owns scrolling -->
<sfListView:SfListView ItemsSource="{Binding Categories}">
    <sfListView:SfListView.ItemTemplate>
        <DataTemplate>
            <VerticalStackLayout>
                <Label Text="{Binding Name}"
                       FontAttributes="Bold" />
                <sfListView:SfListView ItemsSource="{Binding Products}"
                                       IsScrollingEnabled="False"
                                       HeightRequest="{Binding Products.Count,
                                                      Converter={StaticResource MultiplyConverter},
                                                      ConverterParameter=72}">
                    <!-- Lightweight item template -->
                </sfListView:SfListView>
            </VerticalStackLayout>
        </DataTemplate>
    </sfListView:SfListView.ItemTemplate>
</sfListView:SfListView>
Vertical Nested List View
Vertical Nested List View

Syncfusion .NET MAUI ListView performance tuning that matters

Regardless of layout strategy, performance depends on a few non-negotiables when using SfListView:

  • ItemSize for uniform rows to skip per-item measurement.
  • QueryItemSize when item heights genuinely vary.
  • Incremental loading to control memory usage.
  • Template discipline: minimal nesting, explicit image sizing, and predictable bindings.

Well-structured layouts can still stutter if templates are heavy or sizing is left ambiguous.

Key takeaways for Syncfusion MAUI ListView layouts

  1. Avoid nesting vertical SfListView controls whenever possible.
  2. Keep a single scroll surface to stabilize virtualization and gestures.
  3. Use grouping, expand/collapse, and template selection to express hierarchy.
  4. Tune Syncfusion .NET MAUI List View for speed: set ItemSize (or use QueryItemSize), enable incremental loading, and keep images sized/cached.
  5. If you need a horizontal strip inside a vertical feed, fix its height and skip inner virtualization so only the outer list does the heavy lifting.

GitHub reference

For a complete working example of nested ListView alternatives in .NET MAUI, see the GitHub demo.

Frequently Asked Questions

How does grouping improve performance and UX?

It buckets items by a key (e.g., CategoryName), shows labelled headers (optionally sticky), keeps a single scroller, and reduces measure/memory overhead.

Is a horizontal ListView inside a vertical ListView ever acceptable?

Yes, as a lightweight, fixed-height horizontal strip (non-virtualized) so the outer vertical ListView remains the sole scroll owner.

What if I must place a vertical ListView inside another vertical ListView?

Disable inner scrolling and give the inner list an exact height (e.g., via a converter on Products.Count). Keep item counts bounded and templates light.

What are the key takeaways to maintain smooth scrolling?

Avoid vertical-in-vertical scrollers, flatten data, use grouping/expand-collapse/template selectors, tune ItemSize/QueryItemSize, enable incremental loading, and fix heights for any inner horizontal strips.

When should grouping be used instead of a DataTemplateSelector?

Use grouping when items share a clear key (e.g., CategoryName) and need labelled sections. Use DataTemplateSelector for mixed row types in one feed.

Can grouping and expand/collapse be combined?

Yes. Group by CategoryName and enable expand/collapse per group to show/hide items inline.

How do sticky group headers interact with expand/collapse?

Sticky headers work independently. Collapsing a group reduces items; the header remains sticky while its section is in view.

Supercharge your cross-platform apps with Syncfusion's robust .NET MAUI controls.

Conclusion

Thank you for reading! Designing list layouts with a single scrolling surface helps keep interaction and measurement predictable as UI complexity grows. Patterns such as grouping, composite templates with DataTemplateSelector, and inline expand/collapse align well with how Syncfusion .NET MAUI List View handles virtualization.

Applying sizing strategies like ItemSize or QueryItemSize, along with incremental loading, further supports consistent scrolling behavior as data volume increases. Together, these approaches help maintain smooth interaction and scalable performance in data‑rich MAUI applications.

If you’re a Syncfusion user, you can download the setup from the license and downloads page. Otherwise, you can download a free 30-day trial.

You can also contact us through our support forum support portal, or feedback portal for queries. We are always happy to assist you!

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

UNION vs UNIONALL: #SQLNewBlogger

1 Share

While writing another post I realized my UNION query didn’t work as one might initiall expect, so I decided a short post was worth writing. This is based on a previous post on QUOTENME().

Another post for me that is simple and hopefully serves as an example for people trying to get blogging as #SQLNewBloggers.

Missing a Row

When I ran this code, I got only a single row. There’s a UNION here, so why? One would expect two rows from these queries.

2026-05_0287

Let’s change to UNION ALL. Now we see this:

2026-05_0288

You can likely spot the reason, but it’s because both rows in the result are the same. In this cse, UNION is designed to remove duplicates. In the docs, it explicitly says

  • UNION ALL – Includes duplicates
  • UNION Excludes duplicates

We can see this in this examples I’ve got this code that gives me two virtual tables of numbers, some of which are duplicate:

WITH myTally(n)
AS
(SELECT n 
 FROM (VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10)) a(n)
)
, myTally2(n)
AS
(SELECT n 
 FROM (VALUES (1), (20), (3), (40), (5), (60), (7), (08), (9), (100)) b(n)
)
SELECT n
FROM myTally
UNION 
SELECT n
 FROM myTally2

When I run the query, with UNION, I see these results, 14 rows:

2026-05_0289

If I change to UNION ALL, 20 results.

2026-05_0290

Use UNION when you want unique things. UNION ALL if you need to see ALL The Rows.

SQL New Blogger

This post was about 8 minutes spent after I finished the other post. It is a quick expansion on something I saw in another post, it has a separate focus, and it shows I’ve realized something and built on previous work.

You can showcase these skills.

The post UNION vs UNIONALL: #SQLNewBlogger appeared first on SQLServerCentral.

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

Microsoft Agent Framework at BUILD 2026: Agent Harness, Hosted Agents, CodeAct, and more

1 Share

Microsoft Agent Framework at BUILD 2026: Agent Harness, Hosted Agents, CodeAct, and more

Screenshot 2026 05 30 222939 image

BUILD 2026 is underway, and the Microsoft Agent Framework team have a round-up of exciting announcements! Microsoft Agent Framework (MAF) is our open-source SDK and runtime for building AI agents and multi-agent workflows, with the same concepts and APIs across .NET and Python. It gives you a clean programming model – chat clients, tools, MCP integrations, context providers, middleware, and multi-step workflows – so you can focus on agent logic instead of plumbing. MAF reached 1.0 GA on April 2, 2026, bringing the convergence of AutoGen and Semantic Kernel into a single, supported platform. Everything below builds on that 1.0 foundation.

What’s new

Agent Harness: production patterns, built in

The agent harness is the layer where model reasoning meets real execution: shell and filesystem access, human-in-the-loop approval flows, and context management across long-running sessions. With MAF, these patterns are now first-class and consistently built in from the get-go. Agent harness extensions turn any chat client into a fully-featured Agent Harness using a single method.

These building blocks ship in the harness:

  • Automatic context compaction: monitors token usage and compacts chat history mid-loop to prevent context window overflow during long tool-calling chains
  • Built-in default instructions and instruction merging: ships with opinionated system instructions for task breakdown, tool usage, and reasoning patterns
  • Instruction merging: harness instructions appear first, then your custom agent instructions

Built-in Providers and tools:

  • FileMemoryProvider: session-scoped file-based memory so the agent can persist notes/learnings across turns; stored in agent-file-memory/{session}/
  • FileAccessProvider: general file access so that the agent can access and change any files it needs to operate on
  • TodoProvider: lets the agent track work items (add, complete, remove, list) in session state for multi-step task management
  • AgentModeProvider: supports “plan” vs “execute” operating modes so the agent can separate planning from action
  • AgentSkillsProvider: skill discovery and execution from the file system, enabling modular capability injection
  • BackgroundAgentsProvider: delegate subtasks to child agents running in parallel for fan-out orchestration
  • Web search: hosted web search tool out of the box (disable with DisableWebSearch)
  • Shell execution (.NET only): run shell commands via a sandboxed ShellExecutor

Middleware and customization:

  • ToolApprovalAgent: “don’t ask again” approval rules for sensitive tool calls
  • OpenTelemetryAgent: automatic opent telemetry Semantic Conventions tracing
  • Pluggable storage backends: swap FileMemoryStore and FileAccessStore with any AgentFileStore implementation (file system, blob storage, etc.)
AIAgent agent =
    chatClient.AsHarnessAgent(MaxContextWindowTokens, MaxOutputTokens, new HarnessAgentOptions
    {
        Name = "BlogWriterAgent",
        Description = "A blog writing assistant that researches a topic, plans an outline, and drafts a blog post.",
        FileMemoryStore = new FileSystemAgentFileStore(Path.Combine(AppContext.BaseDirectory, "artifacts")),
        ChatOptions = new ChatOptions
        {
            Instructions = instructions,
            Tools =
            [
                new WebBrowsingTool(),
            ],
        },
    });

// Run the interactive console session using the shared HarnessConsole helper.
await HarnessConsole.RunAgentAsync(
    agent,
    userPrompt: "Enter a blog topic to get started.",
    new HarnessConsoleOptions
    {
        Observers = [
            new OpenAIResponsesWebSearchDisplayObserver(),
            new OpenAIResponsesErrorObserver()
        ]
        CommandHandlers = HarnessConsoleOptions.BuildDefaultCommandHandlers(agent),
    });

Example in python:

# Create a harness agent with research-specific instructions.
# All other features (todo, mode, compaction, skills, telemetry, web search) are
# automatically configured with sensible defaults.
agent = create_harness_agent(
    client=client,
    max_context_window_tokens=128_000,
    max_output_tokens=16_384,
    name="ResearchAgent",
    description="A research assistant that plans and executes research tasks.",
    agent_instructions=RESEARCH_INSTRUCTIONS,
)

Learn more: Agent Harness in Agent Framework · Harness samples on GitHub

Foundry Hosted Agents: from local to production

Once your MAF agent runs locally, the next question is how to deploy, monitor, evaluate, and version it. Hosted Agents in Foundry Agent Service is the easiest way to give that agent a production home with your own code, packaged as a container and deployed onto Foundry-managed infrastructure, with built-in identity, automatic scaling, managed session state, observability, and versioning.

What you get out of the box:

  • Scale to zero, pay nothing while the agent is idle; it scales back up on the next request.
  • Resume with filesystem intact, files, disk state, and session identity persist across scale-to-zero, so the agent restarts exactly where it left off.
  • Per-session isolation, every session gets its own VM-isolated sandbox with persistent state.
  • Built-in observability, MAF’s OpenTelemetry traces flow into Application Insights with zero extra wiring.

Turning a local agent into a hosted agent takes only a few lines. In .NET:

using Microsoft.Agents.AI.Foundry.Hosting;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddFoundryResponses(agent);

var app = builder.Build();
app.MapFoundryResponses();

app.Run();

And in Python:

server = ResponsesHostServer(agent)

server.run()

Learn more: From Local to Production with Foundry Hosted Agents · .NET samples · Python samples

CodeAct: faster agents with fewer model turns

Many agents aren’t bottlenecked by model quality, they’re bottlenecked by orchestration overhead. When an agent chains together many small tool calls, each step is a separate model turn, driving up latency and token usage.

CodeAct collapses that loop. Instead of choosing a tool, waiting, and choosing the next one, the model writes a single short Python program that calls your tools via call_tool(…), runs it once in a sandbox, and returns a consolidated result. CodeAct ships in the new agent-framework-hyperlight (alpha) package, which runs the model-generated code in a fresh, locally isolated Hyperlight micro-VM per call, so strong isolation is essentially free at the granularity of a single tool call.

Wiring it in is a one-line change to how your tools are registered:

from agent_framework import Agent, tool
from agent_framework_hyperlight import HyperlightCodeActProvider

@tool
def get_weather(city: str) -> dict[str, float | str]:
    """Return the current weather for a city."""
    return {"city": city, "temperature_c": 21.5, "conditions": "partly cloudy"}

codeact = HyperlightCodeActProvider(
    tools=[get_weather],
    approval_mode="never_require",
)

agent = Agent(
    client=client,
    name="CodeActAgent",
    instructions="You are a helpful assistant.",
    context_providers=[codeact],
)

result = await agent.run(
    "Get the weather for Seattle and Amsterdam and compare them."
)

On a representative multi-step workload (computing order totals across many users, dozens of tool calls), the difference is significant:

Wiring Time Tokens
Traditional 27.81s 6,890
CodeAct 13.23s 2,489
Improvement 52.4% 63.9%

Learn more: CodeAct in Agent Framework · Hyperlight package · Benchmark sample

Also reaching 1.0

The features in Microsoft Agent Framework are graduating from preview to release:

GitHub Copilot SDK integration

MAF now supports building agents on the GitHub Copilot SDK as a backend, bringing Copilot’s coding-oriented capabilities  (shell execution, file operations, URL fetching, and MCP server integration) into the standard MAF programming model.

Python:


import asyncio
from agent_framework.github import GitHubCopilotAgent

async def basic_example():
    agent = GitHubCopilotAgent(
        default_options={"instructions": "You are a helpful assistant."},
    )

    async with agent:
        result = await agent.run("What is Microsoft Agent Framework?")
        print(result)

.NET:

using GitHub.Copilot.SDK;
using Microsoft.Agents.AI;

await using CopilotClient copilotClient = new();
await copilotClient.StartAsync();

AIAgent agent = copilotClient.AsAIAgent();

Console.WriteLine(await agent.RunAsync("What is Microsoft Agent Framework?"));

The Copilot agent is a standard MAF agent, so it supports tools, instructions, streaming, sessions, MCP servers, and built-in OpenTelemetry observability.

Learn more: GitHub Copilot provider docs

Multi-agent orchestration: the Handoff pattern

Multi-agent systems often start as a router that forwards to a specialist, and sometimes break the first time an agent needs a follow-up question, more context from a peer, or realizes mid-turn that the request belongs elsewhere. Handoff orchestration is built for exactly that: you declare the agents and the directed edges between them, and the framework injects the handoff tools each agent uses to transfer control. Topology and guardrails stay with the developer; routing decisions stay with the agents.

csharp

using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Workflows;

AIAgent triage = chatClient.AsAIAgent(
    instructions: "You receive a user request and route it to the right specialist.",
    name: "Triage");

AIAgent billing = chatClient.AsAIAgent(
    instructions: "You handle billing questions.", name: "Billing");

AIAgent tech = chatClient.AsAIAgent(
    instructions: "You handle technical support questions.", name: "Tech");

Workflow workflow = AgentWorkflowBuilder
    .CreateHandoffBuilderWith(triage)
    .WithHandoff(triage, billing)
    .WithHandoff(triage, tech)
    .Build();

The same graph in Python:

from agent_framework_orchestrations import HandoffBuilder

workflow = (
    HandoffBuilder(participants=[triage, billing, tech])
    .with_start_agent(triage)
    .add_handoff(triage, [billing, tech])
    .build()
)

Learn more: A Tour of the Handoff Orchestration Pattern

See us at BUILD

Come find the team at the Foundry booths and sessions at BUILD. Bring your agents and your questions!

Can’t make it in person? Watch online. Sessions featuring Microsoft Agent Framework:

If you’ve enjoyed building with Agent Framework, give us a star on GitHub and share feedback in our Discussions. We can’t wait to see what you build. Download the SDK on GitHub, read the documentation, visit the developer blog, or join the Discord.

 

The post Microsoft Agent Framework at BUILD 2026: Agent Harness, Hosted Agents, CodeAct, and more appeared first on Microsoft Agent Framework.

Read the whole story
alvinashcraft
48 minutes ago
reply
Pennsylvania, USA
Share this story
Delete
Next Page of Stories