@rei-standard/amsg-shared 0.1.0-next.3 → 0.1.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 +40 -1
- package/dist/index.d.cts +38 -17
- package/dist/index.d.ts +38 -17
- package/dist/index.mjs +40 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -22,15 +22,18 @@ __export(src_exports, {
|
|
|
22
22
|
MESSAGE_KIND: () => MESSAGE_KIND,
|
|
23
23
|
MESSAGE_TYPE: () => MESSAGE_TYPE,
|
|
24
24
|
PUSH_SOURCE: () => PUSH_SOURCE,
|
|
25
|
+
base64UrlToBytes: () => base64UrlToBytes,
|
|
25
26
|
buildContentPush: () => buildContentPush,
|
|
26
27
|
buildErrorPush: () => buildErrorPush,
|
|
27
28
|
buildReasoningPush: () => buildReasoningPush,
|
|
28
29
|
buildToolRequestPush: () => buildToolRequestPush,
|
|
29
30
|
chunkReasoningByUtf8Bytes: () => chunkReasoningByUtf8Bytes,
|
|
31
|
+
concatBytes: () => concatBytes,
|
|
30
32
|
isContentPush: () => isContentPush,
|
|
31
33
|
isErrorPush: () => isErrorPush,
|
|
32
34
|
isReasoningPush: () => isReasoningPush,
|
|
33
|
-
isToolRequestPush: () => isToolRequestPush
|
|
35
|
+
isToolRequestPush: () => isToolRequestPush,
|
|
36
|
+
toUint8: () => toUint8
|
|
34
37
|
});
|
|
35
38
|
module.exports = __toCommonJS(src_exports);
|
|
36
39
|
var MESSAGE_KIND = Object.freeze({
|
|
@@ -91,6 +94,7 @@ function buildReasoningPush(args) {
|
|
|
91
94
|
if (typeof args.reasoningContent !== "string" || !args.reasoningContent) {
|
|
92
95
|
throw new Error("[amsg-shared] ReasoningPush: 'reasoningContent' must be a non-empty string");
|
|
93
96
|
}
|
|
97
|
+
validateNotificationArg("ReasoningPush", args.notification);
|
|
94
98
|
const push = {
|
|
95
99
|
messageKind: "reasoning",
|
|
96
100
|
messageType: args.messageType,
|
|
@@ -109,6 +113,7 @@ function buildReasoningPush(args) {
|
|
|
109
113
|
if (args.chunkIndex !== void 0) push.chunkIndex = args.chunkIndex;
|
|
110
114
|
if (args.totalChunks !== void 0) push.totalChunks = args.totalChunks;
|
|
111
115
|
if (args.metadata !== void 0) push.metadata = args.metadata;
|
|
116
|
+
if (args.notification !== void 0) push.notification = args.notification;
|
|
112
117
|
return push;
|
|
113
118
|
}
|
|
114
119
|
function buildToolRequestPush(args) {
|
|
@@ -146,6 +151,9 @@ function validateNotificationArg(kind, value) {
|
|
|
146
151
|
/** @type {Record<string, unknown>} */
|
|
147
152
|
value
|
|
148
153
|
);
|
|
154
|
+
if (n.show !== void 0 && !["auto", "always", "when-hidden", false].includes(n.show)) {
|
|
155
|
+
throw new Error(`[amsg-shared] ${kind}: 'notification.show' must be "auto", "always", "when-hidden", or false`);
|
|
156
|
+
}
|
|
149
157
|
for (const f of ["title", "body", "icon", "badge", "tag"]) {
|
|
150
158
|
if (n[f] !== void 0 && typeof n[f] !== "string") {
|
|
151
159
|
throw new Error(`[amsg-shared] ${kind}: 'notification.${f}' must be a string when present`);
|
|
@@ -156,6 +164,9 @@ function validateNotificationArg(kind, value) {
|
|
|
156
164
|
throw new Error(`[amsg-shared] ${kind}: 'notification.${f}' must be a boolean when present`);
|
|
157
165
|
}
|
|
158
166
|
}
|
|
167
|
+
if (n.data !== void 0 && (n.data === null || typeof n.data !== "object" || Array.isArray(n.data))) {
|
|
168
|
+
throw new Error(`[amsg-shared] ${kind}: 'notification.data' must be a plain object when present`);
|
|
169
|
+
}
|
|
159
170
|
}
|
|
160
171
|
function buildErrorPush(args) {
|
|
161
172
|
requireField("ErrorPush", "messageType", args.messageType);
|
|
@@ -166,6 +177,7 @@ function buildErrorPush(args) {
|
|
|
166
177
|
if (typeof args.message !== "string") {
|
|
167
178
|
throw new Error("[amsg-shared] ErrorPush: 'message' must be a string");
|
|
168
179
|
}
|
|
180
|
+
validateNotificationArg("ErrorPush", args.notification);
|
|
169
181
|
const push = {
|
|
170
182
|
messageKind: "error",
|
|
171
183
|
messageType: args.messageType,
|
|
@@ -179,6 +191,7 @@ function buildErrorPush(args) {
|
|
|
179
191
|
if (args.iteration !== void 0) push.iteration = args.iteration;
|
|
180
192
|
if (args.messageSubtype !== void 0) push.messageSubtype = args.messageSubtype;
|
|
181
193
|
if (args.metadata !== void 0) push.metadata = args.metadata;
|
|
194
|
+
if (args.notification !== void 0) push.notification = args.notification;
|
|
182
195
|
return push;
|
|
183
196
|
}
|
|
184
197
|
function isContentPush(value) {
|
|
@@ -225,3 +238,29 @@ function chunkReasoningByUtf8Bytes(text, maxBytes) {
|
|
|
225
238
|
}
|
|
226
239
|
return chunks;
|
|
227
240
|
}
|
|
241
|
+
function toUint8(buf) {
|
|
242
|
+
if (buf instanceof Uint8Array) return buf;
|
|
243
|
+
if (buf instanceof ArrayBuffer) return new Uint8Array(buf);
|
|
244
|
+
if (ArrayBuffer.isView(buf)) return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
245
|
+
throw new TypeError("Expected ArrayBuffer / Uint8Array");
|
|
246
|
+
}
|
|
247
|
+
function base64UrlToBytes(input) {
|
|
248
|
+
const s = String(input).replace(/-/g, "+").replace(/_/g, "/");
|
|
249
|
+
const pad = (4 - s.length % 4) % 4;
|
|
250
|
+
const padded = s + "=".repeat(pad);
|
|
251
|
+
const bin = typeof atob === "function" ? atob(padded) : Buffer.from(padded, "base64").toString("binary");
|
|
252
|
+
const out = new Uint8Array(bin.length);
|
|
253
|
+
for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);
|
|
254
|
+
return out;
|
|
255
|
+
}
|
|
256
|
+
function concatBytes(...chunks) {
|
|
257
|
+
let total = 0;
|
|
258
|
+
for (const c of chunks) total += c.byteLength;
|
|
259
|
+
const out = new Uint8Array(total);
|
|
260
|
+
let offset = 0;
|
|
261
|
+
for (const c of chunks) {
|
|
262
|
+
out.set(c instanceof Uint8Array ? c : new Uint8Array(c.buffer || c), offset);
|
|
263
|
+
offset += c.byteLength;
|
|
264
|
+
}
|
|
265
|
+
return out;
|
|
266
|
+
}
|
package/dist/index.d.cts
CHANGED
|
@@ -153,6 +153,7 @@ export function buildToolRequestPush(args: {
|
|
|
153
153
|
* @param {number} [args.iteration]
|
|
154
154
|
* @param {string} [args.messageSubtype]
|
|
155
155
|
* @param {Object} [args.metadata]
|
|
156
|
+
* @param {NotificationDirective} [args.notification]
|
|
156
157
|
* @returns {ErrorPush}
|
|
157
158
|
*/
|
|
158
159
|
export function buildErrorPush(args: {
|
|
@@ -166,6 +167,7 @@ export function buildErrorPush(args: {
|
|
|
166
167
|
iteration?: number;
|
|
167
168
|
messageSubtype?: string;
|
|
168
169
|
metadata?: any;
|
|
170
|
+
notification?: NotificationDirective;
|
|
169
171
|
}): ErrorPush;
|
|
170
172
|
/**
|
|
171
173
|
* Type guard: returns true if the argument is a {@link ContentPush}.
|
|
@@ -229,6 +231,22 @@ export function isErrorPush(value: unknown): value is ErrorPush;
|
|
|
229
231
|
* @returns {string[]}
|
|
230
232
|
*/
|
|
231
233
|
export function chunkReasoningByUtf8Bytes(text: string, maxBytes: number): string[];
|
|
234
|
+
/**
|
|
235
|
+
* Coerce ArrayBuffer | Uint8Array | view → Uint8Array (no copy when possible).
|
|
236
|
+
*/
|
|
237
|
+
export function toUint8(buf: any): Uint8Array<ArrayBufferLike>;
|
|
238
|
+
/**
|
|
239
|
+
* Decode base64url (with or without padding) → Uint8Array.
|
|
240
|
+
* @param {string} input
|
|
241
|
+
* @returns {Uint8Array}
|
|
242
|
+
*/
|
|
243
|
+
export function base64UrlToBytes(input: string): Uint8Array;
|
|
244
|
+
/**
|
|
245
|
+
* Concatenate Uint8Arrays into a single Uint8Array.
|
|
246
|
+
* @param {...(Uint8Array | ArrayBuffer | ArrayBufferView)} chunks
|
|
247
|
+
* @returns {Uint8Array}
|
|
248
|
+
*/
|
|
249
|
+
export function concatBytes(...chunks: (Uint8Array | ArrayBuffer | ArrayBufferView)[]): Uint8Array;
|
|
232
250
|
/**
|
|
233
251
|
* @rei-standard/amsg-shared
|
|
234
252
|
*
|
|
@@ -336,30 +354,31 @@ export type AmsgPushCommon = {
|
|
|
336
354
|
* - Caller passthrough. Packages MUST NOT write here.
|
|
337
355
|
*/
|
|
338
356
|
metadata?: any;
|
|
357
|
+
/**
|
|
358
|
+
* - SW notification strategy.
|
|
359
|
+
*/
|
|
360
|
+
notification?: NotificationDirective;
|
|
339
361
|
};
|
|
340
362
|
/**
|
|
341
|
-
* SW-rendering directive
|
|
342
|
-
*
|
|
343
|
-
*
|
|
344
|
-
* — typing all seven (rather than just `title` / `body`) so callers
|
|
345
|
-
* don't lose IDE checking on the other five and slip back into the
|
|
346
|
-
* untyped-spread footgun this typedef was added to close.
|
|
363
|
+
* SW-rendering directive. Mirrors the fields that `amsg-sw`'s
|
|
364
|
+
* `createNotificationFromPayload` consumes (`notification.{title,body,icon,badge,tag,renotify,requireInteraction,data}`)
|
|
365
|
+
* — typing all fields so callers don't lose IDE checking and slip back into the untyped-spread footgun.
|
|
347
366
|
*
|
|
348
367
|
* Routing in SW (kept here so producers don't have to cross-check):
|
|
349
|
-
* - `messageKind: 'content'` (and legacy un-kinded payloads)
|
|
350
|
-
*
|
|
368
|
+
* - By default (`show: "auto"` or omitted), `messageKind: 'content'` (and legacy un-kinded payloads)
|
|
369
|
+
* will display a system notification. `reasoning` / `tool_request` / `error` will dispatch silently.
|
|
370
|
+
* - `show: "always"`, `"when-hidden"`, or `false` overrides this default.
|
|
371
|
+
* - When rendering, `notification.*` is consulted, with per-field fallback to
|
|
351
372
|
* the top-level `title` / `avatarUrl` / `messageId` and finally
|
|
352
373
|
* to the SW's `defaultIcon` / `defaultBadge` options. Everything
|
|
353
374
|
* else (`tag`, `renotify`, `requireInteraction`) has no top-level
|
|
354
|
-
* fallback — set them under `notification` or accept the SW
|
|
355
|
-
* default (`messageId`-derived tag, no renotify, no requireInteraction).
|
|
356
|
-
* - `messageKind: 'reasoning'` / `'tool_request'` / `'error'` →
|
|
357
|
-
* dispatched silently to controlled clients. `notification` is
|
|
358
|
-
* ignored. (It's still typed on `ToolRequestPush` because the
|
|
359
|
-
* splitter demotes prefix chunks to `messageKind: 'content'`, at
|
|
360
|
-
* which point the field starts mattering.)
|
|
375
|
+
* fallback — set them under `notification` or accept the SW default.
|
|
361
376
|
*/
|
|
362
377
|
export type NotificationDirective = {
|
|
378
|
+
/**
|
|
379
|
+
* - Rendering strategy. Defaults to "auto" (render only if messageKind is content).
|
|
380
|
+
*/
|
|
381
|
+
show?: "auto" | "always" | "when-hidden" | false;
|
|
363
382
|
/**
|
|
364
383
|
* - Notification title override.
|
|
365
384
|
*/
|
|
@@ -388,6 +407,10 @@ export type NotificationDirective = {
|
|
|
388
407
|
* - Notification stays until user dismisses. Default false at SW.
|
|
389
408
|
*/
|
|
390
409
|
requireInteraction?: boolean;
|
|
410
|
+
/**
|
|
411
|
+
* - Custom payload data to attach to the notification.
|
|
412
|
+
*/
|
|
413
|
+
data?: Record<string, unknown>;
|
|
391
414
|
};
|
|
392
415
|
/**
|
|
393
416
|
* Final user-facing content. Sentence-split bursts of N use
|
|
@@ -403,7 +426,6 @@ export type ContentPush = AmsgPushCommon & {
|
|
|
403
426
|
messageIndex?: number;
|
|
404
427
|
totalMessages?: number;
|
|
405
428
|
taskId?: string | null;
|
|
406
|
-
notification?: NotificationDirective;
|
|
407
429
|
};
|
|
408
430
|
/**
|
|
409
431
|
* LLM "meta-thinking" — `choices[0].message.reasoning_content` lifted
|
|
@@ -455,7 +477,6 @@ export type ToolRequestPush = AmsgPushCommon & {
|
|
|
455
477
|
title?: string;
|
|
456
478
|
contactName?: string;
|
|
457
479
|
message?: string;
|
|
458
|
-
notification?: NotificationDirective;
|
|
459
480
|
};
|
|
460
481
|
/**
|
|
461
482
|
* Producer-level error. Replaces the legacy
|
package/dist/index.d.ts
CHANGED
|
@@ -153,6 +153,7 @@ export function buildToolRequestPush(args: {
|
|
|
153
153
|
* @param {number} [args.iteration]
|
|
154
154
|
* @param {string} [args.messageSubtype]
|
|
155
155
|
* @param {Object} [args.metadata]
|
|
156
|
+
* @param {NotificationDirective} [args.notification]
|
|
156
157
|
* @returns {ErrorPush}
|
|
157
158
|
*/
|
|
158
159
|
export function buildErrorPush(args: {
|
|
@@ -166,6 +167,7 @@ export function buildErrorPush(args: {
|
|
|
166
167
|
iteration?: number;
|
|
167
168
|
messageSubtype?: string;
|
|
168
169
|
metadata?: any;
|
|
170
|
+
notification?: NotificationDirective;
|
|
169
171
|
}): ErrorPush;
|
|
170
172
|
/**
|
|
171
173
|
* Type guard: returns true if the argument is a {@link ContentPush}.
|
|
@@ -229,6 +231,22 @@ export function isErrorPush(value: unknown): value is ErrorPush;
|
|
|
229
231
|
* @returns {string[]}
|
|
230
232
|
*/
|
|
231
233
|
export function chunkReasoningByUtf8Bytes(text: string, maxBytes: number): string[];
|
|
234
|
+
/**
|
|
235
|
+
* Coerce ArrayBuffer | Uint8Array | view → Uint8Array (no copy when possible).
|
|
236
|
+
*/
|
|
237
|
+
export function toUint8(buf: any): Uint8Array<ArrayBufferLike>;
|
|
238
|
+
/**
|
|
239
|
+
* Decode base64url (with or without padding) → Uint8Array.
|
|
240
|
+
* @param {string} input
|
|
241
|
+
* @returns {Uint8Array}
|
|
242
|
+
*/
|
|
243
|
+
export function base64UrlToBytes(input: string): Uint8Array;
|
|
244
|
+
/**
|
|
245
|
+
* Concatenate Uint8Arrays into a single Uint8Array.
|
|
246
|
+
* @param {...(Uint8Array | ArrayBuffer | ArrayBufferView)} chunks
|
|
247
|
+
* @returns {Uint8Array}
|
|
248
|
+
*/
|
|
249
|
+
export function concatBytes(...chunks: (Uint8Array | ArrayBuffer | ArrayBufferView)[]): Uint8Array;
|
|
232
250
|
/**
|
|
233
251
|
* @rei-standard/amsg-shared
|
|
234
252
|
*
|
|
@@ -336,30 +354,31 @@ export type AmsgPushCommon = {
|
|
|
336
354
|
* - Caller passthrough. Packages MUST NOT write here.
|
|
337
355
|
*/
|
|
338
356
|
metadata?: any;
|
|
357
|
+
/**
|
|
358
|
+
* - SW notification strategy.
|
|
359
|
+
*/
|
|
360
|
+
notification?: NotificationDirective;
|
|
339
361
|
};
|
|
340
362
|
/**
|
|
341
|
-
* SW-rendering directive
|
|
342
|
-
*
|
|
343
|
-
*
|
|
344
|
-
* — typing all seven (rather than just `title` / `body`) so callers
|
|
345
|
-
* don't lose IDE checking on the other five and slip back into the
|
|
346
|
-
* untyped-spread footgun this typedef was added to close.
|
|
363
|
+
* SW-rendering directive. Mirrors the fields that `amsg-sw`'s
|
|
364
|
+
* `createNotificationFromPayload` consumes (`notification.{title,body,icon,badge,tag,renotify,requireInteraction,data}`)
|
|
365
|
+
* — typing all fields so callers don't lose IDE checking and slip back into the untyped-spread footgun.
|
|
347
366
|
*
|
|
348
367
|
* Routing in SW (kept here so producers don't have to cross-check):
|
|
349
|
-
* - `messageKind: 'content'` (and legacy un-kinded payloads)
|
|
350
|
-
*
|
|
368
|
+
* - By default (`show: "auto"` or omitted), `messageKind: 'content'` (and legacy un-kinded payloads)
|
|
369
|
+
* will display a system notification. `reasoning` / `tool_request` / `error` will dispatch silently.
|
|
370
|
+
* - `show: "always"`, `"when-hidden"`, or `false` overrides this default.
|
|
371
|
+
* - When rendering, `notification.*` is consulted, with per-field fallback to
|
|
351
372
|
* the top-level `title` / `avatarUrl` / `messageId` and finally
|
|
352
373
|
* to the SW's `defaultIcon` / `defaultBadge` options. Everything
|
|
353
374
|
* else (`tag`, `renotify`, `requireInteraction`) has no top-level
|
|
354
|
-
* fallback — set them under `notification` or accept the SW
|
|
355
|
-
* default (`messageId`-derived tag, no renotify, no requireInteraction).
|
|
356
|
-
* - `messageKind: 'reasoning'` / `'tool_request'` / `'error'` →
|
|
357
|
-
* dispatched silently to controlled clients. `notification` is
|
|
358
|
-
* ignored. (It's still typed on `ToolRequestPush` because the
|
|
359
|
-
* splitter demotes prefix chunks to `messageKind: 'content'`, at
|
|
360
|
-
* which point the field starts mattering.)
|
|
375
|
+
* fallback — set them under `notification` or accept the SW default.
|
|
361
376
|
*/
|
|
362
377
|
export type NotificationDirective = {
|
|
378
|
+
/**
|
|
379
|
+
* - Rendering strategy. Defaults to "auto" (render only if messageKind is content).
|
|
380
|
+
*/
|
|
381
|
+
show?: "auto" | "always" | "when-hidden" | false;
|
|
363
382
|
/**
|
|
364
383
|
* - Notification title override.
|
|
365
384
|
*/
|
|
@@ -388,6 +407,10 @@ export type NotificationDirective = {
|
|
|
388
407
|
* - Notification stays until user dismisses. Default false at SW.
|
|
389
408
|
*/
|
|
390
409
|
requireInteraction?: boolean;
|
|
410
|
+
/**
|
|
411
|
+
* - Custom payload data to attach to the notification.
|
|
412
|
+
*/
|
|
413
|
+
data?: Record<string, unknown>;
|
|
391
414
|
};
|
|
392
415
|
/**
|
|
393
416
|
* Final user-facing content. Sentence-split bursts of N use
|
|
@@ -403,7 +426,6 @@ export type ContentPush = AmsgPushCommon & {
|
|
|
403
426
|
messageIndex?: number;
|
|
404
427
|
totalMessages?: number;
|
|
405
428
|
taskId?: string | null;
|
|
406
|
-
notification?: NotificationDirective;
|
|
407
429
|
};
|
|
408
430
|
/**
|
|
409
431
|
* LLM "meta-thinking" — `choices[0].message.reasoning_content` lifted
|
|
@@ -455,7 +477,6 @@ export type ToolRequestPush = AmsgPushCommon & {
|
|
|
455
477
|
title?: string;
|
|
456
478
|
contactName?: string;
|
|
457
479
|
message?: string;
|
|
458
|
-
notification?: NotificationDirective;
|
|
459
480
|
};
|
|
460
481
|
/**
|
|
461
482
|
* Producer-level error. Replaces the legacy
|
package/dist/index.mjs
CHANGED
|
@@ -57,6 +57,7 @@ function buildReasoningPush(args) {
|
|
|
57
57
|
if (typeof args.reasoningContent !== "string" || !args.reasoningContent) {
|
|
58
58
|
throw new Error("[amsg-shared] ReasoningPush: 'reasoningContent' must be a non-empty string");
|
|
59
59
|
}
|
|
60
|
+
validateNotificationArg("ReasoningPush", args.notification);
|
|
60
61
|
const push = {
|
|
61
62
|
messageKind: "reasoning",
|
|
62
63
|
messageType: args.messageType,
|
|
@@ -75,6 +76,7 @@ function buildReasoningPush(args) {
|
|
|
75
76
|
if (args.chunkIndex !== void 0) push.chunkIndex = args.chunkIndex;
|
|
76
77
|
if (args.totalChunks !== void 0) push.totalChunks = args.totalChunks;
|
|
77
78
|
if (args.metadata !== void 0) push.metadata = args.metadata;
|
|
79
|
+
if (args.notification !== void 0) push.notification = args.notification;
|
|
78
80
|
return push;
|
|
79
81
|
}
|
|
80
82
|
function buildToolRequestPush(args) {
|
|
@@ -112,6 +114,9 @@ function validateNotificationArg(kind, value) {
|
|
|
112
114
|
/** @type {Record<string, unknown>} */
|
|
113
115
|
value
|
|
114
116
|
);
|
|
117
|
+
if (n.show !== void 0 && !["auto", "always", "when-hidden", false].includes(n.show)) {
|
|
118
|
+
throw new Error(`[amsg-shared] ${kind}: 'notification.show' must be "auto", "always", "when-hidden", or false`);
|
|
119
|
+
}
|
|
115
120
|
for (const f of ["title", "body", "icon", "badge", "tag"]) {
|
|
116
121
|
if (n[f] !== void 0 && typeof n[f] !== "string") {
|
|
117
122
|
throw new Error(`[amsg-shared] ${kind}: 'notification.${f}' must be a string when present`);
|
|
@@ -122,6 +127,9 @@ function validateNotificationArg(kind, value) {
|
|
|
122
127
|
throw new Error(`[amsg-shared] ${kind}: 'notification.${f}' must be a boolean when present`);
|
|
123
128
|
}
|
|
124
129
|
}
|
|
130
|
+
if (n.data !== void 0 && (n.data === null || typeof n.data !== "object" || Array.isArray(n.data))) {
|
|
131
|
+
throw new Error(`[amsg-shared] ${kind}: 'notification.data' must be a plain object when present`);
|
|
132
|
+
}
|
|
125
133
|
}
|
|
126
134
|
function buildErrorPush(args) {
|
|
127
135
|
requireField("ErrorPush", "messageType", args.messageType);
|
|
@@ -132,6 +140,7 @@ function buildErrorPush(args) {
|
|
|
132
140
|
if (typeof args.message !== "string") {
|
|
133
141
|
throw new Error("[amsg-shared] ErrorPush: 'message' must be a string");
|
|
134
142
|
}
|
|
143
|
+
validateNotificationArg("ErrorPush", args.notification);
|
|
135
144
|
const push = {
|
|
136
145
|
messageKind: "error",
|
|
137
146
|
messageType: args.messageType,
|
|
@@ -145,6 +154,7 @@ function buildErrorPush(args) {
|
|
|
145
154
|
if (args.iteration !== void 0) push.iteration = args.iteration;
|
|
146
155
|
if (args.messageSubtype !== void 0) push.messageSubtype = args.messageSubtype;
|
|
147
156
|
if (args.metadata !== void 0) push.metadata = args.metadata;
|
|
157
|
+
if (args.notification !== void 0) push.notification = args.notification;
|
|
148
158
|
return push;
|
|
149
159
|
}
|
|
150
160
|
function isContentPush(value) {
|
|
@@ -191,17 +201,46 @@ function chunkReasoningByUtf8Bytes(text, maxBytes) {
|
|
|
191
201
|
}
|
|
192
202
|
return chunks;
|
|
193
203
|
}
|
|
204
|
+
function toUint8(buf) {
|
|
205
|
+
if (buf instanceof Uint8Array) return buf;
|
|
206
|
+
if (buf instanceof ArrayBuffer) return new Uint8Array(buf);
|
|
207
|
+
if (ArrayBuffer.isView(buf)) return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
208
|
+
throw new TypeError("Expected ArrayBuffer / Uint8Array");
|
|
209
|
+
}
|
|
210
|
+
function base64UrlToBytes(input) {
|
|
211
|
+
const s = String(input).replace(/-/g, "+").replace(/_/g, "/");
|
|
212
|
+
const pad = (4 - s.length % 4) % 4;
|
|
213
|
+
const padded = s + "=".repeat(pad);
|
|
214
|
+
const bin = typeof atob === "function" ? atob(padded) : Buffer.from(padded, "base64").toString("binary");
|
|
215
|
+
const out = new Uint8Array(bin.length);
|
|
216
|
+
for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);
|
|
217
|
+
return out;
|
|
218
|
+
}
|
|
219
|
+
function concatBytes(...chunks) {
|
|
220
|
+
let total = 0;
|
|
221
|
+
for (const c of chunks) total += c.byteLength;
|
|
222
|
+
const out = new Uint8Array(total);
|
|
223
|
+
let offset = 0;
|
|
224
|
+
for (const c of chunks) {
|
|
225
|
+
out.set(c instanceof Uint8Array ? c : new Uint8Array(c.buffer || c), offset);
|
|
226
|
+
offset += c.byteLength;
|
|
227
|
+
}
|
|
228
|
+
return out;
|
|
229
|
+
}
|
|
194
230
|
export {
|
|
195
231
|
MESSAGE_KIND,
|
|
196
232
|
MESSAGE_TYPE,
|
|
197
233
|
PUSH_SOURCE,
|
|
234
|
+
base64UrlToBytes,
|
|
198
235
|
buildContentPush,
|
|
199
236
|
buildErrorPush,
|
|
200
237
|
buildReasoningPush,
|
|
201
238
|
buildToolRequestPush,
|
|
202
239
|
chunkReasoningByUtf8Bytes,
|
|
240
|
+
concatBytes,
|
|
203
241
|
isContentPush,
|
|
204
242
|
isErrorPush,
|
|
205
243
|
isReasoningPush,
|
|
206
|
-
isToolRequestPush
|
|
244
|
+
isToolRequestPush,
|
|
245
|
+
toUint8
|
|
207
246
|
};
|
package/package.json
CHANGED