پروژه CodePilot یک ربات گفتگو (Chatbot) مبتنی بر ASP.NET Core 6.0 است که با استفاده از مدل زبان Gemma 3.0 27B از طریق API هوش مصنوعی HuggingFace عمل میکند. این اپلیکیشن برای پاسخ به سوالات برنامهنویسی و تجزیه و تحلیل کد طراحی شده است و پاسخها را به صورت استریم (Stream) به کاربر ارسال میکند.
CodePilot/
├── Areas/
│ └── Identity/
│ ├── Data/
│ │ ├── ApplicationUser.cs
│ │ └── CodePilotContext.cs
│ └── Pages/
│ ├── _ValidationScriptsPartial.cshtml
│ └── _ViewStart.cshtml
├── Controllers/
│ ├── AccountController.cs
│ └── ChatController.cs
├── Models/
│ ├── Chat.cs
│ └── Message.cs
├── ViewModels/
│ └── AuthViewModel.cs
├── Views/
│ ├── Account/
│ │ └── RegLog.cshtml
│ ├── Chat/
│ │ ├── Chat.cshtml
│ │ ├── ChatHistory.cshtml
│ │ └── ChatMessages.cshtml
│ ├── Shared/
│ │ └── _Layout.cshtml
│ ├── _ViewImports.cshtml
│ └── _ViewStart.cshtml
├── appsettings.Development.json
├── appsettings.json
├── CodePilot.csproj
└── Program.cs
این پوشه مربوط به احراز هویت (Authentication) و مجوزها (Authorization) با استفاده از ASP.NET Identity است.
3.1 ApplicationUser.cs:
public class ApplicationUser : IdentityUser
{
// فیلد های پیش فرض برای ساخت جدول کاربران نظیر نام و نام خانوادگی...
}
کلاس ApplicationUser از IdentityUser ارثبری میکند و برای ذخیره اطلاعات کاربر در پایگاه داده استفاده میشود.
3.2 CodePilotContext.cs:
public class CodePilotContext : IdentityDbContext<ApplicationUser>
{
public DbSet<Chat> Chats { get; set; }
public DbSet<Message> Messages { get; set; }
public CodePilotContext(DbContextOptions<CodePilotContext> options)
: base(options)
{
}
}
این کلاس کانتکست EF Core است که نمایانگر اتصال به پایگاه داده و نگاشت مدلها (Chat و Message) به جداول است.
مدلها نمایانگر ساختار دادهای هستند که در پایگاه داده ذخیره میشوند.
4.1 Chat.cs:
public class Chat
{
public int Id { get; set; }
public string Title { get; set; }
public string UserId { get; set; }
[ForeignKey("UserId")]
public ApplicationUser User { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime LastModified { get; set; }
public ICollection<Message> Messages { get; set; }
}
4.2 Message.cs:
public class Message
{
public int Id { get; set; }
public int ChatId { get; set; }
[ForeignKey("ChatId")]
public Chat Chat { get; set; }
public bool IsUserMessage { get; set; }
public string Content { get; set; }
public DateTime Timestamp { get; set; } = DateTime.UtcNow;
}
AuthViewModel.cs:
public class AuthViewModel
{
[Required]
public string regUsername { get; set; }
[Required]
[EmailAddress]
public string regEmail { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
[DataType(DataType.Password)]
[Compare("Password")]
public string ConfirmPassword { get; set; }
// برای بخش ورود
[Required]
public string logUsername { get; set; }
}
این کلاس برای تبادل داده بین فرمهای ثبتنام و ورود و کنترلر Account استفاده میشود.
6.1 AccountController.cs این کنترلر مسئول ثبتنام، ورود، خروج و بررسی یکتا بودن نام کاربری و ایمیل است:
public class AccountController : Controller
{
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly UserManager<ApplicationUser> _userManager;
public AccountController(
SignInManager<ApplicationUser> signInManager,
UserManager<ApplicationUser> userManager)
{
_signInManager = signInManager;
_userManager = userManager;
}
public IActionResult RegLog(string message)
{
ViewData["alert"] = message;
return View();
}
public IActionResult CheckUsername(string regUsername)
{
var exists = _userManager.Users.Any(x => x.UserName == regUsername);
return Json(!exists);
}
public IActionResult CheckEmail(string regEmail)
{
var exists = _userManager.Users.Any(x => x.Email == regEmail);
return Json(!exists);
}
[HttpPost]
public async Task<IActionResult> Register(AuthViewModel model)
{
var user = new ApplicationUser { UserName = model.regUsername, Email = model.regEmail };
var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
var sent = await SendConfirmationEmail(user);
var msg = sent ?
"Registration successful! Confirm your Email to login." :
"Error sending confirmation email. Please try again.";
return RedirectToAction("RegLog", new { message = msg });
}
return RedirectToAction("RegLog", new { message = "Registration failed. Please try again." });
}
[HttpPost]
public async Task<IActionResult> Login(AuthViewModel model)
{
var user = await _userManager.FindByNameAsync(model.logUsername);
if (user == null) return RedirectToAction("RegLog", new { message = "Invalid credentials." });
if (!user.EmailConfirmed)
{
await SendConfirmationEmail(user);
return RedirectToAction("RegLog", new { message = "Email not confirmed. Please check your inbox." });
}
var result = await _signInManager.PasswordSignInAsync(model.logUsername, model.Password, true, true);
if (result.Succeeded) return RedirectToAction("Chat", "Chat");
return RedirectToAction("RegLog", new { message = "Invalid credentials." });
}
public async Task<IActionResult> Logout()
{
await _signInManager.SignOutAsync();
return RedirectToAction("RegLog", new { message = "You have been logged out." });
}
// متد فرضی ارسال ایمیل تأیید
private Task<bool> SendConfirmationEmail(ApplicationUser user)
{
// پیادهسازی ارسال ایمیل
return Task.FromResult(true);
}
}
6.2 ChatController.cs این کنترلر مسئول نمایش صفحه چت، بارگذاری تاریخچه، ارسال درخواست به API، دریافت و استریم پاسخ، ذخیره گفتگو و حذف آن است:
[Authorize]
public class ChatController : Controller
{
private readonly CodePilotContext _dbContext;
private readonly UserManager<ApplicationUser> _userManager;
public ChatController(CodePilotContext dbContext,
UserManager<ApplicationUser> userManager)
{
_dbContext = dbContext;
_userManager = userManager;
}
public IActionResult Chat()
{
return View();
}
public async Task<IActionResult> ChatHistory()
{
var userId = (await _userManager.FindByNameAsync(User.Identity.Name)).Id;
var chats = await _dbContext.Chats
.Where(c => c.UserId == userId)
.OrderByDescending(c => c.LastModified)
.ToListAsync();
return View(chats);
}
public async Task<IActionResult> ChatMessages(int chatId)
{
var messages = await _dbContext.Messages
.Where(m => m.ChatId == chatId)
.ToListAsync();
return View(messages);
}
[HttpPost]
public async Task<IActionResult> GetChatResponse([FromBody] ChatRequest request)
{
Response.ContentType = "text/event-stream";
// بارگذاری تاریخچه گفتگو
var chatHistory = await _dbContext.Messages
.Where(m => m.ChatId == request.ChatId)
.OrderBy(m => m.Timestamp)
.ToListAsync();
var messages = chatHistory.Select(m => new { role = m.IsUserMessage ? "user" : "assistant", content = m.Content }).ToList();
messages.Add(new { role = "user", content = request.Message });
// ساخت payload برای HuggingFace
var payload = new {
model = "google/gemma-3-27b-it-fast",
messages,
max_tokens = 1024,
temperature = 0.5,
stream = true
};
// ارسال درخواست
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", "<TOKEN_HERE>");
var httpContent = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json");
var response = await client.SendAsync(
new HttpRequestMessage(HttpMethod.Post, "https://router.huggingface.co/nebius/v1/chat/completions") { Content = httpContent },
HttpCompletionOption.ResponseHeadersRead);
response.EnsureSuccessStatusCode();
// خواندن و استریم پاسخ
using var reader = new StreamReader(await response.Content.ReadAsStreamAsync());
string? line; var botResponse = new StringBuilder();
while ((line = await reader.ReadLineAsync()) != null) {
if (!line.StartsWith("data: ")) continue;
var json = JsonDocument.Parse(line.Substring(6));
var delta = json.RootElement.GetProperty("choices")[0].GetProperty("delta");
if (delta.TryGetProperty("content", out var contentEl)) {
var content = contentEl.GetString();
await Response.WriteAsync(content);
await Response.Body.FlushAsync();
botResponse.Append(content);
}
}
// ذخیره پیامها در پایگاه داده
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
Chat chat;
if (request.ChatId.HasValue)
{
chat = await _dbContext.Chats.FindAsync(request.ChatId.Value);
chat.LastModified = DateTime.UtcNow;
}
else
{
chat = new Chat {
UserId = userId,
Title = TrimText(request.Message, 20),
CreatedAt = DateTime.UtcNow,
LastModified = DateTime.UtcNow
};
_dbContext.Chats.Add(chat);
await _dbContext.SaveChangesAsync();
}
_dbContext.Messages.AddRange(
new Message { ChatId = chat.Id, IsUserMessage = true, Content = request.Message, Timestamp = DateTime.UtcNow },
new Message { ChatId = chat.Id, IsUserMessage = false, Content = botResponse.ToString(), Timestamp = DateTime.UtcNow }
);
await _dbContext.SaveChangesAsync();
return new EmptyResult();
}
[HttpPost]
public async Task<IActionResult> DeleteChat([FromBody] int chatId)
{
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
var chat = await _dbContext.Chats.FirstOrDefaultAsync(c => c.Id == chatId && c.UserId == userId);
if (chat == null) return NotFound();
_dbContext.Chats.Remove(chat);
await _dbContext.SaveChangesAsync();
return Ok();
}
private static string TrimText(string text, int maxLength) { /* ... */ }
public class ChatRequest
{
public string Message { get; set; }
public int? ChatId { get; set; }
}
}
در متد GetChatResponse:
7.1 RegLog.cshtml (ثبتنام/ورود):
7.2 Chat.cshtml (صفحه اصلی چت):
7.3 ChatHistory.cshtml:
7.4 ChatMessages.cshtml:
7.5 Shared/_Layout.cshtml:
این مستند به بررسی کاملی از اجزای پروژه CodePilot پرداخت. با مطالعه این مستند، توسعهدهنده میتواند درک کاملی از ساختار و جریان کار اپلیکیشن بهدست آورد و در صورت نیاز، قابلیتها را گسترش دهد.
C#
53.1%
CSS
31.1%
HTML
14.3%
JavaScript
1.4%
پروژه CodePilot یک ربات گفتگو (Chatbot) مبتنی بر ASP.NET Core 6.0 است که با استفاده از مدل زبان Gemma 3.0 27B از طریق API هوش مصنوعی HuggingFace عمل میکند. این اپلیکیشن برای پاسخ به سوالات برنامهنویسی و تجزیه و تحلیل کد طراحی شده است و پاسخها را به صورت استریم (Stream) به کاربر ارسال میکند.
CodePilot/
├── Areas/
│ └── Identity/
│ ├── Data/
│ │ ├── ApplicationUser.cs
│ │ └── CodePilotContext.cs
│ └── Pages/
│ ├── _ValidationScriptsPartial.cshtml
│ └── _ViewStart.cshtml
├── Controllers/
│ ├── AccountController.cs
│ └── ChatController.cs
├── Models/
│ ├── Chat.cs
│ └── Message.cs
├── ViewModels/
│ └── AuthViewModel.cs
├── Views/
│ ├── Account/
│ │ └── RegLog.cshtml
│ ├── Chat/
│ │ ├── Chat.cshtml
│ │ ├── ChatHistory.cshtml
│ │ └── ChatMessages.cshtml
│ ├── Shared/
│ │ └── _Layout.cshtml
│ ├── _ViewImports.cshtml
│ └── _ViewStart.cshtml
├── appsettings.Development.json
├── appsettings.json
├── CodePilot.csproj
└── Program.cs
این پوشه مربوط به احراز هویت (Authentication) و مجوزها (Authorization) با استفاده از ASP.NET Identity است.
3.1 ApplicationUser.cs:
public class ApplicationUser : IdentityUser
{
// فیلد های پیش فرض برای ساخت جدول کاربران نظیر نام و نام خانوادگی...
}
کلاس ApplicationUser از IdentityUser ارثبری میکند و برای ذخیره اطلاعات کاربر در پایگاه داده استفاده میشود.
3.2 CodePilotContext.cs:
public class CodePilotContext : IdentityDbContext<ApplicationUser>
{
public DbSet<Chat> Chats { get; set; }
public DbSet<Message> Messages { get; set; }
public CodePilotContext(DbContextOptions<CodePilotContext> options)
: base(options)
{
}
}
این کلاس کانتکست EF Core است که نمایانگر اتصال به پایگاه داده و نگاشت مدلها (Chat و Message) به جداول است.
مدلها نمایانگر ساختار دادهای هستند که در پایگاه داده ذخیره میشوند.
4.1 Chat.cs:
public class Chat
{
public int Id { get; set; }
public string Title { get; set; }
public string UserId { get; set; }
[ForeignKey("UserId")]
public ApplicationUser User { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime LastModified { get; set; }
public ICollection<Message> Messages { get; set; }
}
4.2 Message.cs:
public class Message
{
public int Id { get; set; }
public int ChatId { get; set; }
[ForeignKey("ChatId")]
public Chat Chat { get; set; }
public bool IsUserMessage { get; set; }
public string Content { get; set; }
public DateTime Timestamp { get; set; } = DateTime.UtcNow;
}
AuthViewModel.cs:
public class AuthViewModel
{
[Required]
public string regUsername { get; set; }
[Required]
[EmailAddress]
public string regEmail { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
[DataType(DataType.Password)]
[Compare("Password")]
public string ConfirmPassword { get; set; }
// برای بخش ورود
[Required]
public string logUsername { get; set; }
}
این کلاس برای تبادل داده بین فرمهای ثبتنام و ورود و کنترلر Account استفاده میشود.
6.1 AccountController.cs این کنترلر مسئول ثبتنام، ورود، خروج و بررسی یکتا بودن نام کاربری و ایمیل است:
public class AccountController : Controller
{
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly UserManager<ApplicationUser> _userManager;
public AccountController(
SignInManager<ApplicationUser> signInManager,
UserManager<ApplicationUser> userManager)
{
_signInManager = signInManager;
_userManager = userManager;
}
public IActionResult RegLog(string message)
{
ViewData["alert"] = message;
return View();
}
public IActionResult CheckUsername(string regUsername)
{
var exists = _userManager.Users.Any(x => x.UserName == regUsername);
return Json(!exists);
}
public IActionResult CheckEmail(string regEmail)
{
var exists = _userManager.Users.Any(x => x.Email == regEmail);
return Json(!exists);
}
[HttpPost]
public async Task<IActionResult> Register(AuthViewModel model)
{
var user = new ApplicationUser { UserName = model.regUsername, Email = model.regEmail };
var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
var sent = await SendConfirmationEmail(user);
var msg = sent ?
"Registration successful! Confirm your Email to login." :
"Error sending confirmation email. Please try again.";
return RedirectToAction("RegLog", new { message = msg });
}
return RedirectToAction("RegLog", new { message = "Registration failed. Please try again." });
}
[HttpPost]
public async Task<IActionResult> Login(AuthViewModel model)
{
var user = await _userManager.FindByNameAsync(model.logUsername);
if (user == null) return RedirectToAction("RegLog", new { message = "Invalid credentials." });
if (!user.EmailConfirmed)
{
await SendConfirmationEmail(user);
return RedirectToAction("RegLog", new { message = "Email not confirmed. Please check your inbox." });
}
var result = await _signInManager.PasswordSignInAsync(model.logUsername, model.Password, true, true);
if (result.Succeeded) return RedirectToAction("Chat", "Chat");
return RedirectToAction("RegLog", new { message = "Invalid credentials." });
}
public async Task<IActionResult> Logout()
{
await _signInManager.SignOutAsync();
return RedirectToAction("RegLog", new { message = "You have been logged out." });
}
// متد فرضی ارسال ایمیل تأیید
private Task<bool> SendConfirmationEmail(ApplicationUser user)
{
// پیادهسازی ارسال ایمیل
return Task.FromResult(true);
}
}
6.2 ChatController.cs این کنترلر مسئول نمایش صفحه چت، بارگذاری تاریخچه، ارسال درخواست به API، دریافت و استریم پاسخ، ذخیره گفتگو و حذف آن است:
[Authorize]
public class ChatController : Controller
{
private readonly CodePilotContext _dbContext;
private readonly UserManager<ApplicationUser> _userManager;
public ChatController(CodePilotContext dbContext,
UserManager<ApplicationUser> userManager)
{
_dbContext = dbContext;
_userManager = userManager;
}
public IActionResult Chat()
{
return View();
}
public async Task<IActionResult> ChatHistory()
{
var userId = (await _userManager.FindByNameAsync(User.Identity.Name)).Id;
var chats = await _dbContext.Chats
.Where(c => c.UserId == userId)
.OrderByDescending(c => c.LastModified)
.ToListAsync();
return View(chats);
}
public async Task<IActionResult> ChatMessages(int chatId)
{
var messages = await _dbContext.Messages
.Where(m => m.ChatId == chatId)
.ToListAsync();
return View(messages);
}
[HttpPost]
public async Task<IActionResult> GetChatResponse([FromBody] ChatRequest request)
{
Response.ContentType = "text/event-stream";
// بارگذاری تاریخچه گفتگو
var chatHistory = await _dbContext.Messages
.Where(m => m.ChatId == request.ChatId)
.OrderBy(m => m.Timestamp)
.ToListAsync();
var messages = chatHistory.Select(m => new { role = m.IsUserMessage ? "user" : "assistant", content = m.Content }).ToList();
messages.Add(new { role = "user", content = request.Message });
// ساخت payload برای HuggingFace
var payload = new {
model = "google/gemma-3-27b-it-fast",
messages,
max_tokens = 1024,
temperature = 0.5,
stream = true
};
// ارسال درخواست
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", "<TOKEN_HERE>");
var httpContent = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json");
var response = await client.SendAsync(
new HttpRequestMessage(HttpMethod.Post, "https://router.huggingface.co/nebius/v1/chat/completions") { Content = httpContent },
HttpCompletionOption.ResponseHeadersRead);
response.EnsureSuccessStatusCode();
// خواندن و استریم پاسخ
using var reader = new StreamReader(await response.Content.ReadAsStreamAsync());
string? line; var botResponse = new StringBuilder();
while ((line = await reader.ReadLineAsync()) != null) {
if (!line.StartsWith("data: ")) continue;
var json = JsonDocument.Parse(line.Substring(6));
var delta = json.RootElement.GetProperty("choices")[0].GetProperty("delta");
if (delta.TryGetProperty("content", out var contentEl)) {
var content = contentEl.GetString();
await Response.WriteAsync(content);
await Response.Body.FlushAsync();
botResponse.Append(content);
}
}
// ذخیره پیامها در پایگاه داده
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
Chat chat;
if (request.ChatId.HasValue)
{
chat = await _dbContext.Chats.FindAsync(request.ChatId.Value);
chat.LastModified = DateTime.UtcNow;
}
else
{
chat = new Chat {
UserId = userId,
Title = TrimText(request.Message, 20),
CreatedAt = DateTime.UtcNow,
LastModified = DateTime.UtcNow
};
_dbContext.Chats.Add(chat);
await _dbContext.SaveChangesAsync();
}
_dbContext.Messages.AddRange(
new Message { ChatId = chat.Id, IsUserMessage = true, Content = request.Message, Timestamp = DateTime.UtcNow },
new Message { ChatId = chat.Id, IsUserMessage = false, Content = botResponse.ToString(), Timestamp = DateTime.UtcNow }
);
await _dbContext.SaveChangesAsync();
return new EmptyResult();
}
[HttpPost]
public async Task<IActionResult> DeleteChat([FromBody] int chatId)
{
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
var chat = await _dbContext.Chats.FirstOrDefaultAsync(c => c.Id == chatId && c.UserId == userId);
if (chat == null) return NotFound();
_dbContext.Chats.Remove(chat);
await _dbContext.SaveChangesAsync();
return Ok();
}
private static string TrimText(string text, int maxLength) { /* ... */ }
public class ChatRequest
{
public string Message { get; set; }
public int? ChatId { get; set; }
}
}
در متد GetChatResponse:
7.1 RegLog.cshtml (ثبتنام/ورود):
7.2 Chat.cshtml (صفحه اصلی چت):
7.3 ChatHistory.cshtml:
7.4 ChatMessages.cshtml:
7.5 Shared/_Layout.cshtml:
این مستند به بررسی کاملی از اجزای پروژه CodePilot پرداخت. با مطالعه این مستند، توسعهدهنده میتواند درک کاملی از ساختار و جریان کار اپلیکیشن بهدست آورد و در صورت نیاز، قابلیتها را گسترش دهد.
C#
53.1%
CSS
31.1%
HTML
14.3%
JavaScript
1.4%