@zhin.js/adapter-satori 1.1.0 → 1.1.3
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/CHANGELOG.md +97 -0
- package/README.md +5 -5
- package/adapters/{satori.js → satori/index.js} +6 -6
- package/adapters/{satori.ts → satori/index.ts} +9 -9
- package/commands/{endpoint/add/[id].js → satori/endpoint/add/[id]/index.js} +1 -1
- package/commands/satori/endpoint/add/[id]/index.ts +3 -0
- package/{lib/satori-endpoint-commands.js → commands/satori/endpoint/definition.js} +4 -3
- package/{src/satori-endpoint-commands.ts → commands/satori/endpoint/definition.ts} +3 -3
- package/commands/{endpoint/list.js → satori/endpoint/list/index.js} +1 -1
- package/commands/satori/endpoint/list/index.ts +3 -0
- package/commands/{endpoint/remove/[id].js → satori/endpoint/remove/[id]/index.js} +1 -1
- package/commands/satori/endpoint/remove/[id]/index.ts +3 -0
- package/lib/index.d.ts +1 -1
- package/lib/protocol.d.ts +7 -17
- package/lib/protocol.js +17 -29
- package/lib/satori-runtime-state.js +1 -1
- package/package.json +19 -14
- package/plugin.js +1 -1
- package/schema.json +16 -2
- package/src/index.ts +1 -1
- package/src/protocol.ts +25 -42
- package/src/satori-runtime-state.ts +1 -1
- package/agent/skills/satori.md +0 -33
- package/commands/endpoint/add/[id].ts +0 -3
- package/commands/endpoint/list.ts +0 -3
- package/commands/endpoint/remove/[id].ts +0 -3
- package/lib/satori-endpoint-commands.d.ts +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,102 @@
|
|
|
1
1
|
# @zhin.js/adapter-satori
|
|
2
2
|
|
|
3
|
+
## 1.1.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [5b5d270]
|
|
8
|
+
- Updated dependencies [36c2eb9]
|
|
9
|
+
- @zhin.js/im-contract@1.1.2
|
|
10
|
+
- @zhin.js/core@1.1.38
|
|
11
|
+
- @zhin.js/adapter@1.1.15
|
|
12
|
+
- @zhin.js/host-http@1.1.2
|
|
13
|
+
- @zhin.js/feature-kit@1.1.2
|
|
14
|
+
- @zhin.js/skill@1.1.2
|
|
15
|
+
|
|
16
|
+
## 1.1.2
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- a9e4a40: Derive Command user routes only from explicit `commands/**/*/index.ts(x)` entry paths instead of prepending the plugin owner. Child plugins can now publish top-level static or dynamic commands, while duplicate routes across owners fail during generation construction. Adapter endpoint commands move to explicit paths such as `commands/qq/endpoint/list/index.ts` and are invoked as `qq endpoint list`.
|
|
21
|
+
- 8740059: Standardize TypeScript capabilities on named module directories such as `commands/foo/index.ts`, `middlewares/audit/index.ts`, `handlers/message-receive/index.ts`, `pages/workroom/index.tsx`, and `mcps/filesystem/index.ts`. Only the fixed `index` entry is discovered; sibling files remain private helpers.
|
|
22
|
+
|
|
23
|
+
Command route segments come from directories, while `[name]`, `[[name]]`, `[...name]`, and `[[...name]]` directories declare dynamic parameters. Plugin owners do not enter the route unless their config explicitly sets `commandNamespace`; Endpoint `commandPrefix` remains platform-owned and defaults to an empty string.
|
|
24
|
+
|
|
25
|
+
Migrate the built-in adapters, plugins, examples, generators, migration tooling, hot reload classification, Agent authoring surfaces, documentation, and release artifacts to the explicit entry convention.
|
|
26
|
+
|
|
27
|
+
Make Tool ownership and progressive disclosure explicit across all four supported locations: plugin-public `tools/`, Agent-private `agents/<name>/tools/`, Skill-private `skills/<name>/tools/`, and Agent-Skill-private `agents/<name>/skills/<name>/tools/`. Move adapter and group-suite operations that require domain instructions into their owning Skills so `load_skill` is the only path that unlocks their schemas.
|
|
28
|
+
|
|
29
|
+
Remove the package-root `agent/` convention. Public capabilities now use named package-root directories, schedules use `schedules/<name>/index.ts` or `plugin.ts` injection, MCP connections use `mcps/<name>/index.ts`, Prompt Sections use `prompt-sections/<name>/index.ts`, Agent definitions use `agents/<name>/`, and permission vocabulary is published as `PERMITS.md`.
|
|
30
|
+
|
|
31
|
+
- 25a845a: Unify Skills on `skills/<name>/SKILL.md`, support Agent-private Skills and nested Skill-private Tools, publish and mount existing plugin Skills, add governed Skill metadata and Turn access filtering, unlock only already-admitted same-owner Tools, and make `on-risk` and `once` approval behavior precise.
|
|
32
|
+
- 4380cf9: Colocate adapter command definitions and Agent Skill handlers with their owning capabilities, and provide a shared validated platform permission constructor.
|
|
33
|
+
- 2acae54: Require the canonical expanded Satori endpoint configuration. The protocol no longer reinterprets nested `endpoints` or reads endpoint identity, base URL, and token from `process.env`. The public config type is now `SatoriEndpointConfig`, and each schema entry uses `id` as its identity.
|
|
34
|
+
- 5c3858e: Make `@zhin.js/im-contract` the explicit zero-dependency owner of transport identities, canonical segments, media guards, conversation facts, stores, and delivery contracts. Platform adapters now read media contracts from that foundation instead of reaching through Core.
|
|
35
|
+
- Updated dependencies [c861789]
|
|
36
|
+
- Updated dependencies [1414ccb]
|
|
37
|
+
- Updated dependencies [743d470]
|
|
38
|
+
- Updated dependencies [62dee52]
|
|
39
|
+
- Updated dependencies [cd54131]
|
|
40
|
+
- Updated dependencies [244e475]
|
|
41
|
+
- Updated dependencies [a9e4a40]
|
|
42
|
+
- Updated dependencies [5855db7]
|
|
43
|
+
- Updated dependencies [ec921d2]
|
|
44
|
+
- Updated dependencies [8740059]
|
|
45
|
+
- Updated dependencies [25a845a]
|
|
46
|
+
- Updated dependencies [103f2c3]
|
|
47
|
+
- Updated dependencies [9110ab8]
|
|
48
|
+
- Updated dependencies [cd2a888]
|
|
49
|
+
- Updated dependencies [eb3227a]
|
|
50
|
+
- Updated dependencies [b853dba]
|
|
51
|
+
- Updated dependencies [e561309]
|
|
52
|
+
- Updated dependencies [d4c6175]
|
|
53
|
+
- Updated dependencies [7a0e1ca]
|
|
54
|
+
- Updated dependencies [103b5d3]
|
|
55
|
+
- Updated dependencies [5a7a7f7]
|
|
56
|
+
- Updated dependencies [b076eae]
|
|
57
|
+
- Updated dependencies [73a24b7]
|
|
58
|
+
- Updated dependencies [2dbbc15]
|
|
59
|
+
- Updated dependencies [1cb1163]
|
|
60
|
+
- Updated dependencies [be3061e]
|
|
61
|
+
- Updated dependencies [75f8332]
|
|
62
|
+
- Updated dependencies [81935e2]
|
|
63
|
+
- Updated dependencies [f9ed01b]
|
|
64
|
+
- Updated dependencies [ac0ab50]
|
|
65
|
+
- Updated dependencies [5140ce1]
|
|
66
|
+
- Updated dependencies [522d75f]
|
|
67
|
+
- Updated dependencies [a7611b3]
|
|
68
|
+
- Updated dependencies [8823044]
|
|
69
|
+
- Updated dependencies [379439b]
|
|
70
|
+
- Updated dependencies [11c9352]
|
|
71
|
+
- Updated dependencies [6b70e46]
|
|
72
|
+
- Updated dependencies [135ac91]
|
|
73
|
+
- Updated dependencies [140cf0f]
|
|
74
|
+
- Updated dependencies [251e4d2]
|
|
75
|
+
- Updated dependencies [203ad34]
|
|
76
|
+
- Updated dependencies [e6c5113]
|
|
77
|
+
- Updated dependencies [e0f6478]
|
|
78
|
+
- Updated dependencies [baef56b]
|
|
79
|
+
- Updated dependencies [da0a8e3]
|
|
80
|
+
- Updated dependencies [2fd8017]
|
|
81
|
+
- Updated dependencies [5c3858e]
|
|
82
|
+
- Updated dependencies [507d602]
|
|
83
|
+
- Updated dependencies [df9f76b]
|
|
84
|
+
- @zhin.js/core@1.1.37
|
|
85
|
+
- @zhin.js/host-http@1.1.1
|
|
86
|
+
- @zhin.js/adapter@1.1.14
|
|
87
|
+
- @zhin.js/feature-kit@1.1.1
|
|
88
|
+
- @zhin.js/skill@1.1.1
|
|
89
|
+
- @zhin.js/logger@1.1.1
|
|
90
|
+
- @zhin.js/im-contract@1.1.1
|
|
91
|
+
|
|
92
|
+
## 1.1.1
|
|
93
|
+
|
|
94
|
+
### Patch Changes
|
|
95
|
+
|
|
96
|
+
- Updated dependencies [769e67f]
|
|
97
|
+
- @zhin.js/adapter@1.1.13
|
|
98
|
+
- @zhin.js/core@1.1.36
|
|
99
|
+
|
|
3
100
|
## 1.1.0
|
|
4
101
|
|
|
5
102
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ pnpm add @zhin.js/adapter-satori
|
|
|
21
21
|
|
|
22
22
|
## Plugin Runtime
|
|
23
23
|
|
|
24
|
-
- `@zhin.js/adapter` — 约定式 `adapters/satori.ts`(`defineAdapter`)
|
|
24
|
+
- `@zhin.js/adapter` — 约定式 `adapters/satori/index.ts`(`defineAdapter`)
|
|
25
25
|
- `@zhin.js/core` — `Endpoint.emit(...)` 入站、`outboundMessageToken` 出站
|
|
26
26
|
- `zhin.js` — `plugin.ts`(`definePlugin`)
|
|
27
27
|
- `@zhin.js/host-http` — Webhook 模式需 `httpHostToken` 注册 POST 路由
|
|
@@ -51,7 +51,7 @@ plugins:
|
|
|
51
51
|
connection: ws
|
|
52
52
|
heartbeat_interval: 10000
|
|
53
53
|
endpoints:
|
|
54
|
-
-
|
|
54
|
+
- id: satori-bot
|
|
55
55
|
baseUrl: "http://127.0.0.1:5140"
|
|
56
56
|
token: "${SATORI_TOKEN}"
|
|
57
57
|
```
|
|
@@ -63,7 +63,7 @@ plugins:
|
|
|
63
63
|
| 字段 | 说明 |
|
|
64
64
|
|------|------|
|
|
65
65
|
| `heartbeat_interval` | WS PING 间隔(毫秒),默认 `10000` |
|
|
66
|
-
| `token` | Bearer
|
|
66
|
+
| `token` | Bearer;可在 YAML 中引用 `${SATORI_TOKEN}` |
|
|
67
67
|
|
|
68
68
|
### Webhook
|
|
69
69
|
|
|
@@ -72,7 +72,7 @@ plugins:
|
|
|
72
72
|
satori:
|
|
73
73
|
connection: webhook
|
|
74
74
|
endpoints:
|
|
75
|
-
-
|
|
75
|
+
- id: satori-bot
|
|
76
76
|
baseUrl: "http://127.0.0.1:5140"
|
|
77
77
|
path: "/satori/webhook"
|
|
78
78
|
token: "${SATORI_TOKEN}"
|
|
@@ -92,7 +92,7 @@ SDK 会向 `path` 发送 POST,请求头 `Satori-Opcode: 0` 表示事件;适
|
|
|
92
92
|
|
|
93
93
|
## AI 工具
|
|
94
94
|
|
|
95
|
-
技能说明见 `
|
|
95
|
+
技能说明见 `skills/satori/SKILL.md`。
|
|
96
96
|
|
|
97
97
|
## 协议文档
|
|
98
98
|
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
2
2
|
/**
|
|
3
|
-
* Convention entry: discover `adapters/satori.ts` → defineAdapter.
|
|
3
|
+
* Convention entry: discover `adapters/satori/index.ts` → defineAdapter.
|
|
4
4
|
*/
|
|
5
5
|
import { defineAdapter } from 'zhin.js/adapter';
|
|
6
6
|
import { httpHostToken } from '@zhin.js/host-http';
|
|
7
|
-
import { SatoriWebhookEndpoint, SatoriWsEndpoint } from "
|
|
8
|
-
import { resolveSatoriConfig, } from "
|
|
9
|
-
import { satoriRuntimeStateToken } from "
|
|
10
|
-
export { SatoriWebhookEndpoint, SatoriWsEndpoint } from "
|
|
7
|
+
import { SatoriWebhookEndpoint, SatoriWsEndpoint } from "../../lib/endpoint.js";
|
|
8
|
+
import { resolveSatoriConfig, } from "../../lib/protocol.js";
|
|
9
|
+
import { satoriRuntimeStateToken } from "../../lib/satori-runtime-state.js";
|
|
10
|
+
export { SatoriWebhookEndpoint, SatoriWsEndpoint } from "../../lib/endpoint.js";
|
|
11
11
|
export default defineAdapter({
|
|
12
12
|
capabilities: ['inbound', 'outbound'],
|
|
13
13
|
operations: ['recall'],
|
|
@@ -18,7 +18,7 @@ export default defineAdapter({
|
|
|
18
18
|
},
|
|
19
19
|
create(context) {
|
|
20
20
|
const config = resolveSatoriConfig(context.config);
|
|
21
|
-
// 注册到插件运行时状态(satori
|
|
21
|
+
// 注册到插件运行时状态(satori endpoint list 的"运行中"数据源)
|
|
22
22
|
context.use(satoriRuntimeStateToken).endpoints.set(config.id, {
|
|
23
23
|
id: config.id,
|
|
24
24
|
mode: config.connection,
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Convention entry: discover `adapters/satori.ts` → defineAdapter.
|
|
2
|
+
* Convention entry: discover `adapters/satori/index.ts` → defineAdapter.
|
|
3
3
|
*/
|
|
4
4
|
import { defineAdapter } from 'zhin.js/adapter';
|
|
5
5
|
import { httpHostToken } from '@zhin.js/host-http';
|
|
6
|
-
import { SatoriWebhookEndpoint, SatoriWsEndpoint } from '
|
|
6
|
+
import { SatoriWebhookEndpoint, SatoriWsEndpoint } from '../../src/endpoint.js';
|
|
7
7
|
import {
|
|
8
8
|
resolveSatoriConfig,
|
|
9
|
-
type
|
|
10
|
-
} from '
|
|
11
|
-
import { satoriRuntimeStateToken } from '
|
|
9
|
+
type SatoriEndpointConfig,
|
|
10
|
+
} from '../../src/protocol.js';
|
|
11
|
+
import { satoriRuntimeStateToken } from '../../src/satori-runtime-state.js';
|
|
12
12
|
|
|
13
|
-
export { SatoriWebhookEndpoint, SatoriWsEndpoint } from '
|
|
13
|
+
export { SatoriWebhookEndpoint, SatoriWsEndpoint } from '../../src/endpoint.js';
|
|
14
14
|
export type {
|
|
15
15
|
CreateSatoriWebSocket,
|
|
16
16
|
SatoriApiCaller,
|
|
17
17
|
SatoriWebhookEndpointOptions,
|
|
18
18
|
SatoriWsEndpointOptions,
|
|
19
19
|
SatoriWsSocket,
|
|
20
|
-
} from '
|
|
20
|
+
} from '../../src/endpoint.js';
|
|
21
21
|
|
|
22
|
-
export default defineAdapter<
|
|
22
|
+
export default defineAdapter<SatoriEndpointConfig>({
|
|
23
23
|
capabilities: ['inbound', 'outbound'],
|
|
24
24
|
operations: ['recall'],
|
|
25
25
|
// Satori 协议 img/file 元素消费 url 与 base64 内联数据;无卡片交互面,交互段降级纯文本。
|
|
@@ -29,7 +29,7 @@ export default defineAdapter<SatoriAdapterConfig>({
|
|
|
29
29
|
},
|
|
30
30
|
create(context) {
|
|
31
31
|
const config = resolveSatoriConfig(context.config);
|
|
32
|
-
// 注册到插件运行时状态(satori
|
|
32
|
+
// 注册到插件运行时状态(satori endpoint list 的"运行中"数据源)
|
|
33
33
|
context.use(satoriRuntimeStateToken).endpoints.set(config.id, {
|
|
34
34
|
id: config.id,
|
|
35
35
|
mode: config.connection,
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
1
2
|
/**
|
|
2
|
-
* `satori
|
|
3
|
-
* commands/endpoint/ 下的 list / add / remove 直接默认导出这三项。
|
|
3
|
+
* `satori endpoint` 命令族:由 @zhin.js/adapter 的 createEndpointCommands 套件生成。
|
|
4
|
+
* commands/satori/endpoint/ 下的 list / add / remove 直接默认导出这三项。
|
|
4
5
|
*/
|
|
5
6
|
import { createEndpointCommands } from 'zhin.js/adapter';
|
|
6
7
|
import { defineCommand } from 'zhin.js/command';
|
|
7
|
-
import { satoriRuntimeStateToken } from
|
|
8
|
+
import { satoriRuntimeStateToken } from "../../../lib/satori-runtime-state.js";
|
|
8
9
|
export const satoriEndpointCommands = createEndpointCommands({
|
|
9
10
|
adapterKey: 'satori',
|
|
10
11
|
adapterDisplayName: 'Satori',
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `satori
|
|
3
|
-
* commands/endpoint/ 下的 list / add / remove 直接默认导出这三项。
|
|
2
|
+
* `satori endpoint` 命令族:由 @zhin.js/adapter 的 createEndpointCommands 套件生成。
|
|
3
|
+
* commands/satori/endpoint/ 下的 list / add / remove 直接默认导出这三项。
|
|
4
4
|
*/
|
|
5
5
|
import { createEndpointCommands } from 'zhin.js/adapter';
|
|
6
6
|
import { defineCommand } from 'zhin.js/command';
|
|
7
|
-
import { satoriRuntimeStateToken } from '
|
|
7
|
+
import { satoriRuntimeStateToken } from '../../../src/satori-runtime-state.js';
|
|
8
8
|
|
|
9
9
|
export const satoriEndpointCommands = createEndpointCommands({
|
|
10
10
|
adapterKey: 'satori',
|
package/lib/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { SatoriOpcode, buildWsUrl, callSatoriApi, extractCreatedMessageId, formatInboundContent, formatSatoriOutbound, isMessageEvent, isPrivateChannel, resolveInboundSender, resolveSatoriConfig, satoriInboundConversation, type ResolvedSatoriWebhookConfig, type ResolvedSatoriWsConfig, type
|
|
1
|
+
export { SatoriOpcode, buildWsUrl, callSatoriApi, extractCreatedMessageId, formatInboundContent, formatSatoriOutbound, isMessageEvent, isPrivateChannel, resolveInboundSender, resolveSatoriConfig, satoriInboundConversation, type ResolvedSatoriWebhookConfig, type ResolvedSatoriWsConfig, type SatoriEndpointConfig, type SatoriApiOptions, type SatoriChannel, type SatoriEventBody, type SatoriLogin, type SatoriMessage, type SatoriSignal, type SatoriUser, type SatoriWireSegment, } from './protocol.js';
|
|
2
2
|
export { SatoriWebhookEndpoint, SatoriWsEndpoint, type CreateSatoriWebSocket, type SatoriApiCaller, type SatoriWebhookEndpointOptions, type SatoriWsEndpointOptions, type SatoriWsSocket, } from './endpoint.js';
|
|
3
3
|
export { handleSatoriWebhookRequest, registerSatoriWebhookRoutes, resolveSatoriOpcode, verifySatoriToken, type SatoriWebhookHandler, } from './webhook.js';
|
|
4
4
|
export { WS_OPEN, defaultCreateWebSocket, } from './ws.js';
|
package/lib/protocol.d.ts
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
* Canonicalization is owned by gateway/core before endpoint.send.
|
|
4
|
-
* Spec: https://satori.chat/zh-CN/protocol/overview.html
|
|
5
|
-
*/
|
|
6
|
-
import type { ConversationRef } from '@zhin.js/im-contract';
|
|
1
|
+
/** Satori protocol helpers. Spec: https://satori.chat/zh-CN/protocol/overview.html */
|
|
2
|
+
import { type ConversationRef } from '@zhin.js/im-contract';
|
|
7
3
|
/** Opcode:EVENT=0, PING=1, PONG=2, IDENTIFY=3, READY=4, META=5 */
|
|
8
4
|
export declare const SatoriOpcode: {
|
|
9
5
|
readonly EVENT: 0;
|
|
@@ -76,21 +72,15 @@ export interface SatoriWireSegment {
|
|
|
76
72
|
readonly type: string;
|
|
77
73
|
readonly data?: Record<string, unknown>;
|
|
78
74
|
}
|
|
79
|
-
/**
|
|
80
|
-
export interface
|
|
81
|
-
readonly id
|
|
75
|
+
/** One endpoint config after AdapterIndex expands `plugins.<instanceKey>.endpoints`. */
|
|
76
|
+
export interface SatoriEndpointConfig {
|
|
77
|
+
readonly id: string;
|
|
82
78
|
readonly connection?: 'ws' | 'webhook';
|
|
83
|
-
readonly baseUrl
|
|
79
|
+
readonly baseUrl: string;
|
|
84
80
|
readonly token?: string;
|
|
85
81
|
readonly heartbeat_interval?: number;
|
|
86
82
|
/** Webhook POST path (connection: webhook). */
|
|
87
83
|
readonly path?: string;
|
|
88
|
-
/** Transitional: legacy root `endpoints[]` with `context: satori`. */
|
|
89
|
-
readonly endpoints?: ReadonlyArray<Partial<ResolvedSatoriWsConfig> & {
|
|
90
|
-
readonly context?: string;
|
|
91
|
-
readonly connection?: 'ws' | 'webhook';
|
|
92
|
-
readonly path?: string;
|
|
93
|
-
}>;
|
|
94
84
|
}
|
|
95
85
|
export interface ResolvedSatoriWsConfig {
|
|
96
86
|
readonly context: 'satori';
|
|
@@ -109,7 +99,7 @@ export interface ResolvedSatoriWebhookConfig {
|
|
|
109
99
|
readonly path: string;
|
|
110
100
|
}
|
|
111
101
|
export type ResolvedSatoriConfig = ResolvedSatoriWsConfig | ResolvedSatoriWebhookConfig;
|
|
112
|
-
export declare function resolveSatoriConfig(config
|
|
102
|
+
export declare function resolveSatoriConfig(config: SatoriEndpointConfig): ResolvedSatoriConfig;
|
|
113
103
|
/** Channel.type 1 = DIRECT (private). */
|
|
114
104
|
export declare function isPrivateChannel(channel?: SatoriChannel): boolean;
|
|
115
105
|
export declare function isMessageEvent(body: SatoriEventBody): body is SatoriEventBody & {
|
package/lib/protocol.js
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
* Canonicalization is owned by gateway/core before endpoint.send.
|
|
4
|
-
* Spec: https://satori.chat/zh-CN/protocol/overview.html
|
|
5
|
-
*/
|
|
6
|
-
import { pickCredential } from 'zhin.js/adapter';
|
|
7
|
-
import { isMediaRef } from '@zhin.js/core';
|
|
1
|
+
/** Satori protocol helpers. Spec: https://satori.chat/zh-CN/protocol/overview.html */
|
|
2
|
+
import { isMediaRef } from '@zhin.js/im-contract';
|
|
8
3
|
import { formatCompact, getLogger } from '@zhin.js/logger';
|
|
9
4
|
const logger = getLogger('satori');
|
|
10
5
|
/** Opcode:EVENT=0, PING=1, PONG=2, IDENTIFY=3, READY=4, META=5 */
|
|
@@ -16,26 +11,15 @@ export const SatoriOpcode = {
|
|
|
16
11
|
READY: 4,
|
|
17
12
|
META: 5,
|
|
18
13
|
};
|
|
19
|
-
export function resolveSatoriConfig(config
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
const baseUrl =
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const id = (typeof config.id === 'string' && config.id)
|
|
27
|
-
|| (typeof entry?.id === 'string' && entry.id)
|
|
28
|
-
|| process.env.SATORI_BOT_NAME
|
|
29
|
-
|| 'satori-bot';
|
|
30
|
-
const token = (typeof config.token === 'string' && config.token)
|
|
31
|
-
|| (typeof entry?.token === 'string' && entry.token)
|
|
32
|
-
|| process.env.SATORI_TOKEN
|
|
33
|
-
|| undefined;
|
|
14
|
+
export function resolveSatoriConfig(config) {
|
|
15
|
+
const connection = config.connection ?? 'ws';
|
|
16
|
+
const id = requiredEndpointField(config.id, 'id');
|
|
17
|
+
const baseUrl = requiredEndpointField(config.baseUrl, 'baseUrl');
|
|
18
|
+
const token = typeof config.token === 'string' && config.token.trim()
|
|
19
|
+
? config.token.trim()
|
|
20
|
+
: undefined;
|
|
34
21
|
if (connection === 'webhook') {
|
|
35
|
-
const path = config.path
|
|
36
|
-
if (!path) {
|
|
37
|
-
throw new TypeError('Satori connection:webhook requires path');
|
|
38
|
-
}
|
|
22
|
+
const path = requiredEndpointField(config.path, 'path');
|
|
39
23
|
return {
|
|
40
24
|
context: 'satori',
|
|
41
25
|
connection: 'webhook',
|
|
@@ -45,9 +29,7 @@ export function resolveSatoriConfig(config = {}) {
|
|
|
45
29
|
path,
|
|
46
30
|
};
|
|
47
31
|
}
|
|
48
|
-
const heartbeat = config.heartbeat_interval
|
|
49
|
-
?? entry?.heartbeat_interval
|
|
50
|
-
?? 10_000;
|
|
32
|
+
const heartbeat = config.heartbeat_interval ?? 10_000;
|
|
51
33
|
return {
|
|
52
34
|
context: 'satori',
|
|
53
35
|
connection: 'ws',
|
|
@@ -57,6 +39,12 @@ export function resolveSatoriConfig(config = {}) {
|
|
|
57
39
|
heartbeat_interval: heartbeat,
|
|
58
40
|
};
|
|
59
41
|
}
|
|
42
|
+
function requiredEndpointField(value, field) {
|
|
43
|
+
if (typeof value !== 'string' || !value.trim()) {
|
|
44
|
+
throw new TypeError(`Satori endpoint requires a non-empty ${field}`);
|
|
45
|
+
}
|
|
46
|
+
return value.trim();
|
|
47
|
+
}
|
|
60
48
|
/** Channel.type 1 = DIRECT (private). */
|
|
61
49
|
export function isPrivateChannel(channel) {
|
|
62
50
|
return channel?.type === 1;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Satori 插件实例的运行时状态:adapter create() 注册的 endpoint 列表。
|
|
3
|
-
* 由 plugin.ts setup() provide,adapter create 与 `satori
|
|
3
|
+
* 由 plugin.ts setup() provide,adapter create 与 `satori endpoint` 命令共享(同一 owner generation)。
|
|
4
4
|
*/
|
|
5
5
|
import { defineEndpointRuntimeStateToken } from 'zhin.js/adapter';
|
|
6
6
|
export const satoriRuntimeStateToken = defineEndpointRuntimeStateToken('satori');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhin.js/adapter-satori",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
4
|
"description": "Zhin.js Satori adapter for Plugin Runtime (WebSocket client)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"schema.json",
|
|
20
20
|
"src",
|
|
21
21
|
"lib",
|
|
22
|
-
"
|
|
22
|
+
"skills",
|
|
23
23
|
"README.md",
|
|
24
24
|
"CHANGELOG.md"
|
|
25
25
|
],
|
|
@@ -41,26 +41,27 @@
|
|
|
41
41
|
"@imhelper/satori-v1": "1.0.7",
|
|
42
42
|
"imhelper": "1.0.7",
|
|
43
43
|
"ws": "^8.21.1",
|
|
44
|
-
"@zhin.js/adapter": "1.1.
|
|
45
|
-
"@zhin.js/core": "1.1.
|
|
46
|
-
"@zhin.js/feature-kit": "1.1.
|
|
47
|
-
"@zhin.js/host-http": "1.1.
|
|
48
|
-
"@zhin.js/im-contract": "1.1.
|
|
49
|
-
"@zhin.js/logger": "1.1.
|
|
44
|
+
"@zhin.js/adapter": "1.1.15",
|
|
45
|
+
"@zhin.js/core": "1.1.38",
|
|
46
|
+
"@zhin.js/feature-kit": "1.1.2",
|
|
47
|
+
"@zhin.js/host-http": "1.1.2",
|
|
48
|
+
"@zhin.js/im-contract": "1.1.2",
|
|
49
|
+
"@zhin.js/logger": "1.1.1",
|
|
50
|
+
"@zhin.js/skill": "1.1.2"
|
|
50
51
|
},
|
|
51
52
|
"devDependencies": {
|
|
52
53
|
"@types/node": "^26.1.2",
|
|
53
54
|
"@types/ws": "^8.18.1",
|
|
54
55
|
"typescript": "^6.0.3",
|
|
55
56
|
"vitest": "^4.1.10",
|
|
56
|
-
"@zhin.js/host-http": "1.1.
|
|
57
|
-
"zhin.js": "1.1.
|
|
57
|
+
"@zhin.js/host-http": "1.1.2",
|
|
58
|
+
"zhin.js": "1.1.3"
|
|
58
59
|
},
|
|
59
60
|
"peerDependencies": {
|
|
60
|
-
"@zhin.js/adapter": "^1.1.
|
|
61
|
-
"@zhin.js/command": "^1.1.
|
|
62
|
-
"@zhin.js/core": "^1.1.
|
|
63
|
-
"zhin.js": "^1.1.
|
|
61
|
+
"@zhin.js/adapter": "^1.1.15",
|
|
62
|
+
"@zhin.js/command": "^1.1.2",
|
|
63
|
+
"@zhin.js/core": "^1.1.38",
|
|
64
|
+
"zhin.js": "^1.1.3"
|
|
64
65
|
},
|
|
65
66
|
"peerDependenciesMeta": {
|
|
66
67
|
"@zhin.js/command": {
|
|
@@ -96,6 +97,10 @@
|
|
|
96
97
|
{
|
|
97
98
|
"package": "@zhin.js/command",
|
|
98
99
|
"api": "^1.0.0"
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"package": "@zhin.js/skill",
|
|
103
|
+
"api": "^1.0.0"
|
|
99
104
|
}
|
|
100
105
|
],
|
|
101
106
|
"plugins": []
|
package/plugin.js
CHANGED
|
@@ -8,7 +8,7 @@ export default definePlugin({
|
|
|
8
8
|
displayName: 'Satori Adapter',
|
|
9
9
|
},
|
|
10
10
|
setup(context) {
|
|
11
|
-
// 运行中 endpoint 注册表(satori
|
|
11
|
+
// 运行中 endpoint 注册表(satori endpoint list 的"运行中"数据源)
|
|
12
12
|
context.resources.provide(satoriRuntimeStateToken, createEndpointRuntimeState());
|
|
13
13
|
},
|
|
14
14
|
});
|
package/schema.json
CHANGED
|
@@ -37,10 +37,11 @@
|
|
|
37
37
|
},
|
|
38
38
|
"endpoints": {
|
|
39
39
|
"type": "array",
|
|
40
|
-
"
|
|
40
|
+
"minItems": 1,
|
|
41
|
+
"description": "多账号:每项定义一个 endpoint,id/baseUrl 必填,其余字段覆盖实例默认值",
|
|
41
42
|
"items": {
|
|
42
43
|
"type": "object",
|
|
43
|
-
"additionalProperties":
|
|
44
|
+
"additionalProperties": false,
|
|
44
45
|
"properties": {
|
|
45
46
|
"master": {
|
|
46
47
|
"type": [
|
|
@@ -64,6 +65,13 @@
|
|
|
64
65
|
"type": "string",
|
|
65
66
|
"description": "Satori SDK HTTP/WS base URL (e.g. http://127.0.0.1:5140)"
|
|
66
67
|
},
|
|
68
|
+
"connection": {
|
|
69
|
+
"type": "string",
|
|
70
|
+
"enum": [
|
|
71
|
+
"ws",
|
|
72
|
+
"webhook"
|
|
73
|
+
]
|
|
74
|
+
},
|
|
67
75
|
"token": {
|
|
68
76
|
"type": "string",
|
|
69
77
|
"description": "Bearer token for API and WS IDENTIFY"
|
|
@@ -72,6 +80,12 @@
|
|
|
72
80
|
"type": "string",
|
|
73
81
|
"description": "Webhook POST path (connection: webhook)"
|
|
74
82
|
},
|
|
83
|
+
"heartbeat_interval": {
|
|
84
|
+
"type": "number"
|
|
85
|
+
},
|
|
86
|
+
"commandPrefix": {
|
|
87
|
+
"type": "string"
|
|
88
|
+
},
|
|
75
89
|
"id": {
|
|
76
90
|
"type": "string",
|
|
77
91
|
"description": "Satori bot name"
|
package/src/index.ts
CHANGED
package/src/protocol.ts
CHANGED
|
@@ -1,12 +1,6 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Satori protocol helpers (no legacy Adapter/Endpoint / segment-mapper).
|
|
3
|
-
* Canonicalization is owned by gateway/core before endpoint.send.
|
|
4
|
-
* Spec: https://satori.chat/zh-CN/protocol/overview.html
|
|
5
|
-
*/
|
|
1
|
+
/** Satori protocol helpers. Spec: https://satori.chat/zh-CN/protocol/overview.html */
|
|
6
2
|
|
|
7
|
-
import {
|
|
8
|
-
import { isMediaRef } from '@zhin.js/core';
|
|
9
|
-
import type { ConversationKind, ConversationRef } from '@zhin.js/im-contract';
|
|
3
|
+
import { isMediaRef, type ConversationKind, type ConversationRef } from '@zhin.js/im-contract';
|
|
10
4
|
import { formatCompact, getLogger } from '@zhin.js/logger';
|
|
11
5
|
|
|
12
6
|
const logger = getLogger('satori');
|
|
@@ -82,21 +76,15 @@ export interface SatoriWireSegment {
|
|
|
82
76
|
readonly data?: Record<string, unknown>;
|
|
83
77
|
}
|
|
84
78
|
|
|
85
|
-
/**
|
|
86
|
-
export interface
|
|
87
|
-
readonly id
|
|
79
|
+
/** One endpoint config after AdapterIndex expands `plugins.<instanceKey>.endpoints`. */
|
|
80
|
+
export interface SatoriEndpointConfig {
|
|
81
|
+
readonly id: string;
|
|
88
82
|
readonly connection?: 'ws' | 'webhook';
|
|
89
|
-
readonly baseUrl
|
|
83
|
+
readonly baseUrl: string;
|
|
90
84
|
readonly token?: string;
|
|
91
85
|
readonly heartbeat_interval?: number;
|
|
92
86
|
/** Webhook POST path (connection: webhook). */
|
|
93
87
|
readonly path?: string;
|
|
94
|
-
/** Transitional: legacy root `endpoints[]` with `context: satori`. */
|
|
95
|
-
readonly endpoints?: ReadonlyArray<Partial<ResolvedSatoriWsConfig> & {
|
|
96
|
-
readonly context?: string;
|
|
97
|
-
readonly connection?: 'ws' | 'webhook';
|
|
98
|
-
readonly path?: string;
|
|
99
|
-
}>;
|
|
100
88
|
}
|
|
101
89
|
|
|
102
90
|
export interface ResolvedSatoriWsConfig {
|
|
@@ -119,29 +107,16 @@ export interface ResolvedSatoriWebhookConfig {
|
|
|
119
107
|
|
|
120
108
|
export type ResolvedSatoriConfig = ResolvedSatoriWsConfig | ResolvedSatoriWebhookConfig;
|
|
121
109
|
|
|
122
|
-
export function resolveSatoriConfig(config:
|
|
123
|
-
const
|
|
124
|
-
const
|
|
125
|
-
const baseUrl =
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
);
|
|
130
|
-
}
|
|
131
|
-
const id = (typeof config.id === 'string' && config.id)
|
|
132
|
-
|| (typeof entry?.id === 'string' && entry.id)
|
|
133
|
-
|| process.env.SATORI_BOT_NAME
|
|
134
|
-
|| 'satori-bot';
|
|
135
|
-
const token = (typeof config.token === 'string' && config.token)
|
|
136
|
-
|| (typeof entry?.token === 'string' && entry.token)
|
|
137
|
-
|| process.env.SATORI_TOKEN
|
|
138
|
-
|| undefined;
|
|
110
|
+
export function resolveSatoriConfig(config: SatoriEndpointConfig): ResolvedSatoriConfig {
|
|
111
|
+
const connection = config.connection ?? 'ws';
|
|
112
|
+
const id = requiredEndpointField(config.id, 'id');
|
|
113
|
+
const baseUrl = requiredEndpointField(config.baseUrl, 'baseUrl');
|
|
114
|
+
const token = typeof config.token === 'string' && config.token.trim()
|
|
115
|
+
? config.token.trim()
|
|
116
|
+
: undefined;
|
|
139
117
|
|
|
140
118
|
if (connection === 'webhook') {
|
|
141
|
-
const path = config.path
|
|
142
|
-
if (!path) {
|
|
143
|
-
throw new TypeError('Satori connection:webhook requires path');
|
|
144
|
-
}
|
|
119
|
+
const path = requiredEndpointField(config.path, 'path');
|
|
145
120
|
return {
|
|
146
121
|
context: 'satori',
|
|
147
122
|
connection: 'webhook',
|
|
@@ -152,9 +127,7 @@ export function resolveSatoriConfig(config: SatoriAdapterConfig = {}): ResolvedS
|
|
|
152
127
|
};
|
|
153
128
|
}
|
|
154
129
|
|
|
155
|
-
const heartbeat = config.heartbeat_interval
|
|
156
|
-
?? entry?.heartbeat_interval
|
|
157
|
-
?? 10_000;
|
|
130
|
+
const heartbeat = config.heartbeat_interval ?? 10_000;
|
|
158
131
|
return {
|
|
159
132
|
context: 'satori',
|
|
160
133
|
connection: 'ws',
|
|
@@ -165,6 +138,16 @@ export function resolveSatoriConfig(config: SatoriAdapterConfig = {}): ResolvedS
|
|
|
165
138
|
};
|
|
166
139
|
}
|
|
167
140
|
|
|
141
|
+
function requiredEndpointField(
|
|
142
|
+
value: unknown,
|
|
143
|
+
field: 'id' | 'baseUrl' | 'path',
|
|
144
|
+
): string {
|
|
145
|
+
if (typeof value !== 'string' || !value.trim()) {
|
|
146
|
+
throw new TypeError(`Satori endpoint requires a non-empty ${field}`);
|
|
147
|
+
}
|
|
148
|
+
return value.trim();
|
|
149
|
+
}
|
|
150
|
+
|
|
168
151
|
/** Channel.type 1 = DIRECT (private). */
|
|
169
152
|
export function isPrivateChannel(channel?: SatoriChannel): boolean {
|
|
170
153
|
return channel?.type === 1;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Satori 插件实例的运行时状态:adapter create() 注册的 endpoint 列表。
|
|
3
|
-
* 由 plugin.ts setup() provide,adapter create 与 `satori
|
|
3
|
+
* 由 plugin.ts setup() provide,adapter create 与 `satori endpoint` 命令共享(同一 owner generation)。
|
|
4
4
|
*/
|
|
5
5
|
import { defineEndpointRuntimeStateToken } from 'zhin.js/adapter';
|
|
6
6
|
|
package/agent/skills/satori.md
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: satori
|
|
3
|
-
platforms:
|
|
4
|
-
- satori
|
|
5
|
-
description: >-
|
|
6
|
-
Satori 协议适配器:支持 WebSocket(正向)和 Webhook 两种连接方式,
|
|
7
|
-
实现 Satori 标准协议的消息收发。纯消息通道,无额外 AI 工具。
|
|
8
|
-
Satori 是跨平台的统一协议,可对接多种 IM 后端。
|
|
9
|
-
keywords:
|
|
10
|
-
- satori
|
|
11
|
-
- adapter:satori
|
|
12
|
-
- protocol
|
|
13
|
-
- websocket
|
|
14
|
-
- webhook
|
|
15
|
-
- 协议
|
|
16
|
-
- 跨平台
|
|
17
|
-
tags:
|
|
18
|
-
- satori
|
|
19
|
-
- protocol
|
|
20
|
-
- adapter
|
|
21
|
-
tools: []
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
# Satori 协议适配器
|
|
25
|
-
|
|
26
|
-
纯协议适配器,收发消息。无 AI 工具可调用。
|
|
27
|
-
|
|
28
|
-
## 连接模式
|
|
29
|
-
|
|
30
|
-
- **WS 正向**:Bot 主动连接 Satori 服务端
|
|
31
|
-
- **Webhook**:Satori 向配置的 URL 推送事件
|
|
32
|
-
|
|
33
|
-
Satori 是跨平台统一协议,可作为中间层对接 QQ、Discord、Telegram 等后端。
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const satoriEndpointCommands: import("@zhin.js/adapter").EndpointCommands<Readonly<import("@zhin.js/command").CommandDefinition<unknown, unknown, import("@zhin.js/command").CommandMessage, string | undefined>>>;
|