@aurelo_npm/sdk 0.1.2 → 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 CHANGED
@@ -95,8 +95,13 @@ export interface AureloToolResultRequest {
95
95
  requestId?: string;
96
96
  callId?: string;
97
97
  toolCallId?: string;
98
- previousResponseId?: string;
99
- previous_response_id?: string;
98
+ tool_call_id?: string;
99
+ toolCall?: {
100
+ call_id?: string;
101
+ callId?: string;
102
+ id?: string;
103
+ [key: string]: unknown;
104
+ };
100
105
  model?: string;
101
106
  publicModel?: string;
102
107
  stream?: boolean;
@@ -152,6 +157,9 @@ export declare class AureloSDK {
152
157
  private clientIdValue;
153
158
  private sessionValue;
154
159
  private reconnectCursors;
160
+ private readonly observedStreamResponses;
161
+ private readonly observedSseComments;
162
+ private observedSseCommentOrder;
155
163
  constructor(options: AureloSDKOptions);
156
164
  getClientId(): Promise<string>;
157
165
  getFullClientId(): Promise<string>;
@@ -164,6 +172,7 @@ export declare class AureloSDK {
164
172
  private setReconnectCursor;
165
173
  private clearReconnectCursor;
166
174
  observeSseComment(comment: string): Promise<void>;
175
+ private rememberSseComment;
167
176
  queueMessage(request: string | AureloQueueMessageRequest): Promise<unknown>;
168
177
  createResponse(request: AureloResponseRequest, options?: {
169
178
  signal?: AbortSignal;
@@ -181,6 +190,9 @@ export declare class AureloSDK {
181
190
  reconnect(request?: AureloReconnectRequest): Promise<Response>;
182
191
  submitToolResult(request: AureloToolResultRequest): Promise<Response | unknown>;
183
192
  streamToolResult(request: AureloToolResultRequest): AsyncGenerator<AureloStreamEvent>;
193
+ private observeResponseStream;
194
+ private observeSseTextFragment;
195
+ private observeSseCommentLine;
184
196
  private handleSseLine;
185
197
  private readErrorPayload;
186
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,13 +721,19 @@ 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
707
728
  ? { ...(await this.getSession()), sessionId: request.sessionId }
708
729
  : await this.getSession();
709
- const callId = String(request.callId || request.toolCallId || '').trim();
730
+ const callId = String(request.callId ||
731
+ request.toolCallId ||
732
+ request.tool_call_id ||
733
+ request.toolCall?.call_id ||
734
+ request.toolCall?.callId ||
735
+ request.toolCall?.id ||
736
+ '').trim();
710
737
  if (!callId) {
711
738
  throw new Error('AureloSDK submitToolResult requires callId.');
712
739
  }
@@ -717,10 +744,8 @@ export class AureloSDK {
717
744
  requestId: request.requestId || session.requestId,
718
745
  sessionId: session.sessionId,
719
746
  callId,
720
- previousResponseId: request.previousResponseId || request.previous_response_id,
721
747
  model: request.model || request.publicModel,
722
748
  };
723
- const previousResponseId = request.previousResponseId || request.previous_response_id;
724
749
  const response = await this.fetchImpl(`${this.baseUrl}/v1/responses`, {
725
750
  method: 'POST',
726
751
  headers: {
@@ -730,8 +755,6 @@ export class AureloSDK {
730
755
  body: JSON.stringify({
731
756
  model: request.model || request.publicModel,
732
757
  publicModel: request.publicModel || request.model,
733
- previousResponseId,
734
- previous_response_id: previousResponseId,
735
758
  stream: request.stream !== false,
736
759
  sessionId: session.sessionId,
737
760
  requestId: request.requestId || session.requestId,
@@ -760,7 +783,7 @@ export class AureloSDK {
760
783
  }
761
784
  const contentType = response.headers.get('content-type') || '';
762
785
  if (contentType.includes('text/event-stream')) {
763
- return response;
786
+ return this.observeResponseStream(response);
764
787
  }
765
788
  return this.readResponsePayload(response);
766
789
  }
@@ -772,14 +795,88 @@ export class AureloSDK {
772
795
  }
773
796
  yield { type: 'event', raw: '', data: result };
774
797
  }
775
- async handleSseLine(line) {
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 = {}) {
776
871
  const trimmed = line.trim();
777
872
  if (!trimmed) {
778
873
  return null;
779
874
  }
780
875
  if (trimmed.startsWith(':')) {
781
876
  const comment = trimmed.slice(1).trim();
782
- await this.observeSseComment(comment);
877
+ if (options.observeComments !== false) {
878
+ await this.observeSseComment(comment);
879
+ }
783
880
  return { type: 'comment', raw: line, comment };
784
881
  }
785
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.2",
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",