mirror of
https://github.com/openai/codex.git
synced 2026-10-22 17:58:46 +00:00
Add local diagnostic ZIP exports to the app server (#55940)
## What changed Add a save RPC that accepts the existing report options and an absolute `savePath` on the server host. Save the report, selected attachments, and a manifest without uploading, and return `savedPath`, `threadId`, and `promptHash`. Local exports remain available when uploads are disabled by configuration. Publish archives atomically without replacing existing files. Bound uncompressed contents to 200 MiB and attachments to 128, preserve duplicate attachment names safely, and fail without publishing a partial ZIP when a selected file cannot be read. Honor `includeLogs` and omit automatic rollouts for untouched threads without materializing them. Update protocol schemas and generated TypeScript and Python types. ## Testing Add coverage for local-only saves, disabled uploads, path validation, overwrite protection, log consent, archive budgets, duplicate names, missing files, and rollout selection before materialization and after writer shutdown. GitOrigin-RevId: 222c0fe7ab923904de9c8a9f12ad27f7a0104875
This commit is contained in:
@@ -1387,6 +1387,12 @@ client_request_definitions! {
|
||||
response: v2::FeedbackUploadResponse,
|
||||
},
|
||||
|
||||
FeedbackSave => "feedback/save" {
|
||||
params: v2::FeedbackSaveParams,
|
||||
serialization: None,
|
||||
response: v2::FeedbackSaveResponse,
|
||||
},
|
||||
|
||||
/// Execute a standalone command (argv vector) under the server's sandbox.
|
||||
OneOffCommandExec => "command/exec" {
|
||||
params: v2::CommandExecParams,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use crate::JsonSchema;
|
||||
use crate::TS;
|
||||
use codex_utils_path_uri::LegacyAppPathString;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use std::collections::BTreeMap;
|
||||
@@ -33,3 +34,24 @@ pub struct FeedbackUploadResponse {
|
||||
#[serde(default)]
|
||||
pub prompt_hash: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct FeedbackSaveParams {
|
||||
#[serde(flatten)]
|
||||
pub feedback: FeedbackUploadParams,
|
||||
/// Absolute, previously unused ZIP path on the app-server host.
|
||||
/// The caller owns this file, including after a disconnected RPC.
|
||||
pub save_path: LegacyAppPathString,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct FeedbackSaveResponse {
|
||||
pub saved_path: LegacyAppPathString,
|
||||
pub thread_id: String,
|
||||
/// Same prompt hash as feedback/upload; null when prompt metadata is absent.
|
||||
pub prompt_hash: Option<String>,
|
||||
}
|
||||
|
||||
@@ -5453,3 +5453,32 @@ fn tool_request_user_input_params_default_legacy_missing_is_blocking_to_true() {
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/// Native path spelling survives serialization so the receiving host can validate it.
|
||||
#[test]
|
||||
fn feedback_paths_preserve_native_wire_spelling_before_host_validation() {
|
||||
for path in [
|
||||
"/tmp/feedback.zip",
|
||||
r"C:\Users\test\feedback.zip",
|
||||
r"\\server\share\feedback.zip",
|
||||
"relative.zip",
|
||||
] {
|
||||
let request: FeedbackSaveParams = serde_json::from_value(json!({
|
||||
"classification": "bug", "savePath": path
|
||||
}))
|
||||
.expect("wire paths remain uninterpreted");
|
||||
assert_eq!(request.save_path.as_str(), path);
|
||||
assert_eq!(
|
||||
serde_json::to_value(&request).expect("serialize request")["savePath"],
|
||||
path
|
||||
);
|
||||
let response: FeedbackSaveResponse = serde_json::from_value(json!({
|
||||
"threadId": "synthetic", "savedPath": path, "promptHash": null
|
||||
}))
|
||||
.expect("wire response");
|
||||
assert_eq!(
|
||||
serde_json::to_value(response).expect("serialize response")["savedPath"],
|
||||
path
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user