@kmlckj/licos-platform-sdk
v0.10.7
Published
LICOS platform SDK package shell for browser and Node runtimes
Readme
@kmlckj/licos-platform-sdk
LICOS platform SDK for server-side project runtime code.
Runtime Configuration
Server-side helpers call platform Studio runtime APIs. Project code does not pass API base URLs, project IDs, tokens, or environment scopes. The SDK loads identity from runtime environment variables injected by LICOS. Authentication is resolved automatically by the runtime:
LICOS_PLATFORM_API_BASE_URLLICOS_PLATFORM_PUBLIC_BASE_URL, used for browser-facing URLs and the Web Gateway/ontology-apirouteLICOS_PROJECT_IDorAGENT_PROJECT_IDLICOS_WORKSPACE_IDorAGENT_WORKSPACE_IDLICOS_USER_IDorAGENT_USER_IDLICOS_PROJECT_ENV, mapped internally todevorprod
Database
Database CRUD helpers call the runtime database data plane only. Tooling helpers can fetch platform schema metadata for ORM export. The SDK does not expose service deletion APIs.
database.table(name) is a query builder. Use it for select queries only.
import { database } from '@kmlckj/licos-platform-sdk';
const rows = await database
.table('todos')
.select('id', 'title')
.eq('done', false)
.order('created_at', { desc: true })
.limit(10)
.execute();Use top-level helpers for mutations:
import { database } from '@kmlckj/licos-platform-sdk';
const inserted = await database.insert('todos', {
row: { title: 'Call customer', done: false },
returning: true,
});
await database.updateRows('todos', {
filters: [{ field: 'id', op: 'eq', value: inserted.data?.[0]?.id }],
values: { done: true },
});
await database.deleteRows('todos', {
filters: [{ field: 'done', op: 'eq', value: true }],
});Do not call .table('todos').insert(...), .table('todos').updateRows(...),
or .table('todos').deleteRows(...); those methods do not exist on the query
builder.
ORM export is a tooling helper. It fetches platform schema metadata and returns source text; it does not use direct database credentials.
import { database } from '@kmlckj/licos-platform-sdk';
const source = await database.exportOrm({ language: 'typescript', orm: 'drizzle' });Studio project database management is exposed through studioDatabase for
server-side tooling flows. Use it for tables, rows, controlled SQL, migrations,
sync, and backup. Do not import it into browser/client bundles. Do not put
schema creation or migration logic in normal project runtime request handlers;
run those operations from LICOS agent/tooling flows before the app starts.
import { studioDatabase } from '@kmlckj/licos-platform-sdk';
await studioDatabase.createTable('users', {
columns: [{ name: 'email', type: 'text', nullable: false }],
});
const schema = await studioDatabase.getSchema({ environment: 'dev' });Object Storage
import { storage } from '@kmlckj/licos-platform-sdk';
await storage.createFolder('reports');
const file = await storage.uploadFile('/tmp/report.pdf');
const link = await storage.shareUrl(file.id);uploadFile limits each file to 100 MiB. Payloads larger than 8 MiB automatically use the platform chunk-upload protocol.
The browser entry does not export object storage helpers because runtime tokens must not be bundled into public frontend code.
Knowledge
Knowledge helpers import project documents and run semantic retrieval through the LICOS Knowledge API. Search without dataset filters retrieves from all accessible datasets. Use dataset IDs or names only when the user explicitly targets a specific knowledge base.
import { knowledge } from '@kmlckj/licos-platform-sdk';
await knowledge.addText('FAQ content', {
datasetName: 'project_docs',
name: 'faq.txt',
});
const results = await knowledge.search('How do I reset my password?', {
topK: 5,
});The browser entry does not export knowledge helpers because runtime tokens must not be bundled into public frontend code.
Enterprise knowledge
Enterprise knowledge is a separate, enterprise-user-only resource model. The platform derives tenant scope and permissions from the current user token; do not pass tenant IDs from application code.
import { enterpriseKnowledge } from '@kmlckj/licos-platform-sdk';
const tree = await enterpriseKnowledge.tree({
includeTypes: ['STANDARD', 'GRAPH', 'OBJECT_STORAGE'],
});
const validation = await enterpriseKnowledge.validateReferences(
['knowledge-source-id'],
{ requiredCapability: 'retrieve' },
);
if (validation.valid) {
const evidence = await enterpriseKnowledge.retrieve(
'设备停机前必须完成哪些检查?',
['knowledge-source-id'],
);
}
await enterpriseKnowledge.uploadDocumentChunked(
'knowledge-source-id',
'/workspace/projects/manual.pdf',
);The API covers folders, knowledge-base lifecycle, resource audits, document
listing and chunk inspection, resumable uploads, processing tasks, retrieval,
and object-storage knowledge bases. Temporary document/object URLs must be
obtained with getDocumentOriginalUrl or getObjectDownloadUrl; do not build
storage URLs manually.
Enterprise Ontology
Ontology helpers are server-only. They use the current platform user identity
and call the external ontology service through the Web Gateway /ontology-api
route. Search the authorized AI tool catalog before invoking a function; do not
hard-code the external service host or its evolving operation paths.
import { ontology } from '@kmlckj/licos-platform-sdk';
const catalog = await ontology.searchTools('查询包装一线设备及其属性');
const selected = catalog.items.find((item) =>
item.selection === 'MATCH'
&& item.mode === 'READ'
&& item.definition.function.name === requestedToolName
);
if (!selected) throw new Error('当前目录中没有匹配的只读本体工具');
const toolArguments = { /* fields from selected.definition.function.parameters */ };
const result = await ontology.invokeTool(
selected.definition.function.name,
toolArguments,
{ catalogVersion: catalog.catalogVersion },
);The catalog describes each function schema, HTTP execution mapping, and mode.
READ queries state, PREPARE validates a change draft, and PERSIST applies
an explicitly confirmed change. The browser entry does not export ontology
helpers or platform user tokens.
从 0.10.6 起,invokeTool 按当前授权目录的 JSON Schema 校验参数,未知字段或非法时间在请求业务接口前报错。只读业务工具可传 { requiredMode: 'READ' },目录模式变化时停止执行。SDK 原样返回测量结果和分页元信息,不丢弃 nextCursorTime、nextCursorTieBreaker,不补造单位、质量或默认数值。返回游标不代表目录已经支持续页入参,续页必须以目录契约为准。
本体实时订阅
从 0.10.5 起,Node 服务端可以直接订阅;SDK 内部查询授权计划、获取当前用户凭据、通过平台网关连接并等待订阅确认。
const subscription = await ontology.subscribeRealtime({
elementIds: authorizedElementIds,
attributeIds: authorizedAttributeIds,
});
try {
for await (const event of subscription) {
sendBusinessEvent(event);
}
} finally {
await subscription.close();
}elementIds 是已解析且授权的非空 ID 数组;attributeIds 省略或为空表示这些元素的全部授权属性,不递归子元素。sendBusinessEvent 是业务代码,不是 SDK 方法。
返回对象支持单消费者异步迭代、只读 state 和幂等 close()。迭代事件包含 type: 'property.changed'、element、property、原始 JSON value、ISO 8601 timestamp 和服务端 source。属性类型和值不强制转换。
可选第二参数:signal(取消)、connectTimeoutMs(默认 15000)、closeTimeoutMs(5000)、heartbeatIntervalMs(20000)、maxReconnectAttempts(默认 null,持续重连;非负整数限制累计次数,0 禁用)、reconnectDelayMs(1000,每次重连前的等待间隔)、maxBufferedMessages(1024)。详细类型和每项支持值见随包提供的 ontology.d.ts。
从 0.10.7 起,已确认的订阅断线(含本体会话失效的 1008)后默认持续重连,每次重新鉴权并校验原用户、网关和订阅范围。临时网络故障、HTTP 408/429/5xx 在重连流程中继续等待;收到新的 uns.subscribed 才恢复 subscribed 状态。HTTP 401 刷新凭据一次,再次 401、403、授权目录变化和协议错误立即报错。创建失败直接抛出异常;订阅后的终止错误从迭代器抛出。不伪造首条数据,不静默去重,不保证断线补发。break 自动关闭;浏览器离开时业务后端也应调用 close()。浏览器只能接收项目后端的业务事件,不导入本体 SDK 或读取任何 Token。
OAuth2 Application Management
OAuth2 management is available only from trusted Node runtime code. It uses the current project owner's platform identity and is not exported by the browser entry.
import { oauth } from '@kmlckj/licos-platform-sdk';
const apps = await oauth.listApps();
const app = await oauth.ensureProjectApp({
appId: apps.list?.[0]?.id,
name: 'Project login',
loginAudience: 'ALL',
redirectUriConfigs: [
{ environment: 'prod', redirectUri: 'https://app.example/auth/callback' },
],
});ensureProjectApp requires an explicit login audience and at least one
callback. Store only public PKCE settings in project configuration; never put
the returned client secret or a platform user token in browser code.
OAuth2 Project Runtime
Project server routes use oauthRuntime for Authorization Code + PKCE. The
runtime module reads config/licos-oauth.json; it is intentionally absent from
the browser entry.
import { oauthRuntime } from '@kmlckj/licos-platform-sdk';
const config = await oauthRuntime.loadConfig();
const attempt = oauthRuntime.createAuthorizationRequest(config, {
redirectUri: 'https://app.example/api/auth/licos/callback',
});
// Persist a hash of attempt.state plus codeVerifier, redirectUri and expiresAt
// in a one-time server-side record before redirecting the browser.
const completed = await oauthRuntime.completeAuthorization(config, {
code,
redirectUri: stored.redirectUri,
codeVerifier: stored.codeVerifier,
});completeAuthorization returns platform tokens and userinfo to trusted server
code. Map completed.user.sub to the project's account, create the project's
own session, then revoke tokens unless the application explicitly needs
delegated platform API access. Never return these tokens to the browser.
