ai-protocol-adapters 1.0.0-alpha.4 → 1.0.0-alpha.5
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.mts +9 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +72 -18
- package/dist/index.mjs +72 -18
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -61,9 +61,17 @@ declare class StreamingProtocolAdapter {
|
|
|
61
61
|
*/
|
|
62
62
|
private processStreamChunk;
|
|
63
63
|
/**
|
|
64
|
-
* 处理工具调用
|
|
64
|
+
* 处理工具调用 - 支持OpenAI流式分块累积
|
|
65
|
+
* OpenAI流式API会将tool_calls分多个chunk发送:
|
|
66
|
+
* - Chunk 1: {index:0, id:"call_xxx", type:"function", function:{name:"web_search"}}
|
|
67
|
+
* - Chunk 2: {index:0, function:{arguments:"{\"query\":\"xxx\"}"}}
|
|
68
|
+
* - Chunk N: 继续累积arguments
|
|
65
69
|
*/
|
|
66
70
|
private processToolCalls;
|
|
71
|
+
/**
|
|
72
|
+
* 在流结束时关闭所有未关闭的工具调用块
|
|
73
|
+
*/
|
|
74
|
+
private closeAllToolCallBlocks;
|
|
67
75
|
/**
|
|
68
76
|
* 添加最终事件 - 支持thinking+content双模式
|
|
69
77
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -61,9 +61,17 @@ declare class StreamingProtocolAdapter {
|
|
|
61
61
|
*/
|
|
62
62
|
private processStreamChunk;
|
|
63
63
|
/**
|
|
64
|
-
* 处理工具调用
|
|
64
|
+
* 处理工具调用 - 支持OpenAI流式分块累积
|
|
65
|
+
* OpenAI流式API会将tool_calls分多个chunk发送:
|
|
66
|
+
* - Chunk 1: {index:0, id:"call_xxx", type:"function", function:{name:"web_search"}}
|
|
67
|
+
* - Chunk 2: {index:0, function:{arguments:"{\"query\":\"xxx\"}"}}
|
|
68
|
+
* - Chunk N: 继续累积arguments
|
|
65
69
|
*/
|
|
66
70
|
private processToolCalls;
|
|
71
|
+
/**
|
|
72
|
+
* 在流结束时关闭所有未关闭的工具调用块
|
|
73
|
+
*/
|
|
74
|
+
private closeAllToolCallBlocks;
|
|
67
75
|
/**
|
|
68
76
|
* 添加最终事件 - 支持thinking+content双模式
|
|
69
77
|
*/
|
package/dist/index.js
CHANGED
|
@@ -626,6 +626,14 @@ var StreamingProtocolAdapter = class {
|
|
|
626
626
|
*/
|
|
627
627
|
processStreamChunk(chunk, state, sseLines) {
|
|
628
628
|
const choice = chunk.choices?.[0];
|
|
629
|
+
if (choice) {
|
|
630
|
+
const hasToolCalls = choice.delta?.tool_calls;
|
|
631
|
+
const hasFinishReason = choice.finish_reason;
|
|
632
|
+
const isNonText = !choice.delta?.content;
|
|
633
|
+
if (hasToolCalls || hasFinishReason || isNonText && choice.delta) {
|
|
634
|
+
console.log("\u{1F50D}\u{1F50D}\u{1F50D} [StreamingProtocolAdapter] CHUNK:", JSON.stringify(chunk, null, 2));
|
|
635
|
+
}
|
|
636
|
+
}
|
|
629
637
|
if (!choice) return;
|
|
630
638
|
const delta = choice.delta;
|
|
631
639
|
if (delta.reasoning_content) {
|
|
@@ -683,37 +691,82 @@ var StreamingProtocolAdapter = class {
|
|
|
683
691
|
}
|
|
684
692
|
}
|
|
685
693
|
/**
|
|
686
|
-
* 处理工具调用
|
|
694
|
+
* 处理工具调用 - 支持OpenAI流式分块累积
|
|
695
|
+
* OpenAI流式API会将tool_calls分多个chunk发送:
|
|
696
|
+
* - Chunk 1: {index:0, id:"call_xxx", type:"function", function:{name:"web_search"}}
|
|
697
|
+
* - Chunk 2: {index:0, function:{arguments:"{\"query\":\"xxx\"}"}}
|
|
698
|
+
* - Chunk N: 继续累积arguments
|
|
687
699
|
*/
|
|
688
700
|
processToolCalls(toolCalls, state, sseLines) {
|
|
701
|
+
console.log("\u{1F50D} [StreamingProtocolAdapter] processToolCalls called:", JSON.stringify(toolCalls, null, 2));
|
|
689
702
|
for (const toolCall of toolCalls) {
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
703
|
+
const index = toolCall.index ?? 0;
|
|
704
|
+
const toolId = toolCall.id;
|
|
705
|
+
const toolName = toolCall.function?.name;
|
|
706
|
+
const toolArgs = toolCall.function?.arguments;
|
|
707
|
+
console.log(`\u{1F50D} [StreamingProtocolAdapter] Processing chunk for index ${index}:`, {
|
|
708
|
+
hasId: !!toolId,
|
|
709
|
+
hasName: !!toolName,
|
|
710
|
+
hasArgs: !!toolArgs,
|
|
711
|
+
argsLength: toolArgs?.length
|
|
712
|
+
});
|
|
713
|
+
const stateKey = `tool_${index}`;
|
|
714
|
+
let toolData = state.toolCallsMap.get(stateKey);
|
|
715
|
+
if (!toolData) {
|
|
716
|
+
toolData = {
|
|
717
|
+
id: toolId || "",
|
|
718
|
+
name: toolName || "",
|
|
719
|
+
input: "",
|
|
720
|
+
blockStartSent: false,
|
|
721
|
+
blockStopSent: false
|
|
696
722
|
};
|
|
697
|
-
state.toolCallsMap.set(
|
|
723
|
+
state.toolCallsMap.set(stateKey, toolData);
|
|
724
|
+
} else {
|
|
725
|
+
if (toolId) toolData.id = toolId;
|
|
726
|
+
if (toolName) toolData.name = toolName;
|
|
727
|
+
}
|
|
728
|
+
if (toolArgs) {
|
|
729
|
+
toolData.input += toolArgs;
|
|
730
|
+
console.log(`\u{1F50D} [StreamingProtocolAdapter] Accumulated arguments for index ${index}:`, {
|
|
731
|
+
currentLength: toolData.input.length,
|
|
732
|
+
totalArgs: toolData.input
|
|
733
|
+
});
|
|
734
|
+
}
|
|
735
|
+
if (toolData.id && toolData.name && !toolData.blockStartSent) {
|
|
698
736
|
const blockIndex = state.completedToolCalls.length + 1;
|
|
737
|
+
toolData.blockIndex = blockIndex;
|
|
699
738
|
sseLines.push(
|
|
700
739
|
"event: content_block_start",
|
|
701
|
-
`data: {"type":"content_block_start","index":${blockIndex},"content_block":{"type":"tool_use","id":"${
|
|
740
|
+
`data: {"type":"content_block_start","index":${blockIndex},"content_block":{"type":"tool_use","id":"${toolData.id}","name":"${toolData.name}","input":{}}}`,
|
|
702
741
|
""
|
|
703
742
|
);
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
743
|
+
toolData.blockStartSent = true;
|
|
744
|
+
console.log(`\u2705 [StreamingProtocolAdapter] Sent content_block_start for ${toolData.name} at index ${blockIndex}`);
|
|
745
|
+
}
|
|
746
|
+
if (toolArgs && toolData.blockStartSent && toolData.blockIndex !== void 0) {
|
|
747
|
+
sseLines.push(
|
|
748
|
+
"event: content_block_delta",
|
|
749
|
+
`data: {"type":"content_block_delta","index":${toolData.blockIndex},"delta":{"type":"input_json_delta","partial_json":${JSON.stringify(toolArgs)}}}`,
|
|
750
|
+
""
|
|
751
|
+
);
|
|
752
|
+
console.log(`\u2705 [StreamingProtocolAdapter] Sent input_json_delta for index ${toolData.blockIndex}`);
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
/**
|
|
757
|
+
* 在流结束时关闭所有未关闭的工具调用块
|
|
758
|
+
*/
|
|
759
|
+
closeAllToolCallBlocks(state, sseLines) {
|
|
760
|
+
for (const [key, toolData] of state.toolCallsMap.entries()) {
|
|
761
|
+
if (toolData.blockStartSent && !toolData.blockStopSent && toolData.blockIndex !== void 0) {
|
|
711
762
|
sseLines.push(
|
|
712
763
|
"event: content_block_stop",
|
|
713
|
-
`data: {"type":"content_block_stop","index":${blockIndex}}`,
|
|
764
|
+
`data: {"type":"content_block_stop","index":${toolData.blockIndex}}`,
|
|
714
765
|
""
|
|
715
766
|
);
|
|
716
|
-
|
|
767
|
+
toolData.blockStopSent = true;
|
|
768
|
+
state.completedToolCalls.push(toolData.id);
|
|
769
|
+
console.log(`\u2705 [StreamingProtocolAdapter] Sent content_block_stop for ${toolData.name} at index ${toolData.blockIndex}`);
|
|
717
770
|
}
|
|
718
771
|
}
|
|
719
772
|
}
|
|
@@ -721,6 +774,7 @@ var StreamingProtocolAdapter = class {
|
|
|
721
774
|
* 添加最终事件 - 支持thinking+content双模式
|
|
722
775
|
*/
|
|
723
776
|
addFinalEvents(state, sseLines) {
|
|
777
|
+
this.closeAllToolCallBlocks(state, sseLines);
|
|
724
778
|
if (state.contentBlockStarted) {
|
|
725
779
|
const blockIndex = state.thinkingBlockStarted ? 1 : 0;
|
|
726
780
|
sseLines.push(
|
package/dist/index.mjs
CHANGED
|
@@ -519,6 +519,14 @@ var StreamingProtocolAdapter = class {
|
|
|
519
519
|
*/
|
|
520
520
|
processStreamChunk(chunk, state, sseLines) {
|
|
521
521
|
const choice = chunk.choices?.[0];
|
|
522
|
+
if (choice) {
|
|
523
|
+
const hasToolCalls = choice.delta?.tool_calls;
|
|
524
|
+
const hasFinishReason = choice.finish_reason;
|
|
525
|
+
const isNonText = !choice.delta?.content;
|
|
526
|
+
if (hasToolCalls || hasFinishReason || isNonText && choice.delta) {
|
|
527
|
+
console.log("\u{1F50D}\u{1F50D}\u{1F50D} [StreamingProtocolAdapter] CHUNK:", JSON.stringify(chunk, null, 2));
|
|
528
|
+
}
|
|
529
|
+
}
|
|
522
530
|
if (!choice) return;
|
|
523
531
|
const delta = choice.delta;
|
|
524
532
|
if (delta.reasoning_content) {
|
|
@@ -576,37 +584,82 @@ var StreamingProtocolAdapter = class {
|
|
|
576
584
|
}
|
|
577
585
|
}
|
|
578
586
|
/**
|
|
579
|
-
* 处理工具调用
|
|
587
|
+
* 处理工具调用 - 支持OpenAI流式分块累积
|
|
588
|
+
* OpenAI流式API会将tool_calls分多个chunk发送:
|
|
589
|
+
* - Chunk 1: {index:0, id:"call_xxx", type:"function", function:{name:"web_search"}}
|
|
590
|
+
* - Chunk 2: {index:0, function:{arguments:"{\"query\":\"xxx\"}"}}
|
|
591
|
+
* - Chunk N: 继续累积arguments
|
|
580
592
|
*/
|
|
581
593
|
processToolCalls(toolCalls, state, sseLines) {
|
|
594
|
+
console.log("\u{1F50D} [StreamingProtocolAdapter] processToolCalls called:", JSON.stringify(toolCalls, null, 2));
|
|
582
595
|
for (const toolCall of toolCalls) {
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
596
|
+
const index = toolCall.index ?? 0;
|
|
597
|
+
const toolId = toolCall.id;
|
|
598
|
+
const toolName = toolCall.function?.name;
|
|
599
|
+
const toolArgs = toolCall.function?.arguments;
|
|
600
|
+
console.log(`\u{1F50D} [StreamingProtocolAdapter] Processing chunk for index ${index}:`, {
|
|
601
|
+
hasId: !!toolId,
|
|
602
|
+
hasName: !!toolName,
|
|
603
|
+
hasArgs: !!toolArgs,
|
|
604
|
+
argsLength: toolArgs?.length
|
|
605
|
+
});
|
|
606
|
+
const stateKey = `tool_${index}`;
|
|
607
|
+
let toolData = state.toolCallsMap.get(stateKey);
|
|
608
|
+
if (!toolData) {
|
|
609
|
+
toolData = {
|
|
610
|
+
id: toolId || "",
|
|
611
|
+
name: toolName || "",
|
|
612
|
+
input: "",
|
|
613
|
+
blockStartSent: false,
|
|
614
|
+
blockStopSent: false
|
|
589
615
|
};
|
|
590
|
-
state.toolCallsMap.set(
|
|
616
|
+
state.toolCallsMap.set(stateKey, toolData);
|
|
617
|
+
} else {
|
|
618
|
+
if (toolId) toolData.id = toolId;
|
|
619
|
+
if (toolName) toolData.name = toolName;
|
|
620
|
+
}
|
|
621
|
+
if (toolArgs) {
|
|
622
|
+
toolData.input += toolArgs;
|
|
623
|
+
console.log(`\u{1F50D} [StreamingProtocolAdapter] Accumulated arguments for index ${index}:`, {
|
|
624
|
+
currentLength: toolData.input.length,
|
|
625
|
+
totalArgs: toolData.input
|
|
626
|
+
});
|
|
627
|
+
}
|
|
628
|
+
if (toolData.id && toolData.name && !toolData.blockStartSent) {
|
|
591
629
|
const blockIndex = state.completedToolCalls.length + 1;
|
|
630
|
+
toolData.blockIndex = blockIndex;
|
|
592
631
|
sseLines.push(
|
|
593
632
|
"event: content_block_start",
|
|
594
|
-
`data: {"type":"content_block_start","index":${blockIndex},"content_block":{"type":"tool_use","id":"${
|
|
633
|
+
`data: {"type":"content_block_start","index":${blockIndex},"content_block":{"type":"tool_use","id":"${toolData.id}","name":"${toolData.name}","input":{}}}`,
|
|
595
634
|
""
|
|
596
635
|
);
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
636
|
+
toolData.blockStartSent = true;
|
|
637
|
+
console.log(`\u2705 [StreamingProtocolAdapter] Sent content_block_start for ${toolData.name} at index ${blockIndex}`);
|
|
638
|
+
}
|
|
639
|
+
if (toolArgs && toolData.blockStartSent && toolData.blockIndex !== void 0) {
|
|
640
|
+
sseLines.push(
|
|
641
|
+
"event: content_block_delta",
|
|
642
|
+
`data: {"type":"content_block_delta","index":${toolData.blockIndex},"delta":{"type":"input_json_delta","partial_json":${JSON.stringify(toolArgs)}}}`,
|
|
643
|
+
""
|
|
644
|
+
);
|
|
645
|
+
console.log(`\u2705 [StreamingProtocolAdapter] Sent input_json_delta for index ${toolData.blockIndex}`);
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
/**
|
|
650
|
+
* 在流结束时关闭所有未关闭的工具调用块
|
|
651
|
+
*/
|
|
652
|
+
closeAllToolCallBlocks(state, sseLines) {
|
|
653
|
+
for (const [key, toolData] of state.toolCallsMap.entries()) {
|
|
654
|
+
if (toolData.blockStartSent && !toolData.blockStopSent && toolData.blockIndex !== void 0) {
|
|
604
655
|
sseLines.push(
|
|
605
656
|
"event: content_block_stop",
|
|
606
|
-
`data: {"type":"content_block_stop","index":${blockIndex}}`,
|
|
657
|
+
`data: {"type":"content_block_stop","index":${toolData.blockIndex}}`,
|
|
607
658
|
""
|
|
608
659
|
);
|
|
609
|
-
|
|
660
|
+
toolData.blockStopSent = true;
|
|
661
|
+
state.completedToolCalls.push(toolData.id);
|
|
662
|
+
console.log(`\u2705 [StreamingProtocolAdapter] Sent content_block_stop for ${toolData.name} at index ${toolData.blockIndex}`);
|
|
610
663
|
}
|
|
611
664
|
}
|
|
612
665
|
}
|
|
@@ -614,6 +667,7 @@ var StreamingProtocolAdapter = class {
|
|
|
614
667
|
* 添加最终事件 - 支持thinking+content双模式
|
|
615
668
|
*/
|
|
616
669
|
addFinalEvents(state, sseLines) {
|
|
670
|
+
this.closeAllToolCallBlocks(state, sseLines);
|
|
617
671
|
if (state.contentBlockStarted) {
|
|
618
672
|
const blockIndex = state.thinkingBlockStarted ? 1 : 0;
|
|
619
673
|
sseLines.push(
|
package/package.json
CHANGED