@faiber/faiber-chat

中文文档
2.8.0发布于 2026/11/14TypeScriptES Module近 30 天下载 3762

Direct, group, channel, and AI conversations with members, messages, threads, reactions, read cursors, realtime events, and Agentic-backed AI turns.

原始使用文档
文档目录23 节
  1. Install
  2. Configure
  3. API surface
  4. Authentication and authorization
  5. Inputs, queries, responses, and transport
  6. Errors and cancellation
  7. Realtime through Sockudo
  8. Workspace assistant roles
  9. Compact microphone capture and speech playback
  10. Live dictation and earlier speech playback
  11. Curriculum-bound teacher
  12. Session interactions and Charge
  13. Attachment upload and download
  14. Scoped note assistance and hands-free speech
  15. Assigned-contact chat and per-user unread state (0.24.1)
  16. Source summary observation policy
  17. Assistant edits and durable Knowledge policy reconciliation
  18. Context selection limits
  19. Response records and message history
  20. Mark a received message unread
  21. Guided workspace clarification
  22. User-owned connectors, documents and streaming
  23. Responsive assistant replies

@faiber/faiber-chat

Direct, group, channel, and AI conversations with members, messages, threads, reactions, read cursors, realtime events, and Agentic-backed AI turns.

Install

npm install @faiber/faiber-chat

Configure

import { FaiberClient, MemoryTokenProvider } from "@faiber/sdk-core";
import { ChatApi } from "@faiber/faiber-chat";

const tokens = new MemoryTokenProvider();
const client = new FaiberClient("chat", {
  domains: { chat: process.env.FAIBER_CHAT_URL! },
  tokenProvider: tokens,
  axios: { timeout: 15_000, withCredentials: true },
});
const api = new ChatApi(client);

const conversation = await api.createConversation({
  kind: "direct",
  member_ids: [recipientUserId],
});
await api.sendMessage(conversation.data.data.id, { content: { text: "Hello" } });

API surface

This package exposes 69 source-extracted operations from the chat service. Common workflows have concise methods on api; every registered backend route is also available as a named function on api.operations. Generated operation input, query, response, path, verb, and permission contracts are exported from operations.types.

Operation registration describes transport coverage; it does not certify deployed behavior or current authorization. Packaged provenance.json identifies the selected service source and contract checksums.

AI turns are executed and billed by Infera Agentic; Chat only coordinates conversation context and reconciliation. The events endpoint is an SSE stream and can be requested with normal SDK authorization headers.

Authentication and authorization

Use a TokenProvider to forward the signed-in user's Bearer token, or enable withCredentials for secure HttpOnly cookie sessions. Permission requirements copied from service route guards are included in each operation's JSDoc. The SDK does not embed API keys, credentials, localhost URLs, sandbox hosts, or production hosts.

Inputs, queries, responses, and transport

All methods return the complete Axios response, including status, headers, and request IDs. Request bodies and query objects are named exported interfaces. Nested pagination uses keys such as page[number] and page[size] where required by the service. Standard Axios request options, headers, timeouts, adapters, interceptors, and AbortSignal cancellation are supported as the final argument.

Generic REST resources are capability-guarded. Calling a legacy method that the service does not register throws UnsupportedOperationError before sending a request instead of producing a backend 405.

Errors and cancellation

try {
  await api.client.get("/health", undefined, { signal: AbortSignal.timeout(5_000) });
} catch (error) {
  // Axios errors retain response.status and the service error body.
}

Use @faiber/faiber-ts-sdk when one application needs multiple Faiber services with one configuration.

Realtime through Sockudo

Use subscribeRealtime from @faiber/sdk-core for private Sockudo subscriptions. Chat configuration comes from ChatApi.realtimeConfig(conversationId) and authorization from ChatApi.realtimeAuth; both require conversation membership and chat:read. Notification configuration and authorization use MessengerApi.operations.notificationNotificationsRealtimeConfigGet and notificationNotificationsRealtimeAuthPost with notification:self:read; the backend permits only the signed-in recipient's channel. Keep these service responsibilities separate. Reload persisted records on subscription/reconnect, close subscriptions on logout, and keep all Sockudo secrets server-side. See the core subscription example.

speechStatus() reports configured local transcription availability. transcribe(audioBlob, 'fa', {signal}) accepts up to 8 MiB of WebM, Ogg, MP4, or WAV audio and returns editable transcript text; it never sends a chat message automatically. Both require chat:ai; invalid audio returns 400, unavailable services return 502, and cancellation uses normal Axios request signals.

Workspace assistant roles

Discover server-managed roles with chat.workspaceAssistant.roles(), and choose role === 'action' for editable capture or role === 'chat' for workspace conversation. Create a conversation with that binding's assistant_id; catalog order has no role meaning. WorkspaceAssistantResult describes structured message metadata: answers, drafts, clarification, citations, and review proposals, with the Knowledge release and retrieval timestamp. A proposal is a preview until Task confirms approval.

Administrators with assistant:manage can call workspaceAssistant.bind(role, input). Enabling requires a compatible published Knowledge contract; expected_version prevents overwriting another administrator's binding. Ordinary discovery requires assistant:read. Both methods preserve Axios responses, cookie/Bearer authentication, cancellation, and error status.

Workspace role bindings use knowledge_slug: "2done-action" or "2done-chat" for the corresponding role. Each role base pins its shared contract release. Structured results expose knowledge_release_id and optional shared_knowledge_release_id for diagnosis. The legacy 2done-assistants slug remains in the client type for older service deployments; new role bindings require the role-specific slug.

Compact microphone capture and speech playback

import { createSpeechRecorder } from '@faiber/faiber-chat';

// Call from a user gesture. Reuse your authenticated ChatApi instance.
const capture = await createSpeechRecorder({ signal: controller.signal });
const chunks: Blob[] = [];
capture.recorder.ondataavailable = ({ data }) => { if (data.size) chunks.push(data); };
capture.recorder.onstop = async () => {
  capture.dispose();
  if (controller.signal.aborted) return;
  const audio = new Blob(chunks, { type: capture.mimeType });
  const response = await chat.transcribe(audio, 'fa', { signal: controller.signal });
  console.log(response.data.data.text);
};
capture.recorder.onerror = () => capture.dispose();
capture.recorder.start(1000);
// Stop on the user's button or your duration limit (2Done uses 60 seconds):
// capture.recorder.stop();
// Cancel/unmount: controller.abort(); capture.dispose();

const voice = await chat.synthesize(
  { text: 'Your next task is ready.', language: 'en', format: 'mp3' },
  { signal: controller.signal },
);
// voice.data is a Blob. Revoke any URL.createObjectURL URL after playback.

createSpeechRecorder is browser-only but safe to import in Node. It requests native noise suppression, echo cancellation, automatic gain control and mono input. It prefers 32 kbit/s Opus in WebM/Ogg; supported MP4/AAC browsers use 64 kbit/s. It applies gentle 80 Hz/8 kHz speech filters when Web Audio is available and otherwise retains native capture. Browser support and actual capture/encoding settings vary; settings, filtered, mimeType and targetBitsPerSecond expose the result. At the target bitrate, one minute is approximately 240 KB for Opus or 480 KB for AAC, plus container overhead. No large encoder/model download is required, and pauses/quiet words are not removed.

Options include audioBitsPerSecond (16,000–64,000), filter: false and an abort signal. Permission/device errors are preserved; cancellation rejects pending setup with AbortError once microphone acquisition resolves and releases any acquired tracks. Always call dispose() on cancellation/unmount and after receiving the final recording chunk. The helper neither uploads nor transcribes automatically and does not enforce a duration or byte limit; enforce the STT service's limits in your application.

synthesize requests MP3 by default: mono, 24 kHz, 64 kbit/s. Explicit format: 'wav' retains lossless output for processing. MP3 requires a service deployment that supports this format; mismatched upstream formats fail rather than being mislabeled. Speech responses are private and not cacheable. Authentication, Axios response metadata, cancellation, and provider billing follow the configured Chat client. Check the returned Blob MIME type rather than assuming a filename extension. Uploading an existing compressed recording through transcribe does not re-encode it in the browser.

Live dictation and earlier speech playback

import { startLiveDictation, playSpeech } from '@faiber/faiber-chat';

// `chat` is your authenticated ChatApi. Start after a microphone button click.
const dictation = await startLiveDictation(chat, {
  language: 'fa',
  signal: abortController.signal,
  onPartial: text => { provisionalText = text; }, // replace, do not append
  onError: error => { showError(error.message); },
});
const finalText = await dictation.finish(); // stop button: insert this editable revision once
// Or dictation.cancel() when leaving the page.

// Starts the first phrase while the next phrase is synthesized; MP3 transfer.
await playSpeech(chat, { text: 'سلام. این برنامه امروز شماست.', language: 'fa' }, {
  signal: abortController.signal,
  onPhase: phase => { playbackState = phase; },
});

Live dictation uploads each compressed chunk once through the normal authenticated FaiberClient transport. liveSpeech() exposes the underlying ordered start/push/finish/cancel operations with full Axios responses. Sessions are caller/organization-bound and expire; recordings are limited to 60 seconds and buffered upload to 128 KiB. Current live support requires the configured Persian Shenava model, an available streaming worker lane, and WebM/Ogg Opus. Unsupported language/codec or busy capacity rejects start; applications may fall back to createSpeechRecorder() and transcribe(). Never treat provisional text as a saved message. Finalization can revise earlier words. Abort and unmount should cancel.

playSpeech() is browser-only progressive phrase synthesis, not provider-level audio streaming. It preserves text order, preloads up to three phrases and schedules ready audio on the browser audio clock. Synthesis slower than playback can still cause buffering. Individual phrases use the configured voice and its billing rules. Synthesis, decode, and playback errors reject the promise; cancellation stops playback and in-flight requests. Short utterances still depend on model generation latency.

Opt into client-side replay with { cacheScope: tenantId + ':' + userId + ':' + voiceRevision, persistCache: true }. The latest utterance's compressed MP3 sections are kept in browser IndexedDB (up to 16 MiB); replay and page reload reuse available sections without TTS requests. Omit persistCache for memory-only replay, or omit cacheScope to disable caching. This stores private audio on the device: only enable persistence when your product permits it. Include the service, tenant, authenticated user and voice revision in the scope. Call exported clearSpeechPlaybackCache() on logout, and abort active playback first. Changing text, language or scope replaces the last entry. Cancelled playback retains already generated sections; a replay requests only missing sections. Storage denial falls back to memory. No server cache is introduced.

Curriculum-bound teacher

chat.learning.ask(runId, { question, idempotency_key }) requires chat:ai and ownership of the LMS run. The server loads the published objective and verified results; callers cannot choose a learner, model, curriculum, tools, or progress. Reuse the idempotency key only when retrying exactly the same question.

chat.learning.history(runId, { signal }) requires chat:read and the same run ownership. It returns at most 40 messages in chronological order as { id, role: 'user' | 'teacher', text } in response.data.data. It does not expose conversation management, internal prompts, metadata, or other learners' records. Both methods retain Axios status/headers and accept cancellation options.

Session interactions and Charge

Chat resolves a session conversation's room from its server-owned binding. Clients cannot remove or change that binding. When the sandbox enables the funded economy, every message and AI request in a bound conversation requires a stable client_id. Reuse it with the same content after an uncertain timeout. A completed retry returns the stored result; a conflicting or pending request is rejected without authorizing another interaction.

import type { SessionEventMessageInput } from '@faiber/faiber-chat';

const reaction: SessionEventMessageInput = {
  message_type: 'session_event',
  client_id: crypto.randomUUID(),
  content: { event_type: 'reaction', emoji: '👏', text: '👏' },
};
await chat.sendMessage(conversationId, reaction, { signal });

Use event_type: 'hand' and state: 'raised' | 'lowered' for hand state. Ordinary text uses sendMessage with its own client_id; AI uses sendAiMessage with a SessionAiMessageInput. Chat authorizes these through RabbitMQ before saving or generating content. Charge costs, independent cooldowns and message burst limits come from sandbox policy and are enforced server-side. Lowering a hand uses the configured lower_hand policy. Axios responses, membership permissions, Bearer/cookie authentication and cancellation remain unchanged. Cancellation does not prove that a server reservation was released; retry with the same ID to reconcile an uncertain result.

Attachment upload and download

upload_url is a short-lived signed storage URL for uploading, not downloading. The attachment's cdn_url is storage metadata and may not be publicly readable. For private homework-chat files, use downloadAttachment(id) instead of opening cdn_url. It forwards the configured Bearer token or secure cookies to Chat, which verifies conversation access before fetching private storage bytes.

Reserve with createAttachment, then call uploadAttachmentContent(id, bytes, { onUploadProgress, signal }). This authenticated route sends raw binary with application/octet-stream (100 MiB maximum). Bytes must match the reserved size and checksum. completeAttachment(id) still finalizes existing presigned uploads.

const response = await api.downloadAttachment(attachmentId, { signal });
const blob = response.data; // Blob in browsers and Node 18+
const previewUrl = URL.createObjectURL(blob);
// Use previewUrl in an image/viewer or a download anchor.
// Revoke only after the viewer/download has finished, never immediately after clicking.
URL.revokeObjectURL(previewUrl);

Downloads use authenticated Chat access (chat:read), preserve Axios metadata, and support onDownloadProgress. Use api.operations.routesDownloadAttachmentGet for raw bytes. Access failures return 403/404; storage failures return 502. Upload completion requires chat:write.

Scoped note assistance and hands-free speech

Workspace chat accepts a selected space_id, optional note_id, and explicitly chosen knowledge_project_ids. A selected import_id refers to a Task extraction preview; Chat rechecks its permission and version before including evidence and before delivery. Imported text cannot grant tools or permissions. Research must be explicitly requested and enabled by the deployment; it consumes the configured research and response limits. Changes are returned as Task proposals and require review and versioned approval.

The typed assistantVoice API supports start/push/finish/cancel, bounded PCM transcription and synthesis. Use stable request IDs and monotonically increasing chunk sequence numbers for retries. It requires an accessible project and configured audio allowance. Release microphone capture on exit/backgrounding and preserve partial text on network failure. Speech settings can select independent language-specific recognition and output models; an English request never silently uses a Persian-only model. Live recognition requires an available compatible Faiber worker or relay. All calls retain authenticated transport, Axios metadata and cancellation options.

Internal operations require a trusted server credential and current tenant scope. Never call them from a browser or expose the service credential to application users.

Assigned-contact chat and per-user unread state (0.24.1)

Use chat.personal.conversations() and unreadCount() for authenticated conversation summaries and actual incoming unread-message counts. Own/deleted messages do not count; do not subtract sequence numbers. Initialize personal.events() before a snapshot and resume from its cursor. Long polls default to 35 seconds; realtimeConfig and realtimeAuth authorize only the current organization's private user channel. All methods require chat:read, preserve Axios responses/authentication and support cancellation.

When the instance enables LMS assigned-contact policy, direct creation/sending requires the current student/teacher/support relationship. Obtain eligible contacts from LMS rather than a public directory. Existing pair deduplication remains authoritative. A revoked assignment retains readable history but disables sending. Generic member routes cannot expand these direct conversations. Message retries reuse client_id with identical content; a changed body conflicts. Read updates are monotonic, cannot exceed accessible message sequences, and should be sent only after visible messages render.

A web application should keep its chat provider above route changes, preserving conversation/draft/scroll state. Safe Markdown must disable raw HTML and unsafe URL schemes; copying and URL/email/phone detection belong in the client. Chat unread counts and Messenger notification counts are separate.

The personal summary, unread-count, cursor-event and private-channel authorization methods require the current member's chat:read permission. Personal methods remain under /api/v1/me/*; internal LMS notification-context reads use a separate server-only x-infera-lms-token and return identifiers/read state without private message content. Do not expose the service token in a browser.

Source summary observation policy

Use the source-owned administration API with a Bearer token authorized for chat:summary_access:manage. The service rechecks current IDP authority on every request; a cookie-only session or caller-supplied user headers do not grant access. Enabling also validates the configured collector's current chat:summary:read permission. This policy does not grant model access or change the collector binding.

const observed = await sdk.chat.operations.nativeSummaryAccessStatus();
await sdk.chat.operations.saveNativeSummaryAccessPolicy({
  enabled: false,
  expected_revision: observed.data.data.policy?.revision ?? 0,
  reason: "Pause collection for review",
});
await sdk.chat.operations.revokeNativeSummaryObject({
  object_id: sourceObjectId,
  reason: "Exclude this source object",
});
await sdk.chat.operations.restoreNativeSummaryObject(sourceObjectId, {
  reason: "Restore after review",
});

A stale policy revision returns 409; reload and review before retrying. Reasons are required and limited to 1024 Unicode characters. Revocations survive policy disabling and re-enabling. The restore operation sends its reason as a JSON DELETE body. Successful saves return the current binding, policy and counts; pending objects can remain until background reconciliation finishes. Axios responses, errors, headers, timeouts and abort signals are preserved. The separate /mcp transport uses signed scoped grants and rejects browser origins; these REST methods do not provide an MCP session.

After a transport error or 503, reload current status before retrying a mutation: the source can commit its policy/revocation before a later status read or reconciliation fails. Use the reloaded revision and review the resulting state.

Assistant edits and durable Knowledge policy reconciliation

managedAssistant(id) returns a typed ManagedAssistantDetailResponse. Capture version and expected_knowledge_policy_revision when opening the edit draft. updateAssistant requires expected_version, expected_knowledge_policy_revision, and a caller-created non-nil configuration_id UUID. createAssistant also requires a configuration_id. Preserve the UUID with the exact request across uncertain responses. Do not generate a new operation automatically or refresh either revision while resubmitting a stale draft.

assistantPolicyOperation(configurationId) returns the tenant-scoped retained AssistantConfigurationIntentResponse. reconcileAssistantPolicy accepts an AssistantPolicyReconciliationInput with action recover or cancel. Recovery checks the authoritative Knowledge outcome before exact idempotent dispatch/application. Current assistant:manage is required after restart; grants and credentials are never retained. An administrator can apply an existing committed outcome or cancel an undispatched intent after its original actor loses authority. Cancellation writes a remote tombstone, blocking a delayed old request.

Pending intents block competing edits and deletion. An already applied operation cannot be cancelled as absent. Terminal repeats return their immutable original result. An assistant changed outside the protocol produces a review conflict; the SDK never infers success or overwrites it. Review/recovery belongs on an explicit routed Manage page. A generic raw JSON form is not a completed workflow.

Generated equivalents are routesGetManagedAssistantGet, routesCreateAssistantPost, routesUpdateAssistantPut, routesGetPolicyOperationGet and routesReconcilePolicyOperationPost. Managed detail, retained intent and reconciliation DTOs are exported from the Chat package. These are canonical v1 methods; no private Summary runner credentials or authority DTOs are browser APIs.

Context selection limits

Configured assistant levels constrain the owning-conversation context request on the selected Chat/Knowledge revisions. Null or omitted request levels do not remove a configured ceiling. Older deployed services may not enforce this behavior; verify the deployed receiver before relying on it.

Selected-assistant group slugs are stored configuration, but forwarding and descendant-versus-exact matching are not fully implemented consistently. Do not use those settings as an authorization boundary or promise that unclassified results are excluded. Server-side current tenant, permissions and base bindings remain authoritative.

Knowledge's selected-media chunk cap applies after governance and deduplication across both packing paths (default 8, valid range 1–20). Query limits are not a strict combined count across all returned lanes. Expansion and reranking settings can be retained as requested values while runtime capabilities report unsupported/not applied; storing a flag does not enable an algorithm or provider. Inspect returned trace/capability information instead of assuming these features ran.

Response records and message history

Conversation records include nullable agent_slug, assistant_id, agentic_thread_id, legacy identifiers and deletion timestamps. Members expose state, notification_level and last_read_sequence. react returns a ChatReaction, including message_id, user_id, emoji and created_at. It does not return a message record. Message history includes an attachments array on each row and meta: { limit, has_more }; other ordinary Chat responses serialize meta: null. before and after are exclusive sequence bounds, ordered newest first. The backend accepts q but currently does not apply a text filter.

The generated routesSynthesizePost operation returns raw audio bytes and accepts lowercase mp3 or wav; omitted/null format selects WAV on the server. The curated synthesize helper explicitly requests MP3 by default. Raw routesTranscribePost requires { language: 'auto' | 'en' | 'fa' } and an audio Content-Type matching the supplied bytes, such as audio/webm or audio/wav; it is not a multipart upload.

Workspace bindings accept 2done-action for the action role and 2done-chat for chat. The shared 2done-assistants slug is not a valid binding request. Speech settings preserve language overrides when language_models is omitted or null; pass {} to clear them. Version conflicts require reloading and reviewing the draft.

Provider catalogs, source-import data, model-generated fitness plans and runtime schema/UI values are forwarded as JSON by the selected backend without a local schema check. Their exported types document that behavior. Catalog listings and assistant lookup scope follow the selected backend: active/managed assistant lists and the public assistant lookup do not apply an organization predicate in their repositories. Do not infer tenant isolation from an SDK type or a catalog result.

Mark a received message unread

api.markRead(conversationId, {sequence: message.sequence, message_id: message.id, unread: true}, {signal}) rewinds only the caller's personal read position to before that received message. This can make later received messages unread too. It does not retract read receipts already delivered to senders. Own, deleted, nonexistent, and other-conversation messages are rejected. Stop automatic visible-message read updates before invoking this action, and resume when the user deliberately reopens the conversation.

Guided workspace clarification

WorkspaceAssistantResult may include optional questions on any user-facing reply, including normal answers, drafts, proposals and clarifications. The named WorkspaceQuestion / WorkspaceQuestionOption types support single_select and multi_select, with up to four questions and eight options per question. The existing clarification type names remain available for compatibility.

Send one chosen value, or all selected values for a multi-select question, as one ordinary AI message in the same conversation. Choices are display data, not commands, identity grants or mutation approvals. The usual composer can still accept a typed reply; voice clients can accept spoken answers. Questions are optional and do not imply ambiguity. Backend rollout is required for the model to emit these additive hints; text-only older results remain valid.

Managed assistant create/update requests accept reasoning_effort (none, low, medium, high, or max). Choose only values declared in the model catalog’s reasoning_levels; default_reasoning_effort describes the structured-workflow default when known. On update, omit this field to retain the saved override or send null to restore automatic behavior. Managed detail includes the saved override and the captured Knowledge policy revision required for a safe save.

User-owned connectors, documents and streaming

ChatApi.integrations discovers connectors, starts OAuth, selects authorized Faiber projects, invokes schema-declared tools, and reads/approves/cancels durable actions. A write tool returns an approval action; only call approve() after an explicit user decision. Provider result JSON is untrusted data. Document extraction accepts a Blob and content type under server limits and requires chat:ai. history({q,cursor,limit}) searches the current user's AI history with server pagination; clear the cursor when the search changes.

ChatApi.streaming.audio(input, {signal}) and .messages(id, input, {signal}) return full Axios responses containing WHATWG NDJSON streams. Parse complete newline-delimited VoiceAudioFrame or AssistantReplyFrame records. Require the terminal done/complete frame, handle error frames, and cancel/release the reader on teardown. Pre-stream HTTP failures are ordinary Axios errors. Speech previews are not proof that a requested task mutation has completed. These APIs inherit configured cookie/Bearer authentication and never create another transport.

Responsive assistant replies

Set stream_progress: true in the message input and use chat.streaming.messages() with readAssistantReplyStream(response.data) to consume typed reply frames. progress is a waiting notice, not an answer or a successful mutation; display or speak it separately from cumulative text. Only complete confirms the final reply. The decoder rejects interrupted or malformed streams and cancels its reader when iteration stops. Pass an AbortSignal to the request to cancel transport work.

Published assistant-contract metadata may include a WorkspaceReadPolicy under read_policy. Its bounded, anchored patterns can prefetch authorized Task records or answer clear read-only lookups directly. Note queries require a selected space; ambiguous matches retain the assistant's normal tools, editing, and approval flow. Only trusted published configuration supplies these rules, never message inputs.

Conversation summaries may include participants, with each peer's user ID and nullable first_name_fa, last_name_fa, first_name_en, and last_name_en. Use the preferred locale and fall back to the other locale or your generic participant label. Names are resolved under the caller's Profile permissions; unavailable profiles do not block the conversation list. Older Chat deployments omit this optional field. No email or phone data is included.

版本与发布记录

@faiber/faiber-chat 共发布 60 个版本,首次发布于 2026/07/23;过去 12 个月发布了 60 个版本。

版本发布日期距今
2.8.0latest2026/11/14今天
2.7.02026/11/059 天前
2.5.02026/11/049 天前
2.4.02026/11/0310 天前
2.3.02026/11/0211 天前
2.2.02026/11/0212 天前

关于 @faiber/faiber-chat 的常见问题

@faiber/faiber-chat 是什么?

Direct, group, channel, and AI conversations with members, messages, threads, reactions, read cursors, realtime events, and Agentic-backed AI turns.

如何安装 @faiber/faiber-chat?

在项目目录运行 npm install @faiber/faiber-chat,或使用 pnpm add / yarn add / bun add。

@faiber/faiber-chat 支持 TypeScript 吗?

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

@faiber/faiber-chat 支持 ESM 还是 CommonJS?

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

@faiber/faiber-chat 可以商用吗?

@faiber/faiber-chat 使用 未声明 许可。package.json 没有声明许可证。没有许可证的代码默认保留全部权利,商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括,不构成法律意见,请以许可原文为准。

@faiber/faiber-chat 的下载量有多少?

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

@faiber/faiber-chat 还在维护吗?

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