Files
awesome-copilot/cookbook/copilot-sdk/dotnet/managing-local-files.md
T
Jon GallowayandCopilot a19b3101cc Update .NET Copilot SDK cookbook for current SDK releases (#3548)
* Update .NET Copilot SDK cookbook: fix On<T> breaking change, add in-process runtime, tool search, and message provenance recipes

- Fix breaking change: Session.On is now generic (On<T> where T : SessionEvent).
  Updated all recipes that used the old non-generic session.On(evt => ...) pattern:
  error-handling, pr-visualization, managing-local-files, accessibility-report,
  ralph-loop (both .md and .cs where applicable).
- Add new 'In-Process Runtime' recipe (in-process-runtime.md + recipe/in-process-runtime.cs)
  demonstrating RuntimeConnection.ForInProcess(), live-tested.
- Document tool search / deferred loading (SessionConfig.ToolSearch / ToolSearchConfig)
  in pr-visualization.md, live-tested.
- Document typed message provenance (MessageOptions.Source / MessageSource) in
  error-handling.md, live-tested.
- Fix dotnet/README.md recipe index: it was missing Ralph Loop and Accessibility
  Report entries; also added the new In-Process Runtime entry.
- Add In-Process Runtime entry to the top-level cookbook/copilot-sdk/README.md
  .NET section.
- Update dotnet/recipe/README.md runnable-examples table with the new recipe.

All existing .NET cookbook recipes were rebuilt and rechecked against the current
GitHub Copilot SDK (Copilot CLI 1.0.85); no other breaking changes were found.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Update cookbook model names to current supported models

- Replace stale/nonexistent model IDs (gpt-5, claude-sonnet-4.5,
  claude-opus-4.6, gpt-5.1-codex-mini) with current values from the
  supported AI models list
- Prefer Model = "auto" wherever a specific model isn't load-bearing
  to the recipe's teaching point
- ralph-loop: pin gpt-5.3-codex (current codex-family GA model), since
  a dedicated coding model is a deliberate, documented choice for the
  autonomous loop
- multiple-sessions: reshape the model narrative so it demonstrates a
  real explicit-override use case (A/B testing via claude-sonnet-5)
  instead of two sessions sharing the same hardcoded model

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Use SendAndWaitAsync in in-process runtime recipe

Replace the event-based TaskCompletionSource pattern with SendAndWaitAsync so the example waits for the final assistant response, propagates session errors, and uses the SDK timeout behavior.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-09-22 00:15:06 +00:00

3.7 KiB

Grouping Files by Metadata

Use Copilot to intelligently organize files in a folder based on their metadata.

Runnable example: recipe/managing-local-files.cs

dotnet run recipe/managing-local-files.cs
dotnet run recipe/managing-local-files.cs -- /path/to/folder

Example scenario

You have a folder with many files and want to organize them into subfolders based on metadata like file type, creation date, size, or other attributes. Copilot can analyze the files and suggest or execute a grouping strategy.

Example code

using GitHub.Copilot;

// Create and start client
await using var client = new CopilotClient();
await client.StartAsync();

// Define tools for file operations
var session = await client.CreateSessionAsync(new SessionConfig
{
    Model = "auto",
    OnPermissionRequest = PermissionHandler.ApproveAll
});

// Wait for completion
var done = new TaskCompletionSource();

session.On<SessionEvent>(evt =>
{
    switch (evt)
    {
        case AssistantMessageEvent msg:
            Console.WriteLine($"\nCopilot: {msg.Data.Content}");
            break;
        case ToolExecutionStartEvent toolStart:
            Console.WriteLine($"  → Running: {toolStart.Data.ToolName} ({toolStart.Data.ToolCallId})");
            break;
        case ToolExecutionCompleteEvent toolEnd:
            Console.WriteLine($"  ✓ Completed: {toolEnd.Data.ToolCallId}");
            break;
        case SessionIdleEvent:
            done.SetResult();
            break;
    }
});

// Use an explicit folder or default to the current directory
var targetFolder = args.FirstOrDefault() ?? Environment.CurrentDirectory;

await session.SendAsync(new MessageOptions
{
    Prompt = $"""
        Analyze the files in "{targetFolder}" and organize them into subfolders.

        1. First, list all files and their metadata
        2. Preview grouping by file extension
        3. Create appropriate subfolders (e.g., "images", "documents", "videos")
        4. Move each file to its appropriate subfolder

        Please confirm before moving any files.
        """
});

await done.Task;

Grouping strategies

By file extension

// Groups files like:
// images/   -> .jpg, .png, .gif
// documents/ -> .pdf, .docx, .txt
// videos/   -> .mp4, .avi, .mov

By creation date

// Groups files like:
// 2024-01/ -> files created in January 2024
// 2024-02/ -> files created in February 2024

By file size

// Groups files like:
// tiny-under-1kb/
// small-under-1mb/
// medium-under-100mb/
// large-over-100mb/

Dry-run mode

For safety, you can ask Copilot to only preview changes:

await session.SendAsync(new MessageOptions
{
    Prompt = $"""
        Analyze files in "{targetFolder}" and show me how you would organize them
        by file type. DO NOT move any files - just show me the plan.
        """
});

Custom grouping with AI analysis

Let Copilot determine the best grouping based on file content:

await session.SendAsync(new MessageOptions
{
    Prompt = $"""
        Look at the files in "{targetFolder}" and suggest a logical organization.
        Consider:
        - File names and what they might contain
        - File types and their typical uses
        - Date patterns that might indicate projects or events

        Propose folder names that are descriptive and useful.
        """
});

Safety considerations

  1. Confirm before moving: Ask Copilot to confirm before executing moves
  2. Handle duplicates: Consider what happens if a file with the same name exists
  3. Preserve originals: Consider copying instead of moving for important files