@realtimex/sdk 1.3.4 → 1.3.5-rc.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/README.md +61 -0
- package/dist/index.d.mts +135 -7
- package/dist/index.d.ts +135 -7
- package/dist/index.js +365 -31
- package/dist/index.mjs +349 -30
- package/package.json +2 -1
package/dist/index.mjs
CHANGED
|
@@ -228,6 +228,204 @@ var ActivitiesModule = class {
|
|
|
228
228
|
}
|
|
229
229
|
};
|
|
230
230
|
|
|
231
|
+
// src/modules/contract.ts
|
|
232
|
+
import { createHash, createHmac, randomUUID } from "crypto";
|
|
233
|
+
var LOCAL_APP_CONTRACT_VERSION = "local-app-contract/v1";
|
|
234
|
+
var CONTRACT_SIGNATURE_HEADER = "x-rtx-contract-signature";
|
|
235
|
+
var CONTRACT_EVENT_ID_HEADER = "x-rtx-event-id";
|
|
236
|
+
var CONTRACT_SIGNATURE_ALGORITHM = "sha256";
|
|
237
|
+
var CONTRACT_ATTEMPT_PREFIX = "run-";
|
|
238
|
+
var CONTRACT_EVENT_ALIASES = {
|
|
239
|
+
"trigger-agent": "task.trigger",
|
|
240
|
+
"task.trigger": "task.trigger",
|
|
241
|
+
ping: "system.ping",
|
|
242
|
+
"system.ping": "system.ping",
|
|
243
|
+
claim: "task.claimed",
|
|
244
|
+
claimed: "task.claimed",
|
|
245
|
+
"task.claimed": "task.claimed",
|
|
246
|
+
"task-start": "task.started",
|
|
247
|
+
start: "task.started",
|
|
248
|
+
"task.started": "task.started",
|
|
249
|
+
"task-progress": "task.progress",
|
|
250
|
+
progress: "task.progress",
|
|
251
|
+
processing: "task.progress",
|
|
252
|
+
"task.progress": "task.progress",
|
|
253
|
+
"task-complete": "task.completed",
|
|
254
|
+
complete: "task.completed",
|
|
255
|
+
completed: "task.completed",
|
|
256
|
+
"task.completed": "task.completed",
|
|
257
|
+
"task-fail": "task.failed",
|
|
258
|
+
fail: "task.failed",
|
|
259
|
+
failed: "task.failed",
|
|
260
|
+
"task.failed": "task.failed",
|
|
261
|
+
"task-cancel": "task.canceled",
|
|
262
|
+
"task-cancelled": "task.canceled",
|
|
263
|
+
"task-canceled": "task.canceled",
|
|
264
|
+
cancel: "task.canceled",
|
|
265
|
+
cancelled: "task.canceled",
|
|
266
|
+
canceled: "task.canceled",
|
|
267
|
+
"task.canceled": "task.canceled"
|
|
268
|
+
};
|
|
269
|
+
var CONTRACT_LEGACY_ACTIONS = {
|
|
270
|
+
"task.trigger": "trigger-agent",
|
|
271
|
+
"system.ping": "ping",
|
|
272
|
+
"task.claimed": "claim",
|
|
273
|
+
"task.started": "start",
|
|
274
|
+
"task.progress": "progress",
|
|
275
|
+
"task.completed": "complete",
|
|
276
|
+
"task.failed": "fail",
|
|
277
|
+
"task.canceled": "cancel"
|
|
278
|
+
};
|
|
279
|
+
function normalizeContractEvent(eventLike) {
|
|
280
|
+
if (!eventLike || typeof eventLike !== "string") return null;
|
|
281
|
+
const normalized = CONTRACT_EVENT_ALIASES[eventLike.trim().toLowerCase()];
|
|
282
|
+
return normalized || null;
|
|
283
|
+
}
|
|
284
|
+
function normalizeAttemptId(attemptLike) {
|
|
285
|
+
if (attemptLike === null || attemptLike === void 0) return void 0;
|
|
286
|
+
if (typeof attemptLike === "number" && Number.isInteger(attemptLike) && attemptLike > 0) {
|
|
287
|
+
return `${CONTRACT_ATTEMPT_PREFIX}${attemptLike}`;
|
|
288
|
+
}
|
|
289
|
+
if (typeof attemptLike !== "string") return void 0;
|
|
290
|
+
const trimmed = attemptLike.trim();
|
|
291
|
+
if (!trimmed) return void 0;
|
|
292
|
+
if (trimmed.startsWith(CONTRACT_ATTEMPT_PREFIX)) return trimmed;
|
|
293
|
+
if (/^\d+$/.test(trimmed)) return `${CONTRACT_ATTEMPT_PREFIX}${trimmed}`;
|
|
294
|
+
return trimmed;
|
|
295
|
+
}
|
|
296
|
+
function parseAttemptRunId(attemptLike) {
|
|
297
|
+
const attemptId = normalizeAttemptId(attemptLike);
|
|
298
|
+
if (!attemptId) return null;
|
|
299
|
+
const matched = attemptId.match(/^run[-_:]?(\d+)$/i);
|
|
300
|
+
if (!matched) return null;
|
|
301
|
+
const value = Number(matched[1]);
|
|
302
|
+
return Number.isInteger(value) && value > 0 ? value : null;
|
|
303
|
+
}
|
|
304
|
+
function hashContractPayload(payload) {
|
|
305
|
+
const normalized = payload && typeof payload === "object" ? payload : { value: payload ?? null };
|
|
306
|
+
return createHash("sha256").update(JSON.stringify(normalized)).digest("hex");
|
|
307
|
+
}
|
|
308
|
+
function createContractEventId() {
|
|
309
|
+
return randomUUID();
|
|
310
|
+
}
|
|
311
|
+
function buildContractSignatureMessage({
|
|
312
|
+
eventId,
|
|
313
|
+
eventType,
|
|
314
|
+
taskId,
|
|
315
|
+
attemptId,
|
|
316
|
+
timestamp,
|
|
317
|
+
payload
|
|
318
|
+
}) {
|
|
319
|
+
return [
|
|
320
|
+
String(eventId || ""),
|
|
321
|
+
String(normalizeContractEvent(String(eventType || "")) || eventType || ""),
|
|
322
|
+
String(taskId || ""),
|
|
323
|
+
String(normalizeAttemptId(attemptId) || ""),
|
|
324
|
+
String(timestamp || ""),
|
|
325
|
+
hashContractPayload(payload ?? {})
|
|
326
|
+
].join(".");
|
|
327
|
+
}
|
|
328
|
+
function signContractEvent(input) {
|
|
329
|
+
const signatureMessage = buildContractSignatureMessage(input);
|
|
330
|
+
const digest = createHmac(CONTRACT_SIGNATURE_ALGORITHM, input.secret).update(signatureMessage).digest("hex");
|
|
331
|
+
return `${CONTRACT_SIGNATURE_ALGORITHM}=${digest}`;
|
|
332
|
+
}
|
|
333
|
+
function canonicalEventToLegacyAction(eventLike) {
|
|
334
|
+
const normalized = normalizeContractEvent(eventLike);
|
|
335
|
+
if (!normalized) return null;
|
|
336
|
+
return CONTRACT_LEGACY_ACTIONS[normalized] || null;
|
|
337
|
+
}
|
|
338
|
+
function buildContractIdempotencyKey({
|
|
339
|
+
taskId,
|
|
340
|
+
eventType,
|
|
341
|
+
eventId,
|
|
342
|
+
attemptId,
|
|
343
|
+
machineId,
|
|
344
|
+
timestamp,
|
|
345
|
+
payload
|
|
346
|
+
}) {
|
|
347
|
+
const canonicalEvent = normalizeContractEvent(eventType) || eventType;
|
|
348
|
+
if (eventId) {
|
|
349
|
+
const eventToken = createHash("sha256").update(String(eventId)).digest("hex");
|
|
350
|
+
return `${taskId}:${canonicalEvent}:event:${eventToken}`;
|
|
351
|
+
}
|
|
352
|
+
const hashInput = {
|
|
353
|
+
task_id: taskId,
|
|
354
|
+
event_type: canonicalEvent,
|
|
355
|
+
attempt_id: normalizeAttemptId(attemptId),
|
|
356
|
+
machine_id: machineId || null,
|
|
357
|
+
timestamp: timestamp || null,
|
|
358
|
+
payload_hash: hashContractPayload(payload ?? {})
|
|
359
|
+
};
|
|
360
|
+
const token = createHash("sha256").update(JSON.stringify(hashInput)).digest("hex");
|
|
361
|
+
return `${taskId}:${canonicalEvent}:hash:${token}`;
|
|
362
|
+
}
|
|
363
|
+
var ContractModule = class {
|
|
364
|
+
constructor(realtimexUrl, appName, appId, apiKey) {
|
|
365
|
+
this.cachedContract = null;
|
|
366
|
+
this.realtimexUrl = realtimexUrl.replace(/\/$/, "");
|
|
367
|
+
this.appName = appName;
|
|
368
|
+
this.appId = appId;
|
|
369
|
+
this.apiKey = apiKey;
|
|
370
|
+
}
|
|
371
|
+
async requestPermission(permission) {
|
|
372
|
+
try {
|
|
373
|
+
const response = await fetch(`${this.realtimexUrl}/api/local-apps/request-permission`, {
|
|
374
|
+
method: "POST",
|
|
375
|
+
headers: { "Content-Type": "application/json" },
|
|
376
|
+
body: JSON.stringify({
|
|
377
|
+
app_id: this.appId,
|
|
378
|
+
app_name: this.appName,
|
|
379
|
+
permission
|
|
380
|
+
})
|
|
381
|
+
});
|
|
382
|
+
const data = await response.json();
|
|
383
|
+
return data.granted === true;
|
|
384
|
+
} catch {
|
|
385
|
+
return false;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
async request(path) {
|
|
389
|
+
const url = `${this.realtimexUrl}${path}`;
|
|
390
|
+
const headers = {
|
|
391
|
+
"Content-Type": "application/json"
|
|
392
|
+
};
|
|
393
|
+
if (this.apiKey) headers.Authorization = `Bearer ${this.apiKey}`;
|
|
394
|
+
if (this.appId) headers["x-app-id"] = this.appId;
|
|
395
|
+
const response = await fetch(url, {
|
|
396
|
+
method: "GET",
|
|
397
|
+
headers
|
|
398
|
+
});
|
|
399
|
+
const data = await response.json();
|
|
400
|
+
if (response.status === 403) {
|
|
401
|
+
const errorCode = data.error;
|
|
402
|
+
const permission = data.permission;
|
|
403
|
+
const message = data.message;
|
|
404
|
+
if (errorCode === "PERMISSION_REQUIRED" && permission) {
|
|
405
|
+
const granted = await this.requestPermission(permission);
|
|
406
|
+
if (granted) return this.request(path);
|
|
407
|
+
throw new PermissionDeniedError(permission, message);
|
|
408
|
+
}
|
|
409
|
+
if (errorCode === "PERMISSION_DENIED") {
|
|
410
|
+
throw new PermissionDeniedError(permission, message);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
if (!response.ok) {
|
|
414
|
+
throw new Error(data.error || `Request failed: ${response.status}`);
|
|
415
|
+
}
|
|
416
|
+
return data;
|
|
417
|
+
}
|
|
418
|
+
async getLocalAppV1(forceRefresh = false) {
|
|
419
|
+
if (!forceRefresh && this.cachedContract) return this.cachedContract;
|
|
420
|
+
const data = await this.request("/contracts/local-app/v1");
|
|
421
|
+
this.cachedContract = data.contract;
|
|
422
|
+
return data.contract;
|
|
423
|
+
}
|
|
424
|
+
clearCache() {
|
|
425
|
+
this.cachedContract = null;
|
|
426
|
+
}
|
|
427
|
+
};
|
|
428
|
+
|
|
231
429
|
// src/modules/webhook.ts
|
|
232
430
|
var WebhookModule = class {
|
|
233
431
|
constructor(realtimexUrl, appName, appId, apiKey) {
|
|
@@ -304,7 +502,9 @@ var WebhookModule = class {
|
|
|
304
502
|
body: JSON.stringify({
|
|
305
503
|
app_name: this.appName,
|
|
306
504
|
app_id: this.appId,
|
|
307
|
-
event: "trigger
|
|
505
|
+
event: "task.trigger",
|
|
506
|
+
event_id: payload.event_id || createContractEventId(),
|
|
507
|
+
attempt_id: normalizeAttemptId(payload.attempt_id),
|
|
308
508
|
payload: {
|
|
309
509
|
raw_data: payload.raw_data,
|
|
310
510
|
auto_run: payload.auto_run ?? false,
|
|
@@ -322,7 +522,8 @@ var WebhookModule = class {
|
|
|
322
522
|
body: JSON.stringify({
|
|
323
523
|
app_name: this.appName,
|
|
324
524
|
app_id: this.appId,
|
|
325
|
-
event: "ping"
|
|
525
|
+
event: "system.ping",
|
|
526
|
+
event_id: createContractEventId()
|
|
326
527
|
})
|
|
327
528
|
});
|
|
328
529
|
}
|
|
@@ -335,49 +536,148 @@ var TaskModule = class {
|
|
|
335
536
|
this.appName = appName;
|
|
336
537
|
this.appId = appId;
|
|
337
538
|
this.apiKey = apiKey;
|
|
539
|
+
this.callbackSecret = process.env.RTX_CONTRACT_CALLBACK_SECRET;
|
|
540
|
+
this.signCallbacksByDefault = process.env.RTX_CONTRACT_SIGN_CALLBACKS === "true";
|
|
338
541
|
}
|
|
339
542
|
/**
|
|
340
|
-
*
|
|
543
|
+
* Configure callback signing behavior.
|
|
341
544
|
*/
|
|
342
|
-
|
|
343
|
-
|
|
545
|
+
configureContract(config) {
|
|
546
|
+
if (typeof config.callbackSecret === "string") {
|
|
547
|
+
this.callbackSecret = config.callbackSecret;
|
|
548
|
+
}
|
|
549
|
+
if (typeof config.signCallbacksByDefault === "boolean") {
|
|
550
|
+
this.signCallbacksByDefault = config.signCallbacksByDefault;
|
|
551
|
+
}
|
|
344
552
|
}
|
|
345
553
|
/**
|
|
346
|
-
*
|
|
554
|
+
* Claim a task before processing.
|
|
347
555
|
*/
|
|
348
|
-
async
|
|
349
|
-
return this._sendEvent("task
|
|
556
|
+
async claim(taskUuid, options = {}) {
|
|
557
|
+
return this._sendEvent("task.claimed", taskUuid, {}, options);
|
|
350
558
|
}
|
|
351
559
|
/**
|
|
352
|
-
*
|
|
560
|
+
* Alias for claim()
|
|
353
561
|
*/
|
|
354
|
-
async
|
|
355
|
-
return this.
|
|
562
|
+
async claimed(taskUuid, options = {}) {
|
|
563
|
+
return this.claim(taskUuid, options);
|
|
356
564
|
}
|
|
357
|
-
|
|
565
|
+
/**
|
|
566
|
+
* Mark task as processing.
|
|
567
|
+
* Backward compatible signature: start(taskUuid, machineId?)
|
|
568
|
+
*/
|
|
569
|
+
async start(taskUuid, machineIdOrOptions) {
|
|
570
|
+
return this._sendEvent("task.started", taskUuid, {}, this._normalizeOptions(machineIdOrOptions));
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
573
|
+
* Report incremental task progress.
|
|
574
|
+
*/
|
|
575
|
+
async progress(taskUuid, progressData = {}, options = {}) {
|
|
576
|
+
return this._sendEvent("task.progress", taskUuid, progressData, options);
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* Mark task as completed with result.
|
|
580
|
+
* Backward compatible signature: complete(taskUuid, result?, machineId?)
|
|
581
|
+
*/
|
|
582
|
+
async complete(taskUuid, result = {}, machineIdOrOptions) {
|
|
583
|
+
return this._sendEvent("task.completed", taskUuid, { result }, this._normalizeOptions(machineIdOrOptions));
|
|
584
|
+
}
|
|
585
|
+
/**
|
|
586
|
+
* Mark task as failed with error.
|
|
587
|
+
* Backward compatible signature: fail(taskUuid, error, machineId?)
|
|
588
|
+
*/
|
|
589
|
+
async fail(taskUuid, error, machineIdOrOptions) {
|
|
590
|
+
return this._sendEvent("task.failed", taskUuid, { error }, this._normalizeOptions(machineIdOrOptions));
|
|
591
|
+
}
|
|
592
|
+
/**
|
|
593
|
+
* Mark task as canceled.
|
|
594
|
+
*/
|
|
595
|
+
async cancel(taskUuid, reason, options = {}) {
|
|
596
|
+
const payload = reason ? { error: reason } : {};
|
|
597
|
+
return this._sendEvent("task.canceled", taskUuid, payload, options);
|
|
598
|
+
}
|
|
599
|
+
_normalizeOptions(machineIdOrOptions) {
|
|
600
|
+
if (!machineIdOrOptions) return {};
|
|
601
|
+
if (typeof machineIdOrOptions === "string") {
|
|
602
|
+
return { machineId: machineIdOrOptions };
|
|
603
|
+
}
|
|
604
|
+
return machineIdOrOptions;
|
|
605
|
+
}
|
|
606
|
+
async _sendEvent(event, taskUuid, eventData = {}, options = {}) {
|
|
607
|
+
if (!taskUuid || !taskUuid.trim()) {
|
|
608
|
+
throw new Error("taskUuid is required");
|
|
609
|
+
}
|
|
610
|
+
const attemptId = normalizeAttemptId(options.attemptId);
|
|
611
|
+
const timestamp = options.timestamp || (/* @__PURE__ */ new Date()).toISOString();
|
|
612
|
+
const eventId = options.eventId || createContractEventId();
|
|
613
|
+
const callbackUrl = options.callbackUrl;
|
|
614
|
+
const targetUrl = callbackUrl || `${this.realtimexUrl}/webhooks/realtimex`;
|
|
615
|
+
const sendingToMainWebhook = !callbackUrl;
|
|
616
|
+
const includeAppAuth = sendingToMainWebhook || targetUrl.startsWith(this.realtimexUrl);
|
|
617
|
+
const payloadData = eventData && typeof eventData === "object" ? eventData : {};
|
|
358
618
|
const headers = { "Content-Type": "application/json" };
|
|
359
|
-
|
|
360
|
-
|
|
619
|
+
headers[CONTRACT_EVENT_ID_HEADER] = eventId;
|
|
620
|
+
if (includeAppAuth) {
|
|
621
|
+
if (this.apiKey) headers.Authorization = `Bearer ${this.apiKey}`;
|
|
622
|
+
if (this.appId) headers["x-app-id"] = this.appId;
|
|
361
623
|
}
|
|
362
|
-
|
|
363
|
-
|
|
624
|
+
const callbackSecret = options.callbackSecret || this.callbackSecret;
|
|
625
|
+
const shouldSign = options.sign ?? this.signCallbacksByDefault;
|
|
626
|
+
if (shouldSign) {
|
|
627
|
+
if (!callbackSecret) {
|
|
628
|
+
throw new Error(
|
|
629
|
+
"Callback signing is enabled but no callbackSecret is configured. Use task.configureContract({ callbackSecret }) or pass options.callbackSecret."
|
|
630
|
+
);
|
|
631
|
+
}
|
|
632
|
+
headers[CONTRACT_SIGNATURE_HEADER] = signContractEvent({
|
|
633
|
+
secret: callbackSecret,
|
|
634
|
+
eventId,
|
|
635
|
+
eventType: event,
|
|
636
|
+
taskId: taskUuid,
|
|
637
|
+
attemptId,
|
|
638
|
+
timestamp,
|
|
639
|
+
payload: payloadData
|
|
640
|
+
});
|
|
364
641
|
}
|
|
365
|
-
const
|
|
642
|
+
const requestBody = sendingToMainWebhook ? {
|
|
643
|
+
app_name: this.appName,
|
|
644
|
+
app_id: this.appId,
|
|
645
|
+
event,
|
|
646
|
+
event_id: eventId,
|
|
647
|
+
attempt_id: attemptId,
|
|
648
|
+
payload: {
|
|
649
|
+
task_uuid: taskUuid,
|
|
650
|
+
machine_id: options.machineId,
|
|
651
|
+
timestamp,
|
|
652
|
+
attempt_id: attemptId,
|
|
653
|
+
...payloadData
|
|
654
|
+
}
|
|
655
|
+
} : {
|
|
656
|
+
event,
|
|
657
|
+
action: canonicalEventToLegacyAction(event),
|
|
658
|
+
event_id: eventId,
|
|
659
|
+
attempt_id: attemptId,
|
|
660
|
+
machine_id: options.machineId,
|
|
661
|
+
user_email: options.userEmail,
|
|
662
|
+
activity_id: options.activityId,
|
|
663
|
+
table_name: options.tableName,
|
|
664
|
+
timestamp,
|
|
665
|
+
data: payloadData
|
|
666
|
+
};
|
|
667
|
+
const response = await fetch(targetUrl, {
|
|
366
668
|
method: "POST",
|
|
367
669
|
headers,
|
|
368
|
-
body: JSON.stringify(
|
|
369
|
-
app_name: this.appName,
|
|
370
|
-
app_id: this.appId,
|
|
371
|
-
event,
|
|
372
|
-
payload: {
|
|
373
|
-
task_uuid: taskUuid,
|
|
374
|
-
...extra
|
|
375
|
-
}
|
|
376
|
-
})
|
|
670
|
+
body: JSON.stringify(requestBody)
|
|
377
671
|
});
|
|
378
|
-
const
|
|
379
|
-
if (!response.ok) throw new Error(
|
|
380
|
-
return
|
|
672
|
+
const responseData = await response.json();
|
|
673
|
+
if (!response.ok) throw new Error(responseData.error || `Failed to ${event}`);
|
|
674
|
+
return {
|
|
675
|
+
...responseData,
|
|
676
|
+
task_uuid: responseData.task_uuid || responseData.task_id || taskUuid,
|
|
677
|
+
event_id: responseData.event_id || eventId,
|
|
678
|
+
attempt_id: responseData.attempt_id || attemptId,
|
|
679
|
+
event_type: responseData.event_type || event
|
|
680
|
+
};
|
|
381
681
|
}
|
|
382
682
|
};
|
|
383
683
|
|
|
@@ -1429,12 +1729,16 @@ var _RealtimeXSDK = class _RealtimeXSDK {
|
|
|
1429
1729
|
this.webhook = new WebhookModule(this.realtimexUrl, this.appName, this.appId, this.apiKey);
|
|
1430
1730
|
this.api = new ApiModule(this.realtimexUrl, this.appId, this.appName, this.apiKey);
|
|
1431
1731
|
this.task = new TaskModule(this.realtimexUrl, this.appName, this.appId, this.apiKey);
|
|
1732
|
+
if (config.contract) {
|
|
1733
|
+
this.task.configureContract(config.contract);
|
|
1734
|
+
}
|
|
1432
1735
|
this.port = new PortModule(config.defaultPort);
|
|
1433
1736
|
this.llm = new LLMModule(this.realtimexUrl, this.appId, this.appName, this.apiKey);
|
|
1434
1737
|
this.tts = new TTSModule(this.realtimexUrl, this.appId, this.appName, this.apiKey);
|
|
1435
1738
|
this.stt = new STTModule(this.realtimexUrl, this.appId, this.appName, this.apiKey);
|
|
1436
1739
|
this.agent = new AgentModule(this.httpClient);
|
|
1437
1740
|
this.mcp = new MCPModule(this.realtimexUrl, this.appId, this.appName, this.apiKey);
|
|
1741
|
+
this.contract = new ContractModule(this.realtimexUrl, this.appName, this.appId, this.apiKey);
|
|
1438
1742
|
if (this.permissions.length > 0 && this.appId && !this.apiKey) {
|
|
1439
1743
|
this.register().catch((err) => {
|
|
1440
1744
|
console.error("[RealtimeX SDK] Auto-registration failed:", err.message);
|
|
@@ -1538,9 +1842,15 @@ export {
|
|
|
1538
1842
|
ActivitiesModule,
|
|
1539
1843
|
AgentModule,
|
|
1540
1844
|
ApiModule,
|
|
1845
|
+
CONTRACT_ATTEMPT_PREFIX,
|
|
1846
|
+
CONTRACT_EVENT_ID_HEADER,
|
|
1847
|
+
CONTRACT_SIGNATURE_ALGORITHM,
|
|
1848
|
+
CONTRACT_SIGNATURE_HEADER,
|
|
1849
|
+
ContractModule,
|
|
1541
1850
|
LLMModule,
|
|
1542
1851
|
LLMPermissionError,
|
|
1543
1852
|
LLMProviderError,
|
|
1853
|
+
LOCAL_APP_CONTRACT_VERSION,
|
|
1544
1854
|
MCPModule,
|
|
1545
1855
|
PermissionDeniedError,
|
|
1546
1856
|
PermissionRequiredError,
|
|
@@ -1550,5 +1860,14 @@ export {
|
|
|
1550
1860
|
TTSModule,
|
|
1551
1861
|
TaskModule,
|
|
1552
1862
|
VectorStore,
|
|
1553
|
-
WebhookModule
|
|
1863
|
+
WebhookModule,
|
|
1864
|
+
buildContractIdempotencyKey,
|
|
1865
|
+
buildContractSignatureMessage,
|
|
1866
|
+
canonicalEventToLegacyAction,
|
|
1867
|
+
createContractEventId,
|
|
1868
|
+
hashContractPayload,
|
|
1869
|
+
normalizeAttemptId,
|
|
1870
|
+
normalizeContractEvent,
|
|
1871
|
+
parseAttemptRunId,
|
|
1872
|
+
signContractEvent
|
|
1554
1873
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@realtimex/sdk",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.5-rc.1",
|
|
4
4
|
"description": "SDK for building Local Apps that integrate with RealtimeX",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"build": "tsup src/index.ts --format cjs,esm --dts --clean",
|
|
17
17
|
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
18
18
|
"test": "vitest run",
|
|
19
|
+
"contract:verify": "node ../scripts/verify-contract-compat.mjs",
|
|
19
20
|
"prepublishOnly": "npm run build"
|
|
20
21
|
},
|
|
21
22
|
"keywords": [
|