@heungtae/codex-chat-bridge 0.1.4 → 0.1.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/Cargo.lock +1 -1
- package/Cargo.toml +1 -1
- package/package.json +1 -1
- package/src/main.rs +72 -0
package/Cargo.lock
CHANGED
package/Cargo.toml
CHANGED
package/package.json
CHANGED
package/src/main.rs
CHANGED
|
@@ -744,6 +744,40 @@ fn map_responses_to_chat_request(
|
|
|
744
744
|
}));
|
|
745
745
|
}
|
|
746
746
|
}
|
|
747
|
+
"function_call" => {
|
|
748
|
+
let name = item
|
|
749
|
+
.get("name")
|
|
750
|
+
.and_then(Value::as_str)
|
|
751
|
+
.unwrap_or_default();
|
|
752
|
+
if name.is_empty() {
|
|
753
|
+
warn!("ignoring function_call item with empty name");
|
|
754
|
+
continue;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
let call_id = item
|
|
758
|
+
.get("call_id")
|
|
759
|
+
.and_then(Value::as_str)
|
|
760
|
+
.filter(|v| !v.trim().is_empty())
|
|
761
|
+
.map(ToString::to_string)
|
|
762
|
+
.unwrap_or_else(|| format!("call_{}", Uuid::now_v7()));
|
|
763
|
+
let arguments = item
|
|
764
|
+
.get("arguments")
|
|
765
|
+
.map(function_arguments_to_text)
|
|
766
|
+
.unwrap_or_else(|| "{}".to_string());
|
|
767
|
+
|
|
768
|
+
messages.push(json!({
|
|
769
|
+
"role": "assistant",
|
|
770
|
+
"content": "",
|
|
771
|
+
"tool_calls": [{
|
|
772
|
+
"id": call_id,
|
|
773
|
+
"type": "function",
|
|
774
|
+
"function": {
|
|
775
|
+
"name": name,
|
|
776
|
+
"arguments": arguments,
|
|
777
|
+
}
|
|
778
|
+
}]
|
|
779
|
+
}));
|
|
780
|
+
}
|
|
747
781
|
"function_call_output" => {
|
|
748
782
|
let call_id = item
|
|
749
783
|
.get("call_id")
|
|
@@ -850,6 +884,13 @@ fn function_output_to_text(value: &Value) -> String {
|
|
|
850
884
|
}
|
|
851
885
|
}
|
|
852
886
|
|
|
887
|
+
fn function_arguments_to_text(value: &Value) -> String {
|
|
888
|
+
match value {
|
|
889
|
+
Value::String(s) => s.clone(),
|
|
890
|
+
other => other.to_string(),
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
|
|
853
894
|
fn normalize_chat_tools(tools: Vec<Value>, drop_tool_types: &HashSet<String>) -> Vec<Value> {
|
|
854
895
|
tools
|
|
855
896
|
.into_iter()
|
|
@@ -1077,6 +1118,37 @@ mod tests {
|
|
|
1077
1118
|
assert_eq!(messages[0]["tool_call_id"], "call_1");
|
|
1078
1119
|
}
|
|
1079
1120
|
|
|
1121
|
+
#[test]
|
|
1122
|
+
fn map_supports_function_call_to_assistant_tool_call() {
|
|
1123
|
+
let input = json!({
|
|
1124
|
+
"model": "gpt-4.1",
|
|
1125
|
+
"input": [
|
|
1126
|
+
{
|
|
1127
|
+
"type": "function_call",
|
|
1128
|
+
"call_id": "call_1",
|
|
1129
|
+
"name": "get_weather",
|
|
1130
|
+
"arguments": "{\"city\":\"seoul\"}"
|
|
1131
|
+
}
|
|
1132
|
+
],
|
|
1133
|
+
"tools": []
|
|
1134
|
+
});
|
|
1135
|
+
|
|
1136
|
+
let req = map_responses_to_chat_request(&input, &HashSet::new()).expect("should map");
|
|
1137
|
+
let messages = req
|
|
1138
|
+
.chat_request
|
|
1139
|
+
.get("messages")
|
|
1140
|
+
.and_then(Value::as_array)
|
|
1141
|
+
.expect("messages");
|
|
1142
|
+
assert_eq!(messages.len(), 1);
|
|
1143
|
+
assert_eq!(messages[0]["role"], "assistant");
|
|
1144
|
+
assert_eq!(messages[0]["tool_calls"][0]["id"], "call_1");
|
|
1145
|
+
assert_eq!(messages[0]["tool_calls"][0]["type"], "function");
|
|
1146
|
+
assert_eq!(
|
|
1147
|
+
messages[0]["tool_calls"][0]["function"]["name"],
|
|
1148
|
+
"get_weather"
|
|
1149
|
+
);
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1080
1152
|
#[test]
|
|
1081
1153
|
fn map_defaults_tool_choice_when_invalid() {
|
|
1082
1154
|
let input = json!({
|