ai-chat-ui-kit 0.1.0 → 0.1.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.
Files changed (96) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +4 -7
  3. package/package.json +8 -4
  4. package/.eslintrc.cjs +0 -74
  5. package/.github/actions/screenshot/action.yml +0 -35
  6. package/.github/workflows/pages.yml +0 -46
  7. package/docs/README.md +0 -176
  8. package/docs/api/components.md +0 -344
  9. package/docs/api/core.md +0 -349
  10. package/docs/chat-style-1-minimal.html +0 -78
  11. package/docs/chat-style-2-neon.html +0 -74
  12. package/docs/chat-style-3-glass.html +0 -73
  13. package/docs/chat-style-4-terminal.html +0 -84
  14. package/docs/chat-style-5-gradient.html +0 -69
  15. package/docs/chat-style-6-corporate.html +0 -116
  16. package/docs/examples/basic-chat.md +0 -291
  17. package/docs/examples/custom-plugins.md +0 -431
  18. package/docs/examples/multi-model.md +0 -466
  19. package/docs/guide/api-adapters.md +0 -431
  20. package/docs/guide/getting-started.md +0 -244
  21. package/docs/guide/headless-mode.md +0 -508
  22. package/docs/guide/plugins.md +0 -416
  23. package/docs/guide/themes.md +0 -327
  24. package/docs/index.html +0 -256
  25. package/docs/theme-preview-1-minimal.html +0 -74
  26. package/docs/theme-preview-2-neon.html +0 -73
  27. package/docs/theme-preview-3-glass.html +0 -77
  28. package/docs/theme-preview-4-terminal.html +0 -86
  29. package/docs/theme-preview-5-gradient.html +0 -79
  30. package/docs/theme-preview-6-corporate.html +0 -71
  31. package/examples/index.html +0 -414
  32. package/examples/react-app/App.tsx +0 -131
  33. package/examples/react-app/index.html +0 -12
  34. package/examples/react-app/main.tsx +0 -15
  35. package/examples/react-app/package.json +0 -24
  36. package/examples/vue-app/index.html +0 -12
  37. package/examples/vue-app/package.json +0 -22
  38. package/examples/vue-app/src/App.vue +0 -145
  39. package/examples/vue-app/src/main.ts +0 -9
  40. package/packages/components/package.json +0 -25
  41. package/packages/components/src/chat/chat.css +0 -80
  42. package/packages/components/src/chat/chat.ts +0 -236
  43. package/packages/components/src/index.ts +0 -36
  44. package/packages/components/src/input/input.css +0 -52
  45. package/packages/components/src/input/input.ts +0 -116
  46. package/packages/components/src/markdown/markdown.css +0 -118
  47. package/packages/components/src/markdown/markdown.ts +0 -229
  48. package/packages/components/src/message/message.css +0 -56
  49. package/packages/components/src/message/message.ts +0 -72
  50. package/packages/components/src/styles/global.css +0 -43
  51. package/packages/components/src/tool-call/tool-call.css +0 -98
  52. package/packages/components/src/tool-call/tool-call.ts +0 -171
  53. package/packages/components/src/types.ts +0 -55
  54. package/packages/components/src/utils/helpers.ts +0 -128
  55. package/packages/components/tsconfig.json +0 -25
  56. package/packages/components/tsup.config.ts +0 -18
  57. package/packages/core/package.json +0 -47
  58. package/packages/core/pnpm-lock.yaml +0 -2032
  59. package/packages/core/pnpm-workspace.yaml +0 -2
  60. package/packages/core/src/api/adapters.ts +0 -717
  61. package/packages/core/src/api/base.ts +0 -210
  62. package/packages/core/src/api/index.ts +0 -54
  63. package/packages/core/src/index.ts +0 -93
  64. package/packages/core/src/parser/latex.ts +0 -274
  65. package/packages/core/src/parser/markdown.test.ts +0 -58
  66. package/packages/core/src/parser/markdown.ts +0 -206
  67. package/packages/core/src/parser/mermaid.ts +0 -276
  68. package/packages/core/src/plugins/PluginManager.ts +0 -232
  69. package/packages/core/src/plugins/builtin.ts +0 -406
  70. package/packages/core/src/store/ChatStore.ts +0 -163
  71. package/packages/core/src/store/ModelConfigStore.ts +0 -136
  72. package/packages/core/src/store/ToolCallStore.ts +0 -164
  73. package/packages/core/src/store/base.ts +0 -75
  74. package/packages/core/src/types/index.ts +0 -133
  75. package/packages/core/tsup.config.ts +0 -18
  76. package/packages/themes/package.json +0 -33
  77. package/packages/themes/src/corporate/index.ts +0 -52
  78. package/packages/themes/src/corporate/theme.css +0 -228
  79. package/packages/themes/src/glass/index.ts +0 -52
  80. package/packages/themes/src/glass/theme.css +0 -237
  81. package/packages/themes/src/gradient/index.ts +0 -53
  82. package/packages/themes/src/gradient/theme.css +0 -218
  83. package/packages/themes/src/index.ts +0 -13
  84. package/packages/themes/src/minimal/index.ts +0 -52
  85. package/packages/themes/src/minimal/theme.css +0 -198
  86. package/packages/themes/src/neon/index.ts +0 -52
  87. package/packages/themes/src/neon/theme.css +0 -233
  88. package/packages/themes/src/terminal/index.ts +0 -52
  89. package/packages/themes/src/terminal/theme.css +0 -235
  90. package/packages/themes/src/types.ts +0 -10
  91. package/packages/themes/src/vite-env.d.ts +0 -9
  92. package/packages/themes/tsup.config.ts +0 -21
  93. package/pnpm-workspace.yaml +0 -4
  94. package/tsconfig.json +0 -27
  95. package/vite.config.ts +0 -25
  96. package/vitest.config.ts +0 -28
@@ -1,118 +0,0 @@
1
- /**
2
- * @generated-by AI: edenxpzhang
3
- * @generated-date 2026-05-13
4
- */
5
- :host {
6
- display: block;
7
- }
8
-
9
- .markdown-content {
10
- line-height: 1.6;
11
- }
12
-
13
- .markdown-content h1 {
14
- font-size: 2em;
15
- margin: 0.67em 0;
16
- font-weight: 600;
17
- }
18
-
19
- .markdown-content h2 {
20
- font-size: 1.5em;
21
- margin: 0.83em 0;
22
- font-weight: 600;
23
- }
24
-
25
- .markdown-content h3 {
26
- font-size: 1.17em;
27
- margin: 1em 0;
28
- font-weight: 600;
29
- }
30
-
31
- .markdown-content p {
32
- margin: 0.5em 0;
33
- }
34
-
35
- .markdown-content code {
36
- background-color: var(--ai-bg-secondary, #f5f5f5);
37
- padding: 2px 6px;
38
- border-radius: 4px;
39
- font-family: 'Courier New', monospace;
40
- font-size: 0.9em;
41
- }
42
-
43
- .markdown-content pre {
44
- background-color: var(--ai-bg-secondary, #f5f5f5);
45
- padding: 12px;
46
- border-radius: var(--ai-border-radius, 8px);
47
- overflow-x: auto;
48
- margin: 0.5em 0;
49
- }
50
-
51
- .markdown-content pre code {
52
- background-color: transparent;
53
- padding: 0;
54
- }
55
-
56
- .markdown-content blockquote {
57
- border-left: 4px solid var(--ai-border, #e8e8e8);
58
- padding-left: 12px;
59
- margin: 0.5em 0;
60
- color: var(--ai-text-secondary, #666666);
61
- }
62
-
63
- .markdown-content ul,
64
- .markdown-content ol {
65
- padding-left: 2em;
66
- margin: 0.5em 0;
67
- }
68
-
69
- .markdown-content a {
70
- color: var(--ai-primary, #1677ff);
71
- text-decoration: none;
72
- }
73
-
74
- .markdown-content a:hover {
75
- text-decoration: underline;
76
- }
77
-
78
- .markdown-content table {
79
- border-collapse: collapse;
80
- width: 100%;
81
- margin: 0.5em 0;
82
- }
83
-
84
- .markdown-content th,
85
- .markdown-content td {
86
- border: 1px solid var(--ai-border, #e8e8e8);
87
- padding: 8px 12px;
88
- text-align: left;
89
- }
90
-
91
- .markdown-content th {
92
- background-color: var(--ai-bg-secondary, #f5f5f5);
93
- font-weight: 600;
94
- }
95
-
96
- /* Mermaid 图表容器 */
97
- .mermaid-container {
98
- margin: 1em 0;
99
- padding: 12px;
100
- background-color: var(--ai-bg, #ffffff);
101
- border: 1px solid var(--ai-border, #e8e8e8);
102
- border-radius: var(--ai-border-radius, 8px);
103
- overflow-x: auto;
104
- text-align: center;
105
- }
106
-
107
- /* Latex 公式 */
108
- .latex-formula {
109
- font-style: italic;
110
- padding: 0 4px;
111
- }
112
-
113
- .latex-block {
114
- display: block;
115
- text-align: center;
116
- margin: 1em 0;
117
- font-size: 1.2em;
118
- }
@@ -1,229 +0,0 @@
1
- /**
2
- * @generated-by AI: edenxpzhang
3
- * @generated-date 2026-05-13
4
- */
5
-
6
- import { LitElement, html, css } from 'lit';
7
- import { customElement, property } from 'lit/decorators.js';
8
- import './markdown.css';
9
-
10
- // 简单的 Markdown 解析器(等待 core 包完成后替换为实际导入)
11
- function parseMarkdown(content: string): string {
12
- let html = content;
13
-
14
- // 代码块
15
- html = html.replace(/```(\w+)?\n([\s\S]*?)```/g, '<pre><code>$2</code></pre>');
16
-
17
- // 行内代码
18
- html = html.replace(/`([^`]+)`/g, '<code>$1</code>');
19
-
20
- // 标题
21
- html = html.replace(/^### (.*$)/gm, '<h3>$1</h3>');
22
- html = html.replace(/^## (.*$)/gm, '<h2>$1</h2>');
23
- html = html.replace(/^# (.*$)/gm, '<h1>$1</h1>');
24
-
25
- // 粗体
26
- html = html.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>');
27
-
28
- // 斜体
29
- html = html.replace(/\*(.*?)\*/g, '<em>$1</em>');
30
-
31
- // 链接
32
- html = html.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" target="_blank">$1</a>');
33
-
34
- // 列表
35
- html = html.replace(/^- (.*$)/gm, '<li>$1</li>');
36
- html = html.replace(/(<li>.*<\/li>)/s, '<ul>$1</ul>');
37
-
38
- // 段落
39
- html = html.replace(/^(?!<[a-z]).*$/gm, '<p>$&</p>');
40
- html = html.replace(/<p><(h[1-6]|pre|ul|ol|blockquote|table)/g, '<$1');
41
- html = html.replace(/<\/(h[1-6]|pre|ul|ol|blockquote|table)><\/p>/g, '</$1>');
42
-
43
- return html;
44
- }
45
-
46
- // 检测是否包含 Mermaid 图表
47
- function hasMermaid(content: string): boolean {
48
- return /```mermaid/.test(content);
49
- }
50
-
51
- // 检测是否包含 Latex 公式
52
- function hasLatex(content: string): boolean {
53
- return /\$.*?\$|\\\(.*?\\\)|\\\[.*?\\\]/.test(content);
54
- }
55
-
56
- @customElement('ai-markdown')
57
- export class AiMarkdown extends LitElement {
58
- static styles = css`
59
- :host {
60
- display: block;
61
- }
62
-
63
- .markdown-content {
64
- line-height: 1.6;
65
- }
66
-
67
- .markdown-content h1 {
68
- font-size: 2em;
69
- margin: 0.67em 0;
70
- font-weight: 600;
71
- }
72
-
73
- .markdown-content h2 {
74
- font-size: 1.5em;
75
- margin: 0.83em 0;
76
- font-weight: 600;
77
- }
78
-
79
- .markdown-content h3 {
80
- font-size: 1.17em;
81
- margin: 1em 0;
82
- font-weight: 600;
83
- }
84
-
85
- .markdown-content p {
86
- margin: 0.5em 0;
87
- }
88
-
89
- .markdown-content code {
90
- background-color: var(--ai-bg-secondary, #f5f5f5);
91
- padding: 2px 6px;
92
- border-radius: 4px;
93
- font-family: 'Courier New', monospace;
94
- font-size: 0.9em;
95
- }
96
-
97
- .markdown-content pre {
98
- background-color: var(--ai-bg-secondary, #f5f5f5);
99
- padding: 12px;
100
- border-radius: var(--ai-border-radius, 8px);
101
- overflow-x: auto;
102
- margin: 0.5em 0;
103
- }
104
-
105
- .markdown-content pre code {
106
- background-color: transparent;
107
- padding: 0;
108
- }
109
-
110
- .markdown-content blockquote {
111
- border-left: 4px solid var(--ai-border, #e8e8e8);
112
- padding-left: 12px;
113
- margin: 0.5em 0;
114
- color: var(--ai-text-secondary, #666666);
115
- }
116
-
117
- .markdown-content ul,
118
- .markdown-content ol {
119
- padding-left: 2em;
120
- margin: 0.5em 0;
121
- }
122
-
123
- .markdown-content a {
124
- color: var(--ai-primary, #1677ff);
125
- text-decoration: none;
126
- }
127
-
128
- .markdown-content a:hover {
129
- text-decoration: underline;
130
- }
131
-
132
- .markdown-content table {
133
- border-collapse: collapse;
134
- width: 100%;
135
- margin: 0.5em 0;
136
- }
137
-
138
- .markdown-content th,
139
- .markdown-content td {
140
- border: 1px solid var(--ai-border, #e8e8e8);
141
- padding: 8px 12px;
142
- text-align: left;
143
- }
144
-
145
- .markdown-content th {
146
- background-color: var(--ai-bg-secondary, #f5f5f5);
147
- font-weight: 600;
148
- }
149
-
150
- .mermaid-container {
151
- margin: 1em 0;
152
- padding: 12px;
153
- background-color: var(--ai-bg, #ffffff);
154
- border: 1px solid var(--ai-border, #e8e8e8);
155
- border-radius: var(--ai-border-radius, 8px);
156
- overflow-x: auto;
157
- text-align: center;
158
- }
159
-
160
- .latex-formula {
161
- font-style: italic;
162
- padding: 0 4px;
163
- }
164
-
165
- .latex-block {
166
- display: block;
167
- text-align: center;
168
- margin: 1em 0;
169
- font-size: 1.2em;
170
- }
171
- `;
172
-
173
- @property({ type: String })
174
- content = '';
175
-
176
- @property({ type: Array })
177
- plugins: string[] = [];
178
-
179
- render() {
180
- const hasMermaidContent = hasMermaid(this.content);
181
- const hasLatexContent = hasLatex(this.content);
182
-
183
- return html`
184
- <div class="markdown-content">
185
- ${hasMermaidContent && this.plugins.includes('mermaid')
186
- ? html`<div class="mermaid-container">Mermaid 图表(需要集成 Mermaid.js)</div>`
187
- : ''}
188
- ${hasLatexContent && this.plugins.includes('latex')
189
- ? html`<div class="latex-block">Latex 公式(需要集成 KaTeX 或 MathJax)</div>`
190
- : ''}
191
- <div>${this.renderMarkdown()}</div>
192
- </div>
193
- `;
194
- }
195
-
196
- private renderMarkdown() {
197
- const htmlContent = parseMarkdown(this.content);
198
- return html`<div .innerHTML=${this.sanitizeHtml(htmlContent)}></div>`;
199
- }
200
-
201
- private sanitizeHtml(html: string): string {
202
- // 简单的 HTML 清理,防止 XSS
203
- // 在生产环境中应使用 DOMPurify 等库
204
- const temp = document.createElement('div');
205
- temp.innerHTML = html;
206
-
207
- // 移除 script 标签
208
- const scripts = temp.querySelectorAll('script');
209
- scripts.forEach(script => script.remove());
210
-
211
- // 移除危险的 on* 属性
212
- const allElements = temp.querySelectorAll('*');
213
- allElements.forEach(el => {
214
- Array.from(el.attributes).forEach(attr => {
215
- if (attr.name.startsWith('on')) {
216
- el.removeAttribute(attr.name);
217
- }
218
- });
219
- });
220
-
221
- return temp.innerHTML;
222
- }
223
- }
224
-
225
- declare global {
226
- interface HTMLElementTagNameMap {
227
- 'ai-markdown': AiMarkdown;
228
- }
229
- }
@@ -1,56 +0,0 @@
1
- /**
2
- * @generated-by AI: edenxpzhang
3
- * @generated-date 2026-05-13
4
- *
5
- * 兜底样式 —— 实际视觉由主题接管
6
- */
7
-
8
- ai-message {
9
- display: block;
10
- }
11
-
12
- ai-message .ai-message {
13
- display: flex;
14
- gap: 8px;
15
- max-width: 80%;
16
- }
17
-
18
- ai-message .ai-message--user {
19
- flex-direction: row-reverse;
20
- margin-left: auto;
21
- }
22
-
23
- ai-message .ai-message--assistant {
24
- margin-right: auto;
25
- }
26
-
27
- ai-message .ai-message__avatar {
28
- width: 32px;
29
- height: 32px;
30
- border-radius: 50%;
31
- display: flex;
32
- align-items: center;
33
- justify-content: center;
34
- font-size: 13px;
35
- flex-shrink: 0;
36
- }
37
-
38
- ai-message .ai-message__content {
39
- padding: 10px 14px;
40
- border-radius: 8px;
41
- line-height: 1.5;
42
- word-break: break-word;
43
- }
44
-
45
- ai-message .ai-message__time {
46
- font-size: 11px;
47
- opacity: 0.55;
48
- margin-top: 4px;
49
- }
50
-
51
- ai-message .ai-message__tool-calls {
52
- margin-top: 8px;
53
- display: flex;
54
- flex-direction: column;
55
- gap: 8px;
56
- }
@@ -1,72 +0,0 @@
1
- /**
2
- * @generated-by AI: edenxpzhang
3
- * @generated-date 2026-05-13
4
- */
5
-
6
- import { LitElement, html } from 'lit';
7
- import { customElement, property } from 'lit/decorators.js';
8
- import './message.css';
9
-
10
- // 导入共享类型
11
- import { Message } from '../types.js';
12
-
13
- @customElement('ai-message')
14
- export class AiMessage extends LitElement {
15
- @property({ type: Boolean })
16
- headless = true;
17
-
18
- @property({ type: Object })
19
- message?: Message;
20
-
21
- @property({ type: String })
22
- theme = 'default';
23
-
24
- // 默认 light DOM,让外部主题 CSS 能命中
25
- createRenderRoot() {
26
- if (this.headless) {
27
- return this;
28
- }
29
- return super.createRenderRoot();
30
- }
31
-
32
- render() {
33
- if (!this.message) {
34
- return html``;
35
- }
36
-
37
- const isUser = this.message.role === 'user';
38
- const roleModifier = isUser ? 'ai-message--user' : 'ai-message--assistant';
39
- const avatarText = isUser ? '我' : 'AI';
40
- const time = new Date(this.message.timestamp).toLocaleTimeString('zh-CN', {
41
- hour: '2-digit',
42
- minute: '2-digit',
43
- });
44
-
45
- return html`
46
- <div class="ai-message ${roleModifier}">
47
- <div class="ai-message__avatar">${avatarText}</div>
48
- <div class="ai-message__body">
49
- <div class="ai-message__content">${this.message.content}</div>
50
- ${this.message.toolCalls && this.message.toolCalls.length > 0
51
- ? html`
52
- <div class="ai-message__tool-calls">
53
- ${this.message.toolCalls.map(
54
- (toolCall) => html`
55
- <ai-tool-call .toolCall=${toolCall}></ai-tool-call>
56
- `
57
- )}
58
- </div>
59
- `
60
- : ''}
61
- <div class="ai-message__time">${time}</div>
62
- </div>
63
- </div>
64
- `;
65
- }
66
- }
67
-
68
- declare global {
69
- interface HTMLElementTagNameMap {
70
- 'ai-message': AiMessage;
71
- }
72
- }
@@ -1,43 +0,0 @@
1
- /**
2
- * @generated-by AI: edenxpzhang
3
- * @generated-date 2026-05-13
4
- */
5
- :host {
6
- /* 颜色 */
7
- --ai-primary: #1677ff;
8
- --ai-bg: #ffffff;
9
- --ai-bg-secondary: #f5f5f5;
10
- --ai-text: #333333;
11
- --ai-text-secondary: #666666;
12
- --ai-border: #e8e8e8;
13
- --ai-user-msg-bg: #1677ff;
14
- --ai-user-msg-text: #ffffff;
15
- --ai-ai-msg-bg: #f5f5f5;
16
- --ai-ai-msg-text: #333333;
17
-
18
- /* 尺寸 */
19
- --ai-border-radius: 8px;
20
- --ai-spacing: 12px;
21
-
22
- /* 字体 */
23
- --ai-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
24
- --ai-font-size: 14px;
25
- }
26
-
27
- /* 全局样式 */
28
- .ai-chat-container {
29
- font-family: var(--ai-font-family);
30
- font-size: var(--ai-font-size);
31
- color: var(--ai-text);
32
- background-color: var(--ai-bg);
33
- }
34
-
35
- .ai-message-user {
36
- background-color: var(--ai-user-msg-bg);
37
- color: var(--ai-user-msg-text);
38
- }
39
-
40
- .ai-message-ai {
41
- background-color: var(--ai-ai-msg-bg);
42
- color: var(--ai-ai-msg-text);
43
- }
@@ -1,98 +0,0 @@
1
- /**
2
- * @generated-by AI: edenxpzhang
3
- * @generated-date 2026-05-13
4
- */
5
- :host {
6
- display: block;
7
- }
8
-
9
- .tool-call {
10
- border: 1px solid var(--ai-border, #e8e8e8);
11
- border-radius: var(--ai-border-radius, 8px);
12
- overflow: hidden;
13
- font-size: 12px;
14
- }
15
-
16
- .tool-call-header {
17
- display: flex;
18
- align-items: center;
19
- gap: 8px;
20
- padding: 8px 12px;
21
- background-color: var(--ai-bg-secondary, #f5f5f5);
22
- cursor: pointer;
23
- user-select: none;
24
- }
25
-
26
- .tool-call-header:hover {
27
- background-color: var(--ai-border, #e8e8e8);
28
- }
29
-
30
- .tool-call-status {
31
- width: 8px;
32
- height: 8px;
33
- border-radius: 50%;
34
- }
35
-
36
- .tool-call-status-pending {
37
- background-color: #faad14;
38
- }
39
-
40
- .tool-call-status-running {
41
- background-color: #1677ff;
42
- animation: pulse 1.5s infinite;
43
- }
44
-
45
- .tool-call-status-completed {
46
- background-color: #52c41a;
47
- }
48
-
49
- .tool-call-status-failed {
50
- background-color: #ff4d4f;
51
- }
52
-
53
- @keyframes pulse {
54
- 0%, 100% { opacity: 1; }
55
- 50% { opacity: 0.5; }
56
- }
57
-
58
- .tool-call-name {
59
- flex: 1;
60
- font-weight: 500;
61
- color: var(--ai-text, #333333);
62
- }
63
-
64
- .tool-call-toggle {
65
- color: var(--ai-text-secondary, #666666);
66
- font-size: 10px;
67
- }
68
-
69
- .tool-call-details {
70
- padding: 12px;
71
- border-top: 1px solid var(--ai-border, #e8e8e8);
72
- background-color: var(--ai-bg, #ffffff);
73
- }
74
-
75
- .tool-call-section {
76
- margin-bottom: 8px;
77
- }
78
-
79
- .tool-call-section:last-child {
80
- margin-bottom: 0;
81
- }
82
-
83
- .tool-call-label {
84
- font-weight: 500;
85
- color: var(--ai-text-secondary, #666666);
86
- margin-bottom: 4px;
87
- }
88
-
89
- .tool-call-content {
90
- background-color: var(--ai-bg-secondary, #f5f5f5);
91
- padding: 8px;
92
- border-radius: 4px;
93
- overflow-x: auto;
94
- font-family: 'Courier New', monospace;
95
- font-size: 11px;
96
- white-space: pre-wrap;
97
- word-break: break-all;
98
- }