@tbox.cn/app-template-agent 0.8.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +88 -33
- package/ENV.md +9 -9
- package/README.md +6 -5
- package/apps/client/index.html +2 -2
- package/apps/client/package.json +2 -2
- package/apps/client/src/app.tsx +1 -1
- package/apps/client/src/cards/registry.ts +1 -1
- package/apps/client/src/main.tsx +1 -1
- package/apps/client/src/modules.ts +1 -1
- package/apps/client/src/platform/AgentChatApp.tsx +6 -5
- package/apps/client/src/platform/agent-runtime.ts +2 -2
- package/apps/client/src/store/chat.ts +2 -2
- package/apps/client/vite.config.ts +1 -3
- package/apps/server/package.json +2 -4
- package/apps/server/src/app-tools.ts +1 -1
- package/apps/server/src/app.ts +86 -18
- package/apps/server/src/cli/collect-registry.ts +1 -1
- package/apps/server/src/cli/plugin-doctor.ts +1 -1
- package/apps/server/src/cli/plugin-inspect.ts +1 -1
- package/apps/server/src/config/integration.ts +1 -1
- package/apps/server/src/dev.ts +2 -2
- package/apps/server/src/index.ts +1 -1
- package/apps/server/src/intent-routes.ts +1 -1
- package/apps/server/src/modules.ts +2 -2
- package/apps/server/src/pre-tools.ts +2 -2
- package/apps/server/src/tools/clock.ts +2 -2
- package/apps/server/src/tools/translate.ts +2 -2
- package/apps/server/tests/agent-prompt.test.ts +4 -4
- package/apps/server/tests/cards-registry.test.ts +1 -1
- package/apps/server/tests/intent-dispatcher.test.ts +1 -1
- package/apps/server/tests/tool-runtime.test.ts +2 -2
- package/package.json +3 -3
- package/packages/agent-ui-kit/package.json +2 -2
- package/packages/agent-ui-kit/src/ChatPage.tsx +1 -1
- package/packages/agent-ui-kit/src/chat-config.ts +1 -1
- package/packages/agent-ui-kit/src/components/ActionBar/DebugButton.tsx +1 -1
- package/packages/agent-ui-kit/src/components/ActionBar/index.tsx +2 -4
- package/packages/agent-ui-kit/src/components/CardRenderer.tsx +1 -1
- package/packages/agent-ui-kit/src/components/ChatInput/index.test.tsx +1 -1
- package/packages/agent-ui-kit/src/components/ChatInput/index.tsx +1 -1
- package/packages/agent-ui-kit/src/components/ChatInput/voice/useVoicePress.ts +2 -2
- package/packages/agent-ui-kit/src/components/MessageBubble/index.tsx +1 -3
- package/packages/agent-ui-kit/src/components/QuickCommands/index.test.tsx +1 -1
- package/packages/agent-ui-kit/src/components/ToolCallBlock/detail.test.ts +1 -1
- package/packages/agent-ui-kit/src/components/ToolCallBlock/detail.ts +1 -1
- package/packages/agent-ui-kit/src/hooks/useMediaUpload.ts +2 -2
- package/packages/agent-ui-kit/src/hooks/useTTSAutoPlay.ts +2 -2
- package/packages/agent-ui-kit/src/store-context.tsx +1 -1
- package/packages/agent-ui-kit/src/types.ts +2 -2
- package/packages/agent-ui-kit/src/utils/haptics.test.ts +1 -1
- package/packages/agent-ui-kit/src/utils/haptics.ts +1 -1
- package/packages/agent-ui-kit/src/utils/tool-call-display.test.ts +15 -15
- package/packages/agent-ui-kit/src/utils/tool-call-display.ts +1 -1
- package/packages/provider-custom/AGENTS.md +47 -21
- package/packages/provider-custom/README.md +1 -1
- package/packages/provider-custom/package.json +3 -2
- package/packages/provider-custom/src/server/index.ts +15 -12
- package/packages/provider-custom/tbox.module.json +8 -8
- package/pnpm-lock.template.yaml +114 -87
- package/pnpm-workspace.template.yaml +8 -4
- package/profiles/mall/TEMPLATE.md +42 -0
- package/profiles/mall.json +3 -2
- package/apps/client/src/shims/node-stub.ts +0 -14
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** 媒体 / 消息类型(协议类型已下沉 @tbox.cn/app-sdk
|
|
1
|
+
/** 媒体 / 消息类型(协议类型已下沉 @tbox.cn/app-agent-sdk-client,此处 re-export 保持单一来源) */
|
|
2
2
|
export type {
|
|
3
3
|
MediaType,
|
|
4
4
|
InputMethod,
|
|
@@ -8,7 +8,7 @@ export type {
|
|
|
8
8
|
MessageStatus,
|
|
9
9
|
ToolCallInfo,
|
|
10
10
|
ChatMessage,
|
|
11
|
-
} from '@tbox.cn/app-sdk
|
|
11
|
+
} from '@tbox.cn/app-agent-sdk-client';
|
|
12
12
|
|
|
13
13
|
/** 单种媒体的上传约束(对齐原模板 FileTypeConfig,UI 层约定,留在模板) */
|
|
14
14
|
export interface FileTypeConfig {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
5
5
|
|
|
6
6
|
const mocks = vi.hoisted(() => ({ callJsapi: vi.fn() }));
|
|
7
|
-
vi.mock('@tbox.cn/app-sdk
|
|
7
|
+
vi.mock('@tbox.cn/app-agent-sdk-client', () => ({ callJsapi: mocks.callJsapi }));
|
|
8
8
|
|
|
9
9
|
import { hapticTap, resetHapticBridgeState } from './haptics';
|
|
10
10
|
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* 注意 iOS 上无论哪条路径都可能无感——Safari 不开放 Taptic Engine 给网页,
|
|
9
9
|
* 容器内是否有感取决于宿主 App 的实现。调用方不应依赖它的成功与否。
|
|
10
10
|
*/
|
|
11
|
-
import { callJsapi } from '@tbox.cn/app-sdk
|
|
11
|
+
import { callJsapi } from '@tbox.cn/app-agent-sdk-client';
|
|
12
12
|
|
|
13
13
|
/** 极短时长(ms):轻点级别,不是提示级别的长震。 */
|
|
14
14
|
const TAP_DURATION_MS = 10;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
2
|
import { describeToolCall, formatCompactToolIo } from './tool-call-display';
|
|
3
|
-
import type { ToolCallInfo } from '@tbox.cn/app-sdk
|
|
3
|
+
import type { ToolCallInfo } from '@tbox.cn/app-agent-sdk-client';
|
|
4
4
|
import { buildPreToolArgsPayload, buildPreToolResultPayload } from '@tbox.cn/app-contracts';
|
|
5
5
|
import {
|
|
6
6
|
buildMemoryToolCallPayload,
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
|
|
11
11
|
const normal = (over: Partial<ToolCallInfo> = {}): ToolCallInfo => ({
|
|
12
12
|
id: 't1',
|
|
13
|
-
name: '
|
|
13
|
+
name: 'queryPoints',
|
|
14
14
|
status: 'done',
|
|
15
15
|
result: JSON.stringify({ temp: 22 }),
|
|
16
16
|
...over,
|
|
@@ -18,7 +18,7 @@ const normal = (over: Partial<ToolCallInfo> = {}): ToolCallInfo => ({
|
|
|
18
18
|
|
|
19
19
|
describe('describeToolCall(010 下沉 S5:展示语义三分支)', () => {
|
|
20
20
|
it('skill:label 取 skillName,无详情', () => {
|
|
21
|
-
const { args } = buildSkillToolCallPayload({ name: '
|
|
21
|
+
const { args } = buildSkillToolCallPayload({ name: 'demo-guide', description: '演示' });
|
|
22
22
|
const d = describeToolCall({
|
|
23
23
|
id: 's1',
|
|
24
24
|
name: '__tbox_skill',
|
|
@@ -26,17 +26,17 @@ describe('describeToolCall(010 下沉 S5:展示语义三分支)', () => {
|
|
|
26
26
|
result: '{}',
|
|
27
27
|
status: 'done',
|
|
28
28
|
});
|
|
29
|
-
expect(d).toEqual({ kind: 'skill', label: '
|
|
29
|
+
expect(d).toEqual({ kind: 'skill', label: 'demo-guide', hasDetail: false });
|
|
30
30
|
});
|
|
31
31
|
|
|
32
32
|
it('preTool done:label 取 description、详情 = 结果文本', () => {
|
|
33
33
|
const args = buildPreToolArgsPayload({
|
|
34
|
-
toolName: '
|
|
35
|
-
description: '
|
|
36
|
-
toolArgs: {
|
|
34
|
+
toolName: 'queryPoints',
|
|
35
|
+
description: '积分查询',
|
|
36
|
+
toolArgs: { accountId: 'M0001' },
|
|
37
37
|
});
|
|
38
38
|
const result = buildPreToolResultPayload({
|
|
39
|
-
toolName: '
|
|
39
|
+
toolName: 'queryPoints',
|
|
40
40
|
status: 'done',
|
|
41
41
|
result: { temp: 22 },
|
|
42
42
|
});
|
|
@@ -49,7 +49,7 @@ describe('describeToolCall(010 下沉 S5:展示语义三分支)', () => {
|
|
|
49
49
|
});
|
|
50
50
|
expect(d.kind).toBe('preTool');
|
|
51
51
|
if (d.kind === 'preTool') {
|
|
52
|
-
expect(d.label).toBe('
|
|
52
|
+
expect(d.label).toBe('积分查询');
|
|
53
53
|
expect(d.status).toBe('done');
|
|
54
54
|
expect(d.hasDetail).toBe(true);
|
|
55
55
|
expect(d.resultText).toContain('"temp": 22');
|
|
@@ -57,7 +57,7 @@ describe('describeToolCall(010 下沉 S5:展示语义三分支)', () => {
|
|
|
57
57
|
});
|
|
58
58
|
|
|
59
59
|
it('preTool calling:label 可用(ARGS 先行)、无详情', () => {
|
|
60
|
-
const args = buildPreToolArgsPayload({ toolName: '
|
|
60
|
+
const args = buildPreToolArgsPayload({ toolName: 'queryPoints', description: '积分查询' });
|
|
61
61
|
const d = describeToolCall({
|
|
62
62
|
id: 'p2',
|
|
63
63
|
name: '__tbox_pretool',
|
|
@@ -68,14 +68,14 @@ describe('describeToolCall(010 下沉 S5:展示语义三分支)', () => {
|
|
|
68
68
|
if (d.kind === 'preTool') {
|
|
69
69
|
expect(d.status).toBe('calling');
|
|
70
70
|
expect(d.hasDetail).toBe(false);
|
|
71
|
-
expect(d.label).toBe('
|
|
71
|
+
expect(d.label).toBe('积分查询');
|
|
72
72
|
}
|
|
73
73
|
});
|
|
74
74
|
|
|
75
75
|
it('preTool error:经 result payload status 判定(ToolCallInfo.status 恒 done,R 语义)', () => {
|
|
76
|
-
const args = buildPreToolArgsPayload({ toolName: '
|
|
76
|
+
const args = buildPreToolArgsPayload({ toolName: 'queryPoints', description: '积分查询' });
|
|
77
77
|
const result = buildPreToolResultPayload({
|
|
78
|
-
toolName: '
|
|
78
|
+
toolName: 'queryPoints',
|
|
79
79
|
status: 'error',
|
|
80
80
|
error: '超时',
|
|
81
81
|
});
|
|
@@ -111,12 +111,12 @@ describe('describeToolCall(010 下沉 S5:展示语义三分支)', () => {
|
|
|
111
111
|
it('normal:label = 工具名,详情 = 有 result/error', () => {
|
|
112
112
|
expect(describeToolCall(normal())).toEqual({
|
|
113
113
|
kind: 'normal',
|
|
114
|
-
label: '
|
|
114
|
+
label: 'queryPoints',
|
|
115
115
|
hasDetail: true,
|
|
116
116
|
});
|
|
117
117
|
expect(describeToolCall(normal({ status: 'calling', result: undefined }))).toEqual({
|
|
118
118
|
kind: 'normal',
|
|
119
|
-
label: '
|
|
119
|
+
label: 'queryPoints',
|
|
120
120
|
hasDetail: false,
|
|
121
121
|
});
|
|
122
122
|
});
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
parsePreToolToolCallResult,
|
|
17
17
|
parseSkillToolCallArgs,
|
|
18
18
|
} from '@tbox.cn/app-contracts';
|
|
19
|
-
import type { ToolCallInfo } from '@tbox.cn/app-sdk
|
|
19
|
+
import type { ToolCallInfo } from '@tbox.cn/app-agent-sdk-client';
|
|
20
20
|
|
|
21
21
|
export type ToolCallDisplay =
|
|
22
22
|
| { kind: 'skill'; label: string; hasDetail: false }
|
|
@@ -1,33 +1,59 @@
|
|
|
1
1
|
# provider-custom —— 自定义 API 实施落点(AI 集成指引)
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
本包是**自定义 API(内联声明)的 adapter 代码落点**:某服务槽在 `config/integrations.json`
|
|
4
|
+
保存内联声明(provider 为对象 + implementation 字面量)而 adapter 未实施时,服务调用报
|
|
5
|
+
`PROVIDER_NOT_IMPLEMENTED`——由 AI 助手按本指引在本包实施,注册命中后即恢复。声明写法与
|
|
6
|
+
维度选择见应用根 `AGENTS.md`「自定义服务集成」。
|
|
6
7
|
|
|
7
8
|
## 实施三步
|
|
8
9
|
|
|
9
|
-
1. **读声明**:`config/integrations.json` 中目标服务(如 `parking.query`)的
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
2. **实现 adapter**:在 `src/server/` 新建实现文件,实现该服务对应模块的 Port
|
|
13
|
-
|
|
14
|
-
`
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
```
|
|
19
|
-
|
|
10
|
+
1. **读声明**:`config/integrations.json` 中目标服务(如 `parking.query`)的 `provider`
|
|
11
|
+
为对象(`{ provider, credentialType, configSchema? }`)+ `implementation` 字面量——这是
|
|
12
|
+
厂商身份与凭据约定。
|
|
13
|
+
2. **实现 adapter**:在 `src/server/` 新建实现文件,实现该服务对应模块的 Port 接口(接口
|
|
14
|
+
定义见消费模块 `src/server/ports.ts`(或 `ports/` 目录)或 `@app/contracts-mall`
|
|
15
|
+
契约包——本包按需加 `@app/contracts-mall` 依赖并 `import type`)。HTTP 调用一律经
|
|
16
|
+
`input.transport`(baseUrl 取自绑定 config;熔断/HTTPS 强制(localhost 的 http 豁免)/
|
|
17
|
+
响应体 1MB 上限内建):
|
|
18
|
+
`await input.transport.request({ path, method, body, query })`。
|
|
20
19
|
3. **注册**:在 `src/server/index.ts` 的 `register(ctx)` 中调用
|
|
21
|
-
`ctx.integrations?.registerAdapter('<provider 名>', '
|
|
22
|
-
|
|
20
|
+
`ctx.integrations?.registerAdapter('<provider 名>', 'inline', factory)`——**注册键
|
|
21
|
+
implementation 段恒为 `'inline'`**(内联声明运行时按合成 `'inline'` 寻址,与声明中的
|
|
22
|
+
implementation 字面量无关)。
|
|
23
|
+
|
|
24
|
+
**多服务单键**:同一 provider 名的全部服务共享唯一注册键——重复注册后者覆盖前者。同一
|
|
25
|
+
后端接多个服务 = 只注册一次,factory 内按 `input.service` 分支返回各 Port 实现;或每服务
|
|
26
|
+
用不同 provider 名分键。adapter 内取凭据值(如自签名):`input.credential()` 惰性 getter
|
|
27
|
+
(返回 `{ scope, type, value }`;未配 credentialRef → undefined)。
|
|
28
|
+
|
|
29
|
+
## 认证与凭据
|
|
30
|
+
|
|
31
|
+
| 认证形态 | credentialType(声明与凭据文件一致) | 机制 |
|
|
32
|
+
|---|---|---|
|
|
33
|
+
| 静态头(x-api-key 等白名单头名) | `static-headers-v1`(SDK 内置) | 头自动注入,adapter 全部经 `input.transport` |
|
|
34
|
+
| 其他(Bearer / 自定义签名…) | 自定(如 `bearer-v1`) | 本包 `register(ctx)` 先 `ctx.authStrategies.register({ credentialType, apply(input) {...} })` 注册策略(SDK `ProviderAuthStrategy`),adapter 同走 `input.transport` |
|
|
35
|
+
|
|
36
|
+
- **勿用 `'-'`**:非 local 供给在 transport 构造期抛「未知认证类型」。
|
|
37
|
+
- 静态头白名单(本应用 `apps/server/src/app.ts`):`content-type` / `sign` / `timestamp` /
|
|
38
|
+
`publickey` / `x-api-key`;白名单外头名走自定义策略。
|
|
39
|
+
- 凭据文件(**嵌套形**,运行时读取格式)`config/credentials/<stem>.json`:
|
|
40
|
+
`{ "type": "<credentialType>", "value": { "<头名/参数名>": "<真值>" } }`(省略 `scope` =
|
|
41
|
+
全域通配)。声明/实例持 `credentialRef: "secret://<stem>"`;服务级 stem =
|
|
42
|
+
`${provider}-${service}`,共享 stem = `${provider}-global`(按实例差异化凭据另有
|
|
43
|
+
`${provider}-${instanceId}-${domain}` 形)。真值只进凭据文件或平台
|
|
44
|
+
env——不进 integrations.json、代码与 prompt。
|
|
45
|
+
- 槽 `instances` 省略 = 通配激活(**勿写空对象 `{}`** = 零激活);已绑字符串厂商的槽整组
|
|
46
|
+
替换前先向用户确认。
|
|
23
47
|
|
|
24
48
|
## 完成判据
|
|
25
49
|
|
|
26
|
-
-
|
|
27
|
-
-
|
|
50
|
+
- `pnpm typecheck && pnpm build` 通过;
|
|
51
|
+
- 平台重启后该服务的调用不再报 `PROVIDER_NOT_IMPLEMENTED`(resolveService 惰性——调用时
|
|
52
|
+
观测;通配槽下 doctor 不检查凭据,运行时为最终裁判)。
|
|
28
53
|
|
|
29
54
|
## 真实厂商接入
|
|
30
55
|
|
|
31
|
-
对外提供正式 API 的厂商(支付/会员等大规模集成)走官方 provider 包形态:
|
|
32
|
-
|
|
33
|
-
`
|
|
56
|
+
对外提供正式 API 的厂商(支付/会员等大规模集成)走官方 provider 包形态:manifest
|
|
57
|
+
`declare.providers.slots` 声明供给 + 独立包发布 + `tbox-app module add` 装配 +
|
|
58
|
+
`tbox-app provider bind` 绑定。样例:`tbox-app module add @tbox.cn/app-provider-mock --mode
|
|
59
|
+
codegen --source @tbox.cn/app-provider-mock` 后参照 `packages/provider-mock` 结构。
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @tbox.cn/app-provider-custom
|
|
2
2
|
|
|
3
|
-
自定义厂商实施落点空包(与 provider-mock 并列的中立空壳):manifest contributes 全空(零贡献
|
|
3
|
+
自定义厂商实施落点空包(与 provider-mock / provider-mocktest 并列的中立空壳):manifest contributes 全空(零贡献
|
|
4
4
|
合法——descriptor zod 全 default),出厂无任何供给/需求/卡片声明,纯为 AI 实施自定义 API
|
|
5
5
|
adapter 提供**有形代码落点**。闭环机制见 AGENTS.md(SDK 零改动——registerAdapter 命中即转 ok)。
|
|
6
6
|
|
|
@@ -21,8 +21,9 @@
|
|
|
21
21
|
"prepack": "pnpm build"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@tbox.cn/app-
|
|
25
|
-
"@tbox.cn/app-
|
|
24
|
+
"@tbox.cn/app-contracts": "catalog:",
|
|
25
|
+
"@tbox.cn/app-agent-sdk-client": "catalog:",
|
|
26
|
+
"@tbox.cn/app-agent-sdk-server": "catalog:"
|
|
26
27
|
},
|
|
27
28
|
"devDependencies": {
|
|
28
29
|
"@types/node": "24.13.3",
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* 自定义厂商实施落点空包·服务端入口(单包多厂商——多个自定义 API 的
|
|
3
3
|
* adapter 均在此包 register,注册表双键不关心包边界)。
|
|
4
4
|
*
|
|
5
5
|
* 零贡献合法(manifest contributes 全空——descriptor zod 全 default):本包出厂无任何
|
|
6
|
-
* 供给/需求/卡片声明,纯为 AI
|
|
7
|
-
* 1.
|
|
8
|
-
* 2.
|
|
9
|
-
* 3. AI
|
|
10
|
-
* registerAdapter(provider,
|
|
11
|
-
* 4.
|
|
6
|
+
* 供给/需求/卡片声明,纯为 AI 实施自定义 API adapter 提供**有形代码落点**。运行时闭环:
|
|
7
|
+
* 1. 某服务槽保存自定义 API 内联声明(integrations.json:provider 对象 + implementation 字面量);
|
|
8
|
+
* 2. 服务调用解析该绑定 → adapter 未注册 → PROVIDER_NOT_IMPLEMENTED(fail-visible);
|
|
9
|
+
* 3. AI 按本包 AGENTS.md 指引实现 adapter 并在 register 挂载
|
|
10
|
+
* ctx.integrations?.registerAdapter(provider, 'inline', factory);
|
|
11
|
+
* 4. 平台重启后 register 命中 → 该服务调用恢复正常(完成信号)。
|
|
12
12
|
*
|
|
13
13
|
* 真实厂商接入(官方 provider 包形态:manifest 槽声明 + 独立包发布)跳转见 AGENTS.md。
|
|
14
14
|
*/
|
|
15
|
-
import type { ServerContext, ServerModule } from '@tbox.cn/app-sdk
|
|
15
|
+
import type { ServerContext, ServerModule } from '@tbox.cn/app-agent-sdk-server';
|
|
16
16
|
|
|
17
17
|
export const PROVIDER_CUSTOM = 'provider-custom';
|
|
18
18
|
|
|
@@ -20,13 +20,16 @@ export const PROVIDER_CUSTOM = 'provider-custom';
|
|
|
20
20
|
* adapter 工厂签名示例(真实实施时替换本注释为具体 adapter 注册):
|
|
21
21
|
*
|
|
22
22
|
* const myApiAdapterFactory: ServiceAdapterFactory = (input) => {
|
|
23
|
-
* // input.service 服务 id(如 'parking.query')
|
|
23
|
+
* // input.service 服务 id(如 'parking.query'——多服务单键时按此分支返回各 Port)
|
|
24
24
|
* // input.instanceId 部署实例键(mall 场景 = mallId;通配激活时由框架解析)
|
|
25
|
-
* // input.config
|
|
26
|
-
* //
|
|
25
|
+
* // input.config 绑定组五层合并后的连接参数(baseUrl 等)
|
|
26
|
+
* // input.transport HTTP 通道(baseUrl/认证/熔断/HTTPS 强制内建):
|
|
27
|
+
* // await input.transport.request({ path, method, body, query })
|
|
28
|
+
* // input.credential?.() 惰性凭据 getter(返回 { scope, type, value };未配 → undefined)
|
|
27
29
|
* return new MyApiServiceImpl(input);
|
|
28
30
|
* };
|
|
29
|
-
*
|
|
31
|
+
* // 注册键 implementation 段恒为 'inline'(内联声明运行时按合成 'inline' 寻址):
|
|
32
|
+
* ctx.integrations?.registerAdapter('my-custom-api', 'inline', myApiAdapterFactory);
|
|
30
33
|
*/
|
|
31
34
|
export function register(ctx: ServerContext): void {
|
|
32
35
|
// 挂点:多个自定义 API 的 adapter 均在此注册(见上方签名示例)。
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"
|
|
3
|
+
"id": "provider-custom",
|
|
4
4
|
"version": "0.1.0",
|
|
5
5
|
"kind": "business",
|
|
6
6
|
"risk": {
|
|
@@ -10,7 +10,11 @@
|
|
|
10
10
|
"distribution": {
|
|
11
11
|
"defaultMode": "codegen"
|
|
12
12
|
},
|
|
13
|
-
"
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"modules": []
|
|
15
|
+
},
|
|
16
|
+
"env": [],
|
|
17
|
+
"declare": {
|
|
14
18
|
"handlers": [],
|
|
15
19
|
"tools": [],
|
|
16
20
|
"cards": [],
|
|
@@ -20,10 +24,6 @@
|
|
|
20
24
|
"providers": {
|
|
21
25
|
"slots": []
|
|
22
26
|
},
|
|
23
|
-
"
|
|
24
|
-
}
|
|
25
|
-
"dependencies": {
|
|
26
|
-
"modules": []
|
|
27
|
-
},
|
|
28
|
-
"env": []
|
|
27
|
+
"consumes": []
|
|
28
|
+
}
|
|
29
29
|
}
|