PowerToys Command Palette 扩展开发完全指南:Root View、Page 体系与 ICommandProvider 扩展机制
Microsoft PowerToys 内置的 Command Palette(命令面板) 是一个以“命令”为核心的可扩展启动器:按下 Win+Ctrl+. 即可呼出,在其中搜索并执行内置命令与第三方扩展提供的命令。本篇技术指南以仓库中的 command-palette-anatomy.md 为骨架,系统讲解 Command Palette 的界面结构(Root View 与各类 Page)、扩展 SDK 的核心接口(ICommandProvider、ICommand 等),并完整演示如何基于扩展模板从零构建一个可运行、可部署的 SSH Keychain 扩展。读完本文,你将掌握 Command Palette 扩展的完整开发流程,并能在 src/modules/cmdpal 的源码中快速定位每一个机制背后的真实实现。
Root View:命令面板的根视图
Root View(根视图)是 Command Palette 首次被打开时显示的那个视图,也是用户见到的第一个界面。从 Command Palette 的角度看,它本质上是一种特殊的 ListPage:
- 它特殊在展示的是所有顶层命令,包括内置命令(built-in commands)与已安装扩展通过 ICommandProvider 提供的命令;
- 在这个语境下,所谓“命令”其实就是在根视图中显示的 ListItem。换句话说,根视图里的所有 ListItem 都被称为“命令”;
- 用户可以通过顶部的 FilterBox 输入文字来搜索/过滤命令,面板会基于用户的输入实时过滤根视图中展示的命令。
当用户点击某个命令时,会执行该命令关联的默认命令(default command);当命令被选中后,用户直接按下 Enter 键也会执行同样的默认命令。
在 UI 工程中,根视图与搜索框的实际渲染位于 Microsoft.CmdPal.UI 工程(例如 SearchBar.xaml、ListPage.xaml 与 ListItemsView.xaml),负责承载顶层命令逻辑的 ViewModel 则在 Microsoft.CmdPal.UI.ViewModels(如 TopLevelViewModel.cs、ListItemViewModel.cs)。
嵌套视图(Page)体系
当一条命令被执行时,它可以在 Command Palette 内部打开一个“嵌套”的新视图,这些视图被称为 Page(页面)。所有 Page 都派生自 IPage 基础契约,并在此之上根据展示形态扩展为若干具体类型。
ListPage(列表页)
列表页在命令面板内展示一个条目列表。文档中给出的设计级接口如下:
interface IListPage requires IPage {
String SearchText { get; };
String PlaceholderText { get; };
Boolean ShowDetails{ get; };
IFilters Filters { get; };
IGridProperties GridProperties { get; };
ISection[] GetItems(); // DevPal 负责对这些条目进行过滤
}
注意 GetItems() 的注释:列表页自身的过滤工作(模糊搜索)由 Command Palette 宿主完成,扩展作者只需要把条目数据交给它。这一点在实战章节会再次验证。
在仓库当前源码中,SDK 的 Toolkit 层提供了对应的可继承基类 ListPage.cs:
PlaceholderText:搜索框占位文本,默认空字符串;SearchText:当前搜索关键字(宿主回写,扩展可读取);ShowDetails:是否展示详情面板(绑定到设置项);HasMoreItems/LoadMore():是否还有更多条目、以及加载更多的回调,用于分页/惰性加载场景;Filters(IFilters)与GridProperties(IGridProperties):分别用于声明页面的筛选器集合与网格布局参数;EmptyContent:列表为空时展示的占位内容;GetItems():返回需要展示的条目,默认返回空数组;ItemsChanged事件与RaiseItemsChanged():条目集合变化时通知宿主刷新 UI。
ISection
一个列表页往往需要把条目组织成多个“分组/分节”。ISection 就是这样一个分节抽象:每一节拥有自己的标题,并承载一组条目。对应 Toolkit 实现为 Section.cs,典型的构造方式是在 GetItems() 中返回一个或多个 new ListSection() { Title = "分组标题", Items = [...] }(下文 SSH Keychain 例子中 "SSH Hosts" 一节即为典型用法)。
GridProperties
GridProperties 控制列表页以网格/宫格布局展示时的属性(列数、尺寸等),对应 IGridProperties 接口。Toolkit 提供 SmallGridLayout.cs、MediumGridLayout.cs 与 GalleryGridLayout.cs 等预设布局实现。若未设置网格属性,列表页按常规列表渲染。
ShowDetails
ShowDetails 是布尔开关:开启后,列表页允许对条目展示“详情”(details)内容。详情的面板模型由 IDetails 支撑,Toolkit 对应 Details.cs;详情承载的元素(链接、分隔符、标签等)分别有 DetailsLink.cs、DetailsSeparator.cs、DetailsTags.cs。
PlaceholderText
PlaceholderText 即搜索框(FilterBox)在没有输入时显示的灰色提示文字。默认值为空字符串,扩展可按需覆盖,例如设置成“搜索 SSH 主机…”。
SearchText
SearchText 是用户在 FilterBox 中实时输入的搜索关键字,由宿主写入列表页对象。普通 ListPage 无需关心它(宿主按此关键字对 GetItems() 结果做模糊过滤);只有 DynamicListPage 需要接管它来亲自实现过滤。
MarkdownPage
Markdown 页面在命令面板内部渲染 Markdown 内容,其设计级接口为:
interface IMarkdownPage requires IPage {
String[] Bodies();
IDetails Details();
IContextItem[] Commands { get; };
}
即:若干 Markdown 正文(Bodies)、可选详情(Details)以及一组上下文命令(Commands)。Toolkit 侧对应的页面基类与内容抽象可参考 ContentPage.cs 与 MarkdownContent.cs。
FormPage
表单页在命令面板内部渲染一个表单(如参数填写、设置编辑),其设计级接口为:
interface IFormPage requires IPage {
IForm[] Forms();
}
表单的能力由 IForm 系列接口承担;Toolkit 中既有面向“设置表单”的 SettingsForm.cs,也有通用的 FormContent(见 FormContent.cs)。表单提交动作通过 IFormContent2.SubmitForm / SubmitAction 等契约返回 ICommandResult(参见 CommandProvider.cs 中用于注册接口的存根实现)。
DynamicListPage(动态列表页)与内置模糊过滤
动态列表页与普通列表页相似,但它把过滤控制权交给开发者,其设计级接口为:
interface IDynamicListPage requires IListPage {
ISection[] GetItems(String query); // DevPal 不再对这些条目做任何过滤
}
也就是说,宿主不会替它过滤,而是把查询字符串透传给扩展,由扩展自己决定展示什么。Toolkit 的 DynamicListPage.cs 在实现上覆盖了 SearchText 的 setter:当宿主写入新的搜索词时,会调用抽象方法 UpdateSearchText(string oldSearch, string newSearch),这正是扩展实现自定义过滤/检索的挂钩点。
与之相对,普通 ListPage 的内置模糊过滤(fuzzy search)由宿主侧完成,其底层实现可在 FuzzyMatcherProvider.cs 等文本匹配组件中看到——这也是为何实战中“搜索 SSH 主机”无需写一行过滤代码即可工作。
附加组件:ListItem、Tags 与 FilterBox
ListItem
ListItem 是显示在 ListPage 上的条目对象,可以被点击以执行命令。根视图中的每个顶层命令本质上也是一个 ListItem。
ListItem 的核心可展示属性包括:
Title:主标题,例如 “Search SSH Keys”;Subtitle:副标题,通常用来补充说明,例如 “Quickly find and launch into hosts from your SSH config file”;Tags:标签数组(见下文);Icon:图标;Command(/关联命令):当该条目被点击或处于选中态按下Enter时所执行的默认命令;MoreCommands:附加的上下文命令列表。
需要说明的是,Command Palette 的 SDK 正在演进中:较早设计中顶层命令以“命令即 ListItem”表达,而当前仓库模板(TemplateCmdPalExtensionCommandsProvider.cs)使用 CommandItem 包装一个命令或页面作为顶层条目,同时 Toolkit 也提供了独立的 ListItem.cs 与 CommandItem.cs。在开发中以“根视图入口用 CommandProvider 的 TopLevelCommands() 返回,页面条目用列表项承载命令”为理解主线即可。文档中的 SSH 示例同时展示了两种表达。
Tags
Tag(标签)用于在条目上渲染一个短文本徽标,帮助用户快速识别条目的类别或状态。Toolkit 中的 Tag.cs 即对应实现;构造时主要设置 Text。例如:
Tags = [new Tag() { Text = "Example Tag" }]
宿主 UI 的标签控件渲染位于 Microsoft.CmdPal.UI/Controls/Tag.xaml。
FilterBox
FilterBox 是命令面板顶部的搜索输入框。它的作用是把用户输入的关键字实时应用于当前页面:
- 在 Root View 中,它过滤顶层命令列表;
- 在普通 ListPage 中,它触发宿主的模糊过滤,并把关键字写入页面的
SearchText; - 在 DynamicListPage 中,它把关键字传给扩展的
UpdateSearchText。
其 UI 实现在 SearchBar.xaml,占位文案的绑定与转换可参考 PlaceholderTextConverter(见 Converters 目录)。
扩展解剖:ICommandProvider 与 ICommand
ICommandProvider:所有扩展进入 Command Palette 的入口
这是扩展进入 Command Palette 的唯一入口点。 扩展实现该接口即可向命令面板提供顶层命令:
public interface ICommandProvider
{
IEnumerable<ICommand> GetCommands();
}
在 Toolkit 中,扩展通常继承抽象基类 CommandProvider.cs,该基类实现了 ICommandProvider 系列接口并额外提供了常用成员:
DisplayName:提供给用户看到的扩展/命令提供者名称;Id:稳定标识符;Icon:在根视图/设置中显示的图标;TopLevelCommands():抽象方法,必须实现,返回将在根视图展示的顶层命令数组;FallbackCommands():返回“兜底命令”(当其它命令无法匹配时展示),默认返回null;GetCommand(string id)/GetCommandItem(string id):按 id 精确取回命令/命令项;Settings:扩展自身的设置对象;Frozen:标记该提供者是否已冻结(不再变更命令集);InitializeWithHost(IExtensionHost host):初始化时由宿主注入IExtensionHost,扩展可用它访问宿主能力(见 ExtensionHost.cs);RaiseItemsChanged():命令集变化时通知宿主刷新。
ICommand:命令面板的“骨干”
ICommand 表示“一个可由命令面板执行的单元工作”,是整条命令链路的骨干。ListItem 与 ContextItem 都通过 ICommand 接口来执行命令:
public interface ICommand
{
string Name { get; }
void Execute();
}
Toolkit 中面向实际开发的两种派生形态值得关注:
- 页面型命令:命令本身就是一个 Page(例如把
SSHHostsListPage直接当作条目的命令),执行它即在该页面中导航; - 可执行型命令:InvokableCommand.cs 中
InvokableCommand.Invoke()返回一个ICommandResult,可用于发起外部进程、执行动作,并通过返回值告诉宿主“执行后是否保持面板打开”。其默认实现为CommandResult.KeepOpen()(保持打开)。
Command 基类(Command.cs)提供了 Name、Icon 等通用属性;而像 NoOpCommand 这样的空操作命令则常被用来先“占位”再逐步替换。
默认命令(Default Command)
每个可交互条目可以关联一个默认命令:用户点击该条目,或在选中该条目后按下 Enter,宿主就执行这个默认命令。若条目关联的是页面型命令,则表现为在命令面板内打开新页面;若关联的是 InvokableCommand,则表现为执行一个具体动作。根视图入口、列表页条目均遵循这一统一交互模型。
实战:一步步构建 SSH Keychain 扩展
需求概述
我们要构建一个名为 “SSH Keychain” 的扩展,需要满足:
- 在命令面板提供一条顶层命令 “Search SSH Keys”;
- 执行该命令后,命令面板内出现一个新页面,列出本机 SSH 配置文件中的所有 SSH 主机;
- 用户点击某个 SSH 主机、或选中后按下
Enter(执行其默认命令),即可用 Windows Terminal 打开一个到该主机的 SSH 会话。
脚手架:用模板生成扩展工程
仓库把可复用的扩展脚手架放在 ExtensionTemplate/TemplateCmdPalExtension(内含模板工程、CommandsProvider、Pages 目录、打包用的 pubxml 等)。文档描述的初始步骤为:
- 进入
src\modules\cmdpal目录; - 运行
ext目录下的NewExtension.ps1PowerShell 脚手架脚本。其中-name参数对应扩展(类)名,-DisplayName参数对应将在根视图显示的顶层命令名:
.\ext\NewExtension.ps1 -name MastodonExtension -DisplayName "Mastodon extension for cmdpal"
- 在 Visual Studio 中打开解决方案;
- 右键点击 “SampleExtensions” 目录,选择 “添加” → “现有项目”;
- 进入
Exts文件夹,找到脚本生成的*.csproj(它位于与 PowerShell 脚本提供的扩展名同名的目录下); - 右键点击刚加入的新项目并选择 “部署”(Deploy);
- 点击 Visual Studio 的“播放/启动”按钮进行构建。
如果一切顺利,新命令就会出现在 Root View 中(此时通常还没有图标)。之后修改代码必须重新构建并再次 Deploy 才能看到效果。
模板生成出的工程结构与当前仓库模板 TemplateCmdPalExtension.csproj 保持一致:程序入口 Program.cs 负责初始化扩展宿主,*CommandsProvider.cs 负责声明顶层命令,Pages/、Data/、Commands/、Helpers/ 分别存放页面、数据模型、命令与辅助类。文档约定:所有页面放进 Pages 文件夹,数据类放进 Data 文件夹,命令放进 Commands 文件夹。
Step 1:提供一个顶层命令
要让用户在命令面板中使用你的扩展,至少需要一个顶层命令。做法是在模板生成的 *CommandsProvider.cs 中继承 ICommandProvider 并实现 TopLevelCommands()(Toolkit 中继承 CommandProvider 重写该方法):
public class SSHKeychainCommandsProvider : CommandProvider
{
public SSHKeychainCommandsProvider()
{
DisplayName = "SSH Keychain Commands";
}
private readonly ICommandItem[] _commands = [
new CommandItem(new NoOpCommand())
{
Title = "Search SSH Keys",
Subtitle = "Quickly find and launch into hosts from your SSH config file",
},
];
public override ICommandItem[] TopLevelCommands()
{
return _commands;
}
}
这里用 NoOpCommand() 占位——它“什么都不做”,只是为了先让命令出现在面板里。按模板约定,把该实现放进独立文件 SSHKeychainCommandProvider.cs。重新构建并部署后,按 Win+Ctrl+. 打开命令面板搜索 “Search SSH Keys”,即可在 Root View 中看到这条命令。可以尝试修改 Title/Subtitle 来观察它对展示效果的影响。
Step 2:实现命令执行(页面导航)
当前命令没有动作,是因为条目绑定的是 NoOpCommand:
private readonly IListItem[] _commands = [
new ListItem(new NoOpCommand())
{
Title = "Search SSH Keys",
Subtitle = "Quickly find and launch into hosts from your SSH config file",
},
];
我们现在要实现执行逻辑:当用户点击/回车触发 “Search SSH Keys” 时,在命令面板内打开一个列出 SSH 主机的新 ListPage。
在 Pages 文件夹新建 SSHHostsListPage:
internal sealed class SSHHostsListPage : ListPage
{
public SSHHostsListPage()
{
Icon = new(string.Empty);
Name = "SSH Keychain";
}
public override ISection[] GetItems()
{
return [
new ListSection()
{
Title = "SSH Hosts",
Items = [
new ListItem(new NoOpCommand()) { Title = "TODO: Implement your extension here" }
],
}
];
}
}
列表页要求从 GetItems() 返回 ISection 数组。作为对照,可以查看仓库中 SamplePagesExtension(ext/SamplePagesExtension)以及文档提到的 HackerNews 页示例——它们示范了一个带分节标题、页面图标与页面名的列表页。
要让根视图的 “Search SSH Keys” 命令默认打开这个新页面,只需把该 ListItem 的默认命令从 NoOpCommand 换成 SSHHostsListPage:
// 更新前:条目没有真正可执行的默认命令
private readonly IListItem[] _commands = [
new ListItem(new NoOpCommand())
{
Title = "Search SSH Keys",
Subtitle = "Quickly find and launch into hosts from your SSH config file",
},
];
// 更新后:默认命令指向我们新创建的页面
private readonly IListItem[] _commands = [
new ListItem(new SSHHostsListPage())
{
Title = "Search SSH Keys",
Subtitle = "Quickly find and launch into hosts from your SSH config file",
},
];
重新构建后,根视图仍显示 “Search SSH Keys”,但触发其默认命令时,命令面板中会出现带有 “TODO: Implement your extension here” 消息的新列表页——第一步需求达成:
- 命令执行后打开新页面 ✅
- 剩余工作:解析 SSH 配置文件以真正列出主机。
接下来先用几条示例条目丰富 SSHHostsListPage,观察 Subtitle 与 Tag 的展示效果:
internal sealed class SSHHostsListPage : ListPage
{
public SSHHostsListPage()
{
Icon = new(string.Empty);
Name = "SSH Keychain";
}
public override ISection[] GetItems()
{
return [
new ListSection()
{
Title = "SSH Hosts",
Items = [
new ListItem(new NoOpCommand()) { Title = "TODO: Implement your extension here" },
new ListItem(new NoOpCommand()) { Title = "Another list item", Subtitle = "this one has a subtitle" },
new ListItem(new NoOpCommand())
{
Title = "A list item with a tag",
Subtitle = "this one with tags",
Tags = [new Tag()
{
Text = "Example Tag",
}
],
}
],
}
];
}
}
到这里我们已经具备:顶层命令 ✅、命令执行后打开新 ListPage ✅、在新页面内展示一组条目 ✅。
解析真实 SSH 主机
先补充“真实数据”。在 Data 文件夹新建 SSHKeychainItem.cs,表示单个 SSH 主机所需展示的信息:
internal class SSHKeychainItem
{
internal string HostName { get; init; }
internal string EscapedHost => JsonEncodedText.Encode(HostName).ToString();
}
说明:关联文档的草稿中该数据类使用了
Host属性名,而后续解析与渲染代码统一使用HostName,为保证代码可编译这里按后文用法统一为HostName。
随后改写 SSHHostsListPage,让它解析 %USERPROFILE%\.ssh\config 并渲染真实主机:
internal sealed partial class SSHHostsListPage : ListPage
{
private static readonly string _defaultConfigFile = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "\\.ssh\\config";
private static readonly Regex _hostRegex = new(@"^Host\s+(?:(\S*) ?)*?\s*$", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Multiline);
public SSHHostsListPage()
{
Icon = new(string.Empty);
Name = "SSH Keychain";
}
private static async Task<List<SSHKeychainItem>> GetSSHHosts()
{
var hosts = new List<SSHKeychainItem>();
var configFile = _defaultConfigFile;
if (!File.Exists(configFile))
{
return hosts;
}
var options = new FileStreamOptions()
{
Access = FileAccess.Read,
};
using var reader = new StreamReader(configFile, options);
var fileContent = await reader.ReadToEndAsync();
if (!string.IsNullOrEmpty(fileContent))
{
var matches = _hostRegex.Matches(fileContent);
hosts = matches.Select(match => new SSHKeychainItem { HostName = match.Groups[1].Value }).ToList();
}
return hosts;
}
public override ISection[] GetItems()
{
var t = DoGetItems();
t.ConfigureAwait(false);
return t.Result;
}
private async Task<ISection[]> DoGetItems()
{
List<SSHKeychainItem> items = await GetSSHHosts();
var s = new ListSection()
{
Title = "SSH Hosts",
Items = items.Select((host) => new ListItem(new NoOpCommand())
{
Title = host.HostName,
Subtitle = host.EscapedHost,
}).ToArray(),
};
return [s];
}
}
逐段解读这段实现:
GetSSHHosts()负责读取 SSH 配置文件并用正则^Host\s+(?:(\S*) ?)*?\s*$解析出各Host条目后的主机名,返回List<SSHKeychainItem>。注意这是一个 async 操作(文件 IO);GetItems()改为调用DoGetItems()——一个异步获取主机并组装ListSection的方法。如果你打算在GetItems()中做任何异步操作,请遵循这个“同步外壳调用异步实现”的模式;- 在
DoGetItems()中拿到主机列表后,为每个主机创建带Title/Subtitle的ListItem(此处Subtitle展示了经 JSON 转义的主机名,避免特殊字符破坏列表渲染)。
重新构建并查看效果。前提:本机必须存在 %USERPROFILE%\.ssh\config 文件,否则列表为空。成功之后,主机列表会出现在 “SSH Hosts” 分节中。
搜索某个具体主机时你会发现:过滤是 Command Palette 的内置能力。用户只需在 FilterBox 中输入,宿主就会基于模糊匹配自动过滤当前页面条目——无需任何额外代码。只有当你想自己接管过滤逻辑时,才需要改用 DynamicListPage。
Step 3:为 SSH 主机实现启动命令
列表已经就绪,最后要让点击某个主机(或选中后按 Enter)真正“连接到该主机”。思路:给每个主机的 ListItem 绑定一个能够启动 Windows Terminal + SSH 会话的命令对象。
按照模板约定,在 Commands 文件夹新建 LaunchSSHHostCommand,继承 InvokableCommand:
internal sealed partial class LaunchSSHHostCommand : InvokableCommand
{
private readonly SSHKeychainItem _host;
internal LaunchSSHHostCommand(SSHKeychainItem host)
{
this._host = host;
this.Name = "Connect";
this.Icon = new("\uE8A7");
}
public override CommandResult Invoke()
{
try
{
Process.Start("cmd.exe", $"/k ssh {_host.HostName}");
}
catch
{
Process.Start(new ProcessStartInfo("cmd.exe", $"/k ssh {_host.HostName}") { UseShellExecute = true });
}
return CommandResult.KeepOpen();
}
}
其工作方式是:用 cmd.exe /k ssh <host> 新开一个持久的命令行会话(即 Windows Terminal 会话窗口),并把 Invoke() 的返回值设为 CommandResult.KeepOpen()(保持命令面板打开)。Name 与 Icon(Segoe MDL2 字体的连接图标字形 \uE8A7)决定了该命令在界面上的呈现。
最后,把 SSHHostsListPage.DoGetItems() 中每个 ListItem 的命令从 NoOpCommand 换成 LaunchSSHHostCommand:
private async Task<ISection[]> DoGetItems()
{
List<SSHKeychainItem> items = await GetSSHHosts();
var s = new ListSection()
{
Title = "SSH Hosts",
Items = items.Select((host) => new ListItem(new LaunchSSHHostCommand(host))
{
Title = host.HostName,
Subtitle = host.EscapedHost,
}).ToArray(),
};
return [s];
}
整条链路只改了一处:把条目默认命令从 NoOpCommand 换成 LaunchSSHHostCommand。至此,用户点击主机或选中后按 Enter,Windows Terminal 就会以 SSH 会话连接到该主机,SSH Keychain 扩展的三个需求全部达成。
代码仓库导航:从文档走向源码
理解本文的所有概念后,可以沿着下面这些路径在仓库中继续深入:
- 扩展 SDK / Toolkit 基类:
IListPage、ICommandProvider、ICommand的契约声明位于 Microsoft.CommandPalette.Extensions.Toolkit,其中ListPage、DynamicListPage、CommandProvider、InvokableCommand、CommandItem、ListItem、Tag、Section、CommandResult等文件是绝大多数扩展的直接父类; - 扩展模板:TemplateCmdPalExtension 是脚手架的权威样例,其
TemplateCmdPalExtensionCommandsProvider.cs展示了TopLevelCommands()、DisplayName、MoreCommands、Settings的标准用法; - 内置扩展范本:ext 目录下几十个内置扩展(Apps、Shell、WebSearch、WindowWalker、RemoteDesktop 等)以及 SamplePagesExtension 提供了各类页面形态的真实实现,可作为 HackerNews 页、动态列表页等场景的对照参考;
- 宿主 UI 与模糊过滤:Microsoft.CmdPal.UI(渲染与交互)、Microsoft.CmdPal.UI.ViewModels(列表/页面 ViewModel)、FuzzyMatcherProvider.cs(内置模糊匹配);
- 单元测试:Tests 下按扩展划分的
UnitTests工程(如Microsoft.CmdPal.Ext.Shell.UnitTests、Microsoft.CmdPal.UI.ViewModels.UnitTests)验证了命令解析、列表组装等核心行为。
据此即可开始把 “Mastodon 扩展”“SSH Keychain 扩展”替换成你自己的创意,让它们在 PowerToys Command Palette 的 Root View 中占有一席之地。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0629
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00