@octavus/client-sdk 2.1.0 → 2.3.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.d.ts +13 -0
- package/dist/index.js +414 -134
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -161,7 +161,8 @@ function createEmptyStreamingState() {
|
|
|
161
161
|
currentTextPartIndex: null,
|
|
162
162
|
currentReasoningPartIndex: null,
|
|
163
163
|
currentObjectPartIndex: null,
|
|
164
|
-
accumulatedJson: ""
|
|
164
|
+
accumulatedJson: "",
|
|
165
|
+
activeWorkers: /* @__PURE__ */ new Map()
|
|
165
166
|
};
|
|
166
167
|
}
|
|
167
168
|
function buildMessageFromState(state, status) {
|
|
@@ -173,6 +174,36 @@ function buildMessageFromState(state, status) {
|
|
|
173
174
|
createdAt: /* @__PURE__ */ new Date()
|
|
174
175
|
};
|
|
175
176
|
}
|
|
177
|
+
function finalizeParts(parts, workerError) {
|
|
178
|
+
return parts.map((part) => {
|
|
179
|
+
if (part.type === "text" || part.type === "reasoning") {
|
|
180
|
+
if (part.status === "streaming") {
|
|
181
|
+
return { ...part, status: "done" };
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
if (part.type === "object" && part.status === "streaming") {
|
|
185
|
+
return { ...part, status: "done" };
|
|
186
|
+
}
|
|
187
|
+
if (part.type === "tool-call") {
|
|
188
|
+
if (part.status === "pending" || part.status === "running") {
|
|
189
|
+
return { ...part, status: "cancelled" };
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
if (part.type === "operation" && part.status === "running") {
|
|
193
|
+
return { ...part, status: "cancelled" };
|
|
194
|
+
}
|
|
195
|
+
if (part.type === "worker" && part.status === "running") {
|
|
196
|
+
return {
|
|
197
|
+
...part,
|
|
198
|
+
status: "error",
|
|
199
|
+
error: workerError,
|
|
200
|
+
parts: finalizeParts(part.parts)
|
|
201
|
+
// Recursive for nested parts
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
return part;
|
|
205
|
+
});
|
|
206
|
+
}
|
|
176
207
|
var OctavusChat = class {
|
|
177
208
|
// Private state
|
|
178
209
|
_messages;
|
|
@@ -197,6 +228,9 @@ var OctavusChat = class {
|
|
|
197
228
|
// Flag indicating automatic client tools have completed and are ready to continue
|
|
198
229
|
// We wait for the finish event before actually continuing to avoid race conditions
|
|
199
230
|
_readyToContinue = false;
|
|
231
|
+
// Flag indicating the finish event with client-tool-calls reason has been received
|
|
232
|
+
// Used to handle the race condition where finish arrives before async tools complete
|
|
233
|
+
_finishEventReceived = false;
|
|
200
234
|
// Listener sets for reactive frameworks
|
|
201
235
|
listeners = /* @__PURE__ */ new Set();
|
|
202
236
|
constructor(options) {
|
|
@@ -350,6 +384,7 @@ var OctavusChat = class {
|
|
|
350
384
|
this._serverToolResults = [];
|
|
351
385
|
this._pendingExecutionId = null;
|
|
352
386
|
this._readyToContinue = false;
|
|
387
|
+
this._finishEventReceived = false;
|
|
353
388
|
this.updatePendingClientToolsCache();
|
|
354
389
|
try {
|
|
355
390
|
for await (const event of this.transport.trigger(triggerName, processedInput)) {
|
|
@@ -369,25 +404,7 @@ var OctavusChat = class {
|
|
|
369
404
|
const messages = [...this._messages];
|
|
370
405
|
const lastMsg = messages[messages.length - 1];
|
|
371
406
|
if (state.parts.length > 0) {
|
|
372
|
-
const finalParts = state.parts
|
|
373
|
-
if (part.type === "text" || part.type === "reasoning") {
|
|
374
|
-
if (part.status === "streaming") {
|
|
375
|
-
return { ...part, status: "done" };
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
if (part.type === "object" && part.status === "streaming") {
|
|
379
|
-
return { ...part, status: "done" };
|
|
380
|
-
}
|
|
381
|
-
if (part.type === "tool-call") {
|
|
382
|
-
if (part.status === "pending" || part.status === "running") {
|
|
383
|
-
return { ...part, status: "cancelled" };
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
if (part.type === "operation" && part.status === "running") {
|
|
387
|
-
return { ...part, status: "cancelled" };
|
|
388
|
-
}
|
|
389
|
-
return part;
|
|
390
|
-
});
|
|
407
|
+
const finalParts = finalizeParts(state.parts, "Stream error");
|
|
391
408
|
const finalMessage = {
|
|
392
409
|
id: state.messageId,
|
|
393
410
|
role: "assistant",
|
|
@@ -464,7 +481,9 @@ var OctavusChat = class {
|
|
|
464
481
|
result: error ? void 0 : result,
|
|
465
482
|
error,
|
|
466
483
|
outputVariable: pendingTool.outputVariable,
|
|
467
|
-
blockIndex: pendingTool.blockIndex
|
|
484
|
+
blockIndex: pendingTool.blockIndex,
|
|
485
|
+
thread: pendingTool.thread,
|
|
486
|
+
workerId: pendingTool.workerId
|
|
468
487
|
};
|
|
469
488
|
this._completedToolResults.push(toolResult);
|
|
470
489
|
if (error) {
|
|
@@ -490,37 +509,12 @@ var OctavusChat = class {
|
|
|
490
509
|
this._serverToolResults = [];
|
|
491
510
|
this._pendingExecutionId = null;
|
|
492
511
|
this._readyToContinue = false;
|
|
512
|
+
this._finishEventReceived = false;
|
|
493
513
|
this.updatePendingClientToolsCache();
|
|
494
514
|
this.transport.stop();
|
|
495
515
|
const state = this.streamingState;
|
|
496
516
|
if (state && state.parts.length > 0) {
|
|
497
|
-
const finalParts = state.parts
|
|
498
|
-
if (part.type === "tool-call") {
|
|
499
|
-
const toolPart = part;
|
|
500
|
-
if (toolPart.status === "pending" || toolPart.status === "running") {
|
|
501
|
-
return { ...toolPart, status: "cancelled" };
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
if (part.type === "operation") {
|
|
505
|
-
const opPart = part;
|
|
506
|
-
if (opPart.status === "running") {
|
|
507
|
-
return { ...opPart, status: "cancelled" };
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
if (part.type === "text" || part.type === "reasoning") {
|
|
511
|
-
const textPart = part;
|
|
512
|
-
if (textPart.status === "streaming") {
|
|
513
|
-
return { ...textPart, status: "done" };
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
if (part.type === "object") {
|
|
517
|
-
const objPart = part;
|
|
518
|
-
if (objPart.status === "streaming") {
|
|
519
|
-
return { ...objPart, status: "done" };
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
return part;
|
|
523
|
-
});
|
|
517
|
+
const finalParts = finalizeParts(state.parts, "Stopped by user");
|
|
524
518
|
const finalMessage = {
|
|
525
519
|
id: state.messageId,
|
|
526
520
|
role: "assistant",
|
|
@@ -547,8 +541,13 @@ var OctavusChat = class {
|
|
|
547
541
|
handleStreamEvent(event, state) {
|
|
548
542
|
switch (event.type) {
|
|
549
543
|
case "start":
|
|
544
|
+
if (event.executionId) {
|
|
545
|
+
this.options.onStart?.(event.executionId);
|
|
546
|
+
}
|
|
550
547
|
break;
|
|
551
548
|
case "block-start": {
|
|
549
|
+
const workerId = event.workerId;
|
|
550
|
+
const workerState = workerId ? state.activeWorkers.get(workerId) : void 0;
|
|
552
551
|
const block = {
|
|
553
552
|
blockId: event.blockId,
|
|
554
553
|
blockName: event.blockName,
|
|
@@ -575,7 +574,13 @@ var OctavusChat = class {
|
|
|
575
574
|
status: "running",
|
|
576
575
|
thread: threadForPart(thread)
|
|
577
576
|
};
|
|
578
|
-
|
|
577
|
+
if (workerState) {
|
|
578
|
+
const workerPart = state.parts[workerState.partIndex];
|
|
579
|
+
workerPart.parts.push(operationPart);
|
|
580
|
+
state.parts[workerState.partIndex] = { ...workerPart };
|
|
581
|
+
} else {
|
|
582
|
+
state.parts.push(operationPart);
|
|
583
|
+
}
|
|
579
584
|
}
|
|
580
585
|
state.currentTextPartIndex = null;
|
|
581
586
|
state.currentReasoningPartIndex = null;
|
|
@@ -583,12 +588,26 @@ var OctavusChat = class {
|
|
|
583
588
|
break;
|
|
584
589
|
}
|
|
585
590
|
case "block-end": {
|
|
586
|
-
const
|
|
587
|
-
|
|
588
|
-
)
|
|
589
|
-
|
|
590
|
-
const
|
|
591
|
-
|
|
591
|
+
const workerId = event.workerId;
|
|
592
|
+
const workerState = workerId ? state.activeWorkers.get(workerId) : void 0;
|
|
593
|
+
if (workerState) {
|
|
594
|
+
const workerPart = state.parts[workerState.partIndex];
|
|
595
|
+
const operationPartIndex = workerPart.parts.findIndex(
|
|
596
|
+
(p) => p.type === "operation" && p.operationId === event.blockId
|
|
597
|
+
);
|
|
598
|
+
if (operationPartIndex >= 0) {
|
|
599
|
+
const part = workerPart.parts[operationPartIndex];
|
|
600
|
+
workerPart.parts[operationPartIndex] = { ...part, status: "done" };
|
|
601
|
+
state.parts[workerState.partIndex] = { ...workerPart };
|
|
602
|
+
}
|
|
603
|
+
} else {
|
|
604
|
+
const operationPartIndex = state.parts.findIndex(
|
|
605
|
+
(p) => p.type === "operation" && p.operationId === event.blockId
|
|
606
|
+
);
|
|
607
|
+
if (operationPartIndex >= 0) {
|
|
608
|
+
const part = state.parts[operationPartIndex];
|
|
609
|
+
state.parts[operationPartIndex] = { ...part, status: "done" };
|
|
610
|
+
}
|
|
592
611
|
}
|
|
593
612
|
if (state.activeBlock?.blockId === event.blockId) {
|
|
594
613
|
state.activeBlock = null;
|
|
@@ -597,31 +616,63 @@ var OctavusChat = class {
|
|
|
597
616
|
break;
|
|
598
617
|
}
|
|
599
618
|
case "reasoning-start": {
|
|
619
|
+
const workerId = event.workerId;
|
|
620
|
+
const workerState = workerId ? state.activeWorkers.get(workerId) : void 0;
|
|
600
621
|
const reasoningPart = {
|
|
601
622
|
type: "reasoning",
|
|
602
623
|
text: "",
|
|
603
624
|
status: "streaming",
|
|
604
625
|
thread: threadForPart(state.activeBlock?.thread)
|
|
605
626
|
};
|
|
606
|
-
|
|
607
|
-
|
|
627
|
+
if (workerState) {
|
|
628
|
+
const workerPart = state.parts[workerState.partIndex];
|
|
629
|
+
workerPart.parts.push(reasoningPart);
|
|
630
|
+
workerState.currentReasoningPartIndex = workerPart.parts.length - 1;
|
|
631
|
+
state.parts[workerState.partIndex] = { ...workerPart };
|
|
632
|
+
} else {
|
|
633
|
+
state.parts.push(reasoningPart);
|
|
634
|
+
state.currentReasoningPartIndex = state.parts.length - 1;
|
|
635
|
+
}
|
|
608
636
|
this.updateStreamingMessage();
|
|
609
637
|
break;
|
|
610
638
|
}
|
|
611
639
|
case "reasoning-delta": {
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
640
|
+
const workerId = event.workerId;
|
|
641
|
+
const workerState = workerId ? state.activeWorkers.get(workerId) : void 0;
|
|
642
|
+
if (workerState) {
|
|
643
|
+
if (workerState.currentReasoningPartIndex !== null) {
|
|
644
|
+
const workerPart = state.parts[workerState.partIndex];
|
|
645
|
+
const part = workerPart.parts[workerState.currentReasoningPartIndex];
|
|
646
|
+
part.text += event.delta;
|
|
647
|
+
workerPart.parts[workerState.currentReasoningPartIndex] = { ...part };
|
|
648
|
+
state.parts[workerState.partIndex] = { ...workerPart };
|
|
649
|
+
}
|
|
650
|
+
} else {
|
|
651
|
+
if (state.currentReasoningPartIndex !== null) {
|
|
652
|
+
const part = state.parts[state.currentReasoningPartIndex];
|
|
653
|
+
part.text += event.delta;
|
|
654
|
+
state.parts[state.currentReasoningPartIndex] = { ...part };
|
|
655
|
+
}
|
|
656
|
+
if (state.activeBlock) {
|
|
657
|
+
state.activeBlock.reasoning += event.delta;
|
|
658
|
+
}
|
|
619
659
|
}
|
|
620
660
|
this.updateStreamingMessage();
|
|
621
661
|
break;
|
|
622
662
|
}
|
|
623
663
|
case "reasoning-end": {
|
|
624
|
-
|
|
664
|
+
const workerId = event.workerId;
|
|
665
|
+
const workerState = workerId ? state.activeWorkers.get(workerId) : void 0;
|
|
666
|
+
if (workerState) {
|
|
667
|
+
if (workerState.currentReasoningPartIndex !== null) {
|
|
668
|
+
const workerPart = state.parts[workerState.partIndex];
|
|
669
|
+
const part = workerPart.parts[workerState.currentReasoningPartIndex];
|
|
670
|
+
part.status = "done";
|
|
671
|
+
workerPart.parts[workerState.currentReasoningPartIndex] = { ...part };
|
|
672
|
+
state.parts[workerState.partIndex] = { ...workerPart };
|
|
673
|
+
workerState.currentReasoningPartIndex = null;
|
|
674
|
+
}
|
|
675
|
+
} else if (state.currentReasoningPartIndex !== null) {
|
|
625
676
|
const part = state.parts[state.currentReasoningPartIndex];
|
|
626
677
|
part.status = "done";
|
|
627
678
|
state.parts[state.currentReasoningPartIndex] = { ...part };
|
|
@@ -631,9 +682,11 @@ var OctavusChat = class {
|
|
|
631
682
|
break;
|
|
632
683
|
}
|
|
633
684
|
case "text-start": {
|
|
685
|
+
const workerId = event.workerId;
|
|
686
|
+
const workerState = workerId ? state.activeWorkers.get(workerId) : void 0;
|
|
634
687
|
const thread = threadForPart(state.activeBlock?.thread);
|
|
635
688
|
const shouldAddPart = state.activeBlock?.outputToChat !== false || thread !== void 0;
|
|
636
|
-
if (shouldAddPart) {
|
|
689
|
+
if (workerState || shouldAddPart) {
|
|
637
690
|
if (event.responseType) {
|
|
638
691
|
const objectPart = {
|
|
639
692
|
type: "object",
|
|
@@ -644,10 +697,19 @@ var OctavusChat = class {
|
|
|
644
697
|
status: "streaming",
|
|
645
698
|
thread
|
|
646
699
|
};
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
700
|
+
if (workerState) {
|
|
701
|
+
const workerPart = state.parts[workerState.partIndex];
|
|
702
|
+
workerPart.parts.push(objectPart);
|
|
703
|
+
workerState.currentObjectPartIndex = workerPart.parts.length - 1;
|
|
704
|
+
workerState.accumulatedJson = "";
|
|
705
|
+
workerState.currentTextPartIndex = null;
|
|
706
|
+
state.parts[workerState.partIndex] = { ...workerPart };
|
|
707
|
+
} else {
|
|
708
|
+
state.parts.push(objectPart);
|
|
709
|
+
state.currentObjectPartIndex = state.parts.length - 1;
|
|
710
|
+
state.accumulatedJson = "";
|
|
711
|
+
state.currentTextPartIndex = null;
|
|
712
|
+
}
|
|
651
713
|
} else {
|
|
652
714
|
const textPart = {
|
|
653
715
|
type: "text",
|
|
@@ -655,36 +717,89 @@ var OctavusChat = class {
|
|
|
655
717
|
status: "streaming",
|
|
656
718
|
thread
|
|
657
719
|
};
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
720
|
+
if (workerState) {
|
|
721
|
+
const workerPart = state.parts[workerState.partIndex];
|
|
722
|
+
workerPart.parts.push(textPart);
|
|
723
|
+
workerState.currentTextPartIndex = workerPart.parts.length - 1;
|
|
724
|
+
workerState.currentObjectPartIndex = null;
|
|
725
|
+
state.parts[workerState.partIndex] = { ...workerPart };
|
|
726
|
+
} else {
|
|
727
|
+
state.parts.push(textPart);
|
|
728
|
+
state.currentTextPartIndex = state.parts.length - 1;
|
|
729
|
+
state.currentObjectPartIndex = null;
|
|
730
|
+
}
|
|
661
731
|
}
|
|
662
732
|
}
|
|
663
733
|
this.updateStreamingMessage();
|
|
664
734
|
break;
|
|
665
735
|
}
|
|
666
736
|
case "text-delta": {
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
const
|
|
671
|
-
if (
|
|
672
|
-
|
|
673
|
-
|
|
737
|
+
const workerId = event.workerId;
|
|
738
|
+
const workerState = workerId ? state.activeWorkers.get(workerId) : void 0;
|
|
739
|
+
if (workerState) {
|
|
740
|
+
const workerPart = state.parts[workerState.partIndex];
|
|
741
|
+
if (workerState.currentObjectPartIndex !== null) {
|
|
742
|
+
workerState.accumulatedJson += event.delta;
|
|
743
|
+
const part = workerPart.parts[workerState.currentObjectPartIndex];
|
|
744
|
+
const parsed = parsePartialJson(workerState.accumulatedJson);
|
|
745
|
+
if (parsed !== void 0) {
|
|
746
|
+
part.partial = parsed;
|
|
747
|
+
workerPart.parts[workerState.currentObjectPartIndex] = { ...part };
|
|
748
|
+
}
|
|
749
|
+
} else if (workerState.currentTextPartIndex !== null) {
|
|
750
|
+
const part = workerPart.parts[workerState.currentTextPartIndex];
|
|
751
|
+
part.text += event.delta;
|
|
752
|
+
workerPart.parts[workerState.currentTextPartIndex] = { ...part };
|
|
753
|
+
}
|
|
754
|
+
state.parts[workerState.partIndex] = { ...workerPart };
|
|
755
|
+
} else {
|
|
756
|
+
if (state.currentObjectPartIndex !== null) {
|
|
757
|
+
state.accumulatedJson += event.delta;
|
|
758
|
+
const part = state.parts[state.currentObjectPartIndex];
|
|
759
|
+
const parsed = parsePartialJson(state.accumulatedJson);
|
|
760
|
+
if (parsed !== void 0) {
|
|
761
|
+
part.partial = parsed;
|
|
762
|
+
state.parts[state.currentObjectPartIndex] = { ...part };
|
|
763
|
+
}
|
|
764
|
+
} else if (state.currentTextPartIndex !== null) {
|
|
765
|
+
const part = state.parts[state.currentTextPartIndex];
|
|
766
|
+
part.text += event.delta;
|
|
767
|
+
state.parts[state.currentTextPartIndex] = { ...part };
|
|
768
|
+
}
|
|
769
|
+
if (state.activeBlock) {
|
|
770
|
+
state.activeBlock.text += event.delta;
|
|
674
771
|
}
|
|
675
|
-
} else if (state.currentTextPartIndex !== null) {
|
|
676
|
-
const part = state.parts[state.currentTextPartIndex];
|
|
677
|
-
part.text += event.delta;
|
|
678
|
-
state.parts[state.currentTextPartIndex] = { ...part };
|
|
679
|
-
}
|
|
680
|
-
if (state.activeBlock) {
|
|
681
|
-
state.activeBlock.text += event.delta;
|
|
682
772
|
}
|
|
683
773
|
this.updateStreamingMessage();
|
|
684
774
|
break;
|
|
685
775
|
}
|
|
686
776
|
case "text-end": {
|
|
687
|
-
|
|
777
|
+
const workerId = event.workerId;
|
|
778
|
+
const workerState = workerId ? state.activeWorkers.get(workerId) : void 0;
|
|
779
|
+
if (workerState) {
|
|
780
|
+
const workerPart = state.parts[workerState.partIndex];
|
|
781
|
+
if (workerState.currentObjectPartIndex !== null) {
|
|
782
|
+
const part = workerPart.parts[workerState.currentObjectPartIndex];
|
|
783
|
+
try {
|
|
784
|
+
const finalObject = JSON.parse(workerState.accumulatedJson);
|
|
785
|
+
part.object = finalObject;
|
|
786
|
+
part.partial = finalObject;
|
|
787
|
+
part.status = "done";
|
|
788
|
+
} catch {
|
|
789
|
+
part.status = "error";
|
|
790
|
+
part.error = "Failed to parse response as JSON";
|
|
791
|
+
}
|
|
792
|
+
workerPart.parts[workerState.currentObjectPartIndex] = { ...part };
|
|
793
|
+
workerState.currentObjectPartIndex = null;
|
|
794
|
+
workerState.accumulatedJson = "";
|
|
795
|
+
} else if (workerState.currentTextPartIndex !== null) {
|
|
796
|
+
const part = workerPart.parts[workerState.currentTextPartIndex];
|
|
797
|
+
part.status = "done";
|
|
798
|
+
workerPart.parts[workerState.currentTextPartIndex] = { ...part };
|
|
799
|
+
workerState.currentTextPartIndex = null;
|
|
800
|
+
}
|
|
801
|
+
state.parts[workerState.partIndex] = { ...workerPart };
|
|
802
|
+
} else if (state.currentObjectPartIndex !== null) {
|
|
688
803
|
const part = state.parts[state.currentObjectPartIndex];
|
|
689
804
|
try {
|
|
690
805
|
const finalObject = JSON.parse(state.accumulatedJson);
|
|
@@ -708,6 +823,8 @@ var OctavusChat = class {
|
|
|
708
823
|
break;
|
|
709
824
|
}
|
|
710
825
|
case "tool-input-start": {
|
|
826
|
+
const workerId = event.workerId;
|
|
827
|
+
const workerState = workerId ? state.activeWorkers.get(workerId) : void 0;
|
|
711
828
|
const toolPart = {
|
|
712
829
|
type: "tool-call",
|
|
713
830
|
toolCallId: event.toolCallId,
|
|
@@ -717,24 +834,49 @@ var OctavusChat = class {
|
|
|
717
834
|
status: "pending",
|
|
718
835
|
thread: threadForPart(state.activeBlock?.thread)
|
|
719
836
|
};
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
837
|
+
if (workerState) {
|
|
838
|
+
const workerPart = state.parts[workerState.partIndex];
|
|
839
|
+
workerPart.parts.push(toolPart);
|
|
840
|
+
state.parts[workerState.partIndex] = { ...workerPart };
|
|
841
|
+
} else {
|
|
842
|
+
state.parts.push(toolPart);
|
|
843
|
+
if (state.activeBlock) {
|
|
844
|
+
state.activeBlock.toolCalls.set(event.toolCallId, toolPart);
|
|
845
|
+
}
|
|
723
846
|
}
|
|
724
847
|
this.updateStreamingMessage();
|
|
725
848
|
break;
|
|
726
849
|
}
|
|
727
850
|
case "tool-input-delta": {
|
|
728
|
-
const
|
|
729
|
-
|
|
730
|
-
)
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
851
|
+
const workerId = event.workerId;
|
|
852
|
+
const workerState = workerId ? state.activeWorkers.get(workerId) : void 0;
|
|
853
|
+
if (workerState) {
|
|
854
|
+
const workerPart = state.parts[workerState.partIndex];
|
|
855
|
+
const toolPartIndex = workerPart.parts.findIndex(
|
|
856
|
+
(p) => p.type === "tool-call" && p.toolCallId === event.toolCallId
|
|
857
|
+
);
|
|
858
|
+
if (toolPartIndex >= 0) {
|
|
859
|
+
try {
|
|
860
|
+
const part = workerPart.parts[toolPartIndex];
|
|
861
|
+
part.args = JSON.parse(event.inputTextDelta);
|
|
862
|
+
workerPart.parts[toolPartIndex] = { ...part };
|
|
863
|
+
state.parts[workerState.partIndex] = { ...workerPart };
|
|
864
|
+
this.updateStreamingMessage();
|
|
865
|
+
} catch {
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
} else {
|
|
869
|
+
const toolPartIndex = state.parts.findIndex(
|
|
870
|
+
(p) => p.type === "tool-call" && p.toolCallId === event.toolCallId
|
|
871
|
+
);
|
|
872
|
+
if (toolPartIndex >= 0) {
|
|
873
|
+
try {
|
|
874
|
+
const part = state.parts[toolPartIndex];
|
|
875
|
+
part.args = JSON.parse(event.inputTextDelta);
|
|
876
|
+
state.parts[toolPartIndex] = { ...part };
|
|
877
|
+
this.updateStreamingMessage();
|
|
878
|
+
} catch {
|
|
879
|
+
}
|
|
738
880
|
}
|
|
739
881
|
}
|
|
740
882
|
break;
|
|
@@ -742,45 +884,98 @@ var OctavusChat = class {
|
|
|
742
884
|
case "tool-input-end":
|
|
743
885
|
break;
|
|
744
886
|
case "tool-input-available": {
|
|
745
|
-
const
|
|
746
|
-
|
|
747
|
-
)
|
|
748
|
-
|
|
749
|
-
const
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
887
|
+
const workerId = event.workerId;
|
|
888
|
+
const workerState = workerId ? state.activeWorkers.get(workerId) : void 0;
|
|
889
|
+
if (workerState) {
|
|
890
|
+
const workerPart = state.parts[workerState.partIndex];
|
|
891
|
+
const toolPartIndex = workerPart.parts.findIndex(
|
|
892
|
+
(p) => p.type === "tool-call" && p.toolCallId === event.toolCallId
|
|
893
|
+
);
|
|
894
|
+
if (toolPartIndex >= 0) {
|
|
895
|
+
const part = workerPart.parts[toolPartIndex];
|
|
896
|
+
part.args = event.input;
|
|
897
|
+
part.status = "running";
|
|
898
|
+
workerPart.parts[toolPartIndex] = { ...part };
|
|
899
|
+
state.parts[workerState.partIndex] = { ...workerPart };
|
|
900
|
+
this.updateStreamingMessage();
|
|
901
|
+
}
|
|
902
|
+
} else {
|
|
903
|
+
const toolPartIndex = state.parts.findIndex(
|
|
904
|
+
(p) => p.type === "tool-call" && p.toolCallId === event.toolCallId
|
|
905
|
+
);
|
|
906
|
+
if (toolPartIndex >= 0) {
|
|
907
|
+
const part = state.parts[toolPartIndex];
|
|
908
|
+
part.args = event.input;
|
|
909
|
+
part.status = "running";
|
|
910
|
+
state.parts[toolPartIndex] = { ...part };
|
|
911
|
+
this.updateStreamingMessage();
|
|
912
|
+
}
|
|
754
913
|
}
|
|
755
914
|
break;
|
|
756
915
|
}
|
|
757
916
|
case "tool-output-available": {
|
|
758
|
-
const
|
|
759
|
-
|
|
760
|
-
)
|
|
761
|
-
|
|
762
|
-
const
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
917
|
+
const workerId = event.workerId;
|
|
918
|
+
const workerState = workerId ? state.activeWorkers.get(workerId) : void 0;
|
|
919
|
+
if (workerState) {
|
|
920
|
+
const workerPart = state.parts[workerState.partIndex];
|
|
921
|
+
const toolPartIndex = workerPart.parts.findIndex(
|
|
922
|
+
(p) => p.type === "tool-call" && p.toolCallId === event.toolCallId
|
|
923
|
+
);
|
|
924
|
+
if (toolPartIndex >= 0) {
|
|
925
|
+
const part = workerPart.parts[toolPartIndex];
|
|
926
|
+
part.result = event.output;
|
|
927
|
+
part.status = "done";
|
|
928
|
+
workerPart.parts[toolPartIndex] = { ...part };
|
|
929
|
+
state.parts[workerState.partIndex] = { ...workerPart };
|
|
930
|
+
this.updateStreamingMessage();
|
|
931
|
+
}
|
|
932
|
+
} else {
|
|
933
|
+
const toolPartIndex = state.parts.findIndex(
|
|
934
|
+
(p) => p.type === "tool-call" && p.toolCallId === event.toolCallId
|
|
935
|
+
);
|
|
936
|
+
if (toolPartIndex >= 0) {
|
|
937
|
+
const part = state.parts[toolPartIndex];
|
|
938
|
+
part.result = event.output;
|
|
939
|
+
part.status = "done";
|
|
940
|
+
state.parts[toolPartIndex] = { ...part };
|
|
941
|
+
this.updateStreamingMessage();
|
|
942
|
+
}
|
|
767
943
|
}
|
|
768
944
|
break;
|
|
769
945
|
}
|
|
770
946
|
case "tool-output-error": {
|
|
771
|
-
const
|
|
772
|
-
|
|
773
|
-
)
|
|
774
|
-
|
|
775
|
-
const
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
947
|
+
const workerId = event.workerId;
|
|
948
|
+
const workerState = workerId ? state.activeWorkers.get(workerId) : void 0;
|
|
949
|
+
if (workerState) {
|
|
950
|
+
const workerPart = state.parts[workerState.partIndex];
|
|
951
|
+
const toolPartIndex = workerPart.parts.findIndex(
|
|
952
|
+
(p) => p.type === "tool-call" && p.toolCallId === event.toolCallId
|
|
953
|
+
);
|
|
954
|
+
if (toolPartIndex >= 0) {
|
|
955
|
+
const part = workerPart.parts[toolPartIndex];
|
|
956
|
+
part.error = event.error;
|
|
957
|
+
part.status = "error";
|
|
958
|
+
workerPart.parts[toolPartIndex] = { ...part };
|
|
959
|
+
state.parts[workerState.partIndex] = { ...workerPart };
|
|
960
|
+
this.updateStreamingMessage();
|
|
961
|
+
}
|
|
962
|
+
} else {
|
|
963
|
+
const toolPartIndex = state.parts.findIndex(
|
|
964
|
+
(p) => p.type === "tool-call" && p.toolCallId === event.toolCallId
|
|
965
|
+
);
|
|
966
|
+
if (toolPartIndex >= 0) {
|
|
967
|
+
const part = state.parts[toolPartIndex];
|
|
968
|
+
part.error = event.error;
|
|
969
|
+
part.status = "error";
|
|
970
|
+
state.parts[toolPartIndex] = { ...part };
|
|
971
|
+
this.updateStreamingMessage();
|
|
972
|
+
}
|
|
780
973
|
}
|
|
781
974
|
break;
|
|
782
975
|
}
|
|
783
976
|
case "source": {
|
|
977
|
+
const workerId = event.workerId;
|
|
978
|
+
const workerState = workerId ? state.activeWorkers.get(workerId) : void 0;
|
|
784
979
|
const thread = threadForPart(state.activeBlock?.thread);
|
|
785
980
|
let sourcePart;
|
|
786
981
|
if (event.sourceType === "url") {
|
|
@@ -803,11 +998,19 @@ var OctavusChat = class {
|
|
|
803
998
|
thread
|
|
804
999
|
};
|
|
805
1000
|
}
|
|
806
|
-
|
|
1001
|
+
if (workerState) {
|
|
1002
|
+
const workerPart = state.parts[workerState.partIndex];
|
|
1003
|
+
workerPart.parts.push(sourcePart);
|
|
1004
|
+
state.parts[workerState.partIndex] = { ...workerPart };
|
|
1005
|
+
} else {
|
|
1006
|
+
state.parts.push(sourcePart);
|
|
1007
|
+
}
|
|
807
1008
|
this.updateStreamingMessage();
|
|
808
1009
|
break;
|
|
809
1010
|
}
|
|
810
1011
|
case "file-available": {
|
|
1012
|
+
const workerId = event.workerId;
|
|
1013
|
+
const workerState = workerId ? state.activeWorkers.get(workerId) : void 0;
|
|
811
1014
|
const filePart = {
|
|
812
1015
|
type: "file",
|
|
813
1016
|
id: event.id,
|
|
@@ -818,19 +1021,83 @@ var OctavusChat = class {
|
|
|
818
1021
|
toolCallId: event.toolCallId,
|
|
819
1022
|
thread: threadForPart(state.activeBlock?.thread)
|
|
820
1023
|
};
|
|
821
|
-
|
|
1024
|
+
if (workerState) {
|
|
1025
|
+
const workerPart = state.parts[workerState.partIndex];
|
|
1026
|
+
workerPart.parts.push(filePart);
|
|
1027
|
+
state.parts[workerState.partIndex] = { ...workerPart };
|
|
1028
|
+
} else {
|
|
1029
|
+
state.parts.push(filePart);
|
|
1030
|
+
}
|
|
822
1031
|
this.updateStreamingMessage();
|
|
823
1032
|
break;
|
|
824
1033
|
}
|
|
825
1034
|
case "resource-update":
|
|
826
1035
|
this.options.onResourceUpdate?.(event.name, event.value);
|
|
827
1036
|
break;
|
|
1037
|
+
case "worker-start": {
|
|
1038
|
+
const existingIndex = state.parts.findIndex(
|
|
1039
|
+
(p) => p.type === "worker" && p.workerId === event.workerId
|
|
1040
|
+
);
|
|
1041
|
+
let partIndex;
|
|
1042
|
+
if (existingIndex !== -1) {
|
|
1043
|
+
const existingPart = state.parts[existingIndex];
|
|
1044
|
+
existingPart.status = "running";
|
|
1045
|
+
partIndex = existingIndex;
|
|
1046
|
+
} else {
|
|
1047
|
+
const workerPart = {
|
|
1048
|
+
type: "worker",
|
|
1049
|
+
workerId: event.workerId,
|
|
1050
|
+
workerSlug: event.workerSlug,
|
|
1051
|
+
description: event.description,
|
|
1052
|
+
parts: [],
|
|
1053
|
+
status: "running"
|
|
1054
|
+
};
|
|
1055
|
+
state.parts.push(workerPart);
|
|
1056
|
+
partIndex = state.parts.length - 1;
|
|
1057
|
+
}
|
|
1058
|
+
const workerState = {
|
|
1059
|
+
partIndex,
|
|
1060
|
+
currentTextPartIndex: null,
|
|
1061
|
+
currentReasoningPartIndex: null,
|
|
1062
|
+
currentObjectPartIndex: null,
|
|
1063
|
+
accumulatedJson: ""
|
|
1064
|
+
};
|
|
1065
|
+
state.activeWorkers.set(event.workerId, workerState);
|
|
1066
|
+
this.updateStreamingMessage();
|
|
1067
|
+
break;
|
|
1068
|
+
}
|
|
1069
|
+
case "worker-result": {
|
|
1070
|
+
const workerState = state.activeWorkers.get(event.workerId);
|
|
1071
|
+
if (workerState !== void 0) {
|
|
1072
|
+
const part = state.parts[workerState.partIndex];
|
|
1073
|
+
part.output = event.output;
|
|
1074
|
+
part.error = event.error;
|
|
1075
|
+
part.status = event.error ? "error" : "done";
|
|
1076
|
+
part.parts = part.parts.map((p) => {
|
|
1077
|
+
if (p.type === "text" || p.type === "reasoning") {
|
|
1078
|
+
if (p.status === "streaming") {
|
|
1079
|
+
return { ...p, status: "done" };
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
if (p.type === "object" && p.status === "streaming") {
|
|
1083
|
+
return { ...p, status: "done" };
|
|
1084
|
+
}
|
|
1085
|
+
return p;
|
|
1086
|
+
});
|
|
1087
|
+
state.parts[workerState.partIndex] = { ...part };
|
|
1088
|
+
state.activeWorkers.delete(event.workerId);
|
|
1089
|
+
}
|
|
1090
|
+
this.updateStreamingMessage();
|
|
1091
|
+
break;
|
|
1092
|
+
}
|
|
828
1093
|
case "finish": {
|
|
829
1094
|
if (event.finishReason === "client-tool-calls") {
|
|
1095
|
+
this._finishEventReceived = true;
|
|
830
1096
|
if (this._pendingToolsByCallId.size > 0) {
|
|
831
1097
|
this.setStatus("awaiting-input");
|
|
832
1098
|
} else if (this._readyToContinue) {
|
|
833
1099
|
this._readyToContinue = false;
|
|
1100
|
+
this._finishEventReceived = false;
|
|
834
1101
|
void this.continueWithClientToolResults();
|
|
835
1102
|
}
|
|
836
1103
|
return;
|
|
@@ -987,7 +1254,9 @@ var OctavusChat = class {
|
|
|
987
1254
|
args: tc.args,
|
|
988
1255
|
source: tc.source,
|
|
989
1256
|
outputVariable: tc.outputVariable,
|
|
990
|
-
blockIndex: tc.blockIndex
|
|
1257
|
+
blockIndex: tc.blockIndex,
|
|
1258
|
+
thread: tc.thread,
|
|
1259
|
+
workerId: tc.workerId
|
|
991
1260
|
};
|
|
992
1261
|
this._pendingToolsByCallId.set(tc.toolCallId, toolState);
|
|
993
1262
|
const existing = this._pendingToolsByName.get(tc.toolName) ?? [];
|
|
@@ -1019,7 +1288,9 @@ var OctavusChat = class {
|
|
|
1019
1288
|
toolName: tc.toolName,
|
|
1020
1289
|
result,
|
|
1021
1290
|
outputVariable: tc.outputVariable,
|
|
1022
|
-
blockIndex: tc.blockIndex
|
|
1291
|
+
blockIndex: tc.blockIndex,
|
|
1292
|
+
thread: tc.thread,
|
|
1293
|
+
workerId: tc.workerId
|
|
1023
1294
|
});
|
|
1024
1295
|
this.emitToolOutputAvailable(tc.toolCallId, result);
|
|
1025
1296
|
} catch (err) {
|
|
@@ -1029,7 +1300,9 @@ var OctavusChat = class {
|
|
|
1029
1300
|
toolName: tc.toolName,
|
|
1030
1301
|
error: errorMessage,
|
|
1031
1302
|
outputVariable: tc.outputVariable,
|
|
1032
|
-
blockIndex: tc.blockIndex
|
|
1303
|
+
blockIndex: tc.blockIndex,
|
|
1304
|
+
thread: tc.thread,
|
|
1305
|
+
workerId: tc.workerId
|
|
1033
1306
|
});
|
|
1034
1307
|
this.emitToolOutputError(tc.toolCallId, errorMessage);
|
|
1035
1308
|
}
|
|
@@ -1040,13 +1313,20 @@ var OctavusChat = class {
|
|
|
1040
1313
|
toolName: tc.toolName,
|
|
1041
1314
|
error: errorMessage,
|
|
1042
1315
|
outputVariable: tc.outputVariable,
|
|
1043
|
-
blockIndex: tc.blockIndex
|
|
1316
|
+
blockIndex: tc.blockIndex,
|
|
1317
|
+
thread: tc.thread,
|
|
1318
|
+
workerId: tc.workerId
|
|
1044
1319
|
});
|
|
1045
1320
|
this.emitToolOutputError(tc.toolCallId, errorMessage);
|
|
1046
1321
|
}
|
|
1047
1322
|
}
|
|
1048
1323
|
if (this._pendingToolsByCallId.size === 0 && this._completedToolResults.length > 0) {
|
|
1049
1324
|
this._readyToContinue = true;
|
|
1325
|
+
if (this._finishEventReceived) {
|
|
1326
|
+
this._readyToContinue = false;
|
|
1327
|
+
this._finishEventReceived = false;
|
|
1328
|
+
void this.continueWithClientToolResults();
|
|
1329
|
+
}
|
|
1050
1330
|
}
|
|
1051
1331
|
}
|
|
1052
1332
|
};
|