Native Shell
Native Shell:AI 生成的 UI,在你的应用中原生呈现,覆盖每个平台。iOS、Android、macOS、Windows 与 Linux 上的应用、GPUI 应用与网页在运行时加载已签名、沙箱隔离的 TSX 模块并绘制 th
AI 翻译
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Code-defined AI agents and tools for .NET, checked at compile time. Built on Microsoft.Extensions.AI.
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗Code-defined agents and toolsets for .NET 10, built on Microsoft.Extensions.AI.
Documentation · Getting started · Changelog
Build AI agents for .NET with just a few lines of code, and let the compiler catch your mistakes.
[!WARNING] Typeshift is in alpha: the API may change between releases. Status lists what is open.
AddTool(FindCompanies) turns a static method into a tool, and its XML docs become what
the model reads. Group your tools by feature, domain or permission level, as you like.Settings record of what you mark configurable. Store
it in your database, under the id type you already use.IChatClient serves a model, nothing uses reflection, and your app
publishes with Native AOT.dotnet add package Typeshift --prerelease
The types are in the Typeshift namespace, so add using Typeshift; to your files. Turn on XML docs and pick your id
type once, in a Directory.Build.props next to your solution:
<Project>
<PropertyGroup>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<!-- Ids are Guids unless you name another type -->
<TypeshiftIdType>int</TypeshiftIdType>
</PropertyGroup>
</Project>
A tool is a static method. Its XML docs describe it to the model, and its settings stay out of the model's reach:
internal partial class CompanyToolset : Toolset
{
public CompanyToolset()
{
WithDisplayName("Companies");
AddTool(FindCompanies)
.WithSettings<FindCompaniesSettings>()
.Configurable(s => s.Limit);
}
/// <summary>
/// Finds the companies of a city.
/// </summary>
/// <param name="city">The city the companies are based in.</param>
public static IReadOnlyList<Company> FindCompanies(string city, FindCompaniesSettings settings) =>
[
.. Companies
.Where(company => company.City.Equals(city, StringComparison.OrdinalIgnoreCase))
.Where(company => company.Active || settings.IncludeInactive)
.Take(settings.Limit)
];
private static readonly Company[] Companies =
[
new("Danube Robotics", "Vienna", Active: true),
new("Prater Motion", "Vienna", Active: true),
new("Graz Gearworks", "Graz", Active: false)
];
}
internal sealed record Company(string Name, string City, bool Active);
snippet source | anchor
{
"name": "find_companies",
"description": "Finds the companies of a city.",
"parameters": {
"type": "object",
"properties": {
"city": { "type": "string", "description": "The city the companies are based in." }
},
"required": ["city"]
}
}
The constructor picks the model, the tools and their settings. Configurable names what may change at runtime:
internal partial class ResearchAgent : Agent
{
public ResearchAgent()
{
WithDescription("Researches the companies of a city.");
WithChatOptions()
.WithModel("openai", "gpt-5-mini")
.WithTemperature(0.2f)
.Configurable(o => o.Instructions)
.Configurable(o => o.Temperature);
UseToolset<CompanyToolset>();
ConfigureFindCompanies()
.WithLimit(3);
}
protected override string GetInstructions() =>
"""
Find companies with the find_companies tool and list them.
""";
}
snippet source | anchor
AddTypeshift() registers every toolset and agent. You bring a chat client provider, which returns the IChatClient
of a provider's model, and a store for settings and conversations:
var services = new ServiceCollection();
services.AddTypeshift()
.WithStore<InMemoryTypeshiftStore>()
.WithChatClientProvider<KeyedChatClientProvider>();
services.AddKeyedSingleton<IChatClient>("openai", new CannedChatClient());
await using var provider = services.BuildServiceProvider(validateScopes: true);
snippet source | anchor
CannedChatClient is a fake that lets the samples run without a network. In your app, register a real client in its
place, such as OpenAI's.
internal sealed class KeyedChatClientProvider(IServiceProvider services) : IChatClientProvider
{
// One client per provider serves all its models: Typeshift puts the model into every request
public ValueTask<IChatClient> GetChatClientAsync(string provider, string model, CancellationToken ct) =>
ValueTask.FromResult(
services.GetKeyedService<IChatClient>(provider)
?? throw new InvalidOperationException($"No IChatClient is registered for the provider '{provider}'."));
}
snippet source | anchor
Store settings under an id you own, then run the agent:
await using var scope = provider.CreateAsyncScope();
var research = scope.ServiceProvider.GetRequiredService<AgentHost<ResearchAgent>>();
var settingsId = 42;
await research.ConfigureAsync(settingsId, settings => settings with
{
Temperature = 0.4f,
FindCompanies = settings.FindCompanies with { Limit = 2 }
});
snippet source | anchor
var answer = await research.RunAsync("Vienna", settingsId, conversationId: 1);
Console.WriteLine($"{research.Agent.Name}: {answer.Text}");
snippet source | anchor
The getting started guide explains every line, and lists what your app implements.
| Feature | What it gives you |
|---|---|
| Tool settings | Limits and timeouts the model cannot choose, set in code, per customer or per run |
| Composable agents | Agents built from toolsets, sub-agents and handoffs |
| One store | Settings and conversations in your database, behind four methods |
| Conversations | Resume after a crash, steer a run while it works, watch it live |
| Tool approval | Let your app approve a call before it runs |
| Plan and auto modes | Let the agent plan first, or run without interruptions |
| Middleware | Wrap every run or tool call |
| Context providers | Add memory, documents or other data to every run |
| MCP servers | Offer an MCP server's tools to an agent |
| Long-running agents | Compaction and crash recovery for hundreds of model calls |
A workspace toolset, a background sub-agent, plan mode and compaction, together:
internal partial class CodingAgent : Agent
{
public CodingAgent()
{
WithChatOptions()
.WithModel("anthropic", "claude-sonnet-5-5");
UseToolset<WorkspaceToolset>();
UseAgent<ExploreAgent>()
.InBackground();
WithRunOptions()
.WithMode(AgentMode.Plan)
.WithMaxToolIterations(500)
.WithMaxInputTokens(150_000)
.WithSummaryModel("claude-haiku-5-5")
.Configurable(r => r.Mode)
.Configurable(r => r.MaxToolIterations)
.Configurable(r => r.SummaryModel);
}
protected override string GetInstructions() =>
"""
Work in the customer's workspace. Read before you change anything, and run the tests after every change.
""";
}
snippet source | anchor
Contributions are welcome. The repository is set up for coding agents: AGENTS.md maps each task to its
playbook, and the contributing guide covers building, testing
and the docs. Code may be written with AI. Docs may be drafted with AI, but a person reviews and rewrites them, because
clear docs are what make Typeshift easy to pick up.
| Observability | OpenTelemetry spans and metrics for every run |
| Native AOT | Publish your app without reflection or trim warnings |