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