# 旧写法与迁移

这一页列出改名前的 SDK 名、命令、API 路径和写法，并给出对应的新写法。旧写法照样能用，已上线的应用不用改。新代码请用新写法。

> [!NOTE]
> 清单 `sdk` 里写旧名，部署时归到新名。旧命令照样能用，`aidc help` 里仍列着它们。

## SDK 名

这一节列出旧 SDK 名和对应的新 SDK。1.20.0 把六个 SDK 并入 Semantic。1.22.0 把 `improve` 并入 `evolve`。

| 旧名 | 对应的新 SDK | 并入版本 |
| --- | --- | --- |
| `connect` | `semantic`：数据流 `semantic.stream`、`semantic.streams`；智能体 `model.agent` | 1.20.0 |
| `data` | `semantic`：对象集 `semantic.ontology()`，见[数据层的写法](#数据层的写法) | 1.20.0 |
| `auth` | `semantic`：账号与成员 `semantic.admin`；资源与分享 `semantic.filesystem` | 1.20.0 |
| `workflow` | `semantic.automate` | 1.20.0 |
| `log` | `semantic.observability` | 1.20.0 |
| `billing` | `semantic.usage` | 1.20.0 |
| `improve` | `evolve`。除 `decide` 改为 `decideProposal` 外，其余函数同名 | 1.22.0 |

旧名在浏览器 SDK（`aidc.js`）里照样导出，写法也照样能用。下面是一个例子：

```js
// 旧
import { log } from "/developer/sdk/v1/aidc.js";
log.track("export", { format: "csv" });

// 新
import { semantic } from "/developer/sdk/v1/aidc.js";
semantic.observability.track("export", { format: "csv" });
```

代码改成导入 `semantic` 后，清单的 `sdk` 也要登记 `semantic`。`aidc app check` 会检查这一项。

## 命令

这一节列出旧命令和新命令。多数旧命令只换了组名，子命令不变。

| 旧命令 | 新命令 | 说明 |
| --- | --- | --- |
| `aidc stream …` | `aidc semantic streams …` | 数据流，子命令不变 |
| `aidc resources …` | `aidc semantic filesystem …` | 访问和分享，子命令不变 |
| `aidc members …` | `aidc semantic admin members …` | 成员，子命令不变 |
| `aidc workflow …` | `aidc semantic automate …` | 自动化，子命令不变 |
| `aidc log …` | `aidc semantic observability …` | 日志，子命令不变 |
| `aidc billing …` | `aidc semantic usage …` | 用量与账单，子命令不变 |
| `aidc improve …` | `aidc evolve …` | 子命令不变 |
| `aidc semantic act <Action>` | `aidc semantic apply <Action>` | 对象主键写成 `--param __object=<主键>` |
| `aidc data query <类型>` | `aidc semantic objects <类型>` | `--where` 的写法不变 |
| `aidc data get <类型> <主键>` | `aidc semantic object <类型> <主键>` | 链接用 `aidc semantic links`，历史用下一行 |
| `aidc data get … --history` | `aidc semantic edits-history <类型> --pk <主键>` | 只包含 Action 产生的改动，不覆盖全部旧历史 |
| `aidc data aggregate` | `aidc semantic aggregate <类型>` | 用 `--select`、`--where`、`--group-by` |
| `aidc data watch --types <类型>` | `aidc semantic subscribe <类型>` | 每次变化打一行 |
| `aidc data bind <流> <类型> --map …` | `aidc semantic datasource set <类型> --stream <流> --map …` | 数据源写在类型定义里 |
| `aidc data bindings` | `aidc semantic datasource list` | 看各类型的数据源和同步进度 |
| `aidc data resync` | `aidc semantic datasource resync <类型> --stream <流>` | 重同步一个数据源 |
| `aidc data unbind` | `aidc semantic datasource remove <类型> --stream <流>` | 从类型定义里去掉数据源 |

下面的旧命令没有新命令。它们照样能用：

| 命令 | 说明 |
| --- | --- |
| `aidc data create`、`update`、`delete`、`import` | 直接写对象，只给开发者。改数据的新写法是 `aidc semantic apply <Action>` |
| `aidc data profile`、`aidc data group` | 本地分析，不联网 |
| `aidc connect datasets`、`aidc connect report` | 固定报告，只含聚合。见[固定报告](#固定报告) |
| `aidc connect send "<消息>"` | 和智能体对话。用 `AIDC_AGENT_KEY` |

## 语义的旧写法

这一节列出 1.2.x 起的语义写法。这些写法照样能用，和新写法用的是同一份数据和同一套 Action 引擎。

| 旧写法 | 新写法 | 说明 |
| --- | --- | --- |
| `semantic.describe()` | 不变 | 说明书，给智能体读 |
| `semantic.objects(类型)` | `semantic.ontology().objects(类型)` | 新代码用 `ontology()` |
| `semantic.action(名字).apply(参数, 选项)` | `semantic.ontology().action(名字).applyAction(参数, 选项)` | 写数据的参数，见[读写对象](data.md) |
| `semantic.define(…)`、`defineAll(…)` | 不变 | 智能体改本体要在分支上做，见[定义本体](ontology.md) |
| `semantic.publish(说明)` | 不变 | 发布一个语义版本 |
| `aidc semantic act` | `aidc semantic apply` | 见[命令](#命令) |
| `aidc semantic describe` | 不变 | `--markdown` 输出给大模型读的说明书 |
| `aidc semantic define`、`aidc semantic publish` | 不变 | 同上 |

## 数据层的写法

这一节列出旧数据层（`data`）的写法和对象集的写法。对象集的写法是 OSDK 的形状。下表的 `…` 代表 `semantic.ontology().objects(类型)`。改数据请用 Action。

| 旧写法（`data`） | 新写法（`semantic.ontology()`） |
| --- | --- |
| `data.table(类型).list({ where, sort, limit })` | `…where(条件).fetchPage({ $pageSize, $orderBy })` |
| `list()` 返回 `objects`、`total`、`seq` | `fetchPage()` 返回 `data`、`totalCount`、`nextPageToken` |
| `data.table(类型).all(…)` | 按响应的 `nextPageToken` 翻页，规则见下文 |
| `…get(主键)` | `…fetchOne(主键)` |
| `…get(主键, { link })` | `client.linked(类型, 主键, 链接)` |
| `…get(主键, { history: true })` | `client.editsHistory(类型, { primaryKey: { … } })` |
| `…aggregate({ groupBy, metrics })` | `…aggregate({ $select, $groupBy })` |
| `…live({ onUpdate })` | `…where(条件).subscribe(监听, { properties })` |
| `data.watch({ types, after }, 监听)` | 对象集订阅，见上一行 |
| `…create`、`…update`、`…remove` | 没有新函数。改数据用 `client.action(名字).applyAction(参数)` |
| `…import(行)` | 批量数据走数据流和数据源，见[数据接入](connect.md) |
| `data.sync.bind`、`list`、`resync`、`unbind` | 照样能用，写法不变 |
| `data.parseCsv`、`toCsv`、`profile`、`groupBy` 等 | 照样能用。这些是纯函数，不连平台 |

把响应的 `nextPageToken` 传给下一次 `fetchPage` 的 `$nextPageToken`。响应没有 `nextPageToken` 时停止。

新编辑历史只包含 Action 产生的改动。它不覆盖同步、导入和直接编辑产生的旧历史。

- 旧数据层的 `list({ pks: [主键, …] })` 只在这些对象里查，最多 100 个。
- 旧数据层的直接写（`create`、`update`、`remove`、`import --layer edits`）只对开放了直接编辑的类型有效。见[对象的编辑方式](ontology.md#对象的编辑方式)。

查询的例子：

```js
// 旧
const page = await data.table("orders.order").list({ where: { status: "open" }, sort: ["-amount"], limit: 50 });

// 新
const client = semantic.ontology();
const page = await client.objects("orders.order").where({ status: "open" }).fetchPage({ $pageSize: 50, $orderBy: { amount: "desc" } });
```

条件的写法不变：`{ 属性: 值 }` 表示相等，`$or` 表示任意一组成立。

## 固定报告

这一节说明 Semantic 之前的固定报告。这些报告照样能用，只含聚合。

`connect.datasets.list()` 列出能读的数据集。`connect.datasets.report(数据集, 报告)` 返回一份固定报告。命令行的 `aidc connect datasets` 和 `aidc connect report` 也照样能用。

新应用用对象集的聚合，不用固定报告：`semantic.ontology().objects(类型).aggregate(…)`。

## 已停用的效果

这一节列出已停用的自动化效果和它们的替代写法。新建的自动化不接受它们，返回 `automate_legacy_effect`（422）。已有的自动化照常运行。替换时可以原样保留，迁走之后再去掉。

| 原来的效果（已停用） | 换成 |
| --- | --- |
| `notification`，`channel` 为 `dingtalk` 或 `wecom` | `action` 效果。执行一个发消息的 Action，这个 Action 配 side effect webhook |
| `agentScript`（在客户箱上跑的 Loop 脚本，读 Semantic） | 函数：用 `aidc semantic functions publish` 发布，`function` 效果执行它 |
| `agentScript` 的 `deliver`（脚本输出发消息） | `action` 效果，配 side effect webhook |

webhook 挂在钉钉或企业微信的 REST 连接上。收件人和标题作为 Action 的参数传入。发给 AIDC 账号的邮件，仍用 `notification` 效果，`channel` 为 `email`。

效果的全部类型见[自动化](workflow.md)。

## API 路径

这一节列出旧的 API 路径和它们的新路径。旧路径照样能用。

清单 `sdk` 里的旧名归到新名：

| 旧名 | 归到 |
| --- | --- |
| `data`、`connect`、`workflow`、`auth`、`log`、`billing` | `semantic` |
| `improve` | `evolve` |

| 旧路径 | 新路径或说明 |
| --- | --- |
| `/api/v1/developer/improve/{namespace}/…` | `/api/v1/developer/evolve/{namespace}/…`。旧路径的响应带 `Deprecation` 头 |
| `/api/v1/developer/evolve/{namespace}/{slug}/…` | `/api/v1/developer/evolve/{namespace}/apps/{slug}/…`。旧路径照样能用 |
| `/api/v1/ontologies/{ontology}/…` | 已标记废弃。有 v2 后继的接口，响应带 `Deprecation: true` 和指向 v2 的 `Link`。见 [API 参考](api.md) |
| `/api/v1/ontologySubscriptions/…` | 已标记废弃。订阅改用 `/api/v2/ontologySubscriptions/…`（WebSocket） |
| `/api/v1/developer/data/{namespace}/objects/{type}` | 照样能用。改数据请用 Action |
| `/api/v1/developer/semantic/{namespace}/actions/{apiName}` | 照样能用。新接入请用 Ontology 的 Action 接口 |
| `/api/v1/sqlQueries/executeOntology` | Postgres 方言，照样能用。响应带 `Link: rel="successor-version"`，指向标准方言 `/api/v2/sqlQueries/executeOntology?preview=true`。见 [SQL 与数据库](sql.md#选方言) |

Loop 报告以前用一个单独的发布入口。这个入口仍接受令牌的旧名。一份报告第一次在 AIDC 里发布后，旧入口对它返回 409。改用 [`aidc semantic loop-report publish`](cli-semantic.md#aidc-semantic-loop-report-publish)。

以前只带 `?embedded=true` 的报告全屏链接，在浏览器里直接打开仍是整页报告。新链接写 `?embedded=true&media=html`。

## 缺省值的变化

1.65.0 改了两个缺省值。已经存在的定义不受影响。

| 项目 | 1.65.0 之前 | 现在 | 已有的定义 |
| --- | --- | --- | --- |
| 数据源不写 `mode` | `mirror` | `upsert` | 已接好的数据源都存了明确的 `mode`，行为不变 |
| 新建 Object Type 的直接编辑 | 开放 | 只能经 Action 改 | 之前建的类型没有 `editsConfiguration`，照旧开放 |

新的 Object Type 名必须是 PascalCase。早先小写开头的名字照常能用，定义时给出警告。

## 迁移步骤

这一节说明怎么把一个应用从旧写法改到新写法。每一步都可以单独做。

1. 把代码里 `log`、`data`、`connect` 等的导入改成 `semantic`。在清单 `sdk` 里登记 `semantic`。
2. 把读对象的代码改成对象集，见[数据层的写法](#数据层的写法)。
3. 把改数据的代码改成 Action。
4. 把脚本和运维命令换成新命令，见[命令](#命令)。
5. 运行 `aidc app check`。检查通过后，内容改了，就升一级清单的 `version`。
6. 运行 `aidc app deploy` 部署到 test 通道。测过后运行 `aidc app publish`。

## 下一步

- [数据接入](connect.md)：数据流和数据源。
- [读写对象](data.md)：对象集、订阅和 Action。
- [访问与安全](auth.md)：管理员、资源和分享。
- [自动化](workflow.md)：效果的类型。
- [自进化](evolve.md)：`improve` 已并入 `evolve`。
- [API 参考](api.md)：路径、凭证和错误码。
