mehdi-ai-assistant 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,16 @@
1
+ type Role = 'user' | 'assistant' | 'system';
2
+ interface Message {
3
+ role: Role;
4
+ content: string;
5
+ }
6
+ interface AiRobotConfig {
7
+ apiKey: string;
8
+ model?: string;
9
+ temperature?: number;
10
+ systemPrompt?: string;
11
+ }
12
+ interface ChatResponse {
13
+ content: string;
14
+ }
15
+
16
+ export type { AiRobotConfig as A, ChatResponse as C, Message as M, Role as R };
@@ -0,0 +1,16 @@
1
+ type Role = 'user' | 'assistant' | 'system';
2
+ interface Message {
3
+ role: Role;
4
+ content: string;
5
+ }
6
+ interface AiRobotConfig {
7
+ apiKey: string;
8
+ model?: string;
9
+ temperature?: number;
10
+ systemPrompt?: string;
11
+ }
12
+ interface ChatResponse {
13
+ content: string;
14
+ }
15
+
16
+ export type { AiRobotConfig as A, ChatResponse as C, Message as M, Role as R };
@@ -0,0 +1,18 @@
1
+ import { A as AiRobotConfig, M as Message } from './index-BeDFcZll.mjs';
2
+ export { C as ChatResponse, R as Role } from './index-BeDFcZll.mjs';
3
+ import * as _langchain_core_utils_stream from '@langchain/core/utils/stream';
4
+ import * as _langchain_core_messages from '@langchain/core/messages';
5
+
6
+ declare class AiRobot {
7
+ private model;
8
+ private systemPrompt;
9
+ constructor(config: AiRobotConfig);
10
+ /**
11
+ * اصلاح شده: تعیین تایپ خروجی و تایپ متغیر formatted
12
+ */
13
+ private formatMessages;
14
+ chat(messages: Message[]): Promise<string>;
15
+ streamChat(messages: Message[]): Promise<_langchain_core_utils_stream.IterableReadableStream<_langchain_core_messages.AIMessageChunk<_langchain_core_messages.MessageStructure>>>;
16
+ }
17
+
18
+ export { AiRobot, AiRobotConfig, Message };
@@ -0,0 +1,18 @@
1
+ import { A as AiRobotConfig, M as Message } from './index-BeDFcZll.js';
2
+ export { C as ChatResponse, R as Role } from './index-BeDFcZll.js';
3
+ import * as _langchain_core_utils_stream from '@langchain/core/utils/stream';
4
+ import * as _langchain_core_messages from '@langchain/core/messages';
5
+
6
+ declare class AiRobot {
7
+ private model;
8
+ private systemPrompt;
9
+ constructor(config: AiRobotConfig);
10
+ /**
11
+ * اصلاح شده: تعیین تایپ خروجی و تایپ متغیر formatted
12
+ */
13
+ private formatMessages;
14
+ chat(messages: Message[]): Promise<string>;
15
+ streamChat(messages: Message[]): Promise<_langchain_core_utils_stream.IterableReadableStream<_langchain_core_messages.AIMessageChunk<_langchain_core_messages.MessageStructure>>>;
16
+ }
17
+
18
+ export { AiRobot, AiRobotConfig, Message };
package/dist/index.js ADDED
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
21
+
22
+ // src/index.ts
23
+ var index_exports = {};
24
+ __export(index_exports, {
25
+ AiRobot: () => AiRobot
26
+ });
27
+ module.exports = __toCommonJS(index_exports);
28
+
29
+ // src/core/ai-robot.ts
30
+ var import_groq = require("@langchain/groq");
31
+ var import_messages = require("@langchain/core/messages");
32
+ var AiRobot = class {
33
+ constructor(config) {
34
+ __publicField(this, "model");
35
+ __publicField(this, "systemPrompt");
36
+ if (!config.apiKey) {
37
+ throw new Error("AiRobot: API Key is required.");
38
+ }
39
+ this.systemPrompt = config.systemPrompt || "You are a helpful AI assistant.";
40
+ this.model = new import_groq.ChatGroq({
41
+ apiKey: config.apiKey,
42
+ model: config.model || "llama3-8b-8192",
43
+ temperature: config.temperature ?? 0.7
44
+ });
45
+ }
46
+ /**
47
+ * اصلاح شده: تعیین تایپ خروجی و تایپ متغیر formatted
48
+ */
49
+ formatMessages(messages) {
50
+ const formatted = [new import_messages.SystemMessage(this.systemPrompt)];
51
+ messages.forEach((msg) => {
52
+ if (msg.role === "user") {
53
+ formatted.push(new import_messages.HumanMessage(msg.content));
54
+ } else if (msg.role === "assistant") {
55
+ formatted.push(new import_messages.AIMessage(msg.content));
56
+ }
57
+ });
58
+ return formatted;
59
+ }
60
+ async chat(messages) {
61
+ try {
62
+ const formattedHistory = this.formatMessages(messages);
63
+ const response = await this.model.invoke(formattedHistory);
64
+ return response.content;
65
+ } catch (error) {
66
+ console.warn("\u26A0\uFE0F AI Connection Failed. Switching to Mock Mode.");
67
+ return "\u0633\u0644\u0627\u0645! \u0645\u0646 \u062F\u0631 \u062D\u0627\u0644 \u062D\u0627\u0636\u0631 \u0628\u0647 \u0627\u06CC\u0646\u062A\u0631\u0646\u062A \u0648\u0635\u0644 \u0646\u06CC\u0633\u062A\u0645\u060C \u0627\u0645\u0627 \u067E\u06A9\u06CC\u062C \u0634\u0645\u0627 \u0628\u0647 \u062F\u0631\u0633\u062A\u06CC \u06A9\u0627\u0631 \u0645\u06CC\u200C\u06A9\u0646\u062F! \u{1F389}\n\n\u0627\u06CC\u0646 \u06CC\u06A9 \u067E\u06CC\u0627\u0645 \u062A\u0633\u062A\u06CC \u0627\u0633\u062A \u062A\u0627 \u0631\u0627\u0628\u0637 \u06A9\u0627\u0631\u0628\u0631\u06CC \u0631\u0627 \u0628\u0631\u0631\u0633\u06CC \u06A9\u0646\u06CC\u062F.";
68
+ }
69
+ }
70
+ async streamChat(messages) {
71
+ const formattedHistory = this.formatMessages(messages);
72
+ return await this.model.stream(formattedHistory);
73
+ }
74
+ };
75
+ // Annotate the CommonJS export names for ESM import in node:
76
+ 0 && (module.exports = {
77
+ AiRobot
78
+ });
79
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/core/ai-robot.ts"],"sourcesContent":["// src/index.ts (فقط سمت سرور)\r\n\r\nexport * from \"./types\";\r\nexport { AiRobot } from \"./core/ai-robot\";\r\n\r\n// ❌ خطوط مربوط به ChatBot را حتماً پاک کن!","// src/core/ai-robot.ts\r\nimport { ChatGroq } from \"@langchain/groq\";\r\n// 1. اضافه کردن BaseMessage به ایمپورت‌ها 👇\r\nimport { HumanMessage, AIMessage, SystemMessage, BaseMessage } from \"@langchain/core/messages\";\r\nimport { AiRobotConfig, Message } from \"../types\";\r\n\r\nexport class AiRobot {\r\n private model: ChatGroq;\r\n private systemPrompt: string;\r\n\r\n constructor(config: AiRobotConfig) {\r\n if (!config.apiKey) {\r\n throw new Error(\"AiRobot: API Key is required.\");\r\n }\r\n\r\n this.systemPrompt = config.systemPrompt || \"You are a helpful AI assistant.\";\r\n\r\n this.model = new ChatGroq({\r\n apiKey: config.apiKey,\r\n model: config.model || \"llama3-8b-8192\",\r\n temperature: config.temperature ?? 0.7,\r\n });\r\n }\r\n\r\n /**\r\n * اصلاح شده: تعیین تایپ خروجی و تایپ متغیر formatted\r\n */\r\n private formatMessages(messages: Message[]): BaseMessage[] {\r\n // 2. تعیین صریح تایپ آرایه به عنوان BaseMessage[] 👇\r\n const formatted: BaseMessage[] = [new SystemMessage(this.systemPrompt)];\r\n\r\n messages.forEach((msg) => {\r\n if (msg.role === 'user') {\r\n formatted.push(new HumanMessage(msg.content));\r\n } else if (msg.role === 'assistant') {\r\n formatted.push(new AIMessage(msg.content));\r\n }\r\n });\r\n\r\n return formatted;\r\n }\r\n\r\n \r\n async chat(messages: Message[]): Promise<string> {\r\n try {\r\n // تلاش برای اتصال واقعی\r\n const formattedHistory = this.formatMessages(messages);\r\n const response = await this.model.invoke(formattedHistory);\r\n return response.content as string;\r\n } catch (error) {\r\n console.warn(\"⚠️ AI Connection Failed. Switching to Mock Mode.\");\r\n \r\n // 👇 بازگشت پاسخ شبیه‌سازی شده (بدون نیاز به اینترنت)\r\n return \"سلام! من در حال حاضر به اینترنت وصل نیستم، اما پکیج شما به درستی کار می‌کند! 🎉\\n\\nاین یک پیام تستی است تا رابط کاربری را بررسی کنید.\";\r\n }\r\n }\r\n async streamChat(messages: Message[]) {\r\n const formattedHistory = this.formatMessages(messages);\r\n return await this.model.stream(formattedHistory);\r\n }\r\n}"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACCA,kBAAyB;AAEzB,sBAAoE;AAG7D,IAAM,UAAN,MAAc;AAAA,EAInB,YAAY,QAAuB;AAHnC,wBAAQ;AACR,wBAAQ;AAGN,QAAI,CAAC,OAAO,QAAQ;AAClB,YAAM,IAAI,MAAM,+BAA+B;AAAA,IACjD;AAEA,SAAK,eAAe,OAAO,gBAAgB;AAE3C,SAAK,QAAQ,IAAI,qBAAS;AAAA,MACxB,QAAQ,OAAO;AAAA,MACf,OAAO,OAAO,SAAS;AAAA,MACvB,aAAa,OAAO,eAAe;AAAA,IACrC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAe,UAAoC;AAEzD,UAAM,YAA2B,CAAC,IAAI,8BAAc,KAAK,YAAY,CAAC;AAEtE,aAAS,QAAQ,CAAC,QAAQ;AACxB,UAAI,IAAI,SAAS,QAAQ;AACvB,kBAAU,KAAK,IAAI,6BAAa,IAAI,OAAO,CAAC;AAAA,MAC9C,WAAW,IAAI,SAAS,aAAa;AACnC,kBAAU,KAAK,IAAI,0BAAU,IAAI,OAAO,CAAC;AAAA,MAC3C;AAAA,IACF,CAAC;AAED,WAAO;AAAA,EACT;AAAA,EAGA,MAAM,KAAK,UAAsC;AAC/C,QAAI;AAEF,YAAM,mBAAmB,KAAK,eAAe,QAAQ;AACrD,YAAM,WAAW,MAAM,KAAK,MAAM,OAAO,gBAAgB;AACzD,aAAO,SAAS;AAAA,IAClB,SAAS,OAAO;AACd,cAAQ,KAAK,4DAAkD;AAG/D,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EACA,MAAM,WAAW,UAAqB;AACpC,UAAM,mBAAmB,KAAK,eAAe,QAAQ;AACrD,WAAO,MAAM,KAAK,MAAM,OAAO,gBAAgB;AAAA,EACjD;AACF;","names":[]}
package/dist/index.mjs ADDED
@@ -0,0 +1,54 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
+
5
+ // src/core/ai-robot.ts
6
+ import { ChatGroq } from "@langchain/groq";
7
+ import { HumanMessage, AIMessage, SystemMessage } from "@langchain/core/messages";
8
+ var AiRobot = class {
9
+ constructor(config) {
10
+ __publicField(this, "model");
11
+ __publicField(this, "systemPrompt");
12
+ if (!config.apiKey) {
13
+ throw new Error("AiRobot: API Key is required.");
14
+ }
15
+ this.systemPrompt = config.systemPrompt || "You are a helpful AI assistant.";
16
+ this.model = new ChatGroq({
17
+ apiKey: config.apiKey,
18
+ model: config.model || "llama3-8b-8192",
19
+ temperature: config.temperature ?? 0.7
20
+ });
21
+ }
22
+ /**
23
+ * اصلاح شده: تعیین تایپ خروجی و تایپ متغیر formatted
24
+ */
25
+ formatMessages(messages) {
26
+ const formatted = [new SystemMessage(this.systemPrompt)];
27
+ messages.forEach((msg) => {
28
+ if (msg.role === "user") {
29
+ formatted.push(new HumanMessage(msg.content));
30
+ } else if (msg.role === "assistant") {
31
+ formatted.push(new AIMessage(msg.content));
32
+ }
33
+ });
34
+ return formatted;
35
+ }
36
+ async chat(messages) {
37
+ try {
38
+ const formattedHistory = this.formatMessages(messages);
39
+ const response = await this.model.invoke(formattedHistory);
40
+ return response.content;
41
+ } catch (error) {
42
+ console.warn("\u26A0\uFE0F AI Connection Failed. Switching to Mock Mode.");
43
+ return "\u0633\u0644\u0627\u0645! \u0645\u0646 \u062F\u0631 \u062D\u0627\u0644 \u062D\u0627\u0636\u0631 \u0628\u0647 \u0627\u06CC\u0646\u062A\u0631\u0646\u062A \u0648\u0635\u0644 \u0646\u06CC\u0633\u062A\u0645\u060C \u0627\u0645\u0627 \u067E\u06A9\u06CC\u062C \u0634\u0645\u0627 \u0628\u0647 \u062F\u0631\u0633\u062A\u06CC \u06A9\u0627\u0631 \u0645\u06CC\u200C\u06A9\u0646\u062F! \u{1F389}\n\n\u0627\u06CC\u0646 \u06CC\u06A9 \u067E\u06CC\u0627\u0645 \u062A\u0633\u062A\u06CC \u0627\u0633\u062A \u062A\u0627 \u0631\u0627\u0628\u0637 \u06A9\u0627\u0631\u0628\u0631\u06CC \u0631\u0627 \u0628\u0631\u0631\u0633\u06CC \u06A9\u0646\u06CC\u062F.";
44
+ }
45
+ }
46
+ async streamChat(messages) {
47
+ const formattedHistory = this.formatMessages(messages);
48
+ return await this.model.stream(formattedHistory);
49
+ }
50
+ };
51
+ export {
52
+ AiRobot
53
+ };
54
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/ai-robot.ts"],"sourcesContent":["// src/core/ai-robot.ts\r\nimport { ChatGroq } from \"@langchain/groq\";\r\n// 1. اضافه کردن BaseMessage به ایمپورت‌ها 👇\r\nimport { HumanMessage, AIMessage, SystemMessage, BaseMessage } from \"@langchain/core/messages\";\r\nimport { AiRobotConfig, Message } from \"../types\";\r\n\r\nexport class AiRobot {\r\n private model: ChatGroq;\r\n private systemPrompt: string;\r\n\r\n constructor(config: AiRobotConfig) {\r\n if (!config.apiKey) {\r\n throw new Error(\"AiRobot: API Key is required.\");\r\n }\r\n\r\n this.systemPrompt = config.systemPrompt || \"You are a helpful AI assistant.\";\r\n\r\n this.model = new ChatGroq({\r\n apiKey: config.apiKey,\r\n model: config.model || \"llama3-8b-8192\",\r\n temperature: config.temperature ?? 0.7,\r\n });\r\n }\r\n\r\n /**\r\n * اصلاح شده: تعیین تایپ خروجی و تایپ متغیر formatted\r\n */\r\n private formatMessages(messages: Message[]): BaseMessage[] {\r\n // 2. تعیین صریح تایپ آرایه به عنوان BaseMessage[] 👇\r\n const formatted: BaseMessage[] = [new SystemMessage(this.systemPrompt)];\r\n\r\n messages.forEach((msg) => {\r\n if (msg.role === 'user') {\r\n formatted.push(new HumanMessage(msg.content));\r\n } else if (msg.role === 'assistant') {\r\n formatted.push(new AIMessage(msg.content));\r\n }\r\n });\r\n\r\n return formatted;\r\n }\r\n\r\n \r\n async chat(messages: Message[]): Promise<string> {\r\n try {\r\n // تلاش برای اتصال واقعی\r\n const formattedHistory = this.formatMessages(messages);\r\n const response = await this.model.invoke(formattedHistory);\r\n return response.content as string;\r\n } catch (error) {\r\n console.warn(\"⚠️ AI Connection Failed. Switching to Mock Mode.\");\r\n \r\n // 👇 بازگشت پاسخ شبیه‌سازی شده (بدون نیاز به اینترنت)\r\n return \"سلام! من در حال حاضر به اینترنت وصل نیستم، اما پکیج شما به درستی کار می‌کند! 🎉\\n\\nاین یک پیام تستی است تا رابط کاربری را بررسی کنید.\";\r\n }\r\n }\r\n async streamChat(messages: Message[]) {\r\n const formattedHistory = this.formatMessages(messages);\r\n return await this.model.stream(formattedHistory);\r\n }\r\n}"],"mappings":";;;;;AACA,SAAS,gBAAgB;AAEzB,SAAS,cAAc,WAAW,qBAAkC;AAG7D,IAAM,UAAN,MAAc;AAAA,EAInB,YAAY,QAAuB;AAHnC,wBAAQ;AACR,wBAAQ;AAGN,QAAI,CAAC,OAAO,QAAQ;AAClB,YAAM,IAAI,MAAM,+BAA+B;AAAA,IACjD;AAEA,SAAK,eAAe,OAAO,gBAAgB;AAE3C,SAAK,QAAQ,IAAI,SAAS;AAAA,MACxB,QAAQ,OAAO;AAAA,MACf,OAAO,OAAO,SAAS;AAAA,MACvB,aAAa,OAAO,eAAe;AAAA,IACrC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAe,UAAoC;AAEzD,UAAM,YAA2B,CAAC,IAAI,cAAc,KAAK,YAAY,CAAC;AAEtE,aAAS,QAAQ,CAAC,QAAQ;AACxB,UAAI,IAAI,SAAS,QAAQ;AACvB,kBAAU,KAAK,IAAI,aAAa,IAAI,OAAO,CAAC;AAAA,MAC9C,WAAW,IAAI,SAAS,aAAa;AACnC,kBAAU,KAAK,IAAI,UAAU,IAAI,OAAO,CAAC;AAAA,MAC3C;AAAA,IACF,CAAC;AAED,WAAO;AAAA,EACT;AAAA,EAGA,MAAM,KAAK,UAAsC;AAC/C,QAAI;AAEF,YAAM,mBAAmB,KAAK,eAAe,QAAQ;AACrD,YAAM,WAAW,MAAM,KAAK,MAAM,OAAO,gBAAgB;AACzD,aAAO,SAAS;AAAA,IAClB,SAAS,OAAO;AACd,cAAQ,KAAK,4DAAkD;AAG/D,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EACA,MAAM,WAAW,UAAqB;AACpC,UAAM,mBAAmB,KAAK,eAAe,QAAQ;AACrD,WAAO,MAAM,KAAK,MAAM,OAAO,gBAAgB;AAAA,EACjD;AACF;","names":[]}
package/dist/react.css ADDED
@@ -0,0 +1,126 @@
1
+ /* src/styles/chat.module.css */
2
+ .container {
3
+ --ai-primary: #2563eb;
4
+ --ai-primary-fg: #ffffff;
5
+ --ai-bg: #ffffff;
6
+ --ai-border: #e5e7eb;
7
+ --ai-text: #1f2937;
8
+ --ai-text-secondary: #6b7280;
9
+ --ai-bot-bg: #f3f4f6;
10
+ --ai-user-bg: #2563eb;
11
+ --ai-user-text: #ffffff;
12
+ font-family: inherit;
13
+ font-size: 16px;
14
+ line-height: 1.5;
15
+ box-sizing: border-box;
16
+ }
17
+ .chatWindow {
18
+ display: flex;
19
+ flex-direction: column;
20
+ height: 500px;
21
+ width: 100%;
22
+ max-width: 400px;
23
+ background-color: var(--ai-bg);
24
+ border: 1px solid var(--ai-border);
25
+ border-radius: 12px;
26
+ overflow: hidden;
27
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
28
+ position: relative;
29
+ }
30
+ .messageList {
31
+ flex: 1;
32
+ overflow-y: auto;
33
+ padding: 16px;
34
+ display: flex;
35
+ flex-direction: column;
36
+ gap: 12px;
37
+ scroll-behavior: smooth;
38
+ }
39
+ .messageRow {
40
+ display: flex;
41
+ width: 100%;
42
+ }
43
+ .messageRow.user {
44
+ justify-content: flex-end;
45
+ }
46
+ .messageRow.assistant {
47
+ justify-content: flex-start;
48
+ }
49
+ .bubble {
50
+ max-width: 80%;
51
+ padding: 8px 12px;
52
+ border-radius: 12px;
53
+ font-size: 0.95em;
54
+ word-wrap: break-word;
55
+ }
56
+ .bubble.user {
57
+ background-color: var(--ai-user-bg);
58
+ color: var(--ai-user-text);
59
+ border-bottom-right-radius: 2px;
60
+ }
61
+ .bubble.assistant {
62
+ background-color: var(--ai-bot-bg);
63
+ color: var(--ai-text);
64
+ border-bottom-left-radius: 2px;
65
+ }
66
+ .inputArea {
67
+ padding: 12px;
68
+ border-top: 1px solid var(--ai-border);
69
+ display: flex;
70
+ gap: 8px;
71
+ background-color: var(--ai-bg);
72
+ }
73
+ .input {
74
+ flex: 1;
75
+ padding: 8px 12px;
76
+ border: 1px solid var(--ai-border);
77
+ border-radius: 8px;
78
+ outline: none;
79
+ font-family: inherit;
80
+ }
81
+ .input:focus {
82
+ border-color: var(--ai-primary);
83
+ }
84
+ .sendButton {
85
+ background-color: var(--ai-primary);
86
+ color: var(--ai-primary-fg);
87
+ border: none;
88
+ border-radius: 8px;
89
+ padding: 8px 12px;
90
+ cursor: pointer;
91
+ display: flex;
92
+ align-items: center;
93
+ justify-content: center;
94
+ transition: opacity 0.2s;
95
+ }
96
+ .sendButton:disabled {
97
+ opacity: 0.5;
98
+ cursor: not-allowed;
99
+ }
100
+ .loading {
101
+ display: flex;
102
+ gap: 4px;
103
+ padding: 4px;
104
+ }
105
+ .dot {
106
+ width: 6px;
107
+ height: 6px;
108
+ background-color: #9ca3af;
109
+ border-radius: 50%;
110
+ animation: bounce 1.4s infinite ease-in-out both;
111
+ }
112
+ .dot:nth-child(1) {
113
+ animation-delay: -0.32s;
114
+ }
115
+ .dot:nth-child(2) {
116
+ animation-delay: -0.16s;
117
+ }
118
+ @keyframes bounce {
119
+ 0%, 80%, 100% {
120
+ transform: scale(0);
121
+ }
122
+ 40% {
123
+ transform: scale(1);
124
+ }
125
+ }
126
+ /*# sourceMappingURL=react.css.map */
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/styles/chat.module.css"],"sourcesContent":["/* src/styles/chat.module.css */\r\n\r\n/* تعریف متغیرها برای اینکه کاربر بتواند رنگ‌ها را شخصی‌سازی کند */\r\n.container {\r\n /* رنگ‌های پیش‌فرض - کاربر می‌تواند این‌ها را در فایل CSS خود بازنویسی کند */\r\n --ai-primary: #2563eb; /* رنگ آبی استاندارد */\r\n --ai-primary-fg: #ffffff; /* رنگ متن روی دکمه‌ها */\r\n --ai-bg: #ffffff; /* رنگ پس‌زمینه چت */\r\n --ai-border: #e5e7eb; /* رنگ حاشیه */\r\n --ai-text: #1f2937; /* رنگ متن اصلی */\r\n --ai-text-secondary: #6b7280; /* رنگ متن فرعی */\r\n --ai-bot-bg: #f3f4f6; /* رنگ حباب پیام ربات */\r\n --ai-user-bg: #2563eb; /* رنگ حباب پیام کاربر */\r\n --ai-user-text: #ffffff; /* رنگ متن پیام کاربر */\r\n \r\n font-family: inherit; /* از فونت وبسایت کاربر ارث‌بری می‌کند */\r\n font-size: 16px;\r\n line-height: 1.5;\r\n box-sizing: border-box;\r\n}\r\n\r\n/* کانتینر اصلی چت */\r\n.chatWindow {\r\n display: flex;\r\n flex-direction: column;\r\n height: 500px;\r\n width: 100%;\r\n max-width: 400px;\r\n background-color: var(--ai-bg);\r\n border: 1px solid var(--ai-border);\r\n border-radius: 12px;\r\n overflow: hidden;\r\n box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);\r\n position: relative;\r\n}\r\n\r\n/* لیست پیام‌ها */\r\n.messageList {\r\n flex: 1;\r\n overflow-y: auto;\r\n padding: 16px;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 12px;\r\n scroll-behavior: smooth;\r\n}\r\n\r\n/* استایل هر پیام */\r\n.messageRow {\r\n display: flex;\r\n width: 100%;\r\n}\r\n\r\n.messageRow.user {\r\n justify-content: flex-end;\r\n}\r\n\r\n.messageRow.assistant {\r\n justify-content: flex-start;\r\n}\r\n\r\n.bubble {\r\n max-width: 80%;\r\n padding: 8px 12px;\r\n border-radius: 12px;\r\n font-size: 0.95em;\r\n word-wrap: break-word;\r\n}\r\n\r\n.bubble.user {\r\n background-color: var(--ai-user-bg);\r\n color: var(--ai-user-text);\r\n border-bottom-right-radius: 2px;\r\n}\r\n\r\n.bubble.assistant {\r\n background-color: var(--ai-bot-bg);\r\n color: var(--ai-text);\r\n border-bottom-left-radius: 2px;\r\n}\r\n\r\n/* ناحیه ورودی متن */\r\n.inputArea {\r\n padding: 12px;\r\n border-top: 1px solid var(--ai-border);\r\n display: flex;\r\n gap: 8px;\r\n background-color: var(--ai-bg);\r\n}\r\n\r\n.input {\r\n flex: 1;\r\n padding: 8px 12px;\r\n border: 1px solid var(--ai-border);\r\n border-radius: 8px;\r\n outline: none;\r\n font-family: inherit;\r\n}\r\n\r\n.input:focus {\r\n border-color: var(--ai-primary);\r\n}\r\n\r\n.sendButton {\r\n background-color: var(--ai-primary);\r\n color: var(--ai-primary-fg);\r\n border: none;\r\n border-radius: 8px;\r\n padding: 8px 12px;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n transition: opacity 0.2s;\r\n}\r\n\r\n.sendButton:disabled {\r\n opacity: 0.5;\r\n cursor: not-allowed;\r\n}\r\n\r\n.loading {\r\n display: flex;\r\n gap: 4px;\r\n padding: 4px;\r\n}\r\n\r\n.dot {\r\n width: 6px;\r\n height: 6px;\r\n background-color: #9ca3af;\r\n border-radius: 50%;\r\n animation: bounce 1.4s infinite ease-in-out both;\r\n}\r\n\r\n.dot:nth-child(1) { animation-delay: -0.32s; }\r\n.dot:nth-child(2) { animation-delay: -0.16s; }\r\n\r\n@keyframes bounce {\r\n 0%, 80%, 100% { transform: scale(0); }\r\n 40% { transform: scale(1); }\r\n}"],"mappings":";AAGA,CAAC;AAEC,gBAAc;AACd,mBAAiB;AACjB,WAAS;AACT,eAAa;AACb,aAAW;AACX,uBAAqB;AACrB,eAAa;AACb,gBAAc;AACd,kBAAgB;AAEhB,eAAa;AACb,aAAW;AACX,eAAa;AACb,cAAY;AACd;AAGA,CAAC;AACC,WAAS;AACT,kBAAgB;AAChB,UAAQ;AACR,SAAO;AACP,aAAW;AACX,oBAAkB,IAAI;AACtB,UAAQ,IAAI,MAAM,IAAI;AACtB,iBAAe;AACf,YAAU;AACV,cAAY,EAAE,IAAI,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;AACzC,YAAU;AACZ;AAGA,CAAC;AACC,QAAM;AACN,cAAY;AACZ,WAAS;AACT,WAAS;AACT,kBAAgB;AAChB,OAAK;AACL,mBAAiB;AACnB;AAGA,CAAC;AACC,WAAS;AACT,SAAO;AACT;AAEA,CALC,UAKU,CAAC;AACV,mBAAiB;AACnB;AAEA,CATC,UASU,CAAC;AACV,mBAAiB;AACnB;AAEA,CAAC;AACC,aAAW;AACX,WAAS,IAAI;AACb,iBAAe;AACf,aAAW;AACX,aAAW;AACb;AAEA,CARC,MAQM,CAhBK;AAiBV,oBAAkB,IAAI;AACtB,SAAO,IAAI;AACX,8BAA4B;AAC9B;AAEA,CAdC,MAcM,CAlBK;AAmBV,oBAAkB,IAAI;AACtB,SAAO,IAAI;AACX,6BAA2B;AAC7B;AAGA,CAAC;AACC,WAAS;AACT,cAAY,IAAI,MAAM,IAAI;AAC1B,WAAS;AACT,OAAK;AACL,oBAAkB,IAAI;AACxB;AAEA,CAAC;AACC,QAAM;AACN,WAAS,IAAI;AACb,UAAQ,IAAI,MAAM,IAAI;AACtB,iBAAe;AACf,WAAS;AACT,eAAa;AACf;AAEA,CATC,KASK;AACJ,gBAAc,IAAI;AACpB;AAEA,CAAC;AACC,oBAAkB,IAAI;AACtB,SAAO,IAAI;AACX,UAAQ;AACR,iBAAe;AACf,WAAS,IAAI;AACb,UAAQ;AACR,WAAS;AACT,eAAa;AACb,mBAAiB;AACjB,cAAY,QAAQ;AACtB;AAEA,CAbC,UAaU;AACT,WAAS;AACT,UAAQ;AACV;AAEA,CAAC;AACC,WAAS;AACT,OAAK;AACL,WAAS;AACX;AAEA,CAAC;AACC,SAAO;AACP,UAAQ;AACR,oBAAkB;AAClB,iBAAe;AACf,aAAW,OAAO,KAAK,SAAS,YAAY;AAC9C;AAEA,CARC,GAQG;AAAgB,mBAAiB;AAAQ;AAC7C,CATC,GASG;AAAgB,mBAAiB;AAAQ;AAE7C,WANa;AAOX;AAAgB,eAAW,MAAM;AAAI;AACrC;AAAM,eAAW,MAAM;AAAI;AAC7B;","names":[]}
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import { M as Message } from './index-BeDFcZll.mjs';
3
+ export { A as AiRobotConfig, C as ChatResponse, R as Role } from './index-BeDFcZll.mjs';
4
+
5
+ interface ChatBotProps {
6
+ /** آدرس ای‌پی‌آی که کاربر در پروژه خودش ساخته */
7
+ apiEndpoint: string;
8
+ /** عنوان بالای چت باکس */
9
+ title?: string;
10
+ /** پیام خوش‌آمدگویی اولیه */
11
+ welcomeMessage?: string;
12
+ }
13
+ declare const ChatBot: React.FC<ChatBotProps>;
14
+
15
+ interface MessageBubbleProps {
16
+ message: Message;
17
+ }
18
+ declare const MessageBubble: React.FC<MessageBubbleProps>;
19
+
20
+ export { ChatBot, type ChatBotProps, Message, MessageBubble };
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import { M as Message } from './index-BeDFcZll.js';
3
+ export { A as AiRobotConfig, C as ChatResponse, R as Role } from './index-BeDFcZll.js';
4
+
5
+ interface ChatBotProps {
6
+ /** آدرس ای‌پی‌آی که کاربر در پروژه خودش ساخته */
7
+ apiEndpoint: string;
8
+ /** عنوان بالای چت باکس */
9
+ title?: string;
10
+ /** پیام خوش‌آمدگویی اولیه */
11
+ welcomeMessage?: string;
12
+ }
13
+ declare const ChatBot: React.FC<ChatBotProps>;
14
+
15
+ interface MessageBubbleProps {
16
+ message: Message;
17
+ }
18
+ declare const MessageBubble: React.FC<MessageBubbleProps>;
19
+
20
+ export { ChatBot, type ChatBotProps, Message, MessageBubble };
package/dist/react.js ADDED
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ "use client";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+
31
+ // src/react.ts
32
+ var react_exports = {};
33
+ __export(react_exports, {
34
+ ChatBot: () => ChatBot,
35
+ MessageBubble: () => MessageBubble
36
+ });
37
+ module.exports = __toCommonJS(react_exports);
38
+
39
+ // src/components/ChatBot.tsx
40
+ var import_react = require("react");
41
+
42
+ // src/styles/chat.module.css
43
+ var chat_default = {};
44
+
45
+ // src/components/MessageBubble.tsx
46
+ var import_clsx = __toESM(require("clsx"));
47
+ var import_jsx_runtime = require("react/jsx-runtime");
48
+ var MessageBubble = ({ message }) => {
49
+ const isUser = message.role === "user";
50
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
51
+ "div",
52
+ {
53
+ className: (0, import_clsx.default)(
54
+ chat_default.messageRow,
55
+ isUser ? chat_default.user : chat_default.assistant
56
+ ),
57
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
58
+ "div",
59
+ {
60
+ className: (0, import_clsx.default)(
61
+ chat_default.bubble,
62
+ isUser ? chat_default.user : chat_default.assistant
63
+ ),
64
+ children: message.content
65
+ }
66
+ )
67
+ }
68
+ );
69
+ };
70
+
71
+ // src/components/ChatBot.tsx
72
+ var import_lucide_react = require("lucide-react");
73
+ var import_clsx2 = __toESM(require("clsx"));
74
+ var import_jsx_runtime2 = require("react/jsx-runtime");
75
+ var ChatBot = ({
76
+ apiEndpoint,
77
+ title = "AI Assistant",
78
+ welcomeMessage = "\u0633\u0644\u0627\u0645! \u0686\u0637\u0648\u0631 \u0645\u06CC\u200C\u062A\u0648\u0627\u0646\u0645 \u06A9\u0645\u06A9\u062A\u0627\u0646 \u06A9\u0646\u0645\u061F"
79
+ }) => {
80
+ const [messages, setMessages] = (0, import_react.useState)([]);
81
+ const [inputValue, setInputValue] = (0, import_react.useState)("");
82
+ const [isLoading, setIsLoading] = (0, import_react.useState)(false);
83
+ const messagesEndRef = (0, import_react.useRef)(null);
84
+ (0, import_react.useEffect)(() => {
85
+ if (welcomeMessage && messages.length === 0) {
86
+ setMessages([{ role: "assistant", content: welcomeMessage }]);
87
+ }
88
+ }, [welcomeMessage]);
89
+ (0, import_react.useEffect)(() => {
90
+ messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
91
+ }, [messages]);
92
+ const handleSendMessage = async () => {
93
+ if (!inputValue.trim() || isLoading) return;
94
+ const userMsg = { role: "user", content: inputValue };
95
+ setMessages((prev) => [...prev, userMsg]);
96
+ setInputValue("");
97
+ setIsLoading(true);
98
+ try {
99
+ const response = await fetch(apiEndpoint, {
100
+ method: "POST",
101
+ headers: { "Content-Type": "application/json" },
102
+ body: JSON.stringify({ messages: [...messages, userMsg] })
103
+ });
104
+ if (!response.ok) throw new Error("Network response was not ok");
105
+ const data = await response.json();
106
+ const botMsg = { role: "assistant", content: data.content };
107
+ setMessages((prev) => [...prev, botMsg]);
108
+ } catch (error) {
109
+ console.error("Chat Error:", error);
110
+ setMessages((prev) => [...prev, { role: "assistant", content: "\u062E\u0637\u0627\u06CC\u06CC \u0631\u062E \u062F\u0627\u062F\u0647 \u0627\u0633\u062A. \u0644\u0637\u0641\u0627\u064B \u062F\u0648\u0628\u0627\u0631\u0647 \u062A\u0644\u0627\u0634 \u06A9\u0646\u06CC\u062F." }]);
111
+ } finally {
112
+ setIsLoading(false);
113
+ }
114
+ };
115
+ const handleKeyDown = (e) => {
116
+ if (e.key === "Enter" && !e.shiftKey) {
117
+ e.preventDefault();
118
+ handleSendMessage();
119
+ }
120
+ };
121
+ return (
122
+ // کلاس کانتینر برای اعمال متغیرهای CSS
123
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: (0, import_clsx2.default)(chat_default.container, chat_default.chatWindow), children: [
124
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { padding: "16px", borderBottom: "1px solid var(--ai-border)", display: "flex", alignItems: "center", gap: "8px", background: "#f9fafb" }, children: [
125
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Bot, { size: 20 }),
126
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { fontWeight: 600 }, children: title })
127
+ ] }),
128
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: chat_default.messageList, children: [
129
+ messages.map((msg, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(MessageBubble, { message: msg }, index)),
130
+ isLoading && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: (0, import_clsx2.default)(chat_default.messageRow, chat_default.assistant), children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: (0, import_clsx2.default)(chat_default.bubble, chat_default.assistant, chat_default.loading), children: [
131
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: chat_default.dot }),
132
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: chat_default.dot }),
133
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: chat_default.dot })
134
+ ] }) }),
135
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { ref: messagesEndRef })
136
+ ] }),
137
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: chat_default.inputArea, children: [
138
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
139
+ "input",
140
+ {
141
+ className: chat_default.input,
142
+ value: inputValue,
143
+ onChange: (e) => setInputValue(e.target.value),
144
+ onKeyDown: handleKeyDown,
145
+ placeholder: "\u067E\u06CC\u0627\u0645 \u062E\u0648\u062F \u0631\u0627 \u0628\u0646\u0648\u06CC\u0633\u06CC\u062F...",
146
+ disabled: isLoading
147
+ }
148
+ ),
149
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
150
+ "button",
151
+ {
152
+ className: chat_default.sendButton,
153
+ onClick: handleSendMessage,
154
+ disabled: isLoading || !inputValue.trim(),
155
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Send, { size: 18 })
156
+ }
157
+ )
158
+ ] })
159
+ ] })
160
+ );
161
+ };
162
+ // Annotate the CommonJS export names for ESM import in node:
163
+ 0 && (module.exports = {
164
+ ChatBot,
165
+ MessageBubble
166
+ });
167
+ //# sourceMappingURL=react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/react.ts","../src/components/ChatBot.tsx","../src/styles/chat.module.css","../src/components/MessageBubble.tsx"],"sourcesContent":["// src/react.ts\r\n\"use client\"; // 👈 این خط حیاتی است\r\n\r\nexport { ChatBot, type ChatBotProps } from \"./components/ChatBot\";\r\nexport { MessageBubble } from \"./components/MessageBubble\";\r\nexport * from \"./types\"; // تایپ‌ها در هر دو مشترک هستند","\"use client\"\r\n\r\nimport React, { useState, useRef, useEffect } from 'react';\r\nimport styles from '../styles/chat.module.css';\r\nimport { MessageBubble } from './MessageBubble';\r\nimport { Message } from '../types';\r\nimport { Send, Bot } from 'lucide-react'; // آیکون‌ها\r\nimport clsx from 'clsx';\r\n\r\nexport interface ChatBotProps {\r\n /** آدرس ای‌پی‌آی که کاربر در پروژه خودش ساخته */\r\n apiEndpoint: string;\r\n /** عنوان بالای چت باکس */\r\n title?: string;\r\n /** پیام خوش‌آمدگویی اولیه */\r\n welcomeMessage?: string;\r\n}\r\n\r\nexport const ChatBot: React.FC<ChatBotProps> = ({\r\n apiEndpoint,\r\n title = \"AI Assistant\",\r\n welcomeMessage = \"سلام! چطور می‌توانم کمکتان کنم؟\"\r\n}) => {\r\n const [messages, setMessages] = useState<Message[]>([]);\r\n const [inputValue, setInputValue] = useState(\"\");\r\n const [isLoading, setIsLoading] = useState(false);\r\n \r\n // برای اسکرول خودکار به پایین\r\n const messagesEndRef = useRef<HTMLDivElement>(null);\r\n\r\n // اضافه کردن پیام خوش‌آمدگویی در شروع\r\n useEffect(() => {\r\n if (welcomeMessage && messages.length === 0) {\r\n setMessages([{ role: 'assistant', content: welcomeMessage }]);\r\n }\r\n }, [welcomeMessage]);\r\n\r\n // اسکرول به پایین وقتی پیام جدید می‌آید\r\n useEffect(() => {\r\n messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });\r\n }, [messages]);\r\n\r\n const handleSendMessage = async () => {\r\n if (!inputValue.trim() || isLoading) return;\r\n\r\n const userMsg: Message = { role: 'user', content: inputValue };\r\n \r\n // 1. اضافه کردن پیام کاربر به لیست و خالی کردن اینپوت\r\n setMessages(prev => [...prev, userMsg]);\r\n setInputValue(\"\");\r\n setIsLoading(true);\r\n\r\n try {\r\n // 2. ارسال درخواست به سرور (API کاربر)\r\n const response = await fetch(apiEndpoint, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ messages: [...messages, userMsg] }),\r\n });\r\n\r\n if (!response.ok) throw new Error(\"Network response was not ok\");\r\n \r\n // نکته: اینجا فعلاً فرض می‌کنیم پاسخ متنی ساده است (بعداً استریم را اضافه می‌کنیم)\r\n const data = await response.json();\r\n \r\n const botMsg: Message = { role: 'assistant', content: data.content };\r\n setMessages(prev => [...prev, botMsg]);\r\n\r\n } catch (error) {\r\n console.error(\"Chat Error:\", error);\r\n setMessages(prev => [...prev, { role: 'assistant', content: \"خطایی رخ داده است. لطفاً دوباره تلاش کنید.\" }]);\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n };\r\n\r\n const handleKeyDown = (e: React.KeyboardEvent) => {\r\n if (e.key === 'Enter' && !e.shiftKey) {\r\n e.preventDefault();\r\n handleSendMessage();\r\n }\r\n };\r\n\r\n return (\r\n // کلاس کانتینر برای اعمال متغیرهای CSS\r\n <div className={clsx(styles.container, styles.chatWindow)}>\r\n {/* هدر */}\r\n <div style={{ padding: '16px', borderBottom: '1px solid var(--ai-border)', display: 'flex', alignItems: 'center', gap: '8px', background: '#f9fafb' }}>\r\n <Bot size={20} />\r\n <span style={{ fontWeight: 600 }}>{title}</span>\r\n </div>\r\n\r\n {/* لیست پیام‌ها */}\r\n <div className={styles.messageList}>\r\n {messages.map((msg, index) => (\r\n <MessageBubble key={index} message={msg} />\r\n ))}\r\n {isLoading && (\r\n <div className={clsx(styles.messageRow, styles.assistant)}>\r\n <div className={clsx(styles.bubble, styles.assistant, styles.loading)}>\r\n <div className={styles.dot}></div>\r\n <div className={styles.dot}></div>\r\n <div className={styles.dot}></div>\r\n </div>\r\n </div>\r\n )}\r\n <div ref={messagesEndRef} />\r\n </div>\r\n\r\n {/* ورودی */}\r\n <div className={styles.inputArea}>\r\n <input\r\n className={styles.input}\r\n value={inputValue}\r\n onChange={(e) => setInputValue(e.target.value)}\r\n onKeyDown={handleKeyDown}\r\n placeholder=\"پیام خود را بنویسید...\"\r\n disabled={isLoading}\r\n />\r\n <button \r\n className={styles.sendButton} \r\n onClick={handleSendMessage}\r\n disabled={isLoading || !inputValue.trim()}\r\n >\r\n <Send size={18} />\r\n </button>\r\n </div>\r\n </div>\r\n );\r\n};","/* src/styles/chat.module.css */\r\n\r\n/* تعریف متغیرها برای اینکه کاربر بتواند رنگ‌ها را شخصی‌سازی کند */\r\n.container {\r\n /* رنگ‌های پیش‌فرض - کاربر می‌تواند این‌ها را در فایل CSS خود بازنویسی کند */\r\n --ai-primary: #2563eb; /* رنگ آبی استاندارد */\r\n --ai-primary-fg: #ffffff; /* رنگ متن روی دکمه‌ها */\r\n --ai-bg: #ffffff; /* رنگ پس‌زمینه چت */\r\n --ai-border: #e5e7eb; /* رنگ حاشیه */\r\n --ai-text: #1f2937; /* رنگ متن اصلی */\r\n --ai-text-secondary: #6b7280; /* رنگ متن فرعی */\r\n --ai-bot-bg: #f3f4f6; /* رنگ حباب پیام ربات */\r\n --ai-user-bg: #2563eb; /* رنگ حباب پیام کاربر */\r\n --ai-user-text: #ffffff; /* رنگ متن پیام کاربر */\r\n \r\n font-family: inherit; /* از فونت وبسایت کاربر ارث‌بری می‌کند */\r\n font-size: 16px;\r\n line-height: 1.5;\r\n box-sizing: border-box;\r\n}\r\n\r\n/* کانتینر اصلی چت */\r\n.chatWindow {\r\n display: flex;\r\n flex-direction: column;\r\n height: 500px;\r\n width: 100%;\r\n max-width: 400px;\r\n background-color: var(--ai-bg);\r\n border: 1px solid var(--ai-border);\r\n border-radius: 12px;\r\n overflow: hidden;\r\n box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);\r\n position: relative;\r\n}\r\n\r\n/* لیست پیام‌ها */\r\n.messageList {\r\n flex: 1;\r\n overflow-y: auto;\r\n padding: 16px;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 12px;\r\n scroll-behavior: smooth;\r\n}\r\n\r\n/* استایل هر پیام */\r\n.messageRow {\r\n display: flex;\r\n width: 100%;\r\n}\r\n\r\n.messageRow.user {\r\n justify-content: flex-end;\r\n}\r\n\r\n.messageRow.assistant {\r\n justify-content: flex-start;\r\n}\r\n\r\n.bubble {\r\n max-width: 80%;\r\n padding: 8px 12px;\r\n border-radius: 12px;\r\n font-size: 0.95em;\r\n word-wrap: break-word;\r\n}\r\n\r\n.bubble.user {\r\n background-color: var(--ai-user-bg);\r\n color: var(--ai-user-text);\r\n border-bottom-right-radius: 2px;\r\n}\r\n\r\n.bubble.assistant {\r\n background-color: var(--ai-bot-bg);\r\n color: var(--ai-text);\r\n border-bottom-left-radius: 2px;\r\n}\r\n\r\n/* ناحیه ورودی متن */\r\n.inputArea {\r\n padding: 12px;\r\n border-top: 1px solid var(--ai-border);\r\n display: flex;\r\n gap: 8px;\r\n background-color: var(--ai-bg);\r\n}\r\n\r\n.input {\r\n flex: 1;\r\n padding: 8px 12px;\r\n border: 1px solid var(--ai-border);\r\n border-radius: 8px;\r\n outline: none;\r\n font-family: inherit;\r\n}\r\n\r\n.input:focus {\r\n border-color: var(--ai-primary);\r\n}\r\n\r\n.sendButton {\r\n background-color: var(--ai-primary);\r\n color: var(--ai-primary-fg);\r\n border: none;\r\n border-radius: 8px;\r\n padding: 8px 12px;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n transition: opacity 0.2s;\r\n}\r\n\r\n.sendButton:disabled {\r\n opacity: 0.5;\r\n cursor: not-allowed;\r\n}\r\n\r\n.loading {\r\n display: flex;\r\n gap: 4px;\r\n padding: 4px;\r\n}\r\n\r\n.dot {\r\n width: 6px;\r\n height: 6px;\r\n background-color: #9ca3af;\r\n border-radius: 50%;\r\n animation: bounce 1.4s infinite ease-in-out both;\r\n}\r\n\r\n.dot:nth-child(1) { animation-delay: -0.32s; }\r\n.dot:nth-child(2) { animation-delay: -0.16s; }\r\n\r\n@keyframes bounce {\r\n 0%, 80%, 100% { transform: scale(0); }\r\n 40% { transform: scale(1); }\r\n}","// src/components/MessageBubble.tsx\r\nimport React from 'react';\r\nimport clsx from 'clsx'; // ابزاری عالی برای ترکیب کلاس‌های CSS\r\nimport styles from '../styles/chat.module.css';\r\nimport { Message } from '../types';\r\n\r\ninterface MessageBubbleProps {\r\n message: Message;\r\n}\r\n\r\nexport const MessageBubble: React.FC<MessageBubbleProps> = ({ message }) => {\r\n const isUser = message.role === 'user';\r\n\r\n return (\r\n <div\r\n className={clsx(\r\n styles.messageRow,\r\n isUser ? styles.user : styles.assistant\r\n )}\r\n >\r\n <div\r\n className={clsx(\r\n styles.bubble,\r\n isUser ? styles.user : styles.assistant\r\n )}\r\n >\r\n {/* فعلاً متن ساده را رندر می‌کنیم. بعداً می‌توانیم Markdown اضافه کنیم */}\r\n {message.content}\r\n </div>\r\n </div>\r\n );\r\n};"],"mappings":"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","names":["clsx","import_clsx","import_jsx_runtime","clsx"]}
package/dist/react.mjs ADDED
@@ -0,0 +1,130 @@
1
+ "use client";
2
+
3
+ // src/components/ChatBot.tsx
4
+ import { useState, useRef, useEffect } from "react";
5
+
6
+ // src/styles/chat.module.css
7
+ var chat_default = {};
8
+
9
+ // src/components/MessageBubble.tsx
10
+ import clsx from "clsx";
11
+ import { jsx } from "react/jsx-runtime";
12
+ var MessageBubble = ({ message }) => {
13
+ const isUser = message.role === "user";
14
+ return /* @__PURE__ */ jsx(
15
+ "div",
16
+ {
17
+ className: clsx(
18
+ chat_default.messageRow,
19
+ isUser ? chat_default.user : chat_default.assistant
20
+ ),
21
+ children: /* @__PURE__ */ jsx(
22
+ "div",
23
+ {
24
+ className: clsx(
25
+ chat_default.bubble,
26
+ isUser ? chat_default.user : chat_default.assistant
27
+ ),
28
+ children: message.content
29
+ }
30
+ )
31
+ }
32
+ );
33
+ };
34
+
35
+ // src/components/ChatBot.tsx
36
+ import { Send, Bot } from "lucide-react";
37
+ import clsx2 from "clsx";
38
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
39
+ var ChatBot = ({
40
+ apiEndpoint,
41
+ title = "AI Assistant",
42
+ welcomeMessage = "\u0633\u0644\u0627\u0645! \u0686\u0637\u0648\u0631 \u0645\u06CC\u200C\u062A\u0648\u0627\u0646\u0645 \u06A9\u0645\u06A9\u062A\u0627\u0646 \u06A9\u0646\u0645\u061F"
43
+ }) => {
44
+ const [messages, setMessages] = useState([]);
45
+ const [inputValue, setInputValue] = useState("");
46
+ const [isLoading, setIsLoading] = useState(false);
47
+ const messagesEndRef = useRef(null);
48
+ useEffect(() => {
49
+ if (welcomeMessage && messages.length === 0) {
50
+ setMessages([{ role: "assistant", content: welcomeMessage }]);
51
+ }
52
+ }, [welcomeMessage]);
53
+ useEffect(() => {
54
+ messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
55
+ }, [messages]);
56
+ const handleSendMessage = async () => {
57
+ if (!inputValue.trim() || isLoading) return;
58
+ const userMsg = { role: "user", content: inputValue };
59
+ setMessages((prev) => [...prev, userMsg]);
60
+ setInputValue("");
61
+ setIsLoading(true);
62
+ try {
63
+ const response = await fetch(apiEndpoint, {
64
+ method: "POST",
65
+ headers: { "Content-Type": "application/json" },
66
+ body: JSON.stringify({ messages: [...messages, userMsg] })
67
+ });
68
+ if (!response.ok) throw new Error("Network response was not ok");
69
+ const data = await response.json();
70
+ const botMsg = { role: "assistant", content: data.content };
71
+ setMessages((prev) => [...prev, botMsg]);
72
+ } catch (error) {
73
+ console.error("Chat Error:", error);
74
+ setMessages((prev) => [...prev, { role: "assistant", content: "\u062E\u0637\u0627\u06CC\u06CC \u0631\u062E \u062F\u0627\u062F\u0647 \u0627\u0633\u062A. \u0644\u0637\u0641\u0627\u064B \u062F\u0648\u0628\u0627\u0631\u0647 \u062A\u0644\u0627\u0634 \u06A9\u0646\u06CC\u062F." }]);
75
+ } finally {
76
+ setIsLoading(false);
77
+ }
78
+ };
79
+ const handleKeyDown = (e) => {
80
+ if (e.key === "Enter" && !e.shiftKey) {
81
+ e.preventDefault();
82
+ handleSendMessage();
83
+ }
84
+ };
85
+ return (
86
+ // کلاس کانتینر برای اعمال متغیرهای CSS
87
+ /* @__PURE__ */ jsxs("div", { className: clsx2(chat_default.container, chat_default.chatWindow), children: [
88
+ /* @__PURE__ */ jsxs("div", { style: { padding: "16px", borderBottom: "1px solid var(--ai-border)", display: "flex", alignItems: "center", gap: "8px", background: "#f9fafb" }, children: [
89
+ /* @__PURE__ */ jsx2(Bot, { size: 20 }),
90
+ /* @__PURE__ */ jsx2("span", { style: { fontWeight: 600 }, children: title })
91
+ ] }),
92
+ /* @__PURE__ */ jsxs("div", { className: chat_default.messageList, children: [
93
+ messages.map((msg, index) => /* @__PURE__ */ jsx2(MessageBubble, { message: msg }, index)),
94
+ isLoading && /* @__PURE__ */ jsx2("div", { className: clsx2(chat_default.messageRow, chat_default.assistant), children: /* @__PURE__ */ jsxs("div", { className: clsx2(chat_default.bubble, chat_default.assistant, chat_default.loading), children: [
95
+ /* @__PURE__ */ jsx2("div", { className: chat_default.dot }),
96
+ /* @__PURE__ */ jsx2("div", { className: chat_default.dot }),
97
+ /* @__PURE__ */ jsx2("div", { className: chat_default.dot })
98
+ ] }) }),
99
+ /* @__PURE__ */ jsx2("div", { ref: messagesEndRef })
100
+ ] }),
101
+ /* @__PURE__ */ jsxs("div", { className: chat_default.inputArea, children: [
102
+ /* @__PURE__ */ jsx2(
103
+ "input",
104
+ {
105
+ className: chat_default.input,
106
+ value: inputValue,
107
+ onChange: (e) => setInputValue(e.target.value),
108
+ onKeyDown: handleKeyDown,
109
+ placeholder: "\u067E\u06CC\u0627\u0645 \u062E\u0648\u062F \u0631\u0627 \u0628\u0646\u0648\u06CC\u0633\u06CC\u062F...",
110
+ disabled: isLoading
111
+ }
112
+ ),
113
+ /* @__PURE__ */ jsx2(
114
+ "button",
115
+ {
116
+ className: chat_default.sendButton,
117
+ onClick: handleSendMessage,
118
+ disabled: isLoading || !inputValue.trim(),
119
+ children: /* @__PURE__ */ jsx2(Send, { size: 18 })
120
+ }
121
+ )
122
+ ] })
123
+ ] })
124
+ );
125
+ };
126
+ export {
127
+ ChatBot,
128
+ MessageBubble
129
+ };
130
+ //# sourceMappingURL=react.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/ChatBot.tsx","../src/styles/chat.module.css","../src/components/MessageBubble.tsx"],"sourcesContent":["\"use client\"\r\n\r\nimport React, { useState, useRef, useEffect } from 'react';\r\nimport styles from '../styles/chat.module.css';\r\nimport { MessageBubble } from './MessageBubble';\r\nimport { Message } from '../types';\r\nimport { Send, Bot } from 'lucide-react'; // آیکون‌ها\r\nimport clsx from 'clsx';\r\n\r\nexport interface ChatBotProps {\r\n /** آدرس ای‌پی‌آی که کاربر در پروژه خودش ساخته */\r\n apiEndpoint: string;\r\n /** عنوان بالای چت باکس */\r\n title?: string;\r\n /** پیام خوش‌آمدگویی اولیه */\r\n welcomeMessage?: string;\r\n}\r\n\r\nexport const ChatBot: React.FC<ChatBotProps> = ({\r\n apiEndpoint,\r\n title = \"AI Assistant\",\r\n welcomeMessage = \"سلام! چطور می‌توانم کمکتان کنم؟\"\r\n}) => {\r\n const [messages, setMessages] = useState<Message[]>([]);\r\n const [inputValue, setInputValue] = useState(\"\");\r\n const [isLoading, setIsLoading] = useState(false);\r\n \r\n // برای اسکرول خودکار به پایین\r\n const messagesEndRef = useRef<HTMLDivElement>(null);\r\n\r\n // اضافه کردن پیام خوش‌آمدگویی در شروع\r\n useEffect(() => {\r\n if (welcomeMessage && messages.length === 0) {\r\n setMessages([{ role: 'assistant', content: welcomeMessage }]);\r\n }\r\n }, [welcomeMessage]);\r\n\r\n // اسکرول به پایین وقتی پیام جدید می‌آید\r\n useEffect(() => {\r\n messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });\r\n }, [messages]);\r\n\r\n const handleSendMessage = async () => {\r\n if (!inputValue.trim() || isLoading) return;\r\n\r\n const userMsg: Message = { role: 'user', content: inputValue };\r\n \r\n // 1. اضافه کردن پیام کاربر به لیست و خالی کردن اینپوت\r\n setMessages(prev => [...prev, userMsg]);\r\n setInputValue(\"\");\r\n setIsLoading(true);\r\n\r\n try {\r\n // 2. ارسال درخواست به سرور (API کاربر)\r\n const response = await fetch(apiEndpoint, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ messages: [...messages, userMsg] }),\r\n });\r\n\r\n if (!response.ok) throw new Error(\"Network response was not ok\");\r\n \r\n // نکته: اینجا فعلاً فرض می‌کنیم پاسخ متنی ساده است (بعداً استریم را اضافه می‌کنیم)\r\n const data = await response.json();\r\n \r\n const botMsg: Message = { role: 'assistant', content: data.content };\r\n setMessages(prev => [...prev, botMsg]);\r\n\r\n } catch (error) {\r\n console.error(\"Chat Error:\", error);\r\n setMessages(prev => [...prev, { role: 'assistant', content: \"خطایی رخ داده است. لطفاً دوباره تلاش کنید.\" }]);\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n };\r\n\r\n const handleKeyDown = (e: React.KeyboardEvent) => {\r\n if (e.key === 'Enter' && !e.shiftKey) {\r\n e.preventDefault();\r\n handleSendMessage();\r\n }\r\n };\r\n\r\n return (\r\n // کلاس کانتینر برای اعمال متغیرهای CSS\r\n <div className={clsx(styles.container, styles.chatWindow)}>\r\n {/* هدر */}\r\n <div style={{ padding: '16px', borderBottom: '1px solid var(--ai-border)', display: 'flex', alignItems: 'center', gap: '8px', background: '#f9fafb' }}>\r\n <Bot size={20} />\r\n <span style={{ fontWeight: 600 }}>{title}</span>\r\n </div>\r\n\r\n {/* لیست پیام‌ها */}\r\n <div className={styles.messageList}>\r\n {messages.map((msg, index) => (\r\n <MessageBubble key={index} message={msg} />\r\n ))}\r\n {isLoading && (\r\n <div className={clsx(styles.messageRow, styles.assistant)}>\r\n <div className={clsx(styles.bubble, styles.assistant, styles.loading)}>\r\n <div className={styles.dot}></div>\r\n <div className={styles.dot}></div>\r\n <div className={styles.dot}></div>\r\n </div>\r\n </div>\r\n )}\r\n <div ref={messagesEndRef} />\r\n </div>\r\n\r\n {/* ورودی */}\r\n <div className={styles.inputArea}>\r\n <input\r\n className={styles.input}\r\n value={inputValue}\r\n onChange={(e) => setInputValue(e.target.value)}\r\n onKeyDown={handleKeyDown}\r\n placeholder=\"پیام خود را بنویسید...\"\r\n disabled={isLoading}\r\n />\r\n <button \r\n className={styles.sendButton} \r\n onClick={handleSendMessage}\r\n disabled={isLoading || !inputValue.trim()}\r\n >\r\n <Send size={18} />\r\n </button>\r\n </div>\r\n </div>\r\n );\r\n};","/* src/styles/chat.module.css */\r\n\r\n/* تعریف متغیرها برای اینکه کاربر بتواند رنگ‌ها را شخصی‌سازی کند */\r\n.container {\r\n /* رنگ‌های پیش‌فرض - کاربر می‌تواند این‌ها را در فایل CSS خود بازنویسی کند */\r\n --ai-primary: #2563eb; /* رنگ آبی استاندارد */\r\n --ai-primary-fg: #ffffff; /* رنگ متن روی دکمه‌ها */\r\n --ai-bg: #ffffff; /* رنگ پس‌زمینه چت */\r\n --ai-border: #e5e7eb; /* رنگ حاشیه */\r\n --ai-text: #1f2937; /* رنگ متن اصلی */\r\n --ai-text-secondary: #6b7280; /* رنگ متن فرعی */\r\n --ai-bot-bg: #f3f4f6; /* رنگ حباب پیام ربات */\r\n --ai-user-bg: #2563eb; /* رنگ حباب پیام کاربر */\r\n --ai-user-text: #ffffff; /* رنگ متن پیام کاربر */\r\n \r\n font-family: inherit; /* از فونت وبسایت کاربر ارث‌بری می‌کند */\r\n font-size: 16px;\r\n line-height: 1.5;\r\n box-sizing: border-box;\r\n}\r\n\r\n/* کانتینر اصلی چت */\r\n.chatWindow {\r\n display: flex;\r\n flex-direction: column;\r\n height: 500px;\r\n width: 100%;\r\n max-width: 400px;\r\n background-color: var(--ai-bg);\r\n border: 1px solid var(--ai-border);\r\n border-radius: 12px;\r\n overflow: hidden;\r\n box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);\r\n position: relative;\r\n}\r\n\r\n/* لیست پیام‌ها */\r\n.messageList {\r\n flex: 1;\r\n overflow-y: auto;\r\n padding: 16px;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 12px;\r\n scroll-behavior: smooth;\r\n}\r\n\r\n/* استایل هر پیام */\r\n.messageRow {\r\n display: flex;\r\n width: 100%;\r\n}\r\n\r\n.messageRow.user {\r\n justify-content: flex-end;\r\n}\r\n\r\n.messageRow.assistant {\r\n justify-content: flex-start;\r\n}\r\n\r\n.bubble {\r\n max-width: 80%;\r\n padding: 8px 12px;\r\n border-radius: 12px;\r\n font-size: 0.95em;\r\n word-wrap: break-word;\r\n}\r\n\r\n.bubble.user {\r\n background-color: var(--ai-user-bg);\r\n color: var(--ai-user-text);\r\n border-bottom-right-radius: 2px;\r\n}\r\n\r\n.bubble.assistant {\r\n background-color: var(--ai-bot-bg);\r\n color: var(--ai-text);\r\n border-bottom-left-radius: 2px;\r\n}\r\n\r\n/* ناحیه ورودی متن */\r\n.inputArea {\r\n padding: 12px;\r\n border-top: 1px solid var(--ai-border);\r\n display: flex;\r\n gap: 8px;\r\n background-color: var(--ai-bg);\r\n}\r\n\r\n.input {\r\n flex: 1;\r\n padding: 8px 12px;\r\n border: 1px solid var(--ai-border);\r\n border-radius: 8px;\r\n outline: none;\r\n font-family: inherit;\r\n}\r\n\r\n.input:focus {\r\n border-color: var(--ai-primary);\r\n}\r\n\r\n.sendButton {\r\n background-color: var(--ai-primary);\r\n color: var(--ai-primary-fg);\r\n border: none;\r\n border-radius: 8px;\r\n padding: 8px 12px;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n transition: opacity 0.2s;\r\n}\r\n\r\n.sendButton:disabled {\r\n opacity: 0.5;\r\n cursor: not-allowed;\r\n}\r\n\r\n.loading {\r\n display: flex;\r\n gap: 4px;\r\n padding: 4px;\r\n}\r\n\r\n.dot {\r\n width: 6px;\r\n height: 6px;\r\n background-color: #9ca3af;\r\n border-radius: 50%;\r\n animation: bounce 1.4s infinite ease-in-out both;\r\n}\r\n\r\n.dot:nth-child(1) { animation-delay: -0.32s; }\r\n.dot:nth-child(2) { animation-delay: -0.16s; }\r\n\r\n@keyframes bounce {\r\n 0%, 80%, 100% { transform: scale(0); }\r\n 40% { transform: scale(1); }\r\n}","// src/components/MessageBubble.tsx\r\nimport React from 'react';\r\nimport clsx from 'clsx'; // ابزاری عالی برای ترکیب کلاس‌های CSS\r\nimport styles from '../styles/chat.module.css';\r\nimport { Message } from '../types';\r\n\r\ninterface MessageBubbleProps {\r\n message: Message;\r\n}\r\n\r\nexport const MessageBubble: React.FC<MessageBubbleProps> = ({ message }) => {\r\n const isUser = message.role === 'user';\r\n\r\n return (\r\n <div\r\n className={clsx(\r\n styles.messageRow,\r\n isUser ? styles.user : styles.assistant\r\n )}\r\n >\r\n <div\r\n className={clsx(\r\n styles.bubble,\r\n isUser ? styles.user : styles.assistant\r\n )}\r\n >\r\n {/* فعلاً متن ساده را رندر می‌کنیم. بعداً می‌توانیم Markdown اضافه کنیم */}\r\n {message.content}\r\n </div>\r\n </div>\r\n );\r\n};"],"mappings":"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","names":["clsx","jsx"]}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "mehdi-ai-assistant",
3
+ "version": "0.0.1",
4
+ "description": "A professional AI Chatbot for Next.js/React powered by LangChain",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ },
14
+ "./react": {
15
+ "types": "./dist/react.d.ts",
16
+ "import": "./dist/react.mjs",
17
+ "require": "./dist/react.js"
18
+ },
19
+ "./dist/react.css": "./dist/react.css"
20
+ },
21
+ "files": [
22
+ "dist"
23
+ ],
24
+
25
+ "scripts": {
26
+ "build": "tsup",
27
+ "dev": "tsup --watch",
28
+ "lint": "tsc"
29
+ },
30
+ "keywords": [
31
+ "react",
32
+ "chatbot",
33
+ "ai",
34
+ "langchain",
35
+ "nextjs"
36
+ ],
37
+ "author": "",
38
+ "license": "ISC",
39
+ "peerDependencies": {
40
+ "react": ">=18",
41
+ "react-dom": ">=18"
42
+ },
43
+ "dependencies": {
44
+ "@langchain/core": "^1.1.8",
45
+ "@langchain/groq": "^1.0.2",
46
+ "@langchain/openai": "^1.2.0",
47
+ "clsx": "^2.1.1",
48
+ "lucide-react": "^0.562.0"
49
+ },
50
+ "devDependencies": {
51
+ "@types/react": "^18.0.0",
52
+ "@types/react-dom": "^18.0.0",
53
+ "react": "^18.0.0",
54
+ "react-dom": "^18.0.0",
55
+ "tsup": "^8.5.1",
56
+ "typescript": "^5.0.0"
57
+ }
58
+ }