Bắt đầu

Thư viện ứng dụng khách Minds

Gọi Builder API với kiểu TypeScript. Khóa Builder API đại diện cho tài khoản của bạn. Access token OAuth đại diện cho người dùng đã đăng nhập qua Minds Connect.

@animocabrands/minds-client-lib là cách bạn gọi Builder API từ ứng dụng. Hầu hết builder bắt đầu với Minds CLI trên tài khoản của mình, rồi dùng thư viện này để đưa cùng những lệnh gọi đó lên production với kiểu TypeScript: nhắn tin, waitForReply, sự kiện SSE và thao tác tài khoản. Ứng dụng trình duyệt để người dùng đăng nhập dùng Minds Connect SDK . Connect bọc client này và làm mới access token của người dùng trước mỗi lệnh gọi.
Dùng từ backend Node, hoặc trong trình duyệt qua Connect. Giao diện, thương hiệu và luồng người dùng vẫn là của bạn; client xử lý HTTP có kiểu và streaming tới api.build. Với khóa Builder API, hoàn tất Cách bắt đầu , kiểm tra bằng CLI, rồi nối các ví dụ bên dưới. Với đăng nhập của người dùng, đăng ký OAuth client và làm theo hướng dẫn Connect.

Cài đặt

Ứng dụng Node cần Node 22+. Connect tải cùng gói này trong trình duyệt.
npm install @animocabrands/minds-client-lib

Xác thực

Lệnh gọi tài khoản và nhắn tin nhận access token OAuth hoặc khóa Builder API. Khi có cả hai, access token được ưu tiên và client gửi Authorization: Bearer. Khi không có token, client gửi X-Api-Key. X-Access-Key đã ngừng hỗ trợ, vui lòng không dùng. Thư viện không đọc .env. Hãy đọc MINDS_BUILDER_API_KEY trong ứng dụng (hằng BUILDER_API_KEY_ENV) rồi truyền vào. Ứng dụng trình duyệt nên dùng Minds Connect SDK . oauth.client của Connect cung cấp token mới trước mỗi request. Trên backend, sau khi trình duyệt đã đăng nhập người dùng, truyền access token đó vào createMindsClient. Khóa Builder API hành động với tư cách tài khoản builder của bạn. Access token hành động với tư cách người dùng đã đăng nhập, và chỉ trong các scope họ đã cấp. Khóa Builder API:
import { BUILDER_API_KEY_ENV, createMindsClient } from "@animocabrands/minds-client-lib";
 
const builderApiKey = process.env[BUILDER_API_KEY_ENV];
if (!builderApiKey) throw new Error(`${BUILDER_API_KEY_ENV} is not set`);
 
const client = createMindsClient({ builderApiKey });
Access token OAuth:
import { createMindsClient } from "@animocabrands/minds-client-lib";
 
const client = createMindsClient({ accessToken });
client.setAccessToken(nextToken);
client.setAccessToken(null);
setAccessToken(null) hoặc chuỗi rỗng xóa token. Các lệnh gọi sau đó dùng khóa Builder API, nếu khóa đã được truyền lúc tạo client. getAccessToken chạy trước mỗi request HTTP hoặc SSE cần xác thực. Token nó trả về được ưu tiên hơn accessToken tĩnh cho request đó. Connect nối việc này trên oauth.client. Nếu hàm trả về null, client dùng lại token tĩnh hoặc khóa.
const client = createMindsClient({
  getAccessToken: async () => accessTokenFromYourSession,
});
Backend, khi phiên trình duyệt đã được thiết lập:
import { createMindsClient } from "@animocabrands/minds-client-lib";
 
const accessToken = req.headers.authorization?.replace(/^Bearer\s+/i, "");
const minds = await createMindsClient({ accessToken }).listMinds();
Hằng sốGiá trị
BUILDER_API_KEY_ENVMINDS_BUILDER_API_KEY
BUILDER_API_KEY_HEADERX-Api-Key

Tạo client

import { createMindsClient } from "@animocabrands/minds-client-lib";
 
const client = createMindsClient({ builderApiKey: yourBuilderApiKey });
// or: createMindsClient({ accessToken })
createMindsClient({}) chỉ hợp lệ với danh mục Bazaar công khai (client.bazaar.*). Phương thức cần xác thực báo MindsApiError với mã missing_builder_api_key tại thời điểm gọi nếu không có access token lẫn khóa Builder API, chứ không phải lúc khởi tạo. Tên mã lỗi giữ nguyên.

Tạo một Mind

Tên Mind là duy nhất. Gọi checkMindName trước (công khai, không cần thông tin xác thực) để kiểm tra tên đã được dùng chưa, rồi gọi awakenMind (cần khóa Builder API hoặc access token). id chọn loại Mind dựng sẵn để tạo. Gói không export danh mục. Chạy minds mind awaken --help trong Minds CLI để liệt kê từng loại kèm mô tả ngắn. Danh sách tương tự nằm trong tham chiếu API . Nếu tên đã được dùng hoặc id không hợp lệ, awakenMind ném MindsApiError. Ví dụ là một sales Mind tên J-Belfort. Bán cho tôi cây bút này.
const check = await client.checkMindName("J-Belfort");
if (!check.isAvailable) throw new Error("name taken");
 
const mind = await client.awakenMind({ name: "J-Belfort", id: "sales" });
await client.ensureConversation("main", mind.mindId);

Danh sách Minds

listMinds() trả về mọi Mind trên tài khoản của bạn (mindId, name, model, species, và các trường liên quan).
const minds = await client.listMinds();
const mindId = minds[0]?.mindId;
Với access token, listMinds() gọi GET /v1/users/{userId}/minds, lấy userId từ sub của token. Khóa Builder API vẫn gọi GET /v1/humans/{humanId}/minds. Truyền listMinds({ humanId }) để dùng đường dẫn humans.

Chi tiết Mind

getMind(mindId) trả về chi tiết đầy đủ - email, địa chỉ ví, chuỗi, loài, isEnabled, và nhiều thứ khác:
const detail = await client.getMind(mindId);
console.log(detail.email, detail.walletAddress, detail.chain);

Số dư và mức sử dụng Cognition

Mức sử dụng và số dư Cognition theo từng Mind tương ứng với các lệnh CLI. Minds tiêu tốn Cognition khi suy luận, chạy công cụ và thực hiện tác vụ tự chủ, chứ không chỉ khi trò chuyện. Cả hai phương thức đều nhận mindId (UUID) và một AbortSignal tùy chọn. Cognition là nguồn năng lượng cho khả năng suy luận, sử dụng công cụ và làm việc tự chủ của Mind. Sử dụng getCognitionUsage và getCognitionUsageByTool để theo dõi mức sử dụng theo thời gian và theo công cụ. Sử dụng getCognitionBalance để xem số dư Cognition còn lại:
const mindId = (await client.listMinds())[0]?.mindId;
if (!mindId) throw new Error("No Minds on this account");
 
const usage = await client.getCognitionUsage(mindId, { interval: "1d" });
console.log(usage.items); // [{ bucket, value }, ...]
 
const byTool = await client.getCognitionUsageByTool(mindId, { interval: "day" });
console.log(byTool.summary); // [{ tool, callCount, creditsUsed, ... }, ...]
console.log(byTool.timeline); // [{ tool, timeBucket, callCount, creditsUsed }, ...]
 
const balance = await client.getCognitionBalance(mindId);
console.log(balance.cognition);
Hai phương thức thống kê chấp nhận các khoảng thời gian khác nhau: getCognitionUsage nhận 1m, 5m, 15m, 1h, 1d, 1w, 1M; còn getCognitionUsageByTool chỉ nhận hour, day, week, month. Có thể dùng thêm startTime và endTime (định dạng ISO date-time) để giới hạn khoảng thời gian cho cả hai.

Trạng thái Mind

Kích hoạt hoặc vô hiệu hóa Mind mà không xóa nó:
await client.updateMindStatus(mindId, { isEnabled: false });
await client.updateMindStatus(mindId, { isEnabled: true });
updateMindStatus trả về { msg, result }.

Circles

Circle của một Mind là tập hợp các cộng tác viên của nó - con người và các Mind khác. getCircle trả về trực tiếp mảng CircleMember[]; addCircleMembers và removeCircleMembers trả về envelope CircleMutationResult kèm kết quả theo từng email và bản tóm tắt best-effort:
const members = await client.getCircle(mindId);
console.log(members.map((m) => m.email));
 
const added = await client.addCircleMembers(mindId, {
  emails: ["someone@company.com", "the.dude@hellominds.ai"],
  isActive: true,
});
console.log(added.items);
 
const removed = await client.removeCircleMembers(mindId, {
  emails: ["someone@company.com"],
});
console.log(removed.items);
Email của người có thể là bất kỳ địa chỉ nào; email của Mind kết thúc bằng @hellominds.ai. listCirclesForAccount() là một tiện ích gọi listMinds() sau đó gọi getCircle() song song cho từng Mind; hãy sử dụng tính năng này để có cái nhìn tổng quan trên toàn bộ tài khoản thay vì cho các đường dẫn hoạt động thường xuyên.

Danh mục Bazaar

Danh mục Bazaar công khai có sẵn dưới dạng client.bazaar, không cần API key. Dùng Bazaar để tra cứu ID (skillId, appId), sau đó trang bị các ID đó bằng các phương thức Mind equip bên dưới. Cấu trúc route nằm trong tham chiếu API ở mục Bazaar và Minds; CLI cũng cung cấp danh mục này qua minds bazaar. Các mục trong danh sách có thể kèm equippedCount - số Mind đã trang bị mục đó trên toàn nền tảng. Đây là mức độ phổ biến trên toàn nền tảng - hãy sử dụng listEquippedSkills / listEquippedApps cho tập trang bị theo từng Mind.
const catalog = createMindsClient({}).bazaar;
 
const skills = await catalog.listSkills({ search: "research", page: 1, pageSize: 25 });
const skill = await catalog.getSkill("skill_abc123");
 
const apps = await catalog.listApps({ search: "notion", tier: "verified" });
const app = await catalog.getApp("app_xyz789");
 
const result = await catalog.collectSearchResults({
  scanMax: 200,
  max: 50,
  sort: "equipped",
  fetchPage: (page, pageSize) => catalog.listSkills({ search: "agent", page, pageSize }),
  getEquippedCount: (s) => s.equippedCount ?? 0,
  getName: (s) => s.name,
  getCreatedAt: (s) => s.createdAt,
});
Các ứng dụng sử dụng appId và appName (không phải name). collectSearchResults tự động phân trang lên đến scanMax, áp dụng sắp xếp/lọc phía máy khách và báo cáo truncated khi số lượng quét được vượt quá max. sort: "equipped" sắp xếp theo equippedCount giảm dần (mức độ phổ biến trên nền tảng), chứ không phải theo trạng thái trang bị của từng Mind.

Trang bị kỹ năng và ứng dụng

Liệt kê, trang bị hoặc tháo trang bị kỹ năng và ứng dụng trên một Mind (yêu cầu khóa Builder API hoặc access token). Body sử dụng { ids: string[] }; các mutation trả về { results: [...] } với skillId / appId, isEquipped và changed (kết quả app có thể bao gồm cả appVersionId và version):
const equippedSkills = await client.listEquippedSkills(mindId);
await client.equipSkills(mindId, { ids: [skill.skillId] });
await client.unequipSkills(mindId, { ids: [skill.skillId] });
 
const equippedApps = await client.listEquippedApps(mindId);
await client.equipApps(mindId, { ids: [app.appId] });
await client.unequipApps(mindId, { ids: [app.appId] });
Khi cần duyệt danh mục, hãy tra cứu ID qua client.bazaar trước. Các kỹ năng được trang bị bao gồm source: mind cho kỹ năng từ danh mục / do Mind tạo, system cho kỹ năng nền tảng (ví dụ: Skill Architect).

Cuộc trò chuyện

Liên kết một bí danh (ví dụ: main) ổn định với một Mind trước khi nhắn tin:
await client.ensureConversation("main", mindId);
ensureConversation là idempotent, nếu bí danh đã tồn tại cho Mind đó, cuộc hội thoại hiện tại sẽ được trả về. Các trình trợ giúp cấp thấp hơn khi bạn tự quản lý bí danh:
const conversations = await client.listConversations();
const conversation = await client.getConversation("main");
await client.createConversation({ alias: "main", mindId });

Gửi và lịch sử

await client.sendMessage({ alias: "main", messageText: "Hello" });
 
const rows = await client.getHistory("main", { limit: 50 });
// rows[0] là mới nhất. Fingerprint cuối cùng → trang cũ hơn tiếp theo (trên wire là `before`).
const cursor = rows.at(-1)?.fingerprint;
const older = await client.getHistory("main", { cursor, limit: 50 });
getHistory trả về toàn bộ bản ghi hội thoại giữa con người và Mind, mới nhất trước (newest-first). Các hàng sử dụng senderType (1 = con người, 0 = Mind). SDK cursor (và after đã ngừng hỗ trợ) được gửi dưới dạng truy vấn before - trang tiếp theo cũ hơn (loại trừ). Cùng trường senderType này xuất hiện trên các sự kiện SSE từ subscribeEvents / eventsIterator / waitForReply. sendMessage yêu cầu alias và messageText. attachments tùy chọn chấp nhận các đối tượng outbound, ưu tiên url HTTPS công khai với fileName và mimeType:
await client.sendMessage({
  alias: "main",
  messageText: "Summarize this PDF in one sentence.",
  attachments: [
    {
      url: "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf",
      fileName: "dummy.pdf",
      mimeType: "application/pdf",
      extension: "pdf",
    },
  ],
});
Các URL hình ảnh sử dụng cùng một dạng (mimeType: "image/png", v.v.). Các phản hồi của Mind trên getHistory, waitForReply và các sự kiện SSE có thể bao gồm các Artifact inbound, ví dụ:
// One attachment on a Mind reply (PDF; artifact body truncated)
{
  artifactId: "7388b65d-144a-49ff-a4dc-cb7c23ded982",
  slug: "whale_watchtower_skill_artifact_1_0_5",
  logicalType: "document",
  mimeType: "application/pdf",
  extension: "pdf",
  artifact: "JVBERi0xLjQK...",
}
Gửi đi sử dụng content cho tải trọng nội tuyến; câu trả lời đến sử dụng artifact cho cùng một vai trò. slug và logicalType là các chuỗi tùy chọn, hãy coi các giá trị như là gợi ý, không phải là một enum cố định. Xem tham chiếu API để biết chi tiết về trường. getLatestHistoryFingerprint trả về fingerprint của tin nhắn mới nhất. Truyền nó dưới dạng afterFingerprint cho waitForReply để bạn chỉ chấp nhận các câu trả lời đến sau khi bạn gửi. Trang getHistory đầu tiên (không có con trỏ) đã là cửa sổ mới nhất - đừng truyền fingerprint đó dưới dạng cursor để mong đợi các hàng mới hơn.
Xác định Mind mà một bí danh đã nói chuyện lần cuối:
const mindId = await client.getMindIdForAlias("main");

Đợi phản hồi từ Mind

waitForReply lắng nghe trên luồng sự kiện trực tiếp trước, sau đó kiểm tra lịch sử định kỳ cho đến khi có phản hồi hoặc hết thời gian chờ.
const before = await client.getLatestHistoryFingerprint("main");
 
await client.sendMessage({ alias: "main", messageText: "Summarize our plan." });
 
const outcome = await client.waitForReply({
  alias: "main",
  timeoutMs: 180_000,
  afterFingerprint: before,
  sentMessageText: "Summarize our plan.",
});
 
if (!outcome.timedOut) {
  console.log(outcome.reply.messageText);
}
Sử dụng isReplyEvent từ gói khi bạn tự lọc các hàng SSE hoặc lịch sử.

Sự kiện trực tiếp (SSE)

Đăng ký với các lệnh gọi lại:
const sub = client.subscribeEvents({
  alias: "main",
  onEvent: (event) => {
    console.log(event.messageText);
  },
  onError: (err) => console.error(err),
});
 
// later
sub.close();
Hoặc sử dụng trình lặp không đồng bộ:
for await (const event of client.eventsIterator({ alias: "main" })) {
  console.log(event.fingerprint, event.messageText);
}
Truyền signal cho các tùy chọn trình lặp hoặc đăng ký để hủy khi quy trình của bạn tắt.

Lỗi

Các lệnh gọi HTTP thất bại sẽ báo lỗi MindsApiError kèm status, code và message. Gọi phương thức cần xác thực khi không có access token lẫn khóa Builder API sẽ báo missing_builder_api_key ngay khi gọi. 401/403 nghĩa là thông tin xác thực bị thiếu, hết hạn, bị thu hồi, hoặc scope mà người dùng chưa cấp. 429 có thể kèm hướng dẫn thử lại.

Phương thức

Khu vựcPhương thức
AuthsetAccessToken
AccountlistMinds
MindscheckMindName, awakenMind, getMind, updateMindStatus
CognitiongetCognitionUsage, getCognitionUsageByTool, getCognitionBalance
EquiplistEquippedSkills, equipSkills, unequipSkills, listEquippedApps, equipApps, unequipApps
CirclesgetCircle, addCircleMembers, removeCircleMembers, listCirclesForAccount
Bazaarbazaar.listSkills, bazaar.getSkill, bazaar.listApps, bazaar.getApp, bazaar.collectSearchResults
ConversationscreateConversation, listConversations, getConversation, ensureConversation, getMindIdForAlias
MessagingsendMessage, getHistory, getLatestHistoryFingerprint
ReplieswaitForReply, isReplyEvent, isReplyHistoryRow
EventssubscribeEvents, eventsIterator, parseSseChunk
Các kiểu (BuilderMind, Conversation, MessageRecord, MessagingEvent, CognitionBalance, BazaarSkill, BazaarApp, EquippedSkill, EquippedApp, CircleMember, CircleMutationResult, CognitionUsageResponse, CognitionUsageByToolResponse, UpdateMindStatusBody, UpdateMindStatusResult, CheckMindNameResult, AwakenMindResult, …), parseUserIdFromAccessToken và parseHumanIdFromBuilderApiKey được xuất từ entry của gói.