mirror of
https://github.com/openai/codex.git
synced 2026-11-06 20:20:34 +00:00
Move context prefixing and request extraction into `user_prompt`, and update IDE context injection, thread routing, thread titles, transcript export, and user message rendering to use the shared helpers. Preserve the request delimiter, text element byte offsets, and input ordering. Move the existing last-delimiter extraction test alongside the shared helpers. GitOrigin-RevId: 3ee350506a536a6dba9575e8311188bc92fed584
117 lines
3.2 KiB
Rust
117 lines
3.2 KiB
Rust
//! IDE context data model and public helpers for TUI `/ide` support.
|
|
|
|
mod ipc;
|
|
mod prompt;
|
|
#[cfg(windows)]
|
|
mod windows_pipe;
|
|
|
|
pub(crate) use ipc::fetch_ide_context;
|
|
pub(crate) use prompt::apply_ide_context_to_user_input;
|
|
pub(crate) use prompt::has_prompt_context;
|
|
|
|
use serde::Deserialize;
|
|
|
|
#[derive(Debug, Clone, Deserialize, PartialEq)]
|
|
#[serde(rename_all = "camelCase")]
|
|
pub(crate) struct IdeContext {
|
|
active_file: Option<ActiveFile>,
|
|
#[serde(default)]
|
|
open_tabs: Vec<FileDescriptor>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Deserialize, PartialEq)]
|
|
#[serde(rename_all = "camelCase")]
|
|
struct ActiveFile {
|
|
#[serde(flatten)]
|
|
descriptor: FileDescriptor,
|
|
selection: Range,
|
|
#[serde(default)]
|
|
active_selection_content: String,
|
|
#[serde(default)]
|
|
selections: Vec<Range>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Deserialize, PartialEq)]
|
|
#[serde(rename_all = "camelCase")]
|
|
struct FileDescriptor {
|
|
label: String,
|
|
path: String,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Deserialize, PartialEq)]
|
|
struct Range {
|
|
start: Position,
|
|
end: Position,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Deserialize, PartialEq)]
|
|
struct Position {
|
|
line: u32,
|
|
character: u32,
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use pretty_assertions::assert_eq;
|
|
use serde_json::json;
|
|
|
|
#[test]
|
|
fn deserializes_existing_ide_context_shape() {
|
|
let value = json!({
|
|
"activeFile": {
|
|
"label": "lib.rs",
|
|
"path": "src/lib.rs",
|
|
"fsPath": "/repo/src/lib.rs",
|
|
"selection": {
|
|
"start": { "line": 1, "character": 2 },
|
|
"end": { "line": 3, "character": 4 }
|
|
},
|
|
"activeSelectionContent": "selected",
|
|
"selections": []
|
|
},
|
|
"openTabs": [
|
|
{
|
|
"label": "main.rs",
|
|
"path": "src/main.rs",
|
|
"fsPath": "/repo/src/main.rs",
|
|
"startLine": 2,
|
|
"endLine": 10
|
|
}
|
|
],
|
|
"processEnv": {
|
|
"path": "/usr/bin"
|
|
}
|
|
});
|
|
|
|
let context: IdeContext = serde_json::from_value(value).expect("deserialize ide context");
|
|
assert_eq!(
|
|
context,
|
|
IdeContext {
|
|
active_file: Some(ActiveFile {
|
|
descriptor: FileDescriptor {
|
|
label: "lib.rs".to_string(),
|
|
path: "src/lib.rs".to_string(),
|
|
},
|
|
selection: Range {
|
|
start: Position {
|
|
line: 1,
|
|
character: 2,
|
|
},
|
|
end: Position {
|
|
line: 3,
|
|
character: 4,
|
|
},
|
|
},
|
|
active_selection_content: "selected".to_string(),
|
|
selections: Vec::new(),
|
|
}),
|
|
open_tabs: vec![FileDescriptor {
|
|
label: "main.rs".to_string(),
|
|
path: "src/main.rs".to_string(),
|
|
}],
|
|
}
|
|
);
|
|
}
|
|
}
|