@aurelo_npm/sdk 0.1.3 → 0.1.4
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.d.ts +7 -0
- package/dist/index.js +102 -7
- package/package.json +3 -2
package/dist/index.d.ts
CHANGED
|
@@ -157,6 +157,9 @@ export declare class AureloSDK {
|
|
|
157
157
|
private clientIdValue;
|
|
158
158
|
private sessionValue;
|
|
159
159
|
private reconnectCursors;
|
|
160
|
+
private readonly observedStreamResponses;
|
|
161
|
+
private readonly observedSseComments;
|
|
162
|
+
private observedSseCommentOrder;
|
|
160
163
|
constructor(options: AureloSDKOptions);
|
|
161
164
|
getClientId(): Promise<string>;
|
|
162
165
|
getFullClientId(): Promise<string>;
|
|
@@ -169,6 +172,7 @@ export declare class AureloSDK {
|
|
|
169
172
|
private setReconnectCursor;
|
|
170
173
|
private clearReconnectCursor;
|
|
171
174
|
observeSseComment(comment: string): Promise<void>;
|
|
175
|
+
private rememberSseComment;
|
|
172
176
|
queueMessage(request: string | AureloQueueMessageRequest): Promise<unknown>;
|
|
173
177
|
createResponse(request: AureloResponseRequest, options?: {
|
|
174
178
|
signal?: AbortSignal;
|
|
@@ -186,6 +190,9 @@ export declare class AureloSDK {
|
|
|
186
190
|
reconnect(request?: AureloReconnectRequest): Promise<Response>;
|
|
187
191
|
submitToolResult(request: AureloToolResultRequest): Promise<Response | unknown>;
|
|
188
192
|
streamToolResult(request: AureloToolResultRequest): AsyncGenerator<AureloStreamEvent>;
|
|
193
|
+
private observeResponseStream;
|
|
194
|
+
private observeSseTextFragment;
|
|
195
|
+
private observeSseCommentLine;
|
|
189
196
|
private handleSseLine;
|
|
190
197
|
private readErrorPayload;
|
|
191
198
|
private readResponsePayload;
|
package/dist/index.js
CHANGED
|
@@ -291,6 +291,9 @@ export class AureloSDK {
|
|
|
291
291
|
clientIdValue = null;
|
|
292
292
|
sessionValue = null;
|
|
293
293
|
reconnectCursors = new Map();
|
|
294
|
+
observedStreamResponses = new WeakSet();
|
|
295
|
+
observedSseComments = new Set();
|
|
296
|
+
observedSseCommentOrder = [];
|
|
294
297
|
constructor(options) {
|
|
295
298
|
if (!options.apiKey || !String(options.apiKey).trim()) {
|
|
296
299
|
throw new Error('AureloSDK requires apiKey.');
|
|
@@ -423,6 +426,9 @@ export class AureloSDK {
|
|
|
423
426
|
if (!normalizedComment) {
|
|
424
427
|
return;
|
|
425
428
|
}
|
|
429
|
+
if (this.rememberSseComment(normalizedComment)) {
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
426
432
|
const reconnectCursor = parseReconnectCursorComment(normalizedComment);
|
|
427
433
|
if (reconnectCursor) {
|
|
428
434
|
await this.setReconnectCursor(reconnectCursor.sessionId, reconnectCursor.cursor);
|
|
@@ -432,6 +438,20 @@ export class AureloSDK {
|
|
|
432
438
|
await this.rotateSession(reason);
|
|
433
439
|
}
|
|
434
440
|
}
|
|
441
|
+
rememberSseComment(comment) {
|
|
442
|
+
if (this.observedSseComments.has(comment)) {
|
|
443
|
+
return true;
|
|
444
|
+
}
|
|
445
|
+
this.observedSseComments.add(comment);
|
|
446
|
+
this.observedSseCommentOrder.push(comment);
|
|
447
|
+
while (this.observedSseCommentOrder.length > 500) {
|
|
448
|
+
const oldest = this.observedSseCommentOrder.shift();
|
|
449
|
+
if (oldest) {
|
|
450
|
+
this.observedSseComments.delete(oldest);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
return false;
|
|
454
|
+
}
|
|
435
455
|
async queueMessage(request) {
|
|
436
456
|
const session = await this.getSession();
|
|
437
457
|
const queueRequest = typeof request === 'string'
|
|
@@ -522,7 +542,7 @@ export class AureloSDK {
|
|
|
522
542
|
};
|
|
523
543
|
await this.storage.set(SESSION_KEY, JSON.stringify(this.sessionValue));
|
|
524
544
|
}
|
|
525
|
-
return response;
|
|
545
|
+
return this.observeResponseStream(response);
|
|
526
546
|
}
|
|
527
547
|
async createResponseWithRotationRetry(request, options = {}) {
|
|
528
548
|
try {
|
|
@@ -614,6 +634,7 @@ export class AureloSDK {
|
|
|
614
634
|
await this.closeSession('request_closed');
|
|
615
635
|
return;
|
|
616
636
|
}
|
|
637
|
+
const observeComments = !this.observedStreamResponses.has(response);
|
|
617
638
|
const reader = response.body.getReader();
|
|
618
639
|
const decoder = new TextDecoder();
|
|
619
640
|
let buffer = '';
|
|
@@ -627,7 +648,7 @@ export class AureloSDK {
|
|
|
627
648
|
const lines = buffer.split('\n');
|
|
628
649
|
buffer = lines.pop() || '';
|
|
629
650
|
for (const line of lines) {
|
|
630
|
-
const event = await this.handleSseLine(line);
|
|
651
|
+
const event = await this.handleSseLine(line, { observeComments });
|
|
631
652
|
if (event) {
|
|
632
653
|
yield event;
|
|
633
654
|
}
|
|
@@ -635,7 +656,7 @@ export class AureloSDK {
|
|
|
635
656
|
}
|
|
636
657
|
buffer += decoder.decode();
|
|
637
658
|
if (buffer.trim()) {
|
|
638
|
-
const event = await this.handleSseLine(buffer);
|
|
659
|
+
const event = await this.handleSseLine(buffer, { observeComments });
|
|
639
660
|
if (event) {
|
|
640
661
|
yield event;
|
|
641
662
|
}
|
|
@@ -700,7 +721,7 @@ export class AureloSDK {
|
|
|
700
721
|
payload,
|
|
701
722
|
});
|
|
702
723
|
}
|
|
703
|
-
return response;
|
|
724
|
+
return this.observeResponseStream(response);
|
|
704
725
|
}
|
|
705
726
|
async submitToolResult(request) {
|
|
706
727
|
const session = request.sessionId
|
|
@@ -762,7 +783,7 @@ export class AureloSDK {
|
|
|
762
783
|
}
|
|
763
784
|
const contentType = response.headers.get('content-type') || '';
|
|
764
785
|
if (contentType.includes('text/event-stream')) {
|
|
765
|
-
return response;
|
|
786
|
+
return this.observeResponseStream(response);
|
|
766
787
|
}
|
|
767
788
|
return this.readResponsePayload(response);
|
|
768
789
|
}
|
|
@@ -774,14 +795,88 @@ export class AureloSDK {
|
|
|
774
795
|
}
|
|
775
796
|
yield { type: 'event', raw: '', data: result };
|
|
776
797
|
}
|
|
777
|
-
|
|
798
|
+
observeResponseStream(response) {
|
|
799
|
+
const contentType = response.headers.get('content-type') || '';
|
|
800
|
+
if (!response.body || !contentType.includes('text/event-stream') || typeof ReadableStream === 'undefined') {
|
|
801
|
+
return response;
|
|
802
|
+
}
|
|
803
|
+
const reader = response.body.getReader();
|
|
804
|
+
const decoder = new TextDecoder();
|
|
805
|
+
let buffer = '';
|
|
806
|
+
const body = new ReadableStream({
|
|
807
|
+
start: async (controller) => {
|
|
808
|
+
try {
|
|
809
|
+
while (true) {
|
|
810
|
+
const { done, value } = await reader.read();
|
|
811
|
+
if (done) {
|
|
812
|
+
break;
|
|
813
|
+
}
|
|
814
|
+
if (value) {
|
|
815
|
+
buffer = await this.observeSseTextFragment(decoder.decode(value, { stream: true }), buffer);
|
|
816
|
+
controller.enqueue(value);
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
const trailing = decoder.decode();
|
|
820
|
+
if (trailing) {
|
|
821
|
+
buffer = await this.observeSseTextFragment(trailing, buffer);
|
|
822
|
+
}
|
|
823
|
+
if (buffer.trim()) {
|
|
824
|
+
await this.observeSseCommentLine(buffer);
|
|
825
|
+
}
|
|
826
|
+
controller.close();
|
|
827
|
+
}
|
|
828
|
+
catch (error) {
|
|
829
|
+
controller.error(error);
|
|
830
|
+
}
|
|
831
|
+
finally {
|
|
832
|
+
reader.releaseLock();
|
|
833
|
+
}
|
|
834
|
+
},
|
|
835
|
+
cancel: async (reason) => {
|
|
836
|
+
try {
|
|
837
|
+
await reader.cancel(reason);
|
|
838
|
+
}
|
|
839
|
+
finally {
|
|
840
|
+
reader.releaseLock();
|
|
841
|
+
}
|
|
842
|
+
},
|
|
843
|
+
});
|
|
844
|
+
const observedResponse = new Response(body, {
|
|
845
|
+
status: response.status,
|
|
846
|
+
statusText: response.statusText,
|
|
847
|
+
headers: response.headers,
|
|
848
|
+
});
|
|
849
|
+
this.observedStreamResponses.add(observedResponse);
|
|
850
|
+
return observedResponse;
|
|
851
|
+
}
|
|
852
|
+
async observeSseTextFragment(fragment, previousBuffer) {
|
|
853
|
+
if (!fragment) {
|
|
854
|
+
return previousBuffer;
|
|
855
|
+
}
|
|
856
|
+
const lines = `${previousBuffer}${fragment}`.split(/\r?\n/);
|
|
857
|
+
const buffer = lines.pop() || '';
|
|
858
|
+
for (const line of lines) {
|
|
859
|
+
await this.observeSseCommentLine(line);
|
|
860
|
+
}
|
|
861
|
+
return buffer;
|
|
862
|
+
}
|
|
863
|
+
async observeSseCommentLine(line) {
|
|
864
|
+
const trimmed = String(line || '').trim();
|
|
865
|
+
if (!trimmed.startsWith(':')) {
|
|
866
|
+
return;
|
|
867
|
+
}
|
|
868
|
+
await this.observeSseComment(trimmed.slice(1).trim());
|
|
869
|
+
}
|
|
870
|
+
async handleSseLine(line, options = {}) {
|
|
778
871
|
const trimmed = line.trim();
|
|
779
872
|
if (!trimmed) {
|
|
780
873
|
return null;
|
|
781
874
|
}
|
|
782
875
|
if (trimmed.startsWith(':')) {
|
|
783
876
|
const comment = trimmed.slice(1).trim();
|
|
784
|
-
|
|
877
|
+
if (options.observeComments !== false) {
|
|
878
|
+
await this.observeSseComment(comment);
|
|
879
|
+
}
|
|
785
880
|
return { type: 'comment', raw: line, comment };
|
|
786
881
|
}
|
|
787
882
|
if (trimmed === 'data: [DONE]') {
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aurelo_npm/sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Aurelo API-key SDK with stable client identity and backend-driven session rotation.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
8
8
|
"files": [
|
|
9
9
|
"dist/index.js",
|
|
10
|
-
"dist/index.d.ts"
|
|
10
|
+
"dist/index.d.ts",
|
|
11
|
+
"!README.md"
|
|
11
12
|
],
|
|
12
13
|
"scripts": {
|
|
13
14
|
"build": "tsc -p tsconfig.json",
|