fix(llm-worker): openai_responsesのroleの最新の投影を反映
This commit is contained in:
parent
d18de45293
commit
31d9b9b2b7
|
|
@ -68,7 +68,11 @@ pub(crate) struct ReasoningConfig {
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
#[serde(tag = "type", rename_all = "snake_case")]
|
#[serde(tag = "type", rename_all = "snake_case")]
|
||||||
pub(crate) enum InputItem {
|
pub(crate) enum InputItem {
|
||||||
/// 会話メッセージ。user / assistant / system のいずれか。
|
/// 会話メッセージ。user / assistant / developer のいずれか。
|
||||||
|
/// `Role::System` items は `developer` として投影する(ChatGPT
|
||||||
|
/// backend が `role: "system"` を拒否するため。Codex CLI も
|
||||||
|
/// system 相当の挿入には DeveloperInstructions = `role: "developer"`
|
||||||
|
/// を使う)。
|
||||||
Message {
|
Message {
|
||||||
role: &'static str,
|
role: &'static str,
|
||||||
content: Vec<InputContent>,
|
content: Vec<InputContent>,
|
||||||
|
|
@ -104,7 +108,7 @@ pub(crate) enum InputItem {
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
#[serde(tag = "type", rename_all = "snake_case")]
|
#[serde(tag = "type", rename_all = "snake_case")]
|
||||||
pub(crate) enum InputContent {
|
pub(crate) enum InputContent {
|
||||||
/// user / system 側のテキスト
|
/// user / developer 側のテキスト
|
||||||
InputText { text: String },
|
InputText { text: String },
|
||||||
/// assistant 側のテキスト
|
/// assistant 側のテキスト
|
||||||
OutputText { text: String },
|
OutputText { text: String },
|
||||||
|
|
@ -230,7 +234,7 @@ fn convert_items_to_input(items: &[Item]) -> Vec<InputItem> {
|
||||||
match role {
|
match role {
|
||||||
Role::User => ("user", |t| InputContent::InputText { text: t }),
|
Role::User => ("user", |t| InputContent::InputText { text: t }),
|
||||||
Role::Assistant => ("assistant", |t| InputContent::OutputText { text: t }),
|
Role::Assistant => ("assistant", |t| InputContent::OutputText { text: t }),
|
||||||
Role::System => ("system", |t| InputContent::InputText { text: t }),
|
Role::System => ("developer", |t| InputContent::InputText { text: t }),
|
||||||
};
|
};
|
||||||
let parts: Vec<InputContent> = content
|
let parts: Vec<InputContent> = content
|
||||||
.iter()
|
.iter()
|
||||||
|
|
@ -387,6 +391,28 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn system_role_item_is_projected_as_developer() {
|
||||||
|
// ChatGPT backend (codex-oauth) は input[] の `role: "system"` を
|
||||||
|
// "System messages are not allowed" で 400 拒否する。in-conversation
|
||||||
|
// な system note (notify / fs_view auto-read / compaction summary) は
|
||||||
|
// `role: "developer"` として投影し、両 backend で受理されるようにする。
|
||||||
|
let scheme = OpenAIResponsesScheme::new();
|
||||||
|
let req = Request::new()
|
||||||
|
.user("hi")
|
||||||
|
.item(Item::system_message("[notify] hello"));
|
||||||
|
let body = scheme.build_request("gpt-5", &req, &cap_with_reasoning());
|
||||||
|
match &body.input[1] {
|
||||||
|
InputItem::Message { role, content } => {
|
||||||
|
assert_eq!(*role, "developer");
|
||||||
|
assert!(
|
||||||
|
matches!(&content[0], InputContent::InputText { text } if text == "[notify] hello"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => panic!("expected message"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn assistant_message_uses_output_text() {
|
fn assistant_message_uses_output_text() {
|
||||||
let scheme = OpenAIResponsesScheme::new();
|
let scheme = OpenAIResponsesScheme::new();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user