@cadraos/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.js CHANGED
@@ -403,6 +403,9 @@ var SSEClient = class {
403
403
  */
404
404
  async connect() {
405
405
  this.abortController = new AbortController();
406
+ console.log("[SDK:SSE] Connecting to:", this.config.url);
407
+ console.log("[SDK:SSE] Auth header:", this.config.authHeader ? `${this.config.authHeader.substring(0, 30)}...` : "MISSING");
408
+ console.log("[SDK:SSE] Org ID:", this.config.orgId);
406
409
  try {
407
410
  const response = await fetch(this.config.url, {
408
411
  method: "GET",
@@ -414,23 +417,39 @@ var SSEClient = class {
414
417
  },
415
418
  signal: this.abortController.signal
416
419
  });
420
+ console.log("[SDK:SSE] Response status:", response.status, response.statusText);
421
+ console.log("[SDK:SSE] Response headers:", {
422
+ contentType: response.headers.get("content-type"),
423
+ cacheControl: response.headers.get("cache-control")
424
+ });
417
425
  if (!response.ok) {
418
- throw new Error(`SSE connection failed: ${response.status} ${response.statusText}`);
426
+ let errorBody = "";
427
+ try {
428
+ errorBody = await response.text();
429
+ console.error("[SDK:SSE] Error response body:", errorBody);
430
+ } catch (e) {
431
+ console.error("[SDK:SSE] Could not read error body");
432
+ }
433
+ throw new Error(`SSE connection failed: ${response.status} ${response.statusText} - ${errorBody}`);
419
434
  }
420
435
  if (!response.body) {
421
436
  throw new Error("Response body not available");
422
437
  }
438
+ console.log("[SDK:SSE] Connection successful, starting stream parsing");
423
439
  this.connected = true;
424
440
  this.config.onConnectionChange(true);
425
441
  await this.parseStream(response.body);
426
442
  } catch (error) {
427
443
  if (error instanceof Error && error.name === "AbortError") {
444
+ console.log("[SDK:SSE] Connection aborted (intentional)");
428
445
  return;
429
446
  }
447
+ console.error("[SDK:SSE] Connection error:", error);
430
448
  this.config.onError(error instanceof Error ? error : new Error(String(error)));
431
449
  } finally {
432
450
  this.connected = false;
433
451
  this.config.onConnectionChange(false);
452
+ console.log("[SDK:SSE] Connection closed");
434
453
  }
435
454
  }
436
455
  /**
@@ -457,18 +476,29 @@ var SSEClient = class {
457
476
  const decoder = new TextDecoder();
458
477
  let buffer = "";
459
478
  let currentEvent = {};
479
+ let chunkCount = 0;
480
+ let eventCount = 0;
481
+ console.log("[SDK:SSE] Starting to parse stream");
460
482
  try {
461
483
  while (true) {
462
484
  const { done, value } = await reader.read();
463
485
  if (done) {
486
+ console.log("[SDK:SSE] Stream reading complete. Total chunks:", chunkCount, "events:", eventCount);
464
487
  break;
465
488
  }
466
- buffer += decoder.decode(value, { stream: true });
489
+ chunkCount++;
490
+ const chunk = decoder.decode(value, { stream: true });
491
+ buffer += chunk;
492
+ if (chunkCount <= 5) {
493
+ console.log(`[SDK:SSE] Chunk ${chunkCount} (${value.length} bytes):`, chunk.substring(0, 200));
494
+ }
467
495
  const lines = buffer.split("\n");
468
496
  buffer = lines.pop() ?? "";
469
497
  for (const line of lines) {
470
498
  if (line === "") {
471
499
  if (currentEvent.type && currentEvent.data !== void 0) {
500
+ eventCount++;
501
+ console.log(`[SDK:SSE] Event ${eventCount}:`, currentEvent.type, "- data length:", currentEvent.data.length);
472
502
  this.dispatchEvent(currentEvent);
473
503
  }
474
504
  currentEvent = {};
@@ -500,6 +530,7 @@ var SSEClient = class {
500
530
  }
501
531
  }
502
532
  } finally {
533
+ console.log("[SDK:SSE] parseStream finished. Releasing reader lock.");
503
534
  reader.releaseLock();
504
535
  }
505
536
  }
@@ -507,10 +538,12 @@ var SSEClient = class {
507
538
  * Dispatch parsed event
508
539
  */
509
540
  dispatchEvent(event) {
541
+ console.log("[SDK:SSE] dispatchEvent called:", event.type, "id:", event.id);
510
542
  try {
511
543
  let data;
512
544
  try {
513
545
  data = JSON.parse(event.data);
546
+ console.log("[SDK:SSE] Parsed event data:", typeof data, data && typeof data === "object" ? Object.keys(data) : "");
514
547
  } catch {
515
548
  data = event.data;
516
549
  }
@@ -554,6 +587,13 @@ var ExecutionStreamControllerImpl = class {
554
587
  toolCall: [],
555
588
  toolResult: [],
556
589
  plan: [],
590
+ paused: [],
591
+ started: [],
592
+ progress: [],
593
+ taskListUpdate: [],
594
+ delegationStarted: [],
595
+ delegationCompleted: [],
596
+ textDelta: [],
557
597
  complete: [],
558
598
  error: [],
559
599
  connectionChange: []
@@ -572,6 +612,18 @@ var ExecutionStreamControllerImpl = class {
572
612
  get lastEventId() {
573
613
  return this._lastEventId;
574
614
  }
615
+ /**
616
+ * Get the execution ID
617
+ */
618
+ get executionId() {
619
+ return this.options.executionId;
620
+ }
621
+ /**
622
+ * Get the session ID (if available)
623
+ */
624
+ get sessionId() {
625
+ return this.options.sessionId;
626
+ }
575
627
  /**
576
628
  * Connect to the execution stream
577
629
  */
@@ -633,13 +685,27 @@ var ExecutionStreamControllerImpl = class {
633
685
  */
634
686
  async connectSSE() {
635
687
  const url = `${this.options.baseUrl}/agents/runs/${this.options.executionId}/stream`;
688
+ let authToken = this.options.apiKey;
689
+ if (!authToken && this.options.tokenProvider) {
690
+ authToken = await this.options.tokenProvider();
691
+ }
692
+ console.log("[SDK:StreamController] Connecting to SSE");
693
+ console.log("[SDK:StreamController] URL:", url);
694
+ console.log("[SDK:StreamController] baseUrl:", this.options.baseUrl);
695
+ console.log("[SDK:StreamController] executionId:", this.options.executionId);
696
+ console.log("[SDK:StreamController] orgId:", this.options.orgId);
697
+ console.log("[SDK:StreamController] apiKey:", authToken ? `${authToken.substring(0, 20)}...` : "MISSING");
636
698
  this.sseClient = new SSEClient({
637
699
  url,
638
- authHeader: `Bearer ${this.options.apiKey}`,
700
+ authHeader: `Bearer ${authToken}`,
639
701
  orgId: this.options.orgId,
640
702
  onEvent: (event) => this.handleEvent(event),
641
- onError: (error) => this.handleConnectionError(error),
703
+ onError: (error) => {
704
+ console.error("[SDK:StreamController] SSE error:", error);
705
+ this.handleConnectionError(error);
706
+ },
642
707
  onConnectionChange: (connected) => {
708
+ console.log("[SDK:StreamController] SSE connection change:", connected);
643
709
  if (connected) {
644
710
  this.status = "connected";
645
711
  this.reconnectAttempts = 0;
@@ -648,15 +714,23 @@ var ExecutionStreamControllerImpl = class {
648
714
  this.emit("connectionChange", { connected, usingFallback: false });
649
715
  }
650
716
  });
651
- await this.sseClient.connect();
717
+ try {
718
+ await this.sseClient.connect();
719
+ console.log("[SDK:StreamController] SSE connect() completed");
720
+ } catch (error) {
721
+ console.error("[SDK:StreamController] SSE connect() threw:", error);
722
+ throw error;
723
+ }
652
724
  }
653
725
  /**
654
726
  * Handle incoming SSE event
655
727
  */
656
728
  handleEvent(event) {
729
+ console.log("[SDK:StreamController] handleEvent called:", event.type, "id:", event.id);
657
730
  this.resetActivityTimeout();
658
731
  if (event.id) {
659
732
  if (this.seenEventIds.has(event.id)) {
733
+ console.log("[SDK:StreamController] Skipping duplicate event:", event.id);
660
734
  return;
661
735
  }
662
736
  this.seenEventIds.add(event.id);
@@ -667,24 +741,52 @@ var ExecutionStreamControllerImpl = class {
667
741
  }
668
742
  }
669
743
  const data = event.data;
744
+ console.log("[SDK:StreamController] Event data keys:", Object.keys(data));
670
745
  switch (event.type) {
671
- case "log":
672
- this.emit("log", data.log);
746
+ case "log": {
747
+ const rawLog = data.log;
748
+ if (!rawLog) {
749
+ console.warn("[StreamController] Received log event without log data");
750
+ break;
751
+ }
752
+ const logTypeValue = rawLog.logType || rawLog.type || "info";
753
+ const transformedLog = {
754
+ uuid: rawLog.uuid || `log-${rawLog.stepIndex || Date.now()}`,
755
+ type: logTypeValue,
756
+ title: rawLog.message || rawLog.title || "",
757
+ content: rawLog.content,
758
+ metadata: {
759
+ ...rawLog.metadata || {},
760
+ // Include stepIndex in metadata for deduplication
761
+ stepIndex: rawLog.stepIndex ?? 0
762
+ },
763
+ timestamp: rawLog.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
764
+ durationMs: rawLog.durationMs
765
+ };
766
+ this.emit("log", transformedLog);
673
767
  break;
768
+ }
674
769
  case "tool_call":
675
770
  this.emit("toolCall", {
676
- toolCallId: data.toolCallId,
677
- toolName: data.toolName,
678
- inputs: data.args,
771
+ toolCallId: data.toolCallId || `tool-call-${Date.now()}`,
772
+ toolName: data.toolName || "Unknown Tool",
773
+ inputs: data.args || {},
679
774
  stepIndex: data.stepIndex ?? 0
680
775
  });
681
776
  break;
682
777
  case "tool_result":
683
778
  this.emit("toolResult", {
684
- toolCallId: data.toolCallId,
685
- toolName: data.toolName,
779
+ toolCallId: data.toolCallId || `tool-result-${Date.now()}`,
780
+ toolName: data.toolName || "Unknown Tool",
686
781
  result: data.result,
687
- durationMs: data.durationMs
782
+ durationMs: data.durationMs ?? 0
783
+ });
784
+ break;
785
+ case "execution_paused":
786
+ this.emit("paused", {
787
+ question: data.question || data.output || "",
788
+ options: data.options,
789
+ reason: "waiting_user_input"
688
790
  });
689
791
  break;
690
792
  case "complete":
@@ -696,6 +798,12 @@ var ExecutionStreamControllerImpl = class {
696
798
  errorCode: data.errorCode
697
799
  });
698
800
  break;
801
+ case "failed":
802
+ this.handleError({
803
+ error: data.error || data.message || "Execution failed",
804
+ errorCode: data.errorCode || "execution_failed"
805
+ });
806
+ break;
699
807
  case "timeout":
700
808
  if (data.retryable) {
701
809
  this.handleConnectionError(new Error("Stream timeout"));
@@ -706,6 +814,74 @@ var ExecutionStreamControllerImpl = class {
706
814
  });
707
815
  }
708
816
  break;
817
+ // Handle started event - immediate feedback that execution began
818
+ case "started":
819
+ this.emit("started", {
820
+ executionId: data.executionId,
821
+ agentUuid: data.agentUuid,
822
+ status: "initializing",
823
+ currentStep: data.currentStep
824
+ });
825
+ break;
826
+ // Handle progress event - status updates during execution
827
+ case "progress":
828
+ this.emit("progress", {
829
+ status: data.status,
830
+ iteration: data.iteration ?? 0,
831
+ currentStep: data.currentStep,
832
+ tokenUsage: data.tokenUsage,
833
+ cost: data.cost,
834
+ toolCalls: data.toolCalls
835
+ });
836
+ break;
837
+ // Handle task list update event from TaskTracker
838
+ case "task_list_update":
839
+ this.emit("taskListUpdate", {
840
+ executionId: data.executionId,
841
+ tasks: data.tasks,
842
+ timestamp: data.timestamp
843
+ });
844
+ break;
845
+ // Handle delegation started event (handoff_to_agent initiated)
846
+ case "delegation_started":
847
+ this.emit("delegationStarted", {
848
+ type: "delegation_started",
849
+ handoffId: data.handoffId,
850
+ targetAgentUuid: data.targetAgentUuid,
851
+ targetAgentName: data.targetAgentName,
852
+ taskPreview: data.taskPreview,
853
+ timestamp: data.timestamp || (/* @__PURE__ */ new Date()).toISOString()
854
+ });
855
+ break;
856
+ // Handle delegation completed event (handoff_to_agent finished)
857
+ case "delegation_completed":
858
+ this.emit("delegationCompleted", {
859
+ type: "delegation_completed",
860
+ handoffId: data.handoffId,
861
+ status: data.status,
862
+ resultPreview: data.resultPreview,
863
+ error: data.error,
864
+ durationMs: data.durationMs,
865
+ timestamp: data.timestamp || (/* @__PURE__ */ new Date()).toISOString()
866
+ });
867
+ break;
868
+ // Handle status_update event - immediate feedback (e.g., "thinking")
869
+ // Map to progress event for consistency
870
+ case "status_update":
871
+ this.emit("progress", {
872
+ status: data.status || "thinking",
873
+ iteration: 0,
874
+ currentStep: data.message
875
+ });
876
+ break;
877
+ // Handle text_delta event - token-by-token streaming
878
+ case "text_delta":
879
+ this.emit("textDelta", {
880
+ delta: data.delta,
881
+ executionId: data.executionId,
882
+ timestamp: data.timestamp || (/* @__PURE__ */ new Date()).toISOString()
883
+ });
884
+ break;
709
885
  }
710
886
  }
711
887
  /**
@@ -714,9 +890,11 @@ var ExecutionStreamControllerImpl = class {
714
890
  handleComplete(data) {
715
891
  this.status = "closed";
716
892
  this.stopActivityTimeout();
893
+ const sessionId = data.sessionId ?? this.options.sessionId;
717
894
  const execution = {
718
895
  uuid: this.options.executionId,
719
896
  agentUuid: "",
897
+ sessionId,
720
898
  status: "completed",
721
899
  input: { task: "" },
722
900
  output: data.output,
@@ -840,6 +1018,7 @@ var ExecutionStreamControllerImpl = class {
840
1018
  */
841
1019
  emit(event, data) {
842
1020
  const listeners = this.listeners[event];
1021
+ console.log(`[SDK:StreamController] Emitting '${event}' to ${listeners?.length || 0} listeners`);
843
1022
  if (listeners) {
844
1023
  for (const listener of listeners) {
845
1024
  try {
@@ -920,8 +1099,10 @@ var AgentsAPI = class extends BaseResourceAPI {
920
1099
  `/${uuid}/execute`,
921
1100
  {
922
1101
  task: input.task,
923
- context: input.context,
924
- options: input.options
1102
+ context: input.context ?? {},
1103
+ attachmentIds: input.attachmentIds,
1104
+ options: input.options,
1105
+ ...input.teamUuid ? { teamUuid: input.teamUuid } : {}
925
1106
  },
926
1107
  { idempotencyKey }
927
1108
  );
@@ -971,16 +1152,71 @@ var AgentsAPI = class extends BaseResourceAPI {
971
1152
  * ```
972
1153
  */
973
1154
  async stream(uuid, input) {
974
- const { executionId } = await this.execute(uuid, input);
1155
+ console.log("[SDK:Agents] stream() called for agent:", uuid);
1156
+ const { executionId, sessionId } = await this.execute(uuid, input);
1157
+ console.log("[SDK:Agents] Execution started:", { executionId, sessionId });
975
1158
  const config = this.getStreamConfig();
1159
+ console.log("[SDK:Agents] Stream config:", {
1160
+ baseUrl: config.baseUrl,
1161
+ apiKey: config.apiKey ? `${config.apiKey.substring(0, 20)}...` : "MISSING",
1162
+ orgId: config.orgId
1163
+ });
976
1164
  const controller = createExecutionStreamController({
977
1165
  executionId,
1166
+ sessionId,
978
1167
  baseUrl: config.baseUrl,
979
1168
  apiKey: config.apiKey,
1169
+ tokenProvider: config.tokenProvider,
980
1170
  orgId: config.orgId,
981
1171
  getExecution: (id) => this.getExecution(id)
982
1172
  });
983
- await controller.connect();
1173
+ console.log("[SDK:Agents] Stream controller created - caller must call connect() after registering listeners");
1174
+ return controller;
1175
+ }
1176
+ /**
1177
+ * Connect to an existing execution's stream
1178
+ *
1179
+ * Use this when the execution was started externally (e.g., via tRPC for team executions)
1180
+ * and you need to connect to its SSE stream for real-time updates.
1181
+ *
1182
+ * @param executionId - Execution UUID (already running)
1183
+ * @param sessionId - Optional session ID for conversation continuity
1184
+ * @returns Stream controller for the execution
1185
+ *
1186
+ * @example
1187
+ * ```typescript
1188
+ * // Execution started via tRPC
1189
+ * const executionId = await trpc.executions.start.mutate({ teamUuid, task });
1190
+ *
1191
+ * // Connect to SSE stream for real-time updates
1192
+ * const stream = client.agents.streamExecution(executionId);
1193
+ *
1194
+ * stream.on('log', (log) => console.log(log.title));
1195
+ * stream.on('delegationStarted', (data) => console.log('Subagent:', data.targetAgentName));
1196
+ * stream.on('complete', ({ execution }) => console.log(execution.output));
1197
+ *
1198
+ * await stream.connect();
1199
+ * const result = await stream.wait();
1200
+ * ```
1201
+ */
1202
+ streamExecution(executionId, sessionId) {
1203
+ console.log("[SDK:Agents] streamExecution() called for execution:", executionId);
1204
+ const config = this.getStreamConfig();
1205
+ console.log("[SDK:Agents] Stream config:", {
1206
+ baseUrl: config.baseUrl,
1207
+ apiKey: config.apiKey ? `${config.apiKey.substring(0, 20)}...` : "MISSING",
1208
+ orgId: config.orgId
1209
+ });
1210
+ const controller = createExecutionStreamController({
1211
+ executionId,
1212
+ sessionId,
1213
+ baseUrl: config.baseUrl,
1214
+ apiKey: config.apiKey,
1215
+ tokenProvider: config.tokenProvider,
1216
+ orgId: config.orgId,
1217
+ getExecution: (id) => this.getExecution(id)
1218
+ });
1219
+ console.log("[SDK:Agents] Stream controller created for existing execution - caller must call connect() after registering listeners");
984
1220
  return controller;
985
1221
  }
986
1222
  // ===== RECEIVE Operations =====
@@ -1512,13 +1748,16 @@ var ArtifactsAPI = class extends BaseResourceAPI {
1512
1748
  while (true) {
1513
1749
  const { done, value } = await reader.read();
1514
1750
  if (done) break;
1515
- const arrayBuffer = value.buffer.slice(
1516
- value.byteOffset,
1517
- value.byteOffset + value.byteLength
1518
- );
1519
- chunks.push(arrayBuffer);
1751
+ chunks.push(new Uint8Array(value));
1520
1752
  }
1521
- const blob = new Blob(chunks, { type: input.mimeType ?? "application/octet-stream" });
1753
+ const totalLength = chunks.reduce((acc, chunk) => acc + chunk.length, 0);
1754
+ const combined = new Uint8Array(totalLength);
1755
+ let offset = 0;
1756
+ for (const chunk of chunks) {
1757
+ combined.set(chunk, offset);
1758
+ offset += chunk.length;
1759
+ }
1760
+ const blob = new Blob([combined.buffer], { type: input.mimeType ?? "application/octet-stream" });
1522
1761
  formData.append("file", blob, input.name);
1523
1762
  }
1524
1763
  if (input.type) {
@@ -1618,7 +1857,9 @@ var SessionsAPI = class extends BaseResourceAPI {
1618
1857
  `/${sessionId}/messages`,
1619
1858
  {
1620
1859
  message: input.message,
1621
- context: input.context
1860
+ context: input.context,
1861
+ // Pass attachment IDs for multi-modal messages (images, documents, etc.)
1862
+ attachmentIds: input.attachmentIds
1622
1863
  },
1623
1864
  { idempotencyKey }
1624
1865
  );
@@ -1669,6 +1910,7 @@ var SessionsAPI = class extends BaseResourceAPI {
1669
1910
  const config = this.getStreamConfig();
1670
1911
  const controller = createExecutionStreamController({
1671
1912
  executionId,
1913
+ sessionId,
1672
1914
  baseUrl: config.baseUrl,
1673
1915
  apiKey: config.apiKey,
1674
1916
  orgId: config.orgId,
@@ -1867,6 +2109,7 @@ var AISaaSClient = class {
1867
2109
  baseUrl: this.config.baseUrl,
1868
2110
  apiKey: this.config.apiKey,
1869
2111
  token: this.config.token,
2112
+ tokenProvider: this.config.tokenProvider,
1870
2113
  orgId: this.config.orgId
1871
2114
  });
1872
2115
  this.agents = new AgentsAPI(this.httpClient, getStreamConfig);