mirror of
https://github.com/openai/codex.git
synced 2026-04-28 18:32:04 +03:00
131 lines
4.4 KiB
Markdown
131 lines
4.4 KiB
Markdown
**DOs**
|
||
- **Keep PRs Focused**: Limit changes to moving `models.rs` and the required import updates; defer unrelated protocol/API additions to a separate PR.
|
||
```rust
|
||
// Good: only path + import updates
|
||
|
||
// core/src/lib.rs
|
||
- mod models;
|
||
+ // models moved to protocol
|
||
|
||
// any module using models
|
||
- use crate::models::ResponseItem;
|
||
+ use codex_protocol::models::ResponseItem;
|
||
```
|
||
|
||
- **Update Imports Consistently**: Replace `crate::models::*` with `codex_protocol::models::*` across the codebase.
|
||
```rust
|
||
- use crate::models::{ContentItem, ResponseItem, ReasoningItemContent};
|
||
+ use codex_protocol::models::{ContentItem, ResponseItem, ReasoningItemContent};
|
||
```
|
||
|
||
- **Use Fully Qualified Paths In Matches When Helpful**: Avoid ambiguity after the move, especially in pattern matches.
|
||
```rust
|
||
let is_assistant_delta = matches!(
|
||
&item,
|
||
codex_protocol::models::ResponseItem::Message { role, .. } if role == "assistant"
|
||
);
|
||
```
|
||
|
||
- **Justify Protocol Dependencies**: Add deps (e.g., `base64`, `mime_guess`, `tracing`) to `protocol` only if `models.rs` truly needs them for serialization or type helpers; note why in the PR.
|
||
```toml
|
||
# codex-rs/protocol/Cargo.toml
|
||
[dependencies]
|
||
base64 = "0.22.1" # encoding attachments in models
|
||
mime_guess = "2.0.5" # inferring content-types for file items
|
||
tracing = "0.1.41" # protocol-level diagnostics (if unavoidable)
|
||
```
|
||
```rust
|
||
// Example: encoding a payload inside protocol models
|
||
let encoded = base64::encode(&bytes);
|
||
```
|
||
|
||
- **Preserve Behavior While Relocating**: Moves should not change runtime logic or filtering; keep conversions and aggregations identical.
|
||
```rust
|
||
// Keep existing content mapping behavior intact when moving code.
|
||
content: items
|
||
.iter()
|
||
.filter_map(|i| match i {
|
||
InputItem::Text { text } => Some(ContentItem::InputText { text: text.clone() }),
|
||
// keep prior arms and catch-alls as-is to avoid behavior drift
|
||
_ => None,
|
||
})
|
||
.collect(),
|
||
```
|
||
|
||
- **Validate With Targeted Tests First**: Run protocol and core tests after changes; then run the full suite if common types changed.
|
||
```bash
|
||
# Format + lint (from codex-rs/)
|
||
just fmt
|
||
just fix -p codex-protocol
|
||
cargo test -p codex-protocol
|
||
cargo test -p codex-core
|
||
cargo test --all-features
|
||
```
|
||
|
||
- **Be Explicit When Constructing Moved Types**: Build items using the new module path to make intent obvious.
|
||
```rust
|
||
let aggregated = codex_protocol::models::ResponseItem::Message {
|
||
id: None,
|
||
role: "assistant".to_string(),
|
||
content: vec![codex_protocol::models::ContentItem::OutputText {
|
||
text: buffer,
|
||
}],
|
||
};
|
||
```
|
||
|
||
**DON’Ts**
|
||
- **Don’t Introduce Unrelated Protocol Ops/Events**: Avoid adding new variants like `Op::GetHistory` or `EventMsg::ConversationHistory` in a “move-only” PR.
|
||
```rust
|
||
// Bad: out-of-scope for a file move
|
||
pub enum Op {
|
||
Compact,
|
||
Shutdown,
|
||
GetHistory, // <-- why in this PR?
|
||
}
|
||
|
||
pub enum EventMsg {
|
||
ShutdownComplete,
|
||
ConversationHistory(ConversationHistoryEvent), // <-- unrelated addition
|
||
}
|
||
```
|
||
|
||
- **Don’t Add New API Variants Without Rationale**: Adding `ResponseItem::CustomToolCall` expands the wire protocol—separate PR with justification and downstream updates.
|
||
```rust
|
||
// Bad: new wire variant slipped into a refactor
|
||
pub enum ResponseItem {
|
||
Message { /* ... */ },
|
||
ToolCall { /* ... */ },
|
||
FunctionCallOutput { /* ... */ },
|
||
CustomToolCall { /* ... */ }, // <-- why now?
|
||
}
|
||
```
|
||
|
||
- **Don’t Expand Protocol Responsibilities Needlessly**: Keep business logic out of `protocol`; it should define types and minimal helpers only.
|
||
```rust
|
||
// Bad: complex aggregation/business logic in protocol
|
||
impl ResponseItem {
|
||
pub fn aggregate_streaming_reasoning(...) -> Self { /* non-protocol logic */ }
|
||
}
|
||
```
|
||
|
||
- **Don’t Create Dependency Drag**: If a helper can live in `core`, don’t add a dependency to `protocol` just to support it.
|
||
```toml
|
||
# Bad: protocol now depends on a heavy crate used only by core features
|
||
some-heavy-crate = "1"
|
||
```
|
||
|
||
- **Don’t Change Formatting/Behavior While Moving**: Avoid incidental logic edits (e.g., removing a match arm) that alter filtering or emitted items.
|
||
```rust
|
||
// Bad: removing a catch-all subtly changes behavior
|
||
- _ => None,
|
||
+ // (removed) now non-matching items are silently dropped differently
|
||
```
|
||
|
||
- **Don’t Leave Type Names Ambiguous**: After the move, don’t rely on old paths or shadowed names.
|
||
```rust
|
||
// Bad
|
||
use crate::models::*; // no longer valid, confusing after the move
|
||
|
||
// Good
|
||
use codex_protocol::models::{ResponseItem, ContentItem};
|
||
``` |