npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@tacoreai/web-sdk

v1.30.0

Published

This file is for app server package, not the real npm package

Readme

@tacoreai/web-sdk

Tacore Web SDK for AI generated applications. This SDK provides tools to interact with Tacore's backend services for applications, including authentication, data, AI, and file storage.

Version

1.0.15

Installation

npm install @tacoreai/web-sdk

Usage

AppsAuthManager

示例略(保持原有章节)

AppsClient (Data & AI)

示例略(保持原有章节)

Apps Auth Session Refresh

AppsAuthManager 持有并刷新 Apps Auth session;AppsClient 只负责业务请求和 Authorization 头注入,不直接持有 refresh token。登录态业务应用必须在自身 AuthStore 中把所有 authenticated appsClient.invoke(...)appsClient.invokeAppServerAPI(...) 接到统一 session bridge:请求前调用 authManager.refreshSessionIfNeeded({ thresholdMs: 5 * 60 * 1000 }),把刷新后的 accessToken 同步给业务 AppsClient,请求返回 401 或 SESSION_EXPIRED 时强制 authManager.refreshSession({ force: true }) 后再同步并重试一次。refresh 失败才清理本地会话并提示重新登录,不能把过期 token 包装成“当前角色没有业务权限”。

const syncSessionToken = () => {
  const token = authManager.getAccessToken?.({ fallbackToStorage: true });
  if (token && typeof appsClient.setAccessToken === 'function') {
    appsClient.setAccessToken(token, { persist: false });
  }
};

const withFreshSession = async request => {
  await authManager.refreshSessionIfNeeded({ thresholdMs: 5 * 60 * 1000 });
  syncSessionToken();
  try {
    return await request();
  } catch (error) {
    const status = Number(error?.status || error?.statusCode || error?.response?.status || 0);
    if (status !== 401 && error?.code !== 'SESSION_EXPIRED') throw error;
    await authManager.refreshSession({ force: true });
    syncSessionToken();
    return request();
  }
};

const rawInvoke = appsClient.invoke.bind(appsClient);
appsClient.invoke = (apiName, params = {}) => withFreshSession(() => rawInvoke(apiName, params));

AppsClient (Assistant Runtime)

数字员工应用的业务无关运行机制应走 Apps Assistant Runtime。SDK 只做薄封装和请求头注入;应用仍负责岗位 SOP、应用内运行态 Skill、allowed tools、确认卡、AppServer 动作和业务模型。

const created = await client.invoke('assistant/runtime/sessions/create', {
  employeeCode: 'digital_sales',
  employeeName: '拓新数字销售',
  title: '临时任务',
});

const sessionId = created?.data?.session?.wyID;

await client.invoke('assistant/runtime/messages/append', {
  sessionId,
  message: {
    role: 'user',
    content: '把这段名片和聊天记录整理成线索候选表单',
    type: 'text',
  },
});

const repaired = await client.invoke('assistant/runtime/json/repair', {
  response: rawModelOutput,
  error: parseErrorMessage,
  expectedProtocol: '输出 type=tool_call | candidate | answer 的 JSON',
});

可用接口包括 assistant/runtime/sessions/list|create|open|update|archiveassistant/runtime/messages/appendassistant/runtime/json/repairassistant/runtime/context/compactassistant/runtime/actions/record。应用前端不要直接普通 CRUD assistant_sessionassistant_messageoperation_audit_log

AppsClient (Document PDF Render)

长文、合同、方案、报价和资料库 Markdown 预览导出 PDF 应走服务端渲染接口,不要在前端用 html2canvas + pdf-lib 把 DOM 截图后切片分页。前端切图会导致中文行被截断、分页切断段落、文字不可选择和文件像素化。若页面已经用 Markdown 预览组件渲染出 HTML,应优先把同一份预览 HTML 传给 html 字段;只有没有预览 HTML 时才传 markdown,避免 PDF 与预览使用两套 Markdown 解析语义。

const response = await client.invoke('documents/render-pdf', {
  title: '客户方案',
  markdown: '# 客户方案\n\n这里是正文。',
  options: {
    format: 'A4',
    margin: '18mm',
    includeOutline: true,
    outlineDepth: 3,
  },
});

const blob = await response.blob();
const url = URL.createObjectURL(blob);

该接口返回原始 Fetch ResponseContent-Typeapplication/pdf。平台后端通过 Browserless 远程浏览器执行 Headless Chrome print,不依赖用户本机 Chrome,也不要在应用 AppServer 里 puppeteer.launch。腾讯云函数部署时后端环境必须配置 BROWSERLESS_TOKEN 并允许出站 WebSocket。

TacoreAppInterfaceSDK (App Interfaces)

数字员工、组织通用 Agent 或外部集成应通过平台网关调用云应用暴露的 /.tacore/interfaces.json,而不是依赖应用 UI、DOM、按钮或页面路径。interfaces.json 只描述应用信息、apiNamepayloadFieldsresponseFields;真实业务逻辑由目标应用 AppServer 中同名 API 实现。

import { TacoreAppInterfaceSDK } from '@tacoreai/web-sdk'

const interfaceSdk = new TacoreAppInterfaceSDK({
  accessToken: 'PLATFORM_ACCESS_TOKEN',
  organizationId: 'org_xxx',
  appId: 'crm_app_xxx',
})

const manifest = await interfaceSdk.listInterfaces()
const addLeadInterface = await interfaceSdk.getInterface('addLead')

await interfaceSdk.invoke('addLead', {
  name: 'Acme',
  phone: '13800000000',
})

SDK 封装平台 /plat/app-interfaces 的发现与 /plat/app-interfaces/invoke 转发请求;平台负责鉴权、目标应用权限校验、payload 字段校验和调用审计,再把请求转发到目标应用 AppServer 的 invokeAppServerAPI?apiName=...

AppsClient (Events)

应用自定义埋点应使用事件日志接口,不要把高频事件写入通用数据模型。 应用代码不要直接请求 /plat 平台接口,也不要读取平台登录 token;写入和读取都应通过 AppsClient.invoke(...)/apps/events/*。事件日志不新增 WebSDK 专用方法,apiName 直接和后端 path 对齐。

const tracked = await client.invoke('events/track', {
  eventName: 'signup_click',
  properties: { plan: 'pro' },
  visitorId: localStorage.getItem('visitor_id'),
  sessionId: sessionStorage.getItem('session_id'),
  path: window.location.pathname,
});

// 以下读取接口仅适用于已登录且具备 app owner/admin 角色的应用管理界面。
const event = await client.invoke('events/read', {
  eventId: tracked?.data?.eventId,
});

const page = await client.invoke('events/query', {
  day: '2026-05-14',
  eventName: 'signup_click',
  limit: 50,
});

可用接口包括 events/trackevents/batch-trackevents/readevents/batch-readevents/query。写入接口由后端校验应用部署域名或自定义域名来源;所有读取接口都要求 Apps 登录态且当前用户为应用 owner/admin。平台通用查看/搜索由平台工作视图承接。


文件存储 API(R2 / GCS)

先确保已通过 AppsAuthManager 登录,并使用 AppsClient 初始化时提供 appId。以下接口均作用于 /apps 路由,需携带 Authorization。

  1. 上传文件到 R2(公开访问 / 前端展示)

import { AppsClient } from '@tacoreai/web-sdk' const client = new AppsClient('YOUR_APP_ID')

const input = document.querySelector('#fileInput') const file = input.files[0] const result = await client.uploadFile(file) // result => { success: true, url, key }

  1. 下载底层 R2 对象

const response = await client.downloadFromR2('') const blob = await response.blob()

业务资料、合同附件和知识库文件不要直接使用该底层方法。应先调用:

const authorization = await client.invoke('files/authorize-download', { resourceModel: 'enterprise_document', resourceId: documentId, key, // 历史资料没有 fileKey 时传 url: fileUrl permission: 'kb.file.download', }) const response = await fetch(authorization.data.downloadUrl) const blob = await response.blob()

对外免登录分享使用 files/public-shares/create|status|revoke 管理分享状态,公开页面通过 AppsPublicClient.invoke('files/public-shares/read', { token }) 读取;不要复制登录态预览地址充当公开链接。

  1. 删除 R2 文件

await client.deleteFromR2('')

  1. 上传文件到 GCS(Gemini / 多模态分析输入)

const gcsResult = await client.uploadToGCS(file) // gcsResult.fileUri => gs://... ,供 Gemini 等模型使用


图片生成 (Apps 路由)

请确保已通过 AppsAuthManager 登录,并使用 AppsClient 发起请求(会自动附带 Authorization)。

generateImage(options)

  • 功能: 调用文生图服务。默认使用 Google Imagen,可按需切换。
  • 返回: Promise<Object> (后端响应对象,包含 data.uridata.images)

1. 调用 Google Imagen (默认)

import { AppsClient } from '@tacoreai/web-sdk' const client = new AppsClient('YOUR_APP_ID')

const result = await client.generateImage({ prompt: '一只在云端奔跑的小狗,卡通风格' }); // 获取图片 URI const imageUri = result.data.uri;

2. 调用豆包 4.0 模型

通过 provider 参数切换服务商。

const result = await client.generateImage({ provider: 'volcengine', // 指定使用火山引擎 prompt: '一只在云端奔跑的小狗,中国水墨画风格', // 可选,指定豆包模型版本,默认为 doubao-seedream-4-5-251128 // model: 'doubao-seedream-4-5-251128', }); const imageUri = result.data.uri;

注意:

  • 计费:Apps 路由会根据 appId 自动解析组织并扣费。
  • 错误码:402(余额不足)、404(组织不存在)、500/503(外部服务异常)等。

[更新] 图片编辑 (Google Image Edit) - Apps 路由

图片编辑支持更复杂的工作流:单图编辑、双图融合(如“把衣服穿到模特身上”)、掩膜修复/扩展(Inpainting/Outpainting)。

  • 接口: /agent/generate-google-image-edit
  • 方法: AppsClient.editImage(options)
  • 返回: Promise<Object> (后端响应对象,包含 data.uridata.images)

核心流程

  1. 上传图片: Google / Gemini 链路下,所有源图片(包括底图、叠加图、掩膜图)都应先通过 uploadToGCS(file) 获取 gs:// 形式的 fileUri
  2. 调用编辑: 使用获取到的 fileUrimimeType,通过 editImage 方法并采用简化的 prompt + inputs 模式进行调用。

前置要求

  • 必须先登录 (AppsAuthManager)
  • uploadToGCS

1. 简化调用 (prompt + inputs 模式,推荐)

SDK 会自动将 promptinputs 数组组合成标准的多模态 messages

import { AppsClient } from '@tacoreai/web-sdk' const client = new AppsClient('YOUR_APP_ID')

// 1. 上传源文件 const baseFile = await client.uploadToGCS(file);

// 2. 调用编辑接口 const result = await client.editImage({ prompt: '仅移除图中叠加的文字,保持其他区域不变,输出高清。', inputs: [ { type: 'uploaded_file', fileUri: baseFile.fileUri, mimeType: file.type } ] }); // 获取图片 URI (兼容不同后端返回结构) const editedBase64 = result.data.uri || (result.data.images && result.data.images[0]?.uri); // editedBase64 即可直接作为

2. 典型场景范式

  • 场景 A:单图编辑(去字/去水印/局部替换)

const base = await client.uploadToGCS(file); const result = await client.editImage({ prompt: '移除叠加文字,其他区域完全保持不变。', inputs: [ { type: 'uploaded_file', fileUri: base.fileUri, mimeType: file.type } ] }); const base64 = result.data.uri || result.data.images?.[0]?.uri;

  • 场景 B:双图融合(将服装穿到模特身上)

const garment = await client.uploadToGCS(garmentFile); const modelPhoto = await client.uploadToGCS(modelFile);

const result = await client.editImage({ prompt: '将服装自然替换到模特身上,保持姿态与光照;去除服装图背景;保持背景不变;不改变面部和发型。', inputs: [ // 建议顺序:底图(模特)放前,叠加/融合图(服装)放后 { type: 'uploaded_file', fileUri: modelPhoto.fileUri, mimeType: modelFile.type }, { type: 'uploaded_file', fileUri: garment.fileUri, mimeType: garmentFile.type } ] }); const base64 = result.data.uri || result.data.images?.[0]?.uri;

  • 场景 C:掩膜修复/扩展(Inpainting / Outpainting)

const base = await client.uploadToGCS(baseFile); const mask = await client.uploadToGCS(maskFile); // 掩膜语义按后端约定

const result = await client.editImage({ prompt: '在掩膜区域进行修复,移除水印并保持纹理一致;不要改变未掩膜区域。', inputs: [ // 建议顺序:底图 -> 掩膜 { type: 'uploaded_file', fileUri: base.fileUri, mimeType: baseFile.type }, { type: 'uploaded_file', fileUri: mask.fileUri, mimeType: maskFile.type } ] }); const base64 = result.data.uri || result.data.images?.[0]?.uri;

3. 高级模式 (messages 透传)

用于完全控制请求结构,不推荐常规使用。

const base = await client.uploadToGCS(file)

const result = await client.editImage({ model: 'gemini-2.5-flash-image-preview', messages: [ { role: 'user', content: [ { type: 'text', text: '移除图中叠加的文字...' }, { type: 'uploaded_file', uploaded_file: { fileUri: base.fileUri, mimeType: file.type } } ] } ] }) const base64 = result.data.uri || result.data.images?.[0]?.uri;


[新增] 视频生成(Seedance 2.0)

通过 AppsClient 调用统一视频任务接口。当前云模式默认视频模型为 agent:tacore-3.3,后端会映射到火山引擎 doubao-seedance-2-0-260128。计费将自动关联到应用所属的组织。

定价

  • agent:tacore-3.3
    • 输入价格:4
    • 输出价格:10

createVideoJob(options)

  • 功能: 创建一个异步的视频生成任务。
  • 参数:
    • options (object):
      • prompt (string, 推荐): 视频描述提示词。
      • content (array, 推荐): 多模态输入数组,支持:
        • { type: 'text', text: '...' }
        • { type: 'image_url', image_url: { url: 'https://...' }, role: 'reference_image' }
        • { type: 'video_url', video_url: { url: 'https://...' }, role: 'reference_video' }
        • { type: 'audio_url', audio_url: { url: 'https://...' }, role: 'reference_audio' }
      • model (string, 可选): 默认 agent:tacore-3.3
      • generate_audio (boolean, 可选): 是否生成音频。
      • ratio (string, 可选): 画幅比例,例如 16:9
      • duration (number, 可选): 视频时长(秒)。
      • watermark (boolean, 可选): 是否保留 provider 水印。
      • resolution (string, 可选): 分辨率。
      • seed (number, 可选): 随机种子。
      • return_last_frame (boolean, 可选): 是否返回尾帧。
      • providerOptions (object, 可选): 透传给 provider 的扩展字段。
  • 返回值: Promise<object> - 包含任务初始状态的文档。

参考素材上传

  • 图片、视频、音频参考素材必须先调用 uploadToR2,然后把返回的公网 url 填到 content 中。
  • 不要直接把本地 File/Blob/base64 传给 createVideoJob

remixVideoJob(jobId, options)

  • 功能: 基于一个已完成的视频,创建一个新的 Remix 任务。后端会自动把原视频作为 reference_video 注入。
  • 参数:
    • jobId (string, 必填): 原始视频任务的 wyID
    • options (object):
      • 兼容 createVideoJob(options) 的全部字段,至少需要 promptcontent
  • 返回值: Promise<object> - 包含新的 Remix 任务初始状态的文档。

getVideoJob(jobId)

  • 功能: 查询指定视频任务的状态。
  • 参数:
    • jobId (string, 必填): createVideoJobremixVideoJob 返回的任务 wyID
  • 返回值: Promise<object> - 包含任务最新状态的文档。当 status 为 'completed' 时,resultUrl 字段将包含视频的下载链接。

listVideoJobs(options)

  • 功能: 获取视频任务列表。
  • 参数:
    • options (object):
      • page (number, 可选): 页码, 默认 1。
      • pageSize (number, 可选): 每页数量, 默认 10。
  • 返回值: Promise<object> - 包含任务列表和分页信息的对象。

工作流示例

const client = new AppsClient('YOUR_APP_ID');

async function generateAndPollVideo() { try { const image = await client.uploadToR2(fileInput.files[0]); const audio = await client.uploadToR2(audioInput.files[0]);

// 1. 提交任务
const jobResult = await client.createVideoJob({
  model: 'agent:tacore-3.3',
  content: [
    { type: 'text', text: '第一视角果茶广告短片' },
    {
      type: 'image_url',
      image_url: { url: image.url },
      role: 'reference_image',
    },
    {
      type: 'audio_url',
      audio_url: { url: audio.url },
      role: 'reference_audio',
    },
  ],
  generate_audio: true,
  ratio: '16:9',
  duration: 11,
  watermark: false,
});
const jobId = jobResult.data.wyID;
console.log('视频任务已创建, ID:', jobId);

// 2. 轮询状态
const pollStatus = setInterval(async () => {
  const updatedJob = await client.getVideoJob(jobId);
  console.log('当前状态:', updatedJob.data.status, '进度:', updatedJob.data.progress);

  if (updatedJob.data.status === 'completed') {
    console.log('视频生成成功! URL:', updatedJob.data.resultUrl);
    clearInterval(pollStatus);
  } else if (updatedJob.data.status === 'failed') {
    console.error('视频生成失败:', updatedJob.data.error);
    clearInterval(pollStatus);
  }
}, 5000); // 每5秒查询一次

} catch (error) { console.error('操作失败:', error.message); } }


网页爬虫服务 - Apps 路由

请确保已通过 AppsAuthManager 登录,并使用 AppsClient 发起请求(会自动附带 Authorization)。

1) 单个URL爬取

import { AppsClient } from '@tacoreai/web-sdk' const client = new AppsClient('YOUR_APP_ID')

try { const result = await client.scrapeUrl({ url: 'https://example.com/article', projectId: 'project_123' // 可选,项目ID })

console.log('爬取成功:', result) // result.data 包含: // - url: 原始URL // - markdown: 转换后的Markdown内容 // - contentLength: HTML内容长度 // - markdownLength: Markdown内容长度 // - creditsCost: 消耗的积分(固定50积分) } catch (error) { console.error('爬取失败:', error.message) // 常见错误: // - 402: 积分余额不足 // - 400: URL格式无效或网页访问失败 // - 404: 组织不存在 }

2) 批量URL爬取

import { AppsClient } from '@tacoreai/web-sdk' const client = new AppsClient('YOUR_APP_ID')

try { const result = await client.scrapeMultipleUrls({ urls: [ 'https://example.com/article1', 'https://example.com/article2', 'https://example.com/article3' ], projectId: 'project_123', // 可选,项目ID maxConcurrent: 3 // 可选,最大并发数,默认3,最大5 })

console.log('批量爬取完成:', result) // result.data 包含: // - totalUrls: 总URL数量 // - successfulUrls: 成功爬取的URL数量 // - failedUrls: 失败的URL数量 // - results: 详细结果数组 // - creditsCost: 总消耗积分(只为成功的URL计费)

// 处理每个URL的结果 result.data.results.forEach((item, index) => { if (item.success) { console.log(URL ${index + 1} 成功:, item.data.markdown) } else { console.log(URL ${index + 1} 失败:, item.error) } }) } catch (error) { console.error('批量爬取失败:', error.message) }

爬虫服务特性

  • 智能转换: 自动将HTML内容转换为干净的Markdown格式
  • 内容限制: 单个页面最大5MB内容限制
  • 并发控制: 批量爬取支持并发控制,最大并发数为5
  • 数量限制: 批量爬取最多支持10个URL
  • 计费模式: 每个成功爬取的URL消耗50积分,失败的URL不计费
  • 错误处理: 详细的错误信息和状态码,便于调试和处理

错误码说明

  • 400: 参数错误或URL格式无效
  • 402: 积分余额不足
  • 404: 组织不存在
  • 500: 服务器内部错误

注意事项

  • 爬虫服务会自动根据 appId 解析组织并进行计费
  • 支持爬取大部分公开网页,但可能受目标网站的反爬虫策略影响
  • 转换后的Markdown内容会自动移除脚本、样式、图片等非文本元素
  • 建议在爬取前先检查积分余额,避免因余额不足导致爬取失败

平台态图片能力(需平台鉴权与 x-org-id)

若在"平台态(/plat)"调用接口,请在请求头中携带:

  • Authorization: Bearer <platform_token>
  • x-org-id: <组织ID>
  1. 文生图 /plat/agent/text2image

POST /plat/agent/text2image Headers: Authorization + x-org-id Body: { "organizationId": "<可不传,若传与 x-org-id 一致>", "userId": "<平台用户ID>", "prompt": "卡通风格的星空小屋", "...其它可选项" }


给 Web Agent 的提示片段

你是生成 App 前端代码的 Web Agent。项目已集成 @tacoreai/web-sdk,提供文件、图片和爬虫 API,请遵循:

  • 文件接口:仅通过 AppsClient 调用,不直接使用 fetch。
  • 图片接口:Apps 路由优先,使用 AppsClient.generateImage() 与 AppsClient.editImage()。
  • 爬虫接口:使用 AppsClient.scrapeUrl() 或 AppsClient.scrapeMultipleUrls()。
  • 爬虫服务必填:url(单个)或 urls(批量)。每个成功URL消耗50积分。
  • 计费:Apps 路由按 appId 归属组织进行计费;平台路由需带 x-org-id,并传 userId。
  • 常用方法: • 文生图:generateImage({ prompt, ... }) • 图像编辑:editImage({ messages }) 或 editImage({ prompt, inputs, ... }) • 单个爬虫:scrapeUrl({ url, projectId? }) • 批量爬虫:scrapeMultipleUrls({ urls, projectId?, maxConcurrent? })
  • 错误处理:注意处理 401 未登录、402 余额不足、404 组织不存在、500/503 外部服务异常等。