vessels-sdk 0.6.0 → 0.8.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/dist/index.cjs +63 -7
- package/dist/index.d.cts +31 -6
- package/dist/index.d.ts +31 -6
- package/dist/index.js +62 -8
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -160,6 +160,8 @@ var WebhookVesselSchema = zod.z.object({
|
|
|
160
160
|
id: zod.z.string(),
|
|
161
161
|
external_id: zod.z.string().nullable(),
|
|
162
162
|
title: zod.z.string().nullable(),
|
|
163
|
+
/** The vessel's type (e.g. "Ticket"). Nullable — agent-created vessels have no type. */
|
|
164
|
+
type: zod.z.string().nullable().optional(),
|
|
163
165
|
metadata: zod.z.record(zod.z.unknown())
|
|
164
166
|
});
|
|
165
167
|
var WebhookContextMessageSchema = zod.z.object({
|
|
@@ -202,9 +204,24 @@ var WebhookUserMessagePayloadSchema = zod.z.object({
|
|
|
202
204
|
context: zod.z.array(WebhookContextMessageSchema)
|
|
203
205
|
})
|
|
204
206
|
});
|
|
207
|
+
var WebhookVesselCreatedPayloadSchema = zod.z.object({
|
|
208
|
+
event: zod.z.literal("vessel.created"),
|
|
209
|
+
vessel_id: zod.z.string(),
|
|
210
|
+
workspace_id: zod.z.string(),
|
|
211
|
+
timestamp: zod.z.string(),
|
|
212
|
+
data: zod.z.object({
|
|
213
|
+
vessel: WebhookVesselSchema,
|
|
214
|
+
message: zod.z.object({
|
|
215
|
+
message_id: zod.z.string(),
|
|
216
|
+
content: zod.z.string().nullable(),
|
|
217
|
+
created_at: zod.z.string()
|
|
218
|
+
})
|
|
219
|
+
})
|
|
220
|
+
});
|
|
205
221
|
var WebhookPayloadSchema = zod.z.discriminatedUnion("event", [
|
|
206
222
|
WebhookInteractionResponsePayloadSchema,
|
|
207
|
-
WebhookUserMessagePayloadSchema
|
|
223
|
+
WebhookUserMessagePayloadSchema,
|
|
224
|
+
WebhookVesselCreatedPayloadSchema
|
|
208
225
|
]);
|
|
209
226
|
|
|
210
227
|
// src/index.ts
|
|
@@ -237,6 +254,12 @@ var VesselsRateLimitError = class extends Error {
|
|
|
237
254
|
this.retryAfter = retryAfter;
|
|
238
255
|
}
|
|
239
256
|
};
|
|
257
|
+
var VesselsConflictError = class extends Error {
|
|
258
|
+
constructor(message) {
|
|
259
|
+
super(message);
|
|
260
|
+
this.name = "VesselsConflictError";
|
|
261
|
+
}
|
|
262
|
+
};
|
|
240
263
|
var Vessels = class {
|
|
241
264
|
apiKey;
|
|
242
265
|
baseUrl;
|
|
@@ -270,38 +293,45 @@ var Vessels = class {
|
|
|
270
293
|
return res;
|
|
271
294
|
}
|
|
272
295
|
async push(payload) {
|
|
296
|
+
const { idempotencyKey, ...body } = payload;
|
|
273
297
|
const res = await this._fetch(`${this.baseUrl}/api/v1/push`, {
|
|
274
298
|
method: "POST",
|
|
275
299
|
headers: {
|
|
276
300
|
"Content-Type": "application/json",
|
|
277
|
-
"Authorization": `Bearer ${this.apiKey}
|
|
301
|
+
"Authorization": `Bearer ${this.apiKey}`,
|
|
302
|
+
...idempotencyKey ? { "Idempotency-Key": idempotencyKey } : {}
|
|
278
303
|
},
|
|
279
|
-
body: JSON.stringify(
|
|
304
|
+
body: JSON.stringify(body)
|
|
280
305
|
});
|
|
281
306
|
const data = await res.json();
|
|
282
307
|
if (res.status === 401) throw new VesselsAuthError(data.error ?? "Unauthorized");
|
|
283
308
|
if (res.status === 429) throw new VesselsRateLimitError(data.error ?? "Rate limited", Number(res.headers.get("retry-after")));
|
|
309
|
+
if (res.status === 409) throw new VesselsConflictError(data.error ?? "Idempotent request in progress");
|
|
284
310
|
if (res.status === 400) throw new VesselsValidationError(data.error ?? "Validation failed", data.details);
|
|
285
311
|
if (!res.ok) throw new Error(data.error ?? `HTTP ${res.status}`);
|
|
286
312
|
return {
|
|
287
313
|
ok: true,
|
|
288
314
|
messageId: data.message_id,
|
|
289
315
|
vesselId: data.vessel_id,
|
|
290
|
-
createdAt: data.created_at
|
|
316
|
+
createdAt: data.created_at,
|
|
317
|
+
replayed: res.headers.get("Idempotent-Replayed") === "true"
|
|
291
318
|
};
|
|
292
319
|
}
|
|
293
320
|
async pushMany(payload) {
|
|
321
|
+
const { idempotencyKey, ...body } = payload;
|
|
294
322
|
const res = await this._fetch(`${this.baseUrl}/api/v1/push/many`, {
|
|
295
323
|
method: "POST",
|
|
296
324
|
headers: {
|
|
297
325
|
"Content-Type": "application/json",
|
|
298
|
-
"Authorization": `Bearer ${this.apiKey}
|
|
326
|
+
"Authorization": `Bearer ${this.apiKey}`,
|
|
327
|
+
...idempotencyKey ? { "Idempotency-Key": idempotencyKey } : {}
|
|
299
328
|
},
|
|
300
|
-
body: JSON.stringify(
|
|
329
|
+
body: JSON.stringify(body)
|
|
301
330
|
});
|
|
302
331
|
const data = await res.json();
|
|
303
332
|
if (res.status === 401) throw new VesselsAuthError(data.error ?? "Unauthorized");
|
|
304
333
|
if (res.status === 429) throw new VesselsRateLimitError(data.error ?? "Rate limited", Number(res.headers.get("retry-after")));
|
|
334
|
+
if (res.status === 409) throw new VesselsConflictError(data.error ?? "Idempotent request in progress");
|
|
305
335
|
if (res.status === 400) throw new VesselsValidationError(data.error ?? "Validation failed", data.details);
|
|
306
336
|
if (!res.ok) throw new Error(data.error ?? `HTTP ${res.status}`);
|
|
307
337
|
return {
|
|
@@ -311,7 +341,8 @@ var Vessels = class {
|
|
|
311
341
|
messageId: r.message_id,
|
|
312
342
|
vesselId: r.vessel_id,
|
|
313
343
|
...r.error ? { error: r.error } : {}
|
|
314
|
-
}))
|
|
344
|
+
})),
|
|
345
|
+
replayed: res.headers.get("Idempotent-Replayed") === "true"
|
|
315
346
|
};
|
|
316
347
|
}
|
|
317
348
|
async editMessage(messageId, patch) {
|
|
@@ -396,9 +427,19 @@ var Vessels = class {
|
|
|
396
427
|
id: e.vessel?.id,
|
|
397
428
|
externalId: e.vessel?.external_id ?? null,
|
|
398
429
|
title: e.vessel?.title ?? null,
|
|
430
|
+
type: e.vessel?.type ?? null,
|
|
399
431
|
metadata: e.vessel?.metadata ?? {},
|
|
400
432
|
labels: e.vessel?.labels ?? []
|
|
401
433
|
};
|
|
434
|
+
if (e.type === "vessel.created") {
|
|
435
|
+
return {
|
|
436
|
+
id: e.id,
|
|
437
|
+
type: "vessel.created",
|
|
438
|
+
timestamp: e.timestamp,
|
|
439
|
+
vessel,
|
|
440
|
+
message: { id: e.message?.id, content: e.message?.content ?? null }
|
|
441
|
+
};
|
|
442
|
+
}
|
|
402
443
|
if (e.type === "interaction.response") {
|
|
403
444
|
return {
|
|
404
445
|
id: e.id,
|
|
@@ -470,9 +511,22 @@ var Vessels = class {
|
|
|
470
511
|
id: v.id,
|
|
471
512
|
externalId: v.external_id ?? null,
|
|
472
513
|
title: v.title ?? null,
|
|
514
|
+
type: v.type ?? null,
|
|
473
515
|
metadata: v.metadata ?? {},
|
|
474
516
|
labels: v.labels ?? []
|
|
475
517
|
};
|
|
518
|
+
if (raw.event === "vessel.created") {
|
|
519
|
+
return {
|
|
520
|
+
id: raw.vessel_id,
|
|
521
|
+
type: "vessel.created",
|
|
522
|
+
timestamp: raw.timestamp,
|
|
523
|
+
vessel,
|
|
524
|
+
message: {
|
|
525
|
+
id: raw.data.message?.message_id,
|
|
526
|
+
content: raw.data.message?.content ?? null
|
|
527
|
+
}
|
|
528
|
+
};
|
|
529
|
+
}
|
|
476
530
|
if (raw.event === "interaction.response") {
|
|
477
531
|
return {
|
|
478
532
|
id: raw.data.response_id,
|
|
@@ -517,8 +571,10 @@ var Vessels = class {
|
|
|
517
571
|
exports.AgentActivityTypes = AgentActivityTypes;
|
|
518
572
|
exports.Vessels = Vessels;
|
|
519
573
|
exports.VesselsAuthError = VesselsAuthError;
|
|
574
|
+
exports.VesselsConflictError = VesselsConflictError;
|
|
520
575
|
exports.VesselsRateLimitError = VesselsRateLimitError;
|
|
521
576
|
exports.VesselsValidationError = VesselsValidationError;
|
|
522
577
|
exports.WebhookInteractionResponsePayloadSchema = WebhookInteractionResponsePayloadSchema;
|
|
523
578
|
exports.WebhookPayloadSchema = WebhookPayloadSchema;
|
|
524
579
|
exports.WebhookUserMessagePayloadSchema = WebhookUserMessagePayloadSchema;
|
|
580
|
+
exports.WebhookVesselCreatedPayloadSchema = WebhookVesselCreatedPayloadSchema;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _vessels_types from '@vessels/types';
|
|
2
|
-
export { AgentActivity, AgentActivityType, ApprovalInteraction, Attachment, Card, ChecklistInteraction, ChoiceInteraction, ConfirmPreviewInteraction, Interaction, MessagePatch, PushManyPayload, PushPayload, TextInputInteraction, WebhookInteractionResponsePayload, WebhookInteractionResponsePayloadSchema, WebhookPayload, WebhookPayloadSchema, WebhookUserMessagePayload, WebhookUserMessagePayloadSchema } from '@vessels/types';
|
|
2
|
+
export { AgentActivity, AgentActivityType, ApprovalInteraction, Attachment, Card, ChecklistInteraction, ChoiceInteraction, ConfirmPreviewInteraction, Interaction, MessagePatch, PushManyOptions, PushManyPayload, PushOptions, PushPayload, TextInputInteraction, WebhookInteractionResponsePayload, WebhookInteractionResponsePayloadSchema, WebhookPayload, WebhookPayloadSchema, WebhookUserMessagePayload, WebhookUserMessagePayloadSchema, WebhookVesselCreatedPayload, WebhookVesselCreatedPayloadSchema } from '@vessels/types';
|
|
3
3
|
|
|
4
4
|
declare const AgentActivityTypes: {
|
|
5
5
|
readonly thinking: "thinking";
|
|
@@ -19,6 +19,10 @@ declare class VesselsRateLimitError extends Error {
|
|
|
19
19
|
retryAfter?: number;
|
|
20
20
|
constructor(message: string, retryAfter?: number);
|
|
21
21
|
}
|
|
22
|
+
/** Thrown on HTTP 409 — an identical idempotent request is still in flight. Back off and retry. */
|
|
23
|
+
declare class VesselsConflictError extends Error {
|
|
24
|
+
constructor(message: string);
|
|
25
|
+
}
|
|
22
26
|
interface VesselsConfig {
|
|
23
27
|
apiKey: string;
|
|
24
28
|
baseUrl?: string;
|
|
@@ -29,6 +33,8 @@ interface PushResponse {
|
|
|
29
33
|
messageId: string;
|
|
30
34
|
vesselId: string;
|
|
31
35
|
createdAt: string;
|
|
36
|
+
/** True when this response is a replay of an earlier request with the same idempotency key. */
|
|
37
|
+
replayed: boolean;
|
|
32
38
|
}
|
|
33
39
|
interface PushManyResult {
|
|
34
40
|
ok: true;
|
|
@@ -38,6 +44,8 @@ interface PushManyResult {
|
|
|
38
44
|
vesselId: string;
|
|
39
45
|
error?: string;
|
|
40
46
|
}>;
|
|
47
|
+
/** True when this response is a replay of an earlier request with the same idempotency key. */
|
|
48
|
+
replayed: boolean;
|
|
41
49
|
}
|
|
42
50
|
interface PollOptions {
|
|
43
51
|
since?: string;
|
|
@@ -48,6 +56,8 @@ interface VesselContext {
|
|
|
48
56
|
id: string;
|
|
49
57
|
externalId: string | null;
|
|
50
58
|
title: string | null;
|
|
59
|
+
/** The vessel's type (e.g. "Ticket"). Null for agent-created vessels. */
|
|
60
|
+
type: string | null;
|
|
51
61
|
metadata: Record<string, unknown>;
|
|
52
62
|
labels: string[];
|
|
53
63
|
}
|
|
@@ -91,6 +101,21 @@ interface UserMessageEvent {
|
|
|
91
101
|
createdAt: string;
|
|
92
102
|
}>;
|
|
93
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* Fired when a human opens a new typed vessel from the app (user-initiated
|
|
106
|
+
* vessels). `message` is the first thing the human typed; `vessel.type` is the
|
|
107
|
+
* vessel's type (e.g. "Ticket").
|
|
108
|
+
*/
|
|
109
|
+
interface VesselCreatedEvent {
|
|
110
|
+
id: string;
|
|
111
|
+
type: 'vessel.created';
|
|
112
|
+
timestamp: string;
|
|
113
|
+
vessel: VesselContext;
|
|
114
|
+
message: {
|
|
115
|
+
id: string;
|
|
116
|
+
content: string | null;
|
|
117
|
+
};
|
|
118
|
+
}
|
|
94
119
|
/** A message in a vessel, as returned by getMessages — the human-facing record. */
|
|
95
120
|
interface Message {
|
|
96
121
|
id: string;
|
|
@@ -103,7 +128,7 @@ interface Message {
|
|
|
103
128
|
metadata: Record<string, unknown>;
|
|
104
129
|
createdAt: string;
|
|
105
130
|
}
|
|
106
|
-
type PollEvent = InteractionResponseEvent | UserMessageEvent;
|
|
131
|
+
type PollEvent = InteractionResponseEvent | UserMessageEvent | VesselCreatedEvent;
|
|
107
132
|
interface PollResponse {
|
|
108
133
|
ok: true;
|
|
109
134
|
events: PollEvent[];
|
|
@@ -115,8 +140,8 @@ declare class Vessels {
|
|
|
115
140
|
private _debug;
|
|
116
141
|
constructor(config: VesselsConfig);
|
|
117
142
|
private _fetch;
|
|
118
|
-
push(payload: _vessels_types.
|
|
119
|
-
pushMany(payload: _vessels_types.
|
|
143
|
+
push(payload: _vessels_types.PushOptions): Promise<PushResponse>;
|
|
144
|
+
pushMany(payload: _vessels_types.PushManyOptions): Promise<PushManyResult>;
|
|
120
145
|
editMessage(messageId: string, patch: _vessels_types.MessagePatch): Promise<{
|
|
121
146
|
ok: true;
|
|
122
147
|
}>;
|
|
@@ -182,7 +207,7 @@ declare class Vessels {
|
|
|
182
207
|
}): _vessels_types.ConfirmPreviewInteraction;
|
|
183
208
|
poll(options?: PollOptions): Promise<PollResponse>;
|
|
184
209
|
verifyWebhook(body: string, signature: string, webhookSecret: string): Promise<boolean>;
|
|
185
|
-
parseWebhookEvent(body: string, signature: string, webhookSecret: string): Promise<InteractionResponseEvent | UserMessageEvent | null>;
|
|
210
|
+
parseWebhookEvent(body: string, signature: string, webhookSecret: string): Promise<InteractionResponseEvent | UserMessageEvent | VesselCreatedEvent | null>;
|
|
186
211
|
}
|
|
187
212
|
|
|
188
|
-
export { AgentActivityTypes, type InteractionResponseEvent, type Message, type OriginMessage, type PollEvent, type PollOptions, type PollResponse, type PushManyResult, type PushResponse, type UserMessageEvent, type VesselContext, Vessels, VesselsAuthError, type VesselsConfig, VesselsRateLimitError, VesselsValidationError };
|
|
213
|
+
export { AgentActivityTypes, type InteractionResponseEvent, type Message, type OriginMessage, type PollEvent, type PollOptions, type PollResponse, type PushManyResult, type PushResponse, type UserMessageEvent, type VesselContext, type VesselCreatedEvent, Vessels, VesselsAuthError, type VesselsConfig, VesselsConflictError, VesselsRateLimitError, VesselsValidationError };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _vessels_types from '@vessels/types';
|
|
2
|
-
export { AgentActivity, AgentActivityType, ApprovalInteraction, Attachment, Card, ChecklistInteraction, ChoiceInteraction, ConfirmPreviewInteraction, Interaction, MessagePatch, PushManyPayload, PushPayload, TextInputInteraction, WebhookInteractionResponsePayload, WebhookInteractionResponsePayloadSchema, WebhookPayload, WebhookPayloadSchema, WebhookUserMessagePayload, WebhookUserMessagePayloadSchema } from '@vessels/types';
|
|
2
|
+
export { AgentActivity, AgentActivityType, ApprovalInteraction, Attachment, Card, ChecklistInteraction, ChoiceInteraction, ConfirmPreviewInteraction, Interaction, MessagePatch, PushManyOptions, PushManyPayload, PushOptions, PushPayload, TextInputInteraction, WebhookInteractionResponsePayload, WebhookInteractionResponsePayloadSchema, WebhookPayload, WebhookPayloadSchema, WebhookUserMessagePayload, WebhookUserMessagePayloadSchema, WebhookVesselCreatedPayload, WebhookVesselCreatedPayloadSchema } from '@vessels/types';
|
|
3
3
|
|
|
4
4
|
declare const AgentActivityTypes: {
|
|
5
5
|
readonly thinking: "thinking";
|
|
@@ -19,6 +19,10 @@ declare class VesselsRateLimitError extends Error {
|
|
|
19
19
|
retryAfter?: number;
|
|
20
20
|
constructor(message: string, retryAfter?: number);
|
|
21
21
|
}
|
|
22
|
+
/** Thrown on HTTP 409 — an identical idempotent request is still in flight. Back off and retry. */
|
|
23
|
+
declare class VesselsConflictError extends Error {
|
|
24
|
+
constructor(message: string);
|
|
25
|
+
}
|
|
22
26
|
interface VesselsConfig {
|
|
23
27
|
apiKey: string;
|
|
24
28
|
baseUrl?: string;
|
|
@@ -29,6 +33,8 @@ interface PushResponse {
|
|
|
29
33
|
messageId: string;
|
|
30
34
|
vesselId: string;
|
|
31
35
|
createdAt: string;
|
|
36
|
+
/** True when this response is a replay of an earlier request with the same idempotency key. */
|
|
37
|
+
replayed: boolean;
|
|
32
38
|
}
|
|
33
39
|
interface PushManyResult {
|
|
34
40
|
ok: true;
|
|
@@ -38,6 +44,8 @@ interface PushManyResult {
|
|
|
38
44
|
vesselId: string;
|
|
39
45
|
error?: string;
|
|
40
46
|
}>;
|
|
47
|
+
/** True when this response is a replay of an earlier request with the same idempotency key. */
|
|
48
|
+
replayed: boolean;
|
|
41
49
|
}
|
|
42
50
|
interface PollOptions {
|
|
43
51
|
since?: string;
|
|
@@ -48,6 +56,8 @@ interface VesselContext {
|
|
|
48
56
|
id: string;
|
|
49
57
|
externalId: string | null;
|
|
50
58
|
title: string | null;
|
|
59
|
+
/** The vessel's type (e.g. "Ticket"). Null for agent-created vessels. */
|
|
60
|
+
type: string | null;
|
|
51
61
|
metadata: Record<string, unknown>;
|
|
52
62
|
labels: string[];
|
|
53
63
|
}
|
|
@@ -91,6 +101,21 @@ interface UserMessageEvent {
|
|
|
91
101
|
createdAt: string;
|
|
92
102
|
}>;
|
|
93
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* Fired when a human opens a new typed vessel from the app (user-initiated
|
|
106
|
+
* vessels). `message` is the first thing the human typed; `vessel.type` is the
|
|
107
|
+
* vessel's type (e.g. "Ticket").
|
|
108
|
+
*/
|
|
109
|
+
interface VesselCreatedEvent {
|
|
110
|
+
id: string;
|
|
111
|
+
type: 'vessel.created';
|
|
112
|
+
timestamp: string;
|
|
113
|
+
vessel: VesselContext;
|
|
114
|
+
message: {
|
|
115
|
+
id: string;
|
|
116
|
+
content: string | null;
|
|
117
|
+
};
|
|
118
|
+
}
|
|
94
119
|
/** A message in a vessel, as returned by getMessages — the human-facing record. */
|
|
95
120
|
interface Message {
|
|
96
121
|
id: string;
|
|
@@ -103,7 +128,7 @@ interface Message {
|
|
|
103
128
|
metadata: Record<string, unknown>;
|
|
104
129
|
createdAt: string;
|
|
105
130
|
}
|
|
106
|
-
type PollEvent = InteractionResponseEvent | UserMessageEvent;
|
|
131
|
+
type PollEvent = InteractionResponseEvent | UserMessageEvent | VesselCreatedEvent;
|
|
107
132
|
interface PollResponse {
|
|
108
133
|
ok: true;
|
|
109
134
|
events: PollEvent[];
|
|
@@ -115,8 +140,8 @@ declare class Vessels {
|
|
|
115
140
|
private _debug;
|
|
116
141
|
constructor(config: VesselsConfig);
|
|
117
142
|
private _fetch;
|
|
118
|
-
push(payload: _vessels_types.
|
|
119
|
-
pushMany(payload: _vessels_types.
|
|
143
|
+
push(payload: _vessels_types.PushOptions): Promise<PushResponse>;
|
|
144
|
+
pushMany(payload: _vessels_types.PushManyOptions): Promise<PushManyResult>;
|
|
120
145
|
editMessage(messageId: string, patch: _vessels_types.MessagePatch): Promise<{
|
|
121
146
|
ok: true;
|
|
122
147
|
}>;
|
|
@@ -182,7 +207,7 @@ declare class Vessels {
|
|
|
182
207
|
}): _vessels_types.ConfirmPreviewInteraction;
|
|
183
208
|
poll(options?: PollOptions): Promise<PollResponse>;
|
|
184
209
|
verifyWebhook(body: string, signature: string, webhookSecret: string): Promise<boolean>;
|
|
185
|
-
parseWebhookEvent(body: string, signature: string, webhookSecret: string): Promise<InteractionResponseEvent | UserMessageEvent | null>;
|
|
210
|
+
parseWebhookEvent(body: string, signature: string, webhookSecret: string): Promise<InteractionResponseEvent | UserMessageEvent | VesselCreatedEvent | null>;
|
|
186
211
|
}
|
|
187
212
|
|
|
188
|
-
export { AgentActivityTypes, type InteractionResponseEvent, type Message, type OriginMessage, type PollEvent, type PollOptions, type PollResponse, type PushManyResult, type PushResponse, type UserMessageEvent, type VesselContext, Vessels, VesselsAuthError, type VesselsConfig, VesselsRateLimitError, VesselsValidationError };
|
|
213
|
+
export { AgentActivityTypes, type InteractionResponseEvent, type Message, type OriginMessage, type PollEvent, type PollOptions, type PollResponse, type PushManyResult, type PushResponse, type UserMessageEvent, type VesselContext, type VesselCreatedEvent, Vessels, VesselsAuthError, type VesselsConfig, VesselsConflictError, VesselsRateLimitError, VesselsValidationError };
|
package/dist/index.js
CHANGED
|
@@ -158,6 +158,8 @@ var WebhookVesselSchema = z.object({
|
|
|
158
158
|
id: z.string(),
|
|
159
159
|
external_id: z.string().nullable(),
|
|
160
160
|
title: z.string().nullable(),
|
|
161
|
+
/** The vessel's type (e.g. "Ticket"). Nullable — agent-created vessels have no type. */
|
|
162
|
+
type: z.string().nullable().optional(),
|
|
161
163
|
metadata: z.record(z.unknown())
|
|
162
164
|
});
|
|
163
165
|
var WebhookContextMessageSchema = z.object({
|
|
@@ -200,9 +202,24 @@ var WebhookUserMessagePayloadSchema = z.object({
|
|
|
200
202
|
context: z.array(WebhookContextMessageSchema)
|
|
201
203
|
})
|
|
202
204
|
});
|
|
205
|
+
var WebhookVesselCreatedPayloadSchema = z.object({
|
|
206
|
+
event: z.literal("vessel.created"),
|
|
207
|
+
vessel_id: z.string(),
|
|
208
|
+
workspace_id: z.string(),
|
|
209
|
+
timestamp: z.string(),
|
|
210
|
+
data: z.object({
|
|
211
|
+
vessel: WebhookVesselSchema,
|
|
212
|
+
message: z.object({
|
|
213
|
+
message_id: z.string(),
|
|
214
|
+
content: z.string().nullable(),
|
|
215
|
+
created_at: z.string()
|
|
216
|
+
})
|
|
217
|
+
})
|
|
218
|
+
});
|
|
203
219
|
var WebhookPayloadSchema = z.discriminatedUnion("event", [
|
|
204
220
|
WebhookInteractionResponsePayloadSchema,
|
|
205
|
-
WebhookUserMessagePayloadSchema
|
|
221
|
+
WebhookUserMessagePayloadSchema,
|
|
222
|
+
WebhookVesselCreatedPayloadSchema
|
|
206
223
|
]);
|
|
207
224
|
|
|
208
225
|
// src/index.ts
|
|
@@ -235,6 +252,12 @@ var VesselsRateLimitError = class extends Error {
|
|
|
235
252
|
this.retryAfter = retryAfter;
|
|
236
253
|
}
|
|
237
254
|
};
|
|
255
|
+
var VesselsConflictError = class extends Error {
|
|
256
|
+
constructor(message) {
|
|
257
|
+
super(message);
|
|
258
|
+
this.name = "VesselsConflictError";
|
|
259
|
+
}
|
|
260
|
+
};
|
|
238
261
|
var Vessels = class {
|
|
239
262
|
apiKey;
|
|
240
263
|
baseUrl;
|
|
@@ -268,38 +291,45 @@ var Vessels = class {
|
|
|
268
291
|
return res;
|
|
269
292
|
}
|
|
270
293
|
async push(payload) {
|
|
294
|
+
const { idempotencyKey, ...body } = payload;
|
|
271
295
|
const res = await this._fetch(`${this.baseUrl}/api/v1/push`, {
|
|
272
296
|
method: "POST",
|
|
273
297
|
headers: {
|
|
274
298
|
"Content-Type": "application/json",
|
|
275
|
-
"Authorization": `Bearer ${this.apiKey}
|
|
299
|
+
"Authorization": `Bearer ${this.apiKey}`,
|
|
300
|
+
...idempotencyKey ? { "Idempotency-Key": idempotencyKey } : {}
|
|
276
301
|
},
|
|
277
|
-
body: JSON.stringify(
|
|
302
|
+
body: JSON.stringify(body)
|
|
278
303
|
});
|
|
279
304
|
const data = await res.json();
|
|
280
305
|
if (res.status === 401) throw new VesselsAuthError(data.error ?? "Unauthorized");
|
|
281
306
|
if (res.status === 429) throw new VesselsRateLimitError(data.error ?? "Rate limited", Number(res.headers.get("retry-after")));
|
|
307
|
+
if (res.status === 409) throw new VesselsConflictError(data.error ?? "Idempotent request in progress");
|
|
282
308
|
if (res.status === 400) throw new VesselsValidationError(data.error ?? "Validation failed", data.details);
|
|
283
309
|
if (!res.ok) throw new Error(data.error ?? `HTTP ${res.status}`);
|
|
284
310
|
return {
|
|
285
311
|
ok: true,
|
|
286
312
|
messageId: data.message_id,
|
|
287
313
|
vesselId: data.vessel_id,
|
|
288
|
-
createdAt: data.created_at
|
|
314
|
+
createdAt: data.created_at,
|
|
315
|
+
replayed: res.headers.get("Idempotent-Replayed") === "true"
|
|
289
316
|
};
|
|
290
317
|
}
|
|
291
318
|
async pushMany(payload) {
|
|
319
|
+
const { idempotencyKey, ...body } = payload;
|
|
292
320
|
const res = await this._fetch(`${this.baseUrl}/api/v1/push/many`, {
|
|
293
321
|
method: "POST",
|
|
294
322
|
headers: {
|
|
295
323
|
"Content-Type": "application/json",
|
|
296
|
-
"Authorization": `Bearer ${this.apiKey}
|
|
324
|
+
"Authorization": `Bearer ${this.apiKey}`,
|
|
325
|
+
...idempotencyKey ? { "Idempotency-Key": idempotencyKey } : {}
|
|
297
326
|
},
|
|
298
|
-
body: JSON.stringify(
|
|
327
|
+
body: JSON.stringify(body)
|
|
299
328
|
});
|
|
300
329
|
const data = await res.json();
|
|
301
330
|
if (res.status === 401) throw new VesselsAuthError(data.error ?? "Unauthorized");
|
|
302
331
|
if (res.status === 429) throw new VesselsRateLimitError(data.error ?? "Rate limited", Number(res.headers.get("retry-after")));
|
|
332
|
+
if (res.status === 409) throw new VesselsConflictError(data.error ?? "Idempotent request in progress");
|
|
303
333
|
if (res.status === 400) throw new VesselsValidationError(data.error ?? "Validation failed", data.details);
|
|
304
334
|
if (!res.ok) throw new Error(data.error ?? `HTTP ${res.status}`);
|
|
305
335
|
return {
|
|
@@ -309,7 +339,8 @@ var Vessels = class {
|
|
|
309
339
|
messageId: r.message_id,
|
|
310
340
|
vesselId: r.vessel_id,
|
|
311
341
|
...r.error ? { error: r.error } : {}
|
|
312
|
-
}))
|
|
342
|
+
})),
|
|
343
|
+
replayed: res.headers.get("Idempotent-Replayed") === "true"
|
|
313
344
|
};
|
|
314
345
|
}
|
|
315
346
|
async editMessage(messageId, patch) {
|
|
@@ -394,9 +425,19 @@ var Vessels = class {
|
|
|
394
425
|
id: e.vessel?.id,
|
|
395
426
|
externalId: e.vessel?.external_id ?? null,
|
|
396
427
|
title: e.vessel?.title ?? null,
|
|
428
|
+
type: e.vessel?.type ?? null,
|
|
397
429
|
metadata: e.vessel?.metadata ?? {},
|
|
398
430
|
labels: e.vessel?.labels ?? []
|
|
399
431
|
};
|
|
432
|
+
if (e.type === "vessel.created") {
|
|
433
|
+
return {
|
|
434
|
+
id: e.id,
|
|
435
|
+
type: "vessel.created",
|
|
436
|
+
timestamp: e.timestamp,
|
|
437
|
+
vessel,
|
|
438
|
+
message: { id: e.message?.id, content: e.message?.content ?? null }
|
|
439
|
+
};
|
|
440
|
+
}
|
|
400
441
|
if (e.type === "interaction.response") {
|
|
401
442
|
return {
|
|
402
443
|
id: e.id,
|
|
@@ -468,9 +509,22 @@ var Vessels = class {
|
|
|
468
509
|
id: v.id,
|
|
469
510
|
externalId: v.external_id ?? null,
|
|
470
511
|
title: v.title ?? null,
|
|
512
|
+
type: v.type ?? null,
|
|
471
513
|
metadata: v.metadata ?? {},
|
|
472
514
|
labels: v.labels ?? []
|
|
473
515
|
};
|
|
516
|
+
if (raw.event === "vessel.created") {
|
|
517
|
+
return {
|
|
518
|
+
id: raw.vessel_id,
|
|
519
|
+
type: "vessel.created",
|
|
520
|
+
timestamp: raw.timestamp,
|
|
521
|
+
vessel,
|
|
522
|
+
message: {
|
|
523
|
+
id: raw.data.message?.message_id,
|
|
524
|
+
content: raw.data.message?.content ?? null
|
|
525
|
+
}
|
|
526
|
+
};
|
|
527
|
+
}
|
|
474
528
|
if (raw.event === "interaction.response") {
|
|
475
529
|
return {
|
|
476
530
|
id: raw.data.response_id,
|
|
@@ -512,4 +566,4 @@ var Vessels = class {
|
|
|
512
566
|
}
|
|
513
567
|
};
|
|
514
568
|
|
|
515
|
-
export { AgentActivityTypes, Vessels, VesselsAuthError, VesselsRateLimitError, VesselsValidationError, WebhookInteractionResponsePayloadSchema, WebhookPayloadSchema, WebhookUserMessagePayloadSchema };
|
|
569
|
+
export { AgentActivityTypes, Vessels, VesselsAuthError, VesselsConflictError, VesselsRateLimitError, VesselsValidationError, WebhookInteractionResponsePayloadSchema, WebhookPayloadSchema, WebhookUserMessagePayloadSchema, WebhookVesselCreatedPayloadSchema };
|