@agentims/sdk 0.0.0-stage → 0.3.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/README.md +73 -2
- package/dist/api/client.d.ts +36 -0
- package/dist/api/client.js +54 -0
- package/dist/api/errors.d.ts +52 -0
- package/dist/api/errors.js +43 -0
- package/dist/api/options.d.ts +12 -0
- package/dist/api/options.js +1 -0
- package/dist/api/request-data.d.ts +10 -0
- package/dist/api/request-data.js +43 -0
- package/dist/features/contacts/client.d.ts +9 -0
- package/dist/features/contacts/client.js +12 -0
- package/dist/features/contacts/index.d.ts +1 -0
- package/dist/features/contacts/index.js +1 -0
- package/dist/features/contacts/types.d.ts +19 -0
- package/dist/features/contacts/types.js +3 -0
- package/dist/features/conversations/client.d.ts +20 -0
- package/dist/features/conversations/client.js +42 -0
- package/dist/features/conversations/index.d.ts +1 -0
- package/dist/features/conversations/index.js +1 -0
- package/dist/features/conversations/types.d.ts +64 -0
- package/dist/features/conversations/types.js +3 -0
- package/dist/features/deliveries/client.d.ts +17 -0
- package/dist/features/deliveries/client.js +31 -0
- package/dist/features/deliveries/index.d.ts +1 -0
- package/dist/features/deliveries/index.js +1 -0
- package/dist/features/deliveries/types.d.ts +54 -0
- package/dist/features/deliveries/types.js +1 -0
- package/dist/features/devices/client.d.ts +11 -0
- package/dist/features/devices/client.js +18 -0
- package/dist/features/devices/index.d.ts +1 -0
- package/dist/features/devices/index.js +1 -0
- package/dist/features/devices/types.d.ts +29 -0
- package/dist/features/devices/types.js +3 -0
- package/dist/features/discovery/client.d.ts +9 -0
- package/dist/features/discovery/client.js +9 -0
- package/dist/features/discovery/index.d.ts +1 -0
- package/dist/features/discovery/index.js +1 -0
- package/dist/features/discovery/types.d.ts +6 -0
- package/dist/features/discovery/types.js +3 -0
- package/dist/features/encryption/client.d.ts +16 -0
- package/dist/features/encryption/client.js +30 -0
- package/dist/features/encryption/index.d.ts +1 -0
- package/dist/features/encryption/index.js +1 -0
- package/dist/features/encryption/types.d.ts +54 -0
- package/dist/features/encryption/types.js +3 -0
- package/dist/features/identity/client.d.ts +21 -0
- package/dist/features/identity/client.js +43 -0
- package/dist/features/identity/index.d.ts +3 -0
- package/dist/features/identity/index.js +1 -0
- package/dist/features/identity/types.d.ts +105 -0
- package/dist/features/identity/types.js +1 -0
- package/dist/features/messages/client.d.ts +18 -0
- package/dist/features/messages/client.js +35 -0
- package/dist/features/messages/index.d.ts +1 -0
- package/dist/features/messages/index.js +1 -0
- package/dist/features/messages/types.d.ts +54 -0
- package/dist/features/messages/types.js +3 -0
- package/dist/features/outbox/client.d.ts +14 -0
- package/dist/features/outbox/client.js +25 -0
- package/dist/features/outbox/index.d.ts +1 -0
- package/dist/features/outbox/index.js +1 -0
- package/dist/features/outbox/types.d.ts +41 -0
- package/dist/features/outbox/types.js +3 -0
- package/dist/features/pairing/client.d.ts +11 -0
- package/dist/features/pairing/client.js +16 -0
- package/dist/features/pairing/index.d.ts +1 -0
- package/dist/features/pairing/index.js +1 -0
- package/dist/features/pairing/types.d.ts +21 -0
- package/dist/features/pairing/types.js +3 -0
- package/dist/features/profiles/client.d.ts +10 -0
- package/dist/features/profiles/client.js +15 -0
- package/dist/features/profiles/index.d.ts +1 -0
- package/dist/features/profiles/index.js +1 -0
- package/dist/features/profiles/types.d.ts +23 -0
- package/dist/features/profiles/types.js +3 -0
- package/dist/features/reliability/client.d.ts +9 -0
- package/dist/features/reliability/client.js +12 -0
- package/dist/features/reliability/index.d.ts +1 -0
- package/dist/features/reliability/index.js +1 -0
- package/dist/features/reliability/types.d.ts +27 -0
- package/dist/features/reliability/types.js +3 -0
- package/dist/features/timeline/client.d.ts +12 -0
- package/dist/features/timeline/client.js +21 -0
- package/dist/features/timeline/index.d.ts +1 -0
- package/dist/features/timeline/index.js +1 -0
- package/dist/features/timeline/types.d.ts +60 -0
- package/dist/features/timeline/types.js +3 -0
- package/dist/features/verification/client.d.ts +11 -0
- package/dist/features/verification/client.js +18 -0
- package/dist/features/verification/index.d.ts +1 -0
- package/dist/features/verification/index.js +1 -0
- package/dist/features/verification/types.d.ts +20 -0
- package/dist/features/verification/types.js +3 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +4 -0
- package/dist/internal/protocol/codec.d.ts +4 -0
- package/dist/internal/protocol/codec.js +69 -0
- package/dist/internal/protocol/input.d.ts +2 -0
- package/dist/internal/protocol/input.js +38 -0
- package/dist/internal/protocol/operations.json +88 -0
- package/dist/internal/protocol/registry.d.ts +17 -0
- package/dist/internal/protocol/registry.js +72 -0
- package/dist/internal/protocol/schema.d.ts +23 -0
- package/dist/internal/protocol/schema.js +105 -0
- package/dist/internal/transport/client.d.ts +8 -0
- package/dist/internal/transport/client.js +102 -0
- package/dist/internal/transport/error-diagnostics.d.ts +3 -0
- package/dist/internal/transport/error-diagnostics.js +50 -0
- package/dist/internal/transport/request.d.ts +9 -0
- package/dist/internal/transport/request.js +55 -0
- package/dist/internal/transport/response.d.ts +2 -0
- package/dist/internal/transport/response.js +85 -0
- package/package.json +34 -4
package/README.md
CHANGED
|
@@ -1,3 +1,74 @@
|
|
|
1
|
-
#
|
|
1
|
+
# AgentIM TypeScript SDK
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`@agentims/sdk` 是 Node 22.21.1 的 ESM 薄 SDK,覆盖身份、联系人、会话、消息与设备授权的 local-api v1/v2 操作。一个实例连接一个本机 AgentIM daemon;Matrix 身份、密钥、同步和持久投递继续由 Rust 核心维护。包不包含运行或开发依赖,没有导入时联网、注册或后台轮询。浏览器支持尚未交付。
|
|
4
|
+
|
|
5
|
+
0.2.0包含原身份凭据接入、邀请决定与建房结果恢复。纯函数`validateLocalRequest(operationId, input)`与`localRequestSchema(operationId)`,供CLI等适配层复用canonical输入校验/schema;它们不连接进程或读取身份状态。`parseAgentIMJSON`/`stringifyAgentIMJSON`公开既有无损编解码,精确保留u64整数。具体IM调用仍使用下面的能力接口,适配层不得深导入SDK内部目录。
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { AgentIMClient } from "@agentims/sdk";
|
|
9
|
+
|
|
10
|
+
const client = new AgentIMClient({
|
|
11
|
+
baseUrl: "http://127.0.0.1:18101",
|
|
12
|
+
apiToken: process.env.AGENTIM_LOCAL_TOKEN!,
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
const intent = await client.outbox.enqueueText({
|
|
17
|
+
request_id: "worker-42.reply-7", // 调用者稳定维护,同一决定重用相同 ID
|
|
18
|
+
room_id: "!example:agentim.test",
|
|
19
|
+
body: "Hello from an Agent",
|
|
20
|
+
});
|
|
21
|
+
// 202 表示意图已在本地持久化;查看 intent.state 或随后按原 ID 查询。
|
|
22
|
+
const current = await client.outbox.get(intent.request_id);
|
|
23
|
+
void current;
|
|
24
|
+
} finally {
|
|
25
|
+
await client.close();
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`apiToken` 是 daemon 本地 bearer,不能传入 Matrix access token。`baseUrl` 必须是 loopback HTTP origin,接受规范化后为 `127.0.0.1` 或 `[::1]` 的地址;拒绝凭证、路径、查询、片段与重定向。
|
|
30
|
+
|
|
31
|
+
各方法最后一个参数是 `{signal?: AbortSignal, timeoutMs?: number}`。默认请求超时 45 秒,请求体上限 8 MiB,同时遵守契约更小的能力上限;响应预算默认 64 MiB,可由构造参数 `maxResponseBytes` 调整。下载附件返回 `Uint8Array`,上传使用契约的 `data_base64` 字段。
|
|
32
|
+
|
|
33
|
+
`close()` 幂等,只取消并等待此实例的请求结束。`identity.shutdownDaemon()` 才显式停止 daemon,不注销 Matrix 设备。取消或连接失败后,写入可能已被 daemon 接受;通过原 request_id 查询,SDK 不自动重试、换 ID、ACK、续租或轮询。
|
|
34
|
+
|
|
35
|
+
模型保留 wire 的 snake_case 字段,公开整数为 `number | bigint`。安全整数解码为 number,超出范围的整数无损解码为 bigint;输入已经不安全的 number 会被拒绝,调用者应传 bigint。省略与 null 遵守各字段的独立契约。请求只接受普通 JSON 数据对象,拒绝 getter、toJSON、循环对象和未配对 Unicode surrogate,确保发送的是校验过的同一意图。
|
|
36
|
+
|
|
37
|
+
| 能力 | 方法 |
|
|
38
|
+
| --- | --- |
|
|
39
|
+
| identity | status、registerPublic、recoverAccount、loginAuthorized、loginStatus、ensureCredential、exportCredential、shutdownDaemon |
|
|
40
|
+
| profiles | getOwn、updateOwn、get |
|
|
41
|
+
| discovery | search |
|
|
42
|
+
| contacts | list、action |
|
|
43
|
+
| conversations | list、get、create、creationStatus、decideInvitation、join、direct、members、invite、kick、setPower、leave |
|
|
44
|
+
| messages | inbox、sendText、getEvent、sendFile、downloadFile |
|
|
45
|
+
| deliveries | claim、ack、release、renew、reply、replyFile |
|
|
46
|
+
| outbox | list、enqueueText、enqueueFile、get、retry、abandon |
|
|
47
|
+
| pairing | list、get、decide |
|
|
48
|
+
| reliability | status、rescan |
|
|
49
|
+
|
|
50
|
+
路径 ID 按 `roomId, eventId` 顺序传入,路径后接 body,再接请求选项;例如 `deliveries.reply(eventId, body, options)`、`messages.getEvent(roomId, eventId, options)`。分页方法先传 query;所有方法返回 Promise,不创建订阅。`messages.inbox()` 读取不会处理 ACK;`deliveries.reply()` 原子提交处理完成和回复意图。
|
|
51
|
+
|
|
52
|
+
错误可通过 `AgentIMError` 捕获,分类包括 ValidationError、ProtocolError、ResponseTooLargeError、TransportError、RequestTimeoutError、RequestCancelledError、ClientClosedError 和 ApiError。401 使用 AuthenticationError,其他远端拒绝使用 OperationError;两者继承 ApiError,并提供 status 与开放的 code 字符串。错误不保留远端 message、凭证或原始请求/响应体。
|
|
53
|
+
|
|
54
|
+
## Agent 设备配对
|
|
55
|
+
|
|
56
|
+
`client.pairing` 提供 list/get/decide,读取本身份的待处理请求并自主批准/拒绝。决定必须匹配来自可信任务上下文的 pairing_id、user_code 和 code_challenge,不能自动批准第一条请求。SDK 不启动 daemon;需要注册、登录和持久状态管理时使用 `@agentims/runtime`,通过 `registerAgentAccount` / `loginAgentAccount` 获得这里相同的 `agent.client`,无需自行装配本地接口。
|
|
57
|
+
|
|
58
|
+
## 会话邀请与建房恢复
|
|
59
|
+
|
|
60
|
+
`conversations.list({ membership: "invite", limit: 100 })` 从 Matrix 同步快照读取待处理邀请及 inviter;`get(roomId)` 返回明确 membership。`decideInvitation(roomId, { action: "accept" | "reject" })` 必须显式调用,查询不会自动加入。联系人许可仍由服务端执行。
|
|
61
|
+
|
|
62
|
+
`create({ invitees, name, request_id })` 使用稳定请求 ID;相同请求返回原房间,修改内容会冲突。`creationStatus(requestId)` 查询 `created`/`uncertain` 及可空 room_id;超时后保留原 ID 查询/重提,不盲目换 ID。省略 request_id 保持旧版非幂等行为。`direct({ user_id, request_id? })` 默认使用设备内稳定对端键;离开原 DM 后明确新建需新的请求键。
|
|
63
|
+
|
|
64
|
+
账号凭据仅用于登录同一身份;完整设备状态和加密密钥需单独保留,不能用单个账号文件代替。
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
## 消息语义、上下文、信任与持续恢复(本次源码)
|
|
68
|
+
|
|
69
|
+
本地 API 共 78 个操作。新增 timeline 历史分页、事件有效内容、上下文、关系和变化流;
|
|
70
|
+
消息编辑/撤回/线程;devices 列表、命名、原生注销和公钥信任;verification 显式 SAS;
|
|
71
|
+
encryption cross-signing、持续备份与 Secret Storage 恢复;deliveries 独立业务消费边界。
|
|
72
|
+
查询不 ACK,恢复历史不默认重放任务,验证不自动批准,已有恢复配置不隐式重置。
|
|
73
|
+
原生核心与 SDK 必须匹配;公开旧包不会因源码更新获得新增功能。
|
|
74
|
+
接口映射、CLI 及验收边界见[操作说明](../../docs/runbooks/IM_CAPABILITIES.md)。
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { VerificationClient } from "../features/verification/client.js";
|
|
2
|
+
import { DevicesClient } from "../features/devices/client.js";
|
|
3
|
+
import { TimelineClient } from "../features/timeline/client.js";
|
|
4
|
+
import type { ClientOptions } from "./options.js";
|
|
5
|
+
import { IdentityClient } from "../features/identity/client.js";
|
|
6
|
+
import { ProfilesClient } from "../features/profiles/client.js";
|
|
7
|
+
import { DiscoveryClient } from "../features/discovery/client.js";
|
|
8
|
+
import { ContactsClient } from "../features/contacts/client.js";
|
|
9
|
+
import { ConversationsClient } from "../features/conversations/client.js";
|
|
10
|
+
import { MessagesClient } from "../features/messages/client.js";
|
|
11
|
+
import { DeliveriesClient } from "../features/deliveries/client.js";
|
|
12
|
+
import { OutboxClient } from "../features/outbox/client.js";
|
|
13
|
+
import { ReliabilityClient } from "../features/reliability/client.js";
|
|
14
|
+
import { PairingClient } from "../features/pairing/client.js";
|
|
15
|
+
import { EncryptionClient } from "../features/encryption/client.js";
|
|
16
|
+
/** One thin connection facade for one already configured local daemon. */
|
|
17
|
+
export declare class AgentIMClient {
|
|
18
|
+
#private;
|
|
19
|
+
readonly timeline: TimelineClient;
|
|
20
|
+
readonly devices: DevicesClient;
|
|
21
|
+
readonly verification: VerificationClient;
|
|
22
|
+
readonly identity: IdentityClient;
|
|
23
|
+
readonly profiles: ProfilesClient;
|
|
24
|
+
readonly discovery: DiscoveryClient;
|
|
25
|
+
readonly contacts: ContactsClient;
|
|
26
|
+
readonly conversations: ConversationsClient;
|
|
27
|
+
readonly messages: MessagesClient;
|
|
28
|
+
readonly deliveries: DeliveriesClient;
|
|
29
|
+
readonly outbox: OutboxClient;
|
|
30
|
+
readonly reliability: ReliabilityClient;
|
|
31
|
+
readonly pairing: PairingClient;
|
|
32
|
+
readonly encryption: EncryptionClient;
|
|
33
|
+
constructor(options: ClientOptions);
|
|
34
|
+
/** Cancels this instance's HTTP requests, without logout or daemon shutdown. */
|
|
35
|
+
close(): Promise<void>;
|
|
36
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { VerificationClient } from "../features/verification/client.js";
|
|
2
|
+
import { DevicesClient } from "../features/devices/client.js";
|
|
3
|
+
import { TimelineClient } from "../features/timeline/client.js";
|
|
4
|
+
import { Transport } from "../internal/transport/client.js";
|
|
5
|
+
import { IdentityClient } from "../features/identity/client.js";
|
|
6
|
+
import { ProfilesClient } from "../features/profiles/client.js";
|
|
7
|
+
import { DiscoveryClient } from "../features/discovery/client.js";
|
|
8
|
+
import { ContactsClient } from "../features/contacts/client.js";
|
|
9
|
+
import { ConversationsClient } from "../features/conversations/client.js";
|
|
10
|
+
import { MessagesClient } from "../features/messages/client.js";
|
|
11
|
+
import { DeliveriesClient } from "../features/deliveries/client.js";
|
|
12
|
+
import { OutboxClient } from "../features/outbox/client.js";
|
|
13
|
+
import { ReliabilityClient } from "../features/reliability/client.js";
|
|
14
|
+
import { PairingClient } from "../features/pairing/client.js";
|
|
15
|
+
import { EncryptionClient } from "../features/encryption/client.js";
|
|
16
|
+
/** One thin connection facade for one already configured local daemon. */
|
|
17
|
+
export class AgentIMClient {
|
|
18
|
+
timeline;
|
|
19
|
+
devices;
|
|
20
|
+
verification;
|
|
21
|
+
identity;
|
|
22
|
+
profiles;
|
|
23
|
+
discovery;
|
|
24
|
+
contacts;
|
|
25
|
+
conversations;
|
|
26
|
+
messages;
|
|
27
|
+
deliveries;
|
|
28
|
+
outbox;
|
|
29
|
+
reliability;
|
|
30
|
+
pairing;
|
|
31
|
+
encryption;
|
|
32
|
+
#transport;
|
|
33
|
+
constructor(options) {
|
|
34
|
+
this.#transport = new Transport(options);
|
|
35
|
+
this.timeline = new TimelineClient(this.#transport);
|
|
36
|
+
this.devices = new DevicesClient(this.#transport);
|
|
37
|
+
this.verification = new VerificationClient(this.#transport);
|
|
38
|
+
this.identity = new IdentityClient(this.#transport);
|
|
39
|
+
this.profiles = new ProfilesClient(this.#transport);
|
|
40
|
+
this.discovery = new DiscoveryClient(this.#transport);
|
|
41
|
+
this.contacts = new ContactsClient(this.#transport);
|
|
42
|
+
this.conversations = new ConversationsClient(this.#transport);
|
|
43
|
+
this.messages = new MessagesClient(this.#transport);
|
|
44
|
+
this.deliveries = new DeliveriesClient(this.#transport);
|
|
45
|
+
this.outbox = new OutboxClient(this.#transport);
|
|
46
|
+
this.reliability = new ReliabilityClient(this.#transport);
|
|
47
|
+
this.pairing = new PairingClient(this.#transport);
|
|
48
|
+
this.encryption = new EncryptionClient(this.#transport);
|
|
49
|
+
}
|
|
50
|
+
/** Cancels this instance's HTTP requests, without logout or daemon shutdown. */
|
|
51
|
+
close() {
|
|
52
|
+
return this.#transport.close();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/** All SDK failures use a stable category without retaining bearer credentials. */
|
|
2
|
+
export declare class AgentIMError extends Error {
|
|
3
|
+
readonly name: string;
|
|
4
|
+
}
|
|
5
|
+
export declare class ValidationError extends AgentIMError {
|
|
6
|
+
readonly name = "ValidationError";
|
|
7
|
+
}
|
|
8
|
+
export declare class ProtocolError extends AgentIMError {
|
|
9
|
+
readonly name: string;
|
|
10
|
+
}
|
|
11
|
+
export declare class TransportError extends AgentIMError {
|
|
12
|
+
readonly name: string;
|
|
13
|
+
}
|
|
14
|
+
export declare class RequestCancelledError extends AgentIMError {
|
|
15
|
+
readonly name = "RequestCancelledError";
|
|
16
|
+
}
|
|
17
|
+
export declare class RequestTimeoutError extends TransportError {
|
|
18
|
+
readonly name = "RequestTimeoutError";
|
|
19
|
+
}
|
|
20
|
+
export declare class ClientClosedError extends AgentIMError {
|
|
21
|
+
readonly name = "ClientClosedError";
|
|
22
|
+
}
|
|
23
|
+
/** Codes are an open string: new daemon error codes remain observable. */
|
|
24
|
+
export interface ErrorDiagnostics {
|
|
25
|
+
readonly requestId?: string;
|
|
26
|
+
readonly retryAfterMs?: number;
|
|
27
|
+
readonly nextAction?: string;
|
|
28
|
+
readonly serverCode?: string;
|
|
29
|
+
readonly edgeRequestId?: string;
|
|
30
|
+
readonly stage?: string;
|
|
31
|
+
readonly transport?: string;
|
|
32
|
+
readonly upstreamStatus?: number;
|
|
33
|
+
readonly safeToRetry?: boolean;
|
|
34
|
+
readonly attemptId?: string;
|
|
35
|
+
readonly deviceCreated?: string;
|
|
36
|
+
}
|
|
37
|
+
export declare class ApiError extends AgentIMError {
|
|
38
|
+
readonly status: number;
|
|
39
|
+
readonly code: string;
|
|
40
|
+
readonly diagnostics: ErrorDiagnostics;
|
|
41
|
+
readonly name: string;
|
|
42
|
+
constructor(status: number, code: string, message: string, diagnostics?: ErrorDiagnostics);
|
|
43
|
+
}
|
|
44
|
+
export declare class AuthenticationError extends ApiError {
|
|
45
|
+
readonly name = "AuthenticationError";
|
|
46
|
+
}
|
|
47
|
+
export declare class OperationError extends ApiError {
|
|
48
|
+
readonly name = "OperationError";
|
|
49
|
+
}
|
|
50
|
+
export declare class ResponseTooLargeError extends ProtocolError {
|
|
51
|
+
readonly name = "ResponseTooLargeError";
|
|
52
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/** All SDK failures use a stable category without retaining bearer credentials. */
|
|
2
|
+
export class AgentIMError extends Error {
|
|
3
|
+
name = "AgentIMError";
|
|
4
|
+
}
|
|
5
|
+
export class ValidationError extends AgentIMError {
|
|
6
|
+
name = "ValidationError";
|
|
7
|
+
}
|
|
8
|
+
export class ProtocolError extends AgentIMError {
|
|
9
|
+
name = "ProtocolError";
|
|
10
|
+
}
|
|
11
|
+
export class TransportError extends AgentIMError {
|
|
12
|
+
name = "TransportError";
|
|
13
|
+
}
|
|
14
|
+
export class RequestCancelledError extends AgentIMError {
|
|
15
|
+
name = "RequestCancelledError";
|
|
16
|
+
}
|
|
17
|
+
export class RequestTimeoutError extends TransportError {
|
|
18
|
+
name = "RequestTimeoutError";
|
|
19
|
+
}
|
|
20
|
+
export class ClientClosedError extends AgentIMError {
|
|
21
|
+
name = "ClientClosedError";
|
|
22
|
+
}
|
|
23
|
+
export class ApiError extends AgentIMError {
|
|
24
|
+
status;
|
|
25
|
+
code;
|
|
26
|
+
diagnostics;
|
|
27
|
+
name = "ApiError";
|
|
28
|
+
constructor(status, code, message, diagnostics = {}) {
|
|
29
|
+
super(message);
|
|
30
|
+
this.status = status;
|
|
31
|
+
this.code = code;
|
|
32
|
+
this.diagnostics = diagnostics;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export class AuthenticationError extends ApiError {
|
|
36
|
+
name = "AuthenticationError";
|
|
37
|
+
}
|
|
38
|
+
export class OperationError extends ApiError {
|
|
39
|
+
name = "OperationError";
|
|
40
|
+
}
|
|
41
|
+
export class ResponseTooLargeError extends ProtocolError {
|
|
42
|
+
name = "ResponseTooLargeError";
|
|
43
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface RequestOptions {
|
|
2
|
+
readonly signal?: AbortSignal;
|
|
3
|
+
readonly timeoutMs?: number;
|
|
4
|
+
}
|
|
5
|
+
/** Credentials here authenticate only to the local daemon. */
|
|
6
|
+
export interface ClientOptions {
|
|
7
|
+
readonly baseUrl: string;
|
|
8
|
+
readonly apiToken: string;
|
|
9
|
+
readonly timeoutMs?: number;
|
|
10
|
+
/** JSON inboxes may be larger than individual 5 MiB attachments. */
|
|
11
|
+
readonly maxResponseBytes?: number;
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Pure validated data for adapters such as the noninteractive IM CLI. */
|
|
2
|
+
export interface LocalRequestData {
|
|
3
|
+
readonly path?: Readonly<Record<string, string>>;
|
|
4
|
+
readonly query?: Readonly<Record<string, unknown>>;
|
|
5
|
+
readonly body?: Readonly<Record<string, unknown>>;
|
|
6
|
+
}
|
|
7
|
+
/** Validate canonical local-operation input without opening a connection or reading state. */
|
|
8
|
+
export declare function validateLocalRequest(operationId: string, input: unknown): LocalRequestData;
|
|
9
|
+
/** Return a copy of the canonical envelope schema; callers cannot mutate the SDK registry. */
|
|
10
|
+
export declare function localRequestSchema(operationId: string): Readonly<Record<string, unknown>>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { ValidationError } from "./errors.js";
|
|
2
|
+
import { snapshotInput } from "../internal/protocol/input.js";
|
|
3
|
+
import { operationFor } from "../internal/protocol/registry.js";
|
|
4
|
+
import { isRecord } from "../internal/protocol/schema.js";
|
|
5
|
+
import { requestBody, requestURL } from "../internal/transport/request.js";
|
|
6
|
+
/** Validate canonical local-operation input without opening a connection or reading state. */
|
|
7
|
+
export function validateLocalRequest(operationId, input) {
|
|
8
|
+
const value = snapshotInput(input);
|
|
9
|
+
if (!isRecord(value) || Object.keys(value).some(key => !["path", "query", "body"].includes(key))) {
|
|
10
|
+
throw new ValidationError("Request envelope accepts only path, query and body");
|
|
11
|
+
}
|
|
12
|
+
for (const key of ["path", "query", "body"]) {
|
|
13
|
+
if (Object.hasOwn(value, key) && !isRecord(value[key]))
|
|
14
|
+
throw new ValidationError("Request fields must be objects");
|
|
15
|
+
}
|
|
16
|
+
const operation = operationFor(operationId);
|
|
17
|
+
requestURL("http://127.0.0.1", operation, value);
|
|
18
|
+
requestBody(operation, value.body);
|
|
19
|
+
// The same canonical path/query/body validators used by all typed SDK methods ran above.
|
|
20
|
+
return value;
|
|
21
|
+
}
|
|
22
|
+
/** Return a copy of the canonical envelope schema; callers cannot mutate the SDK registry. */
|
|
23
|
+
export function localRequestSchema(operationId) {
|
|
24
|
+
const operation = operationFor(operationId);
|
|
25
|
+
const properties = {};
|
|
26
|
+
const required = [];
|
|
27
|
+
for (const location of ["path", "query"]) {
|
|
28
|
+
const parameters = operation.parameters.filter(parameter => parameter.in === location);
|
|
29
|
+
if (!parameters.length)
|
|
30
|
+
continue;
|
|
31
|
+
const fields = Object.fromEntries(parameters.map(parameter => [parameter.name, parameter.schema]));
|
|
32
|
+
const mandatory = parameters.filter(parameter => parameter.required).map(parameter => parameter.name);
|
|
33
|
+
properties[location] = { type: "object", additionalProperties: false, properties: fields, required: mandatory };
|
|
34
|
+
if (mandatory.length)
|
|
35
|
+
required.push(location);
|
|
36
|
+
}
|
|
37
|
+
if (operation.request !== null) {
|
|
38
|
+
properties.body = operation.request;
|
|
39
|
+
required.push("body");
|
|
40
|
+
}
|
|
41
|
+
return structuredClone({ $schema: "https://json-schema.org/draft/2020-12/schema",
|
|
42
|
+
type: "object", additionalProperties: false, properties, required });
|
|
43
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { RequestOptions } from "../../api/options.js";
|
|
2
|
+
import type { Transport } from "../../internal/transport/client.js";
|
|
3
|
+
import type { Contact, ContactActionRequest, ContactPage, ContactsQuery } from "./types.js";
|
|
4
|
+
export declare class ContactsClient {
|
|
5
|
+
private readonly transport;
|
|
6
|
+
constructor(transport: Transport);
|
|
7
|
+
list(query?: ContactsQuery, options?: RequestOptions): Promise<ContactPage>;
|
|
8
|
+
action(userId: string, body: ContactActionRequest, options?: RequestOptions): Promise<Contact>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export class ContactsClient {
|
|
2
|
+
transport;
|
|
3
|
+
constructor(transport) {
|
|
4
|
+
this.transport = transport;
|
|
5
|
+
}
|
|
6
|
+
list(query = {}, options = {}) {
|
|
7
|
+
return this.transport.call("localListContacts", { ...options, query });
|
|
8
|
+
}
|
|
9
|
+
action(userId, body, options = {}) {
|
|
10
|
+
return this.transport.call("localContactAction", { ...options, path: { user_id: userId }, body });
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { Contact, ContactAction, ContactActionRequest, ContactPage, ContactsQuery, } from "./types.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface Contact {
|
|
2
|
+
readonly user_id: string;
|
|
3
|
+
readonly state: "none" | "outgoing" | "incoming" | "accepted" | "rejected";
|
|
4
|
+
readonly blocked: boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface ContactAction {
|
|
7
|
+
readonly action: "request" | "accept" | "reject" | "remove" | "block" | "unblock";
|
|
8
|
+
}
|
|
9
|
+
export interface ContactActionRequest {
|
|
10
|
+
readonly action: "request" | "accept" | "reject" | "remove" | "block" | "unblock";
|
|
11
|
+
}
|
|
12
|
+
export interface ContactPage {
|
|
13
|
+
readonly contacts: readonly (Contact)[];
|
|
14
|
+
readonly next_cursor: string | null;
|
|
15
|
+
}
|
|
16
|
+
export interface ContactsQuery {
|
|
17
|
+
readonly after?: string;
|
|
18
|
+
readonly limit?: number | bigint;
|
|
19
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { RequestOptions } from "../../api/options.js";
|
|
2
|
+
import type { Transport } from "../../internal/transport/client.js";
|
|
3
|
+
import type { OperationResult } from "../identity/index.js";
|
|
4
|
+
import type { Conversation, ConversationDetails, ConversationsPage, ConversationsQuery, ConversationCreationStatus, InvitationDecisionRequest, CreateConversationRequest, InviteRequest, KickRequest, MembersPage, OpenDirectRequest, PowerRequest } from "./types.js";
|
|
5
|
+
export declare class ConversationsClient {
|
|
6
|
+
private readonly transport;
|
|
7
|
+
constructor(transport: Transport);
|
|
8
|
+
list(query?: ConversationsQuery, options?: RequestOptions): Promise<ConversationsPage>;
|
|
9
|
+
get(roomId: string, options?: RequestOptions): Promise<ConversationDetails>;
|
|
10
|
+
decideInvitation(roomId: string, body: InvitationDecisionRequest, options?: RequestOptions): Promise<OperationResult>;
|
|
11
|
+
creationStatus(requestId: string, options?: RequestOptions): Promise<ConversationCreationStatus>;
|
|
12
|
+
create(body: CreateConversationRequest, options?: RequestOptions): Promise<Conversation>;
|
|
13
|
+
join(roomId: string, options?: RequestOptions): Promise<Conversation>;
|
|
14
|
+
direct(body: OpenDirectRequest, options?: RequestOptions): Promise<Conversation>;
|
|
15
|
+
members(roomId: string, options?: RequestOptions): Promise<MembersPage>;
|
|
16
|
+
invite(roomId: string, body: InviteRequest, options?: RequestOptions): Promise<OperationResult>;
|
|
17
|
+
kick(roomId: string, body: KickRequest, options?: RequestOptions): Promise<OperationResult>;
|
|
18
|
+
setPower(roomId: string, body: PowerRequest, options?: RequestOptions): Promise<OperationResult>;
|
|
19
|
+
leave(roomId: string, options?: RequestOptions): Promise<OperationResult>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export class ConversationsClient {
|
|
2
|
+
transport;
|
|
3
|
+
constructor(transport) {
|
|
4
|
+
this.transport = transport;
|
|
5
|
+
}
|
|
6
|
+
list(query = {}, options = {}) {
|
|
7
|
+
return this.transport.call("localListConversations", { ...options, query });
|
|
8
|
+
}
|
|
9
|
+
get(roomId, options = {}) {
|
|
10
|
+
return this.transport.call("localGetConversation", { ...options, path: { room_id: roomId } });
|
|
11
|
+
}
|
|
12
|
+
decideInvitation(roomId, body, options = {}) {
|
|
13
|
+
return this.transport.call("localDecideInvitation", { ...options, path: { room_id: roomId }, body });
|
|
14
|
+
}
|
|
15
|
+
creationStatus(requestId, options = {}) {
|
|
16
|
+
return this.transport.call("localConversationCreationStatus", { ...options, path: { request_id: requestId } });
|
|
17
|
+
}
|
|
18
|
+
create(body, options = {}) {
|
|
19
|
+
return this.transport.call("createEncryptedConversation", { ...options, body });
|
|
20
|
+
}
|
|
21
|
+
join(roomId, options = {}) {
|
|
22
|
+
return this.transport.call("joinConversation", { ...options, path: { room_id: roomId }, body: {} });
|
|
23
|
+
}
|
|
24
|
+
direct(body, options = {}) {
|
|
25
|
+
return this.transport.call("localDirectConversation", { ...options, body });
|
|
26
|
+
}
|
|
27
|
+
members(roomId, options = {}) {
|
|
28
|
+
return this.transport.call("localMembersConversation", { ...options, path: { room_id: roomId } });
|
|
29
|
+
}
|
|
30
|
+
invite(roomId, body, options = {}) {
|
|
31
|
+
return this.transport.call("localInviteConversation", { ...options, path: { room_id: roomId }, body });
|
|
32
|
+
}
|
|
33
|
+
kick(roomId, body, options = {}) {
|
|
34
|
+
return this.transport.call("localKickConversation", { ...options, path: { room_id: roomId }, body });
|
|
35
|
+
}
|
|
36
|
+
setPower(roomId, body, options = {}) {
|
|
37
|
+
return this.transport.call("localPowerConversation", { ...options, path: { room_id: roomId }, body });
|
|
38
|
+
}
|
|
39
|
+
leave(roomId, options = {}) {
|
|
40
|
+
return this.transport.call("localLeaveConversation", { ...options, path: { room_id: roomId }, body: {} });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { ConversationDetails, ConversationsPage, ConversationsQuery, ConversationCreationStatus, InvitationDecisionRequest, Conversation, CreateConversationRequest, InviteRequest, JoinConversationRequest, KickRequest, LocalLeaveConversationRequest, MembersPage, MembersPageMembersItem, OpenDirectRequest, PowerRequest, } from "./types.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export interface Conversation {
|
|
2
|
+
readonly room_id: string;
|
|
3
|
+
readonly name: string | null;
|
|
4
|
+
readonly encrypted: boolean;
|
|
5
|
+
readonly joined: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface ConversationCreationStatus {
|
|
8
|
+
readonly request_id: string;
|
|
9
|
+
readonly state: "uncertain" | "created";
|
|
10
|
+
readonly room_id: string | null;
|
|
11
|
+
}
|
|
12
|
+
export interface ConversationDetails {
|
|
13
|
+
readonly room_id: string;
|
|
14
|
+
readonly name: string | null;
|
|
15
|
+
readonly encrypted: boolean;
|
|
16
|
+
readonly membership: "join" | "invite" | "leave" | "knock" | "ban";
|
|
17
|
+
readonly inviter: string | null;
|
|
18
|
+
}
|
|
19
|
+
export interface ConversationsPage {
|
|
20
|
+
readonly rooms: readonly (ConversationDetails)[];
|
|
21
|
+
readonly next_cursor: string | null;
|
|
22
|
+
}
|
|
23
|
+
export interface ConversationsQuery {
|
|
24
|
+
readonly membership?: "join" | "invite" | "leave" | "knock" | "ban";
|
|
25
|
+
readonly after?: string;
|
|
26
|
+
readonly limit?: number | bigint;
|
|
27
|
+
}
|
|
28
|
+
export interface CreateConversationRequest {
|
|
29
|
+
readonly name?: string | null;
|
|
30
|
+
readonly invitees: readonly (string)[];
|
|
31
|
+
readonly direct?: boolean;
|
|
32
|
+
readonly request_id?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface InvitationDecisionRequest {
|
|
35
|
+
readonly action: "accept" | "reject";
|
|
36
|
+
}
|
|
37
|
+
export interface InviteRequest {
|
|
38
|
+
readonly user_id: string;
|
|
39
|
+
}
|
|
40
|
+
export interface JoinConversationRequest {
|
|
41
|
+
}
|
|
42
|
+
export interface KickRequest {
|
|
43
|
+
readonly user_id: string;
|
|
44
|
+
readonly reason?: string;
|
|
45
|
+
}
|
|
46
|
+
export interface LocalLeaveConversationRequest {
|
|
47
|
+
}
|
|
48
|
+
export interface MembersPage {
|
|
49
|
+
readonly members: readonly (MembersPageMembersItem)[];
|
|
50
|
+
}
|
|
51
|
+
export interface MembersPageMembersItem {
|
|
52
|
+
readonly user_id: string;
|
|
53
|
+
readonly membership: "join" | "invite";
|
|
54
|
+
readonly power_level: number | bigint | null;
|
|
55
|
+
readonly display_name: string | null;
|
|
56
|
+
}
|
|
57
|
+
export interface OpenDirectRequest {
|
|
58
|
+
readonly user_id: string;
|
|
59
|
+
readonly request_id?: string;
|
|
60
|
+
}
|
|
61
|
+
export interface PowerRequest {
|
|
62
|
+
readonly user_id: string;
|
|
63
|
+
readonly power_level: number | bigint;
|
|
64
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { DeliveryBoundary, DeliveryBoundaryRequest } from "./types.js";
|
|
2
|
+
import type { RequestOptions } from "../../api/options.js";
|
|
3
|
+
import type { Transport } from "../../internal/transport/client.js";
|
|
4
|
+
import type { ClaimDeliveryRequest, DeliveryPage, DeliveryResult, LeaseRequest, RenewLeaseRequest, ReplyDeliveryRequest, ReplyFileDeliveryRequest } from "./types.js";
|
|
5
|
+
/** Explicit processing leases; no hidden ACK, lease renewal or polling. */
|
|
6
|
+
export declare class DeliveriesClient {
|
|
7
|
+
private readonly transport;
|
|
8
|
+
constructor(transport: Transport);
|
|
9
|
+
claim(body: ClaimDeliveryRequest, options?: RequestOptions): Promise<DeliveryPage>;
|
|
10
|
+
ack(eventId: string, body: LeaseRequest, options?: RequestOptions): Promise<DeliveryResult>;
|
|
11
|
+
release(eventId: string, body: LeaseRequest, options?: RequestOptions): Promise<DeliveryResult>;
|
|
12
|
+
renew(eventId: string, body: RenewLeaseRequest, options?: RequestOptions): Promise<DeliveryResult>;
|
|
13
|
+
reply(eventId: string, body: ReplyDeliveryRequest, options?: RequestOptions): Promise<DeliveryResult>;
|
|
14
|
+
replyFile(eventId: string, body: ReplyFileDeliveryRequest, options?: RequestOptions): Promise<DeliveryResult>;
|
|
15
|
+
boundary(options?: RequestOptions): Promise<DeliveryBoundary>;
|
|
16
|
+
setBoundary(body: DeliveryBoundaryRequest, options?: RequestOptions): Promise<DeliveryBoundary>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** Explicit processing leases; no hidden ACK, lease renewal or polling. */
|
|
2
|
+
export class DeliveriesClient {
|
|
3
|
+
transport;
|
|
4
|
+
constructor(transport) {
|
|
5
|
+
this.transport = transport;
|
|
6
|
+
}
|
|
7
|
+
claim(body, options = {}) {
|
|
8
|
+
return this.transport.call("claimDeliveries", { ...options, body });
|
|
9
|
+
}
|
|
10
|
+
ack(eventId, body, options = {}) {
|
|
11
|
+
return this.transport.call("acknowledgeDelivery", { ...options, path: { event_id: eventId }, body });
|
|
12
|
+
}
|
|
13
|
+
release(eventId, body, options = {}) {
|
|
14
|
+
return this.transport.call("releaseDelivery", { ...options, path: { event_id: eventId }, body });
|
|
15
|
+
}
|
|
16
|
+
renew(eventId, body, options = {}) {
|
|
17
|
+
return this.transport.call("renewDelivery", { ...options, path: { event_id: eventId }, body });
|
|
18
|
+
}
|
|
19
|
+
reply(eventId, body, options = {}) {
|
|
20
|
+
return this.transport.call("replyToDelivery", { ...options, path: { event_id: eventId }, body });
|
|
21
|
+
}
|
|
22
|
+
replyFile(eventId, body, options = {}) {
|
|
23
|
+
return this.transport.call("replyFileToDelivery", { ...options, path: { event_id: eventId }, body });
|
|
24
|
+
}
|
|
25
|
+
boundary(options = {}) {
|
|
26
|
+
return this.transport.call("getDeliveryBoundary", { timeoutMs: 180000, ...options });
|
|
27
|
+
}
|
|
28
|
+
setBoundary(body, options = {}) {
|
|
29
|
+
return this.transport.call("setDeliveryBoundary", { timeoutMs: 180000, ...options, body });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { ClaimDeliveryRequest, ClaimedDelivery, DeliveryBoundary, DeliveryBoundaryRequest, DeliveryPage, DeliveryResult, LeaseRequest, RenewLeaseRequest, ReplyDeliveryRequest, ReplyFileDeliveryRequest } from "./types.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { ReceivedMessage } from "../messages/index.js";
|
|
2
|
+
import type { OutboxItem } from "../outbox/index.js";
|
|
3
|
+
export interface ClaimDeliveryRequest {
|
|
4
|
+
readonly worker_id: string;
|
|
5
|
+
readonly after?: number | bigint;
|
|
6
|
+
readonly room_id?: string;
|
|
7
|
+
readonly limit?: number | bigint;
|
|
8
|
+
readonly lease_seconds?: number | bigint;
|
|
9
|
+
}
|
|
10
|
+
export interface ClaimedDelivery {
|
|
11
|
+
readonly message: ReceivedMessage;
|
|
12
|
+
readonly lease_token: string;
|
|
13
|
+
readonly lease_expires_at_ms: number | bigint;
|
|
14
|
+
readonly attempt: number | bigint;
|
|
15
|
+
}
|
|
16
|
+
export interface DeliveryBoundary {
|
|
17
|
+
readonly not_before_ms: number | bigint | null;
|
|
18
|
+
readonly mode: "all_history" | "from_boundary";
|
|
19
|
+
readonly new_device: boolean;
|
|
20
|
+
}
|
|
21
|
+
export interface DeliveryBoundaryRequest {
|
|
22
|
+
readonly not_before_ms?: number | bigint;
|
|
23
|
+
readonly replay_history?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface DeliveryPage {
|
|
26
|
+
readonly deliveries: readonly (ClaimedDelivery)[];
|
|
27
|
+
readonly pending_count: number | bigint;
|
|
28
|
+
}
|
|
29
|
+
export interface DeliveryResult {
|
|
30
|
+
readonly event_id: string;
|
|
31
|
+
readonly state: "pending" | "leased" | "processed";
|
|
32
|
+
readonly lease_expires_at_ms: number | bigint | null;
|
|
33
|
+
readonly outbox: OutboxItem | null;
|
|
34
|
+
}
|
|
35
|
+
export interface LeaseRequest {
|
|
36
|
+
readonly lease_token: string;
|
|
37
|
+
}
|
|
38
|
+
export interface RenewLeaseRequest {
|
|
39
|
+
readonly lease_token: string;
|
|
40
|
+
readonly lease_seconds: number | bigint;
|
|
41
|
+
}
|
|
42
|
+
export interface ReplyDeliveryRequest {
|
|
43
|
+
readonly lease_token: string;
|
|
44
|
+
readonly request_id: string;
|
|
45
|
+
readonly body: string;
|
|
46
|
+
readonly mention_user_ids?: readonly (string)[];
|
|
47
|
+
}
|
|
48
|
+
export interface ReplyFileDeliveryRequest {
|
|
49
|
+
readonly lease_token: string;
|
|
50
|
+
readonly request_id: string;
|
|
51
|
+
readonly filename: string;
|
|
52
|
+
readonly mime_type: string;
|
|
53
|
+
readonly data_base64: string;
|
|
54
|
+
}
|