Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/auto-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ jobs:
- name: Install dependencies
run: pnpm i --no-frozen-lockfile

# 步骤7: 构建组件
- name: Run Build Components
run: pnpm build
# 步骤7: 构建发布包
- name: Run Build Packages
run: pnpm build:packages

- name: Parse Publish tag
id: parse_tag
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/dispatch-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ jobs:
- name: Install dependencies
run: pnpm i --no-frozen-lockfile

# 步骤7: 构建组件
- name: Run Build Components
run: pnpm build
# 步骤7: 构建发布包
- name: Run Build Packages
run: pnpm build:packages

# 步骤8: 发布组件到NPM
- name: Publish components
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/pr-ci-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ jobs:
- name: Install dependencies
run: pnpm i --no-frozen-lockfile

- name: Build components
run: pnpm build
- name: Build packages
run: pnpm build:packages

- name: Build docs
run: pnpm -F docs build
Expand All @@ -55,6 +55,7 @@ jobs:
name: build-${{ github.event.pull_request.head.sha || github.sha }}
path: |
packages/components/dist
packages/chat/dist
packages/kit/dist
packages/svgs/dist
docs/dist
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/pr-ci-publish-packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ jobs:
run: |
npx pkg-pr-new publish \
./packages/components \
./packages/chat \
./packages/kit \
./packages/svgs \
--pnpm \
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@
"postbuild:docs": "node scripts/copy-playground.js packages/playground/dist docs/dist/playground",
"dev:playground": "pnpm -F @opentiny/tiny-robot-playground dev",
"build:playground": "pnpm -F @opentiny/tiny-robot-playground build",
"build:deps": "pnpm -F @opentiny/tiny-robot-* -F \"!@opentiny/tiny-robot-playground\" build",
"build:deps": "pnpm -F @opentiny/tiny-robot-* -F \"!@opentiny/tiny-robot-playground\" -F \"!@opentiny/tiny-robot-chat\" build",
"dev:components": "pnpm build:deps && pnpm -F @opentiny/tiny-robot dev",
"build:components": "pnpm build:deps && pnpm -F @opentiny/tiny-robot build",
"build:packages": "pnpm build:components && pnpm -F @opentiny/tiny-robot-chat build",
"dev:kit": "pnpm -F @opentiny/tiny-robot-kit dev",
"build:kit": "pnpm -F @opentiny/tiny-robot-kit build",
"build:svgs": "pnpm -F @opentiny/tiny-robot-svgs build",
Expand Down
190 changes: 190 additions & 0 deletions packages/chat/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
# @opentiny/tiny-robot-chat

`@opentiny/tiny-robot-chat` 是 TinyRobot 提供的高级聊天 UI 包,基于 `@opentiny/tiny-robot`(基础组件库)和 `@opentiny/tiny-robot-kit`(数据层工具包)构建。
它提供开箱即用的完整聊天页面,也支持逐步深入的白盒定制。

## 安装

```bash
pnpm add @opentiny/tiny-robot-chat
```

需要同时安装 peer dependencies:

```bash
pnpm add @opentiny/tiny-robot @opentiny/tiny-robot-kit vue markstream-vue
```

## 基本用法

### 引入样式

```ts
import '@opentiny/tiny-robot-chat/style'
```

### 开箱即用(TrChat)

传入一个 `TrChatConfig` 配置对象,即可渲染完整聊天页面:

```vue
<template>
<TrChat :config="chatConfig" />
</template>

<script setup lang="ts">
import { TrChat, type TrChatConfig } from '@opentiny/tiny-robot-chat'

const chatConfig: TrChatConfig = {
request: {
providers: {
openai: {
type: 'openai-compatible',
endpoint: '/api/chat/completions',
},
},
models: [{ id: 'gpt-4o-mini', label: 'GPT-4o Mini', providerId: 'openai' }],
defaultModelId: 'gpt-4o-mini',
},
ui: {
brand: { title: '我的助手' },
welcome: { title: '你好!有什么可以帮你的?' },
},
}
</script>
```

## 三层入口

包提供三个官方入口层级,按定制深度递进:

### 1. TrChat — 黑盒入口

适合快速接入,传入 `TrChatConfig` 即可。

```vue
<TrChat :config="config" />
```

### 2. TrChat.Root + TrChat.Page — 白盒页面

适合需要自己创建 runtime 但保留官方页面组合的场景。

```vue
<TrChat.Root :runtime="runtime" :ui="ui">
<TrChat.Page />
</TrChat.Root>
```

使用 `createRuntimeFromConfig(config)` 从配置创建 runtime:

```ts
import { createRuntimeFromConfig } from '@opentiny/tiny-robot-chat'

const { runtime, ui, dispose } = createRuntimeFromConfig(config)
```

### 3. TrChat.Root + primitives — 细粒度组合

适合需要完全控制页面结构的场景,使用公开的 primitive 组件自由拼装。

```vue
<TrChat.Root :runtime="runtime" :ui="ui">
<TrChat.Layout>
<TrChat.Header title="我的助手" />
<TrChat.MessageList />
<TrChat.Footer>
<TrChat.Attachments />
<TrChat.Sender />
</TrChat.Footer>
</TrChat.Layout>
</TrChat.Root>
```

### 高级:TrChat.Provider — 自定义 transport

适合需要使用包的 UI 和聊天编排能力,但自带 transport / 数据层的团队。

```vue
<TrChat.Provider :transport-adapter="myAdapter">
<TrChat.Layout>
<TrChat.Header />
<TrChat.MessageList />
<TrChat.Footer>
<TrChat.Sender />
</TrChat.Footer>
</TrChat.Layout>
</TrChat.Provider>
```

## 配置域

`TrChatConfig` 按功能域组织:

| 配置域 | 职责 |
| --- | --- |
| `request` | 模型列表、默认模型、transport 配置 |
| `conversation` | 初始消息、持久化策略 |
| `ui` | 品牌、欢迎区、外观、内容布局、i18n 文案 |
| `sender` | 输入框占位符、模式、字数限制、语音 |
| `attachments` | 附件上传、列表配置 |
| `messages` | 消息操作、feedback、渲染器、transform |
| `history` | 历史记录启用、默认展开 |
| `workspace` | 工作区视图、左右区域配置 |
| `lifecycle` | `beforeSend` / `afterReceive` / `error` 钩子 |

## 公开组件

| 组件 | 说明 |
| --- | --- |
| `TrChat` | 黑盒入口(含 `.Root` / `.Page` / `.Provider` 等子组件) |
| `TrChat.Layout` | 聊天布局容器 |
| `TrChat.WorkspaceLayout` | 工作区布局(含侧边栏) |
| `TrChat.Header` | 聊天头部 |
| `TrChat.Welcome` | 欢迎区 |
| `TrChat.MessageList` | 消息列表 |
| `TrChat.Footer` | 底部区域 |
| `TrChat.Sender` | 输入框 |
| `TrChat.Attachments` | 附件区 |
| `TrChat.History` | 历史记录 |
| `TrChatFeedback` | 消息反馈(独立导出) |
| `TrMcpTrigger` | MCP 触发器(独立导出) |

## 验证命令

```bash
# 类型检查
pnpm -F @opentiny/tiny-robot-chat type-check

# 构建
pnpm -F @opentiny/tiny-robot-chat build
```

## 目录结构

```
Comment thread
SonyLeo marked this conversation as resolved.
src/
entry/ # 入口组件(TrChat、TrChatRoot、TrChatPage、TrChatProvider)
components/ # UI 组件
page-regions/ # 默认页面区域(Header/Body/Footer Region、ChatPageContent)
workspace/ # 工作区布局(WorkspaceShell、LeftSheet、RightSheet 等)
attachments/ # 附件
feedback/ # 消息反馈
history/ # 历史记录
mcp/ # MCP 触发器和面板
model-selector/ # 模型选择器
renderers/ # 消息渲染器(Error、Edit、ToolCalls、Markdown 等)
shared/ # 共享组件(ConditionalThemeProvider)
runtime/
config/ # createRuntimeFromConfig、config entry、provider resolution
core/ # normalizeRuntime、messageIdentity
engine/ # useChatKit、useChatConversation、useChatMessages、useChatRequest
transport/ # openaiCompatibleTransport
features/ # feature registry
shared/
context/ # chatUiContext、injection keys
messages/ # i18n 文案(CHAT_MESSAGES)
utils/ # 工具函数
types/ # 类型定义(component、config、runtime、message、workspace 等)
styles/ # CSS 样式
```
53 changes: 53 additions & 0 deletions packages/chat/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
"name": "@opentiny/tiny-robot-chat",
"version": "0.4.2",
"type": "module",
"main": "./dist/index.js",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.js",
"types": "./dist/index.d.ts"
},
"./internal": {
"import": "./dist/internal.js",
"types": "./dist/internal.d.ts"
},
"./style": {
"default": "./dist/style.css"
}
},
"files": [
"dist"
],
"sideEffects": [
"./dist/style.css"
],
"scripts": {
"dev": "vue-tsc && vite build --watch",
"build": "vue-tsc && vite build",
"type-check": "vue-tsc --noEmit"
},
"peerDependencies": {
"vue": "^3.3.11",
"markstream-vue": "^0.0.9-beta.0",
"@opentiny/tiny-robot": "workspace:*",
"@opentiny/tiny-robot-kit": "workspace:*"
},
"dependencies": {
"@floating-ui/dom": "^1.7.5",
"@opentiny/tiny-robot-svgs": "workspace:*",
"@vueuse/core": "^13.1.0",
"markdown-it": "^14.1.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.5.2",
"less": "^4.2.2",
"typescript": "^5.2.2",
"vite": "^5.0.8",
"vite-plugin-dts": "^4.5.3",
"vue": "^3.3.11",
"vue-tsc": "^2.2.8"
}
}
14 changes: 14 additions & 0 deletions packages/chat/src/components/ChatFooter.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<script setup lang="ts">
defineOptions({ name: 'TrChatFooter' })
</script>

<template>
<div class="tr-chat__footer">
<div class="tr-chat__footer-inner">
<div v-if="$slots.extra" class="tr-chat__footer-extra">
<slot name="extra" />
</div>
<slot />
</div>
</div>
</template>
Loading
Loading