@asyncify-hq/node 0.1.0 → 0.2.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.
package/dist/index.cjs CHANGED
@@ -65,7 +65,67 @@ var AsyncifyClient = class {
65
65
  list: () => this.request("GET", "/v1/workflows")
66
66
  };
67
67
  subscribers = {
68
- upsert: (subscriber) => this.request("PUT", "/v1/subscribers", subscriber)
68
+ upsert: (subscriber) => this.request("PUT", "/v1/subscribers", subscriber),
69
+ /** Channel identities linked to this subscriber (telegram, email). */
70
+ identities: (subscriberId) => this.request("GET", `/v1/subscribers/${encodeURIComponent(subscriberId)}/identities`),
71
+ /** Drop a linked identity — future messages fall back to a channel-local one. */
72
+ unlink: (subscriberId, identity) => this.request(
73
+ "DELETE",
74
+ `/v1/subscribers/${encodeURIComponent(subscriberId)}/identities`,
75
+ identity
76
+ )
77
+ };
78
+ agents = {
79
+ /** Create an agent. The signing secret is returned EXACTLY ONCE — store it. */
80
+ create: (options) => this.request("POST", "/v1/agents", options),
81
+ list: () => this.request("GET", "/v1/agents"),
82
+ get: (identifier) => this.request("GET", `/v1/agents/${encodeURIComponent(identifier)}`),
83
+ /** Patch any subset; `autoResolveMinutes: null` switches the backstop off. */
84
+ update: (identifier, patch) => this.request(
85
+ "PATCH",
86
+ `/v1/agents/${encodeURIComponent(identifier)}`,
87
+ patch
88
+ ),
89
+ /** New signing secret, shown once; the old one stops working immediately. */
90
+ rotateSecret: (identifier) => this.request(
91
+ "POST",
92
+ `/v1/agents/${encodeURIComponent(identifier)}/rotate-secret`
93
+ ),
94
+ delete: (identifier) => this.request(
95
+ "DELETE",
96
+ `/v1/agents/${encodeURIComponent(identifier)}`
97
+ ),
98
+ /**
99
+ * Mint the single-use deep link (24h TTL) that merges a user's Telegram
100
+ * into this subscriber: generate it server-side for your LOGGED-IN user
101
+ * and hand them the returned t.me link. When they tap Start, their
102
+ * Telegram identity, history, and notifications unify with the
103
+ * subscriber — agent replies and triggers reach the real person.
104
+ */
105
+ linkToken: (agentIdentifier, subscriberId) => this.request(
106
+ "POST",
107
+ `/v1/agents/${encodeURIComponent(agentIdentifier)}/subscribers/${encodeURIComponent(subscriberId)}/link-token`
108
+ )
109
+ };
110
+ conversations = {
111
+ /** Conversations across your agents, newest first. */
112
+ list: (filters = {}) => {
113
+ const qs = new URLSearchParams();
114
+ if (filters.agent) qs.set("agent", filters.agent);
115
+ if (filters.status) qs.set("status", filters.status);
116
+ const suffix = qs.toString();
117
+ return this.request(
118
+ "GET",
119
+ `/v1/conversations${suffix ? `?${suffix}` : ""}`
120
+ );
121
+ },
122
+ /** Full transcript + metadata + LLM usage totals for one conversation. */
123
+ get: (id) => this.request("GET", `/v1/conversations/${encodeURIComponent(id)}`),
124
+ /** Close a conversation (a new message from the user reopens it). */
125
+ resolve: (id) => this.request(
126
+ "POST",
127
+ `/v1/conversations/${encodeURIComponent(id)}/resolve`
128
+ )
69
129
  };
70
130
  templates = {
71
131
  upsert: (template) => this.request("PUT", "/v1/templates", template),
package/dist/index.d.cts CHANGED
@@ -56,6 +56,55 @@ interface WorkflowStep {
56
56
  statusIn: string[];
57
57
  };
58
58
  }
59
+ /** An agent as the API returns it — secrets (signing, LLM key) never included. */
60
+ interface Agent {
61
+ identifier: string;
62
+ name: string;
63
+ description: string | null;
64
+ runtime: 'bridge' | 'managed';
65
+ bridgeUrl: string | null;
66
+ model: string | null;
67
+ systemPrompt: string | null;
68
+ llmBaseUrl: string | null;
69
+ maxTokens: number | null;
70
+ autoResolveMinutes: number | null;
71
+ hasLlmKey: boolean;
72
+ status: 'active' | 'disabled';
73
+ createdAt: string;
74
+ updatedAt: string;
75
+ }
76
+ interface CreateAgentOptions {
77
+ identifier: string;
78
+ name: string;
79
+ description?: string;
80
+ /** 'bridge' (default): we POST turns to your bridgeUrl. 'managed': we run the LLM. */
81
+ runtime?: 'bridge' | 'managed';
82
+ bridgeUrl?: string;
83
+ model?: string;
84
+ systemPrompt?: string;
85
+ /** Managed reply cap, 256–8192 (default 1024). */
86
+ maxTokens?: number;
87
+ /** Auto-resolve conversations idle this many minutes, 1–43200 (default: never). */
88
+ autoResolveMinutes?: number;
89
+ /** Managed runtime: the LLM key (stored encrypted, write-only) + optional compat base URL. */
90
+ llm?: {
91
+ apiKey?: string;
92
+ baseUrl?: string;
93
+ };
94
+ }
95
+ interface ConversationSummary {
96
+ id: string;
97
+ agent: {
98
+ identifier: string;
99
+ name: string;
100
+ };
101
+ subscriberId: string;
102
+ channel: string;
103
+ status: 'active' | 'resolved';
104
+ messageCount: number;
105
+ lastMessagePreview: string | null;
106
+ lastMessageAt: string;
107
+ }
59
108
  declare class AsyncifyError extends Error {
60
109
  readonly status: number;
61
110
  constructor(status: number, message: string);
@@ -98,6 +147,101 @@ declare class AsyncifyClient {
98
147
  id: string;
99
148
  subscriberId: string;
100
149
  }>;
150
+ /** Channel identities linked to this subscriber (telegram, email). */
151
+ identities: (subscriberId: string) => Promise<{
152
+ identities: Array<{
153
+ channel: string;
154
+ externalKey: string;
155
+ linkedAt: string;
156
+ }>;
157
+ }>;
158
+ /** Drop a linked identity — future messages fall back to a channel-local one. */
159
+ unlink: (subscriberId: string, identity: {
160
+ channel: "telegram" | "email" | "slack";
161
+ externalKey: string;
162
+ }) => Promise<{
163
+ deleted: boolean;
164
+ }>;
165
+ };
166
+ readonly agents: {
167
+ /** Create an agent. The signing secret is returned EXACTLY ONCE — store it. */
168
+ create: (options: CreateAgentOptions) => Promise<{
169
+ agent: Agent;
170
+ signingSecret: string;
171
+ }>;
172
+ list: () => Promise<{
173
+ agents: Agent[];
174
+ }>;
175
+ get: (identifier: string) => Promise<{
176
+ agent: Agent;
177
+ }>;
178
+ /** Patch any subset; `autoResolveMinutes: null` switches the backstop off. */
179
+ update: (identifier: string, patch: Partial<Omit<CreateAgentOptions, "identifier" | "autoResolveMinutes">> & {
180
+ status?: "active" | "disabled";
181
+ autoResolveMinutes?: number | null;
182
+ }) => Promise<{
183
+ agent: Agent;
184
+ }>;
185
+ /** New signing secret, shown once; the old one stops working immediately. */
186
+ rotateSecret: (identifier: string) => Promise<{
187
+ signingSecret: string;
188
+ }>;
189
+ delete: (identifier: string) => Promise<{
190
+ deleted: boolean;
191
+ }>;
192
+ /**
193
+ * Mint the single-use deep link (24h TTL) that merges a user's Telegram
194
+ * into this subscriber: generate it server-side for your LOGGED-IN user
195
+ * and hand them the returned t.me link. When they tap Start, their
196
+ * Telegram identity, history, and notifications unify with the
197
+ * subscriber — agent replies and triggers reach the real person.
198
+ */
199
+ linkToken: (agentIdentifier: string, subscriberId: string) => Promise<{
200
+ token: string;
201
+ deepLink: string;
202
+ expiresAt: string;
203
+ }>;
204
+ };
205
+ readonly conversations: {
206
+ /** Conversations across your agents, newest first. */
207
+ list: (filters?: {
208
+ agent?: string;
209
+ status?: "active" | "resolved";
210
+ }) => Promise<{
211
+ conversations: ConversationSummary[];
212
+ }>;
213
+ /** Full transcript + metadata + LLM usage totals for one conversation. */
214
+ get: (id: string) => Promise<{
215
+ conversation: {
216
+ id: string;
217
+ channel: string;
218
+ status: "active" | "resolved";
219
+ metadata: Record<string, unknown>;
220
+ summary: string | null;
221
+ messageCount: number;
222
+ createdAt: string;
223
+ };
224
+ messages: Array<{
225
+ id: string;
226
+ role: "user" | "agent" | "system";
227
+ content: string;
228
+ createdAt: string;
229
+ buttons?: Array<{
230
+ id: string;
231
+ label: string;
232
+ }>;
233
+ clicked?: boolean;
234
+ }>;
235
+ usage: {
236
+ inputTokens: number;
237
+ outputTokens: number;
238
+ modelCalls: number;
239
+ };
240
+ }>;
241
+ /** Close a conversation (a new message from the user reopens it). */
242
+ resolve: (id: string) => Promise<{
243
+ status: string;
244
+ }>;
101
245
  };
102
246
  readonly templates: {
103
247
  upsert: (template: {
@@ -154,4 +298,4 @@ declare class AsyncifyClient {
154
298
  }>;
155
299
  }
156
300
 
157
- export { AsyncifyClient, type AsyncifyClientOptions, AsyncifyError, type Priority, type Recipient, type TriggerOptions, type TriggerRecipient, type TriggerResult, type WorkflowStep };
301
+ export { type Agent, AsyncifyClient, type AsyncifyClientOptions, AsyncifyError, type ConversationSummary, type CreateAgentOptions, type Priority, type Recipient, type TriggerOptions, type TriggerRecipient, type TriggerResult, type WorkflowStep };
package/dist/index.d.ts CHANGED
@@ -56,6 +56,55 @@ interface WorkflowStep {
56
56
  statusIn: string[];
57
57
  };
58
58
  }
59
+ /** An agent as the API returns it — secrets (signing, LLM key) never included. */
60
+ interface Agent {
61
+ identifier: string;
62
+ name: string;
63
+ description: string | null;
64
+ runtime: 'bridge' | 'managed';
65
+ bridgeUrl: string | null;
66
+ model: string | null;
67
+ systemPrompt: string | null;
68
+ llmBaseUrl: string | null;
69
+ maxTokens: number | null;
70
+ autoResolveMinutes: number | null;
71
+ hasLlmKey: boolean;
72
+ status: 'active' | 'disabled';
73
+ createdAt: string;
74
+ updatedAt: string;
75
+ }
76
+ interface CreateAgentOptions {
77
+ identifier: string;
78
+ name: string;
79
+ description?: string;
80
+ /** 'bridge' (default): we POST turns to your bridgeUrl. 'managed': we run the LLM. */
81
+ runtime?: 'bridge' | 'managed';
82
+ bridgeUrl?: string;
83
+ model?: string;
84
+ systemPrompt?: string;
85
+ /** Managed reply cap, 256–8192 (default 1024). */
86
+ maxTokens?: number;
87
+ /** Auto-resolve conversations idle this many minutes, 1–43200 (default: never). */
88
+ autoResolveMinutes?: number;
89
+ /** Managed runtime: the LLM key (stored encrypted, write-only) + optional compat base URL. */
90
+ llm?: {
91
+ apiKey?: string;
92
+ baseUrl?: string;
93
+ };
94
+ }
95
+ interface ConversationSummary {
96
+ id: string;
97
+ agent: {
98
+ identifier: string;
99
+ name: string;
100
+ };
101
+ subscriberId: string;
102
+ channel: string;
103
+ status: 'active' | 'resolved';
104
+ messageCount: number;
105
+ lastMessagePreview: string | null;
106
+ lastMessageAt: string;
107
+ }
59
108
  declare class AsyncifyError extends Error {
60
109
  readonly status: number;
61
110
  constructor(status: number, message: string);
@@ -98,6 +147,101 @@ declare class AsyncifyClient {
98
147
  id: string;
99
148
  subscriberId: string;
100
149
  }>;
150
+ /** Channel identities linked to this subscriber (telegram, email). */
151
+ identities: (subscriberId: string) => Promise<{
152
+ identities: Array<{
153
+ channel: string;
154
+ externalKey: string;
155
+ linkedAt: string;
156
+ }>;
157
+ }>;
158
+ /** Drop a linked identity — future messages fall back to a channel-local one. */
159
+ unlink: (subscriberId: string, identity: {
160
+ channel: "telegram" | "email" | "slack";
161
+ externalKey: string;
162
+ }) => Promise<{
163
+ deleted: boolean;
164
+ }>;
165
+ };
166
+ readonly agents: {
167
+ /** Create an agent. The signing secret is returned EXACTLY ONCE — store it. */
168
+ create: (options: CreateAgentOptions) => Promise<{
169
+ agent: Agent;
170
+ signingSecret: string;
171
+ }>;
172
+ list: () => Promise<{
173
+ agents: Agent[];
174
+ }>;
175
+ get: (identifier: string) => Promise<{
176
+ agent: Agent;
177
+ }>;
178
+ /** Patch any subset; `autoResolveMinutes: null` switches the backstop off. */
179
+ update: (identifier: string, patch: Partial<Omit<CreateAgentOptions, "identifier" | "autoResolveMinutes">> & {
180
+ status?: "active" | "disabled";
181
+ autoResolveMinutes?: number | null;
182
+ }) => Promise<{
183
+ agent: Agent;
184
+ }>;
185
+ /** New signing secret, shown once; the old one stops working immediately. */
186
+ rotateSecret: (identifier: string) => Promise<{
187
+ signingSecret: string;
188
+ }>;
189
+ delete: (identifier: string) => Promise<{
190
+ deleted: boolean;
191
+ }>;
192
+ /**
193
+ * Mint the single-use deep link (24h TTL) that merges a user's Telegram
194
+ * into this subscriber: generate it server-side for your LOGGED-IN user
195
+ * and hand them the returned t.me link. When they tap Start, their
196
+ * Telegram identity, history, and notifications unify with the
197
+ * subscriber — agent replies and triggers reach the real person.
198
+ */
199
+ linkToken: (agentIdentifier: string, subscriberId: string) => Promise<{
200
+ token: string;
201
+ deepLink: string;
202
+ expiresAt: string;
203
+ }>;
204
+ };
205
+ readonly conversations: {
206
+ /** Conversations across your agents, newest first. */
207
+ list: (filters?: {
208
+ agent?: string;
209
+ status?: "active" | "resolved";
210
+ }) => Promise<{
211
+ conversations: ConversationSummary[];
212
+ }>;
213
+ /** Full transcript + metadata + LLM usage totals for one conversation. */
214
+ get: (id: string) => Promise<{
215
+ conversation: {
216
+ id: string;
217
+ channel: string;
218
+ status: "active" | "resolved";
219
+ metadata: Record<string, unknown>;
220
+ summary: string | null;
221
+ messageCount: number;
222
+ createdAt: string;
223
+ };
224
+ messages: Array<{
225
+ id: string;
226
+ role: "user" | "agent" | "system";
227
+ content: string;
228
+ createdAt: string;
229
+ buttons?: Array<{
230
+ id: string;
231
+ label: string;
232
+ }>;
233
+ clicked?: boolean;
234
+ }>;
235
+ usage: {
236
+ inputTokens: number;
237
+ outputTokens: number;
238
+ modelCalls: number;
239
+ };
240
+ }>;
241
+ /** Close a conversation (a new message from the user reopens it). */
242
+ resolve: (id: string) => Promise<{
243
+ status: string;
244
+ }>;
101
245
  };
102
246
  readonly templates: {
103
247
  upsert: (template: {
@@ -154,4 +298,4 @@ declare class AsyncifyClient {
154
298
  }>;
155
299
  }
156
300
 
157
- export { AsyncifyClient, type AsyncifyClientOptions, AsyncifyError, type Priority, type Recipient, type TriggerOptions, type TriggerRecipient, type TriggerResult, type WorkflowStep };
301
+ export { type Agent, AsyncifyClient, type AsyncifyClientOptions, AsyncifyError, type ConversationSummary, type CreateAgentOptions, type Priority, type Recipient, type TriggerOptions, type TriggerRecipient, type TriggerResult, type WorkflowStep };
package/dist/index.js CHANGED
@@ -40,7 +40,67 @@ var AsyncifyClient = class {
40
40
  list: () => this.request("GET", "/v1/workflows")
41
41
  };
42
42
  subscribers = {
43
- upsert: (subscriber) => this.request("PUT", "/v1/subscribers", subscriber)
43
+ upsert: (subscriber) => this.request("PUT", "/v1/subscribers", subscriber),
44
+ /** Channel identities linked to this subscriber (telegram, email). */
45
+ identities: (subscriberId) => this.request("GET", `/v1/subscribers/${encodeURIComponent(subscriberId)}/identities`),
46
+ /** Drop a linked identity — future messages fall back to a channel-local one. */
47
+ unlink: (subscriberId, identity) => this.request(
48
+ "DELETE",
49
+ `/v1/subscribers/${encodeURIComponent(subscriberId)}/identities`,
50
+ identity
51
+ )
52
+ };
53
+ agents = {
54
+ /** Create an agent. The signing secret is returned EXACTLY ONCE — store it. */
55
+ create: (options) => this.request("POST", "/v1/agents", options),
56
+ list: () => this.request("GET", "/v1/agents"),
57
+ get: (identifier) => this.request("GET", `/v1/agents/${encodeURIComponent(identifier)}`),
58
+ /** Patch any subset; `autoResolveMinutes: null` switches the backstop off. */
59
+ update: (identifier, patch) => this.request(
60
+ "PATCH",
61
+ `/v1/agents/${encodeURIComponent(identifier)}`,
62
+ patch
63
+ ),
64
+ /** New signing secret, shown once; the old one stops working immediately. */
65
+ rotateSecret: (identifier) => this.request(
66
+ "POST",
67
+ `/v1/agents/${encodeURIComponent(identifier)}/rotate-secret`
68
+ ),
69
+ delete: (identifier) => this.request(
70
+ "DELETE",
71
+ `/v1/agents/${encodeURIComponent(identifier)}`
72
+ ),
73
+ /**
74
+ * Mint the single-use deep link (24h TTL) that merges a user's Telegram
75
+ * into this subscriber: generate it server-side for your LOGGED-IN user
76
+ * and hand them the returned t.me link. When they tap Start, their
77
+ * Telegram identity, history, and notifications unify with the
78
+ * subscriber — agent replies and triggers reach the real person.
79
+ */
80
+ linkToken: (agentIdentifier, subscriberId) => this.request(
81
+ "POST",
82
+ `/v1/agents/${encodeURIComponent(agentIdentifier)}/subscribers/${encodeURIComponent(subscriberId)}/link-token`
83
+ )
84
+ };
85
+ conversations = {
86
+ /** Conversations across your agents, newest first. */
87
+ list: (filters = {}) => {
88
+ const qs = new URLSearchParams();
89
+ if (filters.agent) qs.set("agent", filters.agent);
90
+ if (filters.status) qs.set("status", filters.status);
91
+ const suffix = qs.toString();
92
+ return this.request(
93
+ "GET",
94
+ `/v1/conversations${suffix ? `?${suffix}` : ""}`
95
+ );
96
+ },
97
+ /** Full transcript + metadata + LLM usage totals for one conversation. */
98
+ get: (id) => this.request("GET", `/v1/conversations/${encodeURIComponent(id)}`),
99
+ /** Close a conversation (a new message from the user reopens it). */
100
+ resolve: (id) => this.request(
101
+ "POST",
102
+ `/v1/conversations/${encodeURIComponent(id)}/resolve`
103
+ )
44
104
  };
45
105
  templates = {
46
106
  upsert: (template) => this.request("PUT", "/v1/templates", template),
package/package.json CHANGED
@@ -1,12 +1,20 @@
1
1
  {
2
2
  "name": "@asyncify-hq/node",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "Server-side SDK for Asyncify — multi-channel notification infrastructure (email, SMS, push, in-app)",
5
- "keywords": ["notifications", "email", "sms", "push", "in-app", "asyncify", "notification-infrastructure"],
5
+ "keywords": [
6
+ "notifications",
7
+ "email",
8
+ "sms",
9
+ "push",
10
+ "in-app",
11
+ "asyncify",
12
+ "notification-infrastructure"
13
+ ],
6
14
  "homepage": "https://asyncify.org",
7
15
  "repository": {
8
16
  "type": "git",
9
- "url": "https://github.com/shubam14dec/Scalable-Notification-System.git",
17
+ "url": "git+https://github.com/shubam14dec/Scalable-Notification-System.git",
10
18
  "directory": "packages/sdk-node"
11
19
  },
12
20
  "license": "MIT",
@@ -22,7 +30,9 @@
22
30
  "require": "./dist/index.cjs"
23
31
  }
24
32
  },
25
- "files": ["dist"],
33
+ "files": [
34
+ "dist"
35
+ ],
26
36
  "sideEffects": false,
27
37
  "publishConfig": {
28
38
  "access": "public"