@relaymessenger/chat-sdk-adapter 0.2.1 → 0.3.0-staging.1

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.
Files changed (69) hide show
  1. package/LICENSE +3 -3
  2. package/README.md +218 -98
  3. package/dist/adapter.d.ts +156 -0
  4. package/dist/adapter.d.ts.map +1 -0
  5. package/dist/adapter.js +723 -0
  6. package/dist/adapter.js.map +1 -0
  7. package/dist/client.d.ts +84 -0
  8. package/dist/client.d.ts.map +1 -0
  9. package/dist/client.js +266 -0
  10. package/dist/client.js.map +1 -0
  11. package/dist/content.d.ts +11 -0
  12. package/dist/content.d.ts.map +1 -0
  13. package/dist/content.js +172 -0
  14. package/dist/content.js.map +1 -0
  15. package/dist/credentials.d.ts +13 -0
  16. package/dist/credentials.d.ts.map +1 -0
  17. package/dist/credentials.js +28 -0
  18. package/dist/credentials.js.map +1 -0
  19. package/dist/index.d.ts +17 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +10 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/reactions.d.ts +15 -0
  24. package/dist/reactions.d.ts.map +1 -0
  25. package/dist/reactions.js +58 -0
  26. package/dist/reactions.js.map +1 -0
  27. package/dist/signature.d.ts +22 -0
  28. package/dist/signature.d.ts.map +1 -0
  29. package/dist/signature.js +98 -0
  30. package/dist/signature.js.map +1 -0
  31. package/dist/thread-id.d.ts +8 -0
  32. package/dist/thread-id.d.ts.map +1 -0
  33. package/dist/thread-id.js +27 -0
  34. package/dist/thread-id.js.map +1 -0
  35. package/dist/turn.d.ts +16 -0
  36. package/dist/turn.d.ts.map +1 -0
  37. package/dist/turn.js +22 -0
  38. package/dist/turn.js.map +1 -0
  39. package/dist/types.d.ts +193 -0
  40. package/dist/types.d.ts.map +1 -0
  41. package/dist/types.js +27 -0
  42. package/dist/types.js.map +1 -0
  43. package/dist/webhook.d.ts +9 -0
  44. package/dist/webhook.d.ts.map +1 -0
  45. package/dist/webhook.js +115 -0
  46. package/dist/webhook.js.map +1 -0
  47. package/package.json +52 -32
  48. package/dist/src/adapter.d.ts +0 -125
  49. package/dist/src/adapter.js +0 -724
  50. package/dist/src/chunk.d.ts +0 -25
  51. package/dist/src/chunk.js +0 -108
  52. package/dist/src/client.d.ts +0 -112
  53. package/dist/src/client.js +0 -180
  54. package/dist/src/format.d.ts +0 -43
  55. package/dist/src/format.js +0 -266
  56. package/dist/src/idempotency.d.ts +0 -50
  57. package/dist/src/idempotency.js +0 -75
  58. package/dist/src/index.d.ts +0 -14
  59. package/dist/src/index.js +0 -8
  60. package/dist/src/reactions.d.ts +0 -12
  61. package/dist/src/reactions.js +0 -98
  62. package/dist/src/signature.d.ts +0 -46
  63. package/dist/src/signature.js +0 -95
  64. package/dist/src/threadId.d.ts +0 -12
  65. package/dist/src/threadId.js +0 -28
  66. package/dist/src/turn.d.ts +0 -38
  67. package/dist/src/turn.js +0 -15
  68. package/dist/src/types.d.ts +0 -177
  69. package/dist/src/types.js +0 -7
@@ -0,0 +1,115 @@
1
+ import { ValidationError } from "@chat-adapter/shared";
2
+ import { RELAY_API_VERSION, RELAY_WEBHOOK_EVENT_TYPES, RELAY_WEBHOOK_VERSION, } from "./types.js";
3
+ import { isRelayUuid } from "./thread-id.js";
4
+ const EVENT_TYPES = new Set(RELAY_WEBHOOK_EVENT_TYPES);
5
+ // One Message may carry 100 text parts of 10,000 UTF-16 units. JSON escaping
6
+ // can expand a valid text unit to six ASCII bytes, before envelope metadata.
7
+ // Eight MiB accepts that locked maximum while still bounding untrusted input.
8
+ export const MAX_WEBHOOK_BODY_BYTES = 8 * 1_048_576;
9
+ function isRecord(value) {
10
+ return (typeof value === "object" &&
11
+ value !== null &&
12
+ !Array.isArray(value));
13
+ }
14
+ function isDateTime(value) {
15
+ return (typeof value === "string" &&
16
+ Number.isFinite(Date.parse(value)));
17
+ }
18
+ export function parseWebhookEnvelope(value) {
19
+ if (!isRecord(value)) {
20
+ throw new ValidationError("relay", "Relay webhook body must be an object");
21
+ }
22
+ if (value.api_version !== RELAY_API_VERSION ||
23
+ value.webhook_version !== RELAY_WEBHOOK_VERSION ||
24
+ typeof value.event_type !== "string" ||
25
+ !EVENT_TYPES.has(value.event_type) ||
26
+ typeof value.event_id !== "string" ||
27
+ !isRelayUuid(value.event_id) ||
28
+ typeof value.agent_id !== "string" ||
29
+ !isRelayUuid(value.agent_id) ||
30
+ typeof value.trace_id !== "string" ||
31
+ !value.trace_id ||
32
+ !isDateTime(value.created_at) ||
33
+ !isRecord(value.data)) {
34
+ throw new ValidationError("relay", `Webhook envelope must match Relay v1/${RELAY_WEBHOOK_VERSION}`);
35
+ }
36
+ return value;
37
+ }
38
+ function isHandle(value) {
39
+ if (!isRecord(value))
40
+ return false;
41
+ return (typeof value.id === "string" &&
42
+ isRelayUuid(value.id) &&
43
+ typeof value.handle === "string" &&
44
+ (value.kind === "user" || value.kind === "agent"));
45
+ }
46
+ export function parseWebhookMessageEvent(data) {
47
+ if (!isRecord(data.chat) ||
48
+ typeof data.chat.id !== "string" ||
49
+ !isRelayUuid(data.chat.id) ||
50
+ typeof data.id !== "string" ||
51
+ !isRelayUuid(data.id) ||
52
+ (data.direction !== "inbound" &&
53
+ data.direction !== "outbound") ||
54
+ !isHandle(data.sender_handle) ||
55
+ !Array.isArray(data.parts)) {
56
+ throw new ValidationError("relay", "message webhook data does not match the locked MessageEvent contract");
57
+ }
58
+ return data;
59
+ }
60
+ export function parseReactionEvent(data) {
61
+ if (typeof data.chat_id !== "string" ||
62
+ !isRelayUuid(data.chat_id) ||
63
+ typeof data.message_id !== "string" ||
64
+ !isRelayUuid(data.message_id) ||
65
+ !isHandle(data.from_handle) ||
66
+ !Number.isInteger(data.part_index) ||
67
+ data.part_index < 0 ||
68
+ typeof data.is_from_me !== "boolean" ||
69
+ typeof data.reaction_type !== "string" ||
70
+ ![
71
+ "love",
72
+ "like",
73
+ "dislike",
74
+ "laugh",
75
+ "emphasize",
76
+ "question",
77
+ "custom",
78
+ ].includes(data.reaction_type) ||
79
+ !isDateTime(data.reacted_at)) {
80
+ throw new ValidationError("relay", "reaction webhook data does not match the locked ReactionEventBase contract");
81
+ }
82
+ return data;
83
+ }
84
+ export function assertExhaustiveEvent(eventType) {
85
+ throw new Error(`Unhandled Relay webhook event: ${eventType}`);
86
+ }
87
+ export async function readWebhookBody(request) {
88
+ if (!request.body)
89
+ return "";
90
+ const reader = request.body.getReader();
91
+ const chunks = [];
92
+ let length = 0;
93
+ while (true) {
94
+ const { done, value } = await reader.read();
95
+ if (done)
96
+ break;
97
+ length += value.byteLength;
98
+ if (length > MAX_WEBHOOK_BODY_BYTES) {
99
+ await reader.cancel();
100
+ throw new RangeError("Relay webhook body exceeds 8 MiB");
101
+ }
102
+ chunks.push(value);
103
+ }
104
+ const bytes = new Uint8Array(length);
105
+ let offset = 0;
106
+ for (const chunk of chunks) {
107
+ bytes.set(chunk, offset);
108
+ offset += chunk.byteLength;
109
+ }
110
+ return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
111
+ }
112
+ export function isMessageEventType(value) {
113
+ return value.startsWith("message.");
114
+ }
115
+ //# sourceMappingURL=webhook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.js","sourceRoot":"","sources":["../src/webhook.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,59 +1,79 @@
1
1
  {
2
2
  "name": "@relaymessenger/chat-sdk-adapter",
3
- "version": "0.2.1",
4
- "description": "Relay adapter for the Vercel Chat SDK. Receive signed Relay webhooks and post replies as one canonical message.",
5
- "homepage": "https://docs.relayapp.im/integrations/chat-sdk",
6
- "bugs": {
7
- "url": "https://github.com/relaymessenger/Relay-SDK/issues"
8
- },
9
- "license": "MIT",
3
+ "version": "0.3.0-staging.1",
4
+ "description": "Vendor-official Relay adapter for Vercel Chat SDK.",
10
5
  "keywords": [
11
6
  "relay",
12
7
  "chat-sdk",
13
8
  "adapter",
14
9
  "messaging",
15
- "agent",
16
10
  "webhook"
17
11
  ],
18
- "engines": {
19
- "node": ">=22.18"
12
+ "homepage": "https://docs.relayapp.im/ecosystem/chat-sdk",
13
+ "bugs": {
14
+ "url": "https://github.com/RelayMessenger/Relay-SDK/issues"
20
15
  },
21
- "publishConfig": {
22
- "access": "public"
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/RelayMessenger/Relay-SDK.git",
19
+ "directory": "packages/chat-sdk-adapter"
23
20
  },
21
+ "license": "MIT",
24
22
  "type": "module",
25
- "main": "./dist/src/index.js",
26
- "types": "./dist/src/index.d.ts",
23
+ "sideEffects": false,
24
+ "engines": {
25
+ "node": ">=20"
26
+ },
27
+ "main": "./dist/index.js",
28
+ "types": "./dist/index.d.ts",
27
29
  "exports": {
28
30
  ".": {
29
- "types": "./dist/src/index.d.ts",
30
- "default": "./dist/src/index.js"
31
- }
31
+ "types": "./dist/index.d.ts",
32
+ "import": "./dist/index.js",
33
+ "default": "./dist/index.js"
34
+ },
35
+ "./package.json": "./package.json"
32
36
  },
33
37
  "files": [
38
+ "dist/",
34
39
  "README.md",
35
- "LICENSE",
36
- "dist/**/*.js",
37
- "dist/**/*.d.ts"
40
+ "LICENSE"
38
41
  ],
42
+ "publishConfig": {
43
+ "access": "public",
44
+ "registry": "https://registry.npmjs.org/",
45
+ "tag": "staging",
46
+ "provenance": true
47
+ },
39
48
  "scripts": {
40
49
  "build": "tsc -p tsconfig.build.json",
41
50
  "check": "tsc --noEmit",
42
- "test": "vitest run",
43
- "prepack": "npm run build"
51
+ "test": "npm run test:unit && npm run test:workerd",
52
+ "test:unit": "vitest run --config vitest.config.ts",
53
+ "test:workerd": "vitest run --config vitest.workerd.config.ts",
54
+ "test:installed": "node scripts/test-installed-package.mjs",
55
+ "test:all": "npm run check && npm run build && npm run test && npm run test:installed",
56
+ "example:check": "RELAY_EXAMPLE_CHECK=1 node examples/server.mjs",
57
+ "prepack": "npm run check && npm run test && npm run build",
58
+ "wrangler:types": "wrangler types",
59
+ "wrangler:types:check": "wrangler types --check"
44
60
  },
45
61
  "peerDependencies": {
46
- "chat": "^4.38.0"
62
+ "chat": "^4.39.0"
47
63
  },
48
- "devDependencies": {
49
- "@types/node": "^26.2.0",
50
- "chat": "^4.38.1",
51
- "typescript": "^7.0.2",
52
- "vitest": "^4.1.10"
64
+ "dependencies": {
65
+ "@chat-adapter/shared": "4.39.0"
53
66
  },
54
- "repository": {
55
- "type": "git",
56
- "url": "git+https://github.com/relaymessenger/Relay-SDK.git",
57
- "directory": "integrations/chat-sdk"
67
+ "devDependencies": {
68
+ "@chat-adapter/state-memory": "4.39.0",
69
+ "@chat-adapter/tests": "4.39.0",
70
+ "@cloudflare/vitest-plugin": "1.1.2",
71
+ "@types/node": "26.4.0",
72
+ "@vitest/coverage-v8": "4.1.11",
73
+ "chat": "4.39.0",
74
+ "typescript": "7.0.2",
75
+ "vitest": "4.1.11",
76
+ "wrangler": "4.127.1",
77
+ "yaml": "2.9.0"
58
78
  }
59
79
  }
@@ -1,125 +0,0 @@
1
- import { Message } from "chat";
2
- import type { Adapter, AdapterPostableMessage, ChatInstance, EmojiValue, FetchOptions, FetchResult, FormattedContent, RawMessage, StreamChunk, ThreadInfo, UserInfo, WebhookOptions } from "chat";
3
- import { RelayClient } from "./client.js";
4
- import type { RelayClientOptions } from "./client.js";
5
- import type { RelayMessage, RelayRawMessage, RelayThreadId } from "./types.js";
6
- export declare const RELAY_ADAPTER_NAME = "relay";
7
- export interface RelayAdapterOptions extends Omit<RelayClientOptions, "token"> {
8
- /** Agent Token. Defaults to `RELAY_AGENT_TOKEN`. */
9
- token?: string;
10
- /** Webhook signing secret. Defaults to `RELAY_WEBHOOK_SECRET`. */
11
- webhookSecret?: string;
12
- /** Display name for the agent. Defaults to `Relay Agent`. */
13
- userName?: string;
14
- /** This agent's `agt_` id, when the caller knows it. */
15
- agentId?: string;
16
- /** Clock tolerance for signature verification, in seconds. */
17
- toleranceSeconds?: number;
18
- /** How many handled `event_id` values to remember. */
19
- dedupeWindow?: number;
20
- /** Override the client, mainly for tests. */
21
- client?: RelayClient;
22
- }
23
- /**
24
- * A group turn tried to commit a second message. Relay's invocation is single
25
- * use, so there is nothing valid for the second message to cite and the server
26
- * would answer 403.
27
- */
28
- export declare class RelayInvocationSpentError extends Error {
29
- constructor(message: string);
30
- }
31
- /**
32
- * Relay adapter for the Vercel Chat SDK.
33
- *
34
- * Relay is a consumer messenger where people talk to agents as contacts, so
35
- * this adapter maps the Chat SDK's thread model onto Relay conversations one
36
- * to one: a Relay conversation has no enclosing channel, and a thread id is
37
- * `relay:{conversation_id}`.
38
- *
39
- * Two Relay rules shape the surface. A streamed turn commits exactly one
40
- * canonical message, so `stream` buffers and posts once rather than editing a
41
- * draft bubble into place. And a group reply is scoped to the single-use
42
- * invocation that produced the inbound event, so the first send of a turn
43
- * carries it and a second cannot.
44
- */
45
- export declare class RelayAdapter implements Adapter<RelayThreadId, RelayRawMessage> {
46
- readonly name = "relay";
47
- readonly userName: string;
48
- readonly botUserId?: string;
49
- readonly lockScope: "thread";
50
- /** Relay serves history from `GET /v1/conversations/{id}/messages`. */
51
- readonly persistThreadHistory = false;
52
- private readonly client;
53
- private readonly webhookSecret?;
54
- private readonly toleranceSeconds?;
55
- private readonly dedupe;
56
- private chat?;
57
- constructor(options?: RelayAdapterOptions);
58
- initialize(chat: ChatInstance): Promise<void>;
59
- encodeThreadId(platformData: RelayThreadId): string;
60
- decodeThreadId(threadId: string): RelayThreadId;
61
- channelIdFromThreadId(threadId: string): string;
62
- renderFormatted(content: FormattedContent): string;
63
- parseMessage(raw: RelayRawMessage): Message<RelayRawMessage>;
64
- postMessage(threadId: string, message: AdapterPostableMessage): Promise<RawMessage<RelayRawMessage>>;
65
- editMessage(threadId: string, messageId: string, message: AdapterPostableMessage): Promise<RawMessage<RelayRawMessage>>;
66
- deleteMessage(threadId: string, messageId: string): Promise<void>;
67
- addReaction(threadId: string, messageId: string, emoji: EmojiValue | string): Promise<void>;
68
- removeReaction(threadId: string, messageId: string, emoji: EmojiValue | string): Promise<void>;
69
- /**
70
- * Relay's typing indicator is ephemeral and carries an optional label of up
71
- * to 80 characters. The invocation is peeked rather than consumed: typing is
72
- * not the group reply the invocation is spent on.
73
- *
74
- * Failures are swallowed. Group typing without a live pending invocation is a
75
- * 403 (`Relay-Server/server/src/domain/typing.ts:70-73`), which is exactly
76
- * what typing after the first send of a group turn looks like. The Chat SDK
77
- * treats this call as best effort and has no `stopTyping` to strand, so a
78
- * hint that cannot be shown must never take the reply down with it.
79
- */
80
- startTyping(threadId: string, status?: string): Promise<void>;
81
- markAsRead(threadId: string, messageId: string): Promise<void>;
82
- getUser(userId: string): Promise<UserInfo | null>;
83
- /**
84
- * Relay pages history backwards with `before_sequence` and returns newest
85
- * first; the Chat SDK wants each page in chronological order. There is no
86
- * forward cursor on the route, so `direction: "forward"` has nothing to call.
87
- */
88
- fetchMessages(threadId: string, options?: FetchOptions): Promise<FetchResult<RelayRawMessage>>;
89
- fetchThread(threadId: string): Promise<ThreadInfo>;
90
- /**
91
- * Relay commits one canonical message per turn and has no draft bubble to
92
- * edit, so the stream is buffered and posted once. Nothing partial ever
93
- * reaches a recipient, and no cleanup is needed if the stream fails midway.
94
- */
95
- stream(threadId: string, textStream: AsyncIterable<string | StreamChunk>): Promise<RawMessage<RelayRawMessage> | null>;
96
- /**
97
- * Verify the Standard Webhooks signature over the exact raw body, refuse a
98
- * replay by `event_id`, and hand the event to the Chat SDK. Relay redelivers
99
- * on 5xx, so a dispatch failure must not answer 2xx.
100
- */
101
- handleWebhook(request: Request, options?: WebhookOptions): Promise<Response>;
102
- private dispatch;
103
- private buildParts;
104
- private textParts;
105
- /**
106
- * Relay has no card surface: interactive components were removed from the
107
- * app, so buttons cannot render and a human cannot answer one in Relay. The
108
- * card's words are still delivered, as text, rather than dropped.
109
- */
110
- private cardToText;
111
- private attachmentPart;
112
- private filePart;
113
- /**
114
- * Send the parts in one call when they fit, and as follow-up calls when
115
- * they do not. The server splits each call at ingest into one or more
116
- * messages, and the one call that carries the invocation owns every message
117
- * it commits. A group turn cannot overflow, and cannot POST twice: Relay's
118
- * invocation is single use per call, so a second POST has nothing valid to
119
- * cite and the server answers 403.
120
- */
121
- private sendParts;
122
- }
123
- /** Build a Relay adapter for the Vercel Chat SDK. */
124
- export declare function createRelayAdapter(options?: RelayAdapterOptions): RelayAdapter;
125
- export type { RelayMessage };