@asteby/metacore-ai-chat

中文文档
7.0.0发布于 2026/10/18Apache-2.0TypeScriptES Module近 30 天下载 1854

Metacore copilot chat — floating widget, chat panel, draggable FAB and an injectable chat client (HTTP, permissions, branding, suggestions)

原始使用文档
文档目录12 节
  1. Install
  2. What you inject
  3. Proposal format
  4. Markdown replies
  5. Channels: bot + agents + team
  6. Full screen
  7. Demo badge
  8. Accessibility and states
  9. Adopting it
  10. ops (ERP)
  11. gobiernos-ops
  12. Also exported

@asteby/metacore-ai-chat

Copilot chat for metacore apps: floating widget (draggable FAB), chat panel, starter prompts, proposals (approve/reject) and an injectable chat client. Everything app-specific is injected; the package imports no stores, API clients or routes.

Install

pnpm add @asteby/metacore-ai-chat @asteby/metacore-app-providers lucide-react

Tailwind must scan the package (same as other metacore UI packages):

@source "../node_modules/@asteby/metacore-ai-chat/dist/**/*.{js,mjs}";

What you inject

ConcernHow
HTTP clientcreateHttpChatClient(api, { basePath: '/chat' }) or your own ChatClient
Permissionspermissions={{ canChat, canDecideProposals }} (canChat: false hides the widget and shows a denied notice in CopilotChat)
Brandingbranding={{ name, mascotSkin, avatar }}; the mascot is Mascot from @asteby/metacore-app-providers
Suggestionssuggestions={[...]}, or omit to use useAgentSuggestions() (tenant agent_suggestions, neutral default)
Copylabels={{ ... }} partial override (Spanish defaults)

Default REST contract (createHttpChatClient):

  • POST {base}/send {message, session_id, attachments} -> {success, session_id, reply|response, proposals?}
  • GET {base}/sessions, GET {base}/history/:id
  • POST {base}/proposals/:id/decide {approve}

Different backend? Implement ChatClient (send required; listSessions, loadHistory, decideProposal optional).

Proposal format

A reply may carry proposals. Both shapes are accepted and normalized (normalizeProposal) on ChatClient.send, loadHistory and the HTTP client:

// A) display shape
{ "id": "p1", "title": "Archivar hallazgo", "summary": "Motivo…", "status": "pending" }
// B) action shape: title = "action · model", summary = compact JSON of payload
{ "id": "p2", "action": "archive", "model": "finding", "payload": { "id": 7 }, "status": "pending" }

id is required (string or number, coerced to string); status is pending (default) | approved | rejected. An explicit title/summary wins over the derived ones. Rows without id or without anything to show are dropped. action, model and payload are kept on the normalized proposal so decideProposal hosts can use them.

Markdown replies

AI replies render as safe Markdown + GFM (Markdown, also exported): headings, lists, tables (horizontal scroll), blockquotes, inline/blocked code with a copy button, links and images. Raw HTML is never rendered, dangerous URL schemes are dropped, external links open with noopener noreferrer, images are limited to http(s)/same-origin. Unterminated code fences are closed while a reply is typed in. Styled with theme tokens only (no typography plugin). Pass onLinkClick to CopilotProvider to route in-app links through your router (return true when handled).

Channels: bot + agents + team

Give the widget an adapter and it becomes a unified inbox. The package knows no endpoint or socket; you map your backend:

const channels: ChannelAdapter = {
  listChannels: () => api.get('/internal-chat/channels').then(toChannels),   // kind: 'bot' | 'agent' | 'team'
  loadMessages: (id) => api.get(`/internal-chat/channels/${id}/messages`).then(toMessages),
  send: (id, body) => api.post(`/internal-chat/channels/${id}/messages`, { body }).then(toMessage),
  markRead: (id) => api.post(`/internal-chat/channels/${id}/read`),
  subscribe: (on) => ws.subscribe('INTERNAL_CHAT_MESSAGE', (e) => on({ type: 'message', message: toMessage(e.payload) })),
}
<CopilotWidget channels={channels} fullscreenHref="/agent" />
  • The bot channel (your ChatClient) is injected first (includeBot={false} to omit). An agent channel with its own client: ChatClient gets the full AI chat (proposals, history); without one it is served by the adapter like a team thread.
  • Unread counts drive a FAB badge (live even while the panel is closed); the last opened channel is remembered.
  • subscribe events: message, unread, presence, channels (refetch).

Full screen

The header's expand button turns the widget into a viewport-filling surface (list + thread side by side from md up; phones always get it). Escape steps back: expanded → floating → closed. fullscreenHref / onOpenFullscreen add an "open full view" link for apps with their own workspace route. hidden removes the widget on routes that already show it.

Demo badge

The badge shows when CopilotProvider demo / CopilotWidget demo is set, or when the backend flags a reply with demo: true (createHttpChatClient reads demo / is_demo). Never leave it permanently on for real data.

Accessibility and states

  • CopilotWidget panel is role="dialog" (aria-label = branding name, aria-modal="false": the page stays usable). Focus moves to the composer on open and returns to the FAB on close; Escape closes (any CopilotChat with onClose).
  • Controls are at least 44x44px with a visible focus ring; animations honour prefers-reduced-motion.
  • Offline (navigator.onLine) shows a status banner and disables sending. Failed turns show an alert with labels.retry; loadHistory and decideProposal failures show an alert (history with retry) instead of failing silently.
  • demo on CopilotProvider (or CopilotChat) renders the labels.demo badge ("Datos demostrativos").
  • Optional session picker: <CopilotChat sessions={list} sessionId={id} onSelectSession={setId} /> (get list from client.listSessions()).

Adopting it

ops (ERP)

import { CopilotProvider, CopilotWidget, createHttpChatClient } from '@asteby/metacore-ai-chat'
import { api } from '@/lib/api'
import { useAuthStore } from '@/stores/auth-store'

const client = createHttpChatClient(api) // ops exposes /chat/send, /chat/sessions, /chat/history/:id

export function Copilot() {
  const canChat = useAuthStore((s) => s.can('chat.use')) // adapt to your permission check
  return (
    <CopilotProvider client={client} permissions={{ canChat }}>
      <CopilotWidget />
    </CopilotProvider>
  )
}

Mount <Copilot /> in the authenticated layout, replacing AIChatWidget. Not covered by this package yet (stay in ops until follow-up): voice/live mode, file upload, guided tours, team-chat embeds, chart/choropleth embeds, Sparks pill. Use the CopilotChat panel directly (/agent page) with className="h-full".

gobiernos-ops

<CopilotProvider
  client={createHttpChatClient(api, { basePath: '/api/v1/chat' })}
  branding={{ name: 'Gobi', mascotSkin: 'gobi-navy' }}
  permissions={{ canChat: hasPermission('copilot:use') }}
  suggestions={['Resumen del tablero', 'Hallazgos pendientes de revisión']}
>
  <CopilotWidget defaultPosition={{ bottom: 24, right: 24 }} />
</CopilotProvider>

If the gobiernos backend uses a different contract, pass a custom ChatClient. Use suggestions to avoid ERP-flavored prompts; omit it to inherit tenant branding.

Also exported

useChat (state machine), chatReducer, useDraggableFab / computePanelLayout, useRevealText, and the AGENT_* surface class constants (use theme tokens --surface-*, --elevation-*).

版本与发布记录

@asteby/metacore-ai-chat 共发布 13 个版本,首次发布于 2026/10/12;过去 12 个月发布了 13 个版本。

版本发布日期距今
7.0.0latest2026/10/1821 天前
6.0.02026/10/1821 天前
5.0.02026/10/1524 天前
4.0.02026/10/1425 天前
3.0.02026/10/1425 天前
2.0.02026/10/1326 天前

关于 @asteby/metacore-ai-chat 的常见问题

@asteby/metacore-ai-chat 是什么?

Metacore copilot chat — floating widget, chat panel, draggable FAB and an injectable chat client (HTTP, permissions, branding, suggestions)

如何安装 @asteby/metacore-ai-chat?

在项目目录运行 npm install @asteby/metacore-ai-chat,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:react(>=18)、react-dom(>=18)、lucide-react(>=0.460)、@asteby/metacore-app-providers(^153.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@asteby/metacore-ai-chat 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@asteby/metacore-ai-chat 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@asteby/metacore-ai-chat 可以商用吗?

@asteby/metacore-ai-chat 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@asteby/metacore-ai-chat 的下载量有多少?

根据 npm 官方下载统计,@asteby/metacore-ai-chat 在 2026/10/07 – 2026/11/05 这 30 天内被下载 1,854 次,日均约 62 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@asteby/metacore-ai-chat 还在维护吗?

最新版本 7.0.0 发布于 2026/10/18(21 天前);至今共发布 13 个版本,其中过去 12 个月发布了 13 个;首次发布于 2026/10/12。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。