Nexttag.Chat
1.1.0
dotnet add package Nexttag.Chat --version 1.1.0
NuGet\Install-Package Nexttag.Chat -Version 1.1.0
<PackageReference Include="Nexttag.Chat" Version="1.1.0" />
<PackageVersion Include="Nexttag.Chat" Version="1.1.0" />
<PackageReference Include="Nexttag.Chat" />
paket add Nexttag.Chat --version 1.1.0
#r "nuget: Nexttag.Chat, 1.1.0"
#:package Nexttag.Chat@1.1.0
#addin nuget:?package=Nexttag.Chat&version=1.1.0
#tool nuget:?package=Nexttag.Chat&version=1.1.0
Nexttag.Chat
Orquestração de bot-chat multi-canal channel-agnostic: abstrai o canal de mensageria e roda o agente LLM com tool-calling.
Instalar
dotnet add package Nexttag.Chat
Requer .NET 10. Depende de: Nexttag.Ai.Agents.
Registrar (Program.cs)
Não há método de extensão de DI. Registre manualmente:
using Nexttag.Chat;
// IChatClientFactory: cria IChatClient para cada modelo (gateway OpenAI-compatível)
services.AddSingleton<IChatClientFactory>(_ =>
new OpenAiGatewayChatClientFactory(new LlmGatewayOptions
{
Endpoint = "http://litellm:4000/v1", // gateway LiteLLM/OpenAI/Ollama
ApiKey = "sk-...", // virtual key do projeto (opcional)
MaxToolIterations = 12, // teto de rodadas de tool-calling
}));
services.AddSingleton<BotChatRunner>();
// Canal de mensageria — ex.: Telegram (pacote Nexttag.Chat.Telegram)
services.AddHttpClient<TelegramChatChannel>();
Configurar
Sem seção de appsettings obrigatória. Os valores de LlmGatewayOptions vêm do código ou de variáveis de ambiente que o host lê.
| Propriedade | Descrição |
|---|---|
Endpoint |
URL base OpenAI-compatível (ex.: http://litellm:4000/v1) |
ApiKey |
Chave da gateway; null = sem autenticação (Ollama local) |
MaxToolIterations |
Teto de rodadas do loop de tool-calling (padrão 12) |
Usar
Resposta com streaming (token a token)
using Microsoft.Extensions.AI;
using Nexttag.Ai.Agents;
using Nexttag.Chat;
var spec = new BotSpec(
SystemPrompt: "Você é o suporte da ACME. Use sempre tom formal.",
ModelCode: "gpt-4o",
MaxOutputTokens: 2048,
Locale: "pt-BR");
var context = new AgentRunContext();
IReadOnlyList<AITool> tools = [ /* kb_search, web_search... montadas pelo host */ ];
await foreach (var evt in runner.StreamAsync(spec, "Como troco minha senha?", tools, context))
{
switch (evt)
{
case AgentTextEvent t: Console.Write(t.Delta); break;
case AgentStepEvent s: /* tool invocada — logar/mostrar na UI */ break;
case AgentDoneEvent d: /* d.FinalText = resposta completa */ break;
}
}
Resposta sem streaming
AgentRunResult result = await runner.RunAsync(spec, "Como troco minha senha?", tools, context);
string resposta = result.FinalText;
Com histórico de conversa
// history: turnos anteriores sem o [system] e sem a mensagem atual
IReadOnlyList<ChatMessage> history = [
new(ChatRole.User, "Olá"),
new(ChatRole.Assistant, "Olá! Como posso ajudar?"),
];
await foreach (var evt in runner.StreamAsync(spec, "Preciso resetar minha senha", tools, context, history: history))
...
Canal (IChatChannel)
IChatChannel canal = new TelegramChatChannel(httpClient);
// Webhook: valida o secret e normaliza para IncomingMessage
IncomingMessage? msg = canal.ParseUpdate(requestBody, headers, webhookSecret);
if (msg is null) return; // edição, status ou sem texto
// Envia de volta pelo mesmo canal
await canal.SendAsync(botToken, new OutgoingMessage(msg.ChatId, resposta));
Receitas
Bot mínimo com Telegram
// Program.cs
services.AddHttpClient<TelegramChatChannel>();
services.AddSingleton<IChatClientFactory>(_ =>
new OpenAiGatewayChatClientFactory(new LlmGatewayOptions { Endpoint = "http://litellm:4000/v1", ApiKey = "sk-..." }));
services.AddSingleton<BotChatRunner>();
// Endpoint POST /webhook/telegram
app.MapPost("/webhook/telegram", async (HttpContext ctx, TelegramChatChannel canal, BotChatRunner runner) =>
{
var body = await new StreamReader(ctx.Request.Body).ReadToEndAsync();
var headers = ctx.Request.Headers.ToDictionary(h => h.Key, h => h.Value.ToString());
var msg = canal.ParseUpdate(body, headers, webhookSecret);
if (msg is null) return Results.Ok();
var spec = new BotSpec("Você é um assistente.", "gpt-4o");
var sb = new StringBuilder();
await foreach (var evt in runner.StreamAsync(spec, msg.Text, [], new AgentRunContext()))
if (evt is AgentDoneEvent d) sb.Append(d.FinalText);
await canal.SendAsync(botToken, new OutgoingMessage(msg.ChatId, sb.ToString()));
return Results.Ok();
});
Registrar webhook do Telegram
await canal.SetupWebhookAsync(botToken, "https://api.seu.com/webhook/telegram", webhookSecret);
Adicionar uma tool ao bot
// Tool definida no host — a lib não conhece RAG/banco
AITool kbSearch = AIFunctionFactory.Create(
async (string query) => await ragService.SearchAsync(query),
name: "kb_search", description: "Busca na base de conhecimento");
IReadOnlyList<AITool> tools = [kbSearch];
await foreach (var evt in runner.StreamAsync(spec, pergunta, tools, context)) ...
Notas
BotChatRunnernão persiste conversa nem histórico — isso é responsabilidade do host.ParseUpdatelançaUnauthorizedAccessExceptionse owebhookSecretnão conferir (comparação em tempo constante).BotSpec.ModelCodedeve ser um modelo roteado pela gateway configurada emLlmGatewayOptions.- Esta lib não faz RAG/embeddings — use
Nexttag.Rag+Nexttag.VectorStorepara isso e passe como tools. TelegramChatChannelestá no pacote separadoNexttag.Chat.Telegram.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Nexttag.Ai.Agents (>= 1.6.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Nexttag.Chat:
| Package | Downloads |
|---|---|
|
Nexttag.Chat.Telegram
Adaptador Telegram para Nexttag.Chat (IChatChannel): parseia o update do webhook (validando o secret token), envia mensagens e registra o webhook via Bot API. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.1.0 | 164 | 6/17/2026 |
1.1.0: BotChatRunner aceita historico de conversa (parametro history: IReadOnlyList<ChatMessage>) — monta [system] + historico + [mensagem atual]. Requer Nexttag.Ai.Agents 1.3.0.