feat(hooks): add explicit remote hook routing

This commit is contained in:
starr-openai
2026-05-28 20:52:24 -07:00
parent 42c80385cd
commit d156f53111
37 changed files with 719 additions and 116 deletions
+12 -4
View File
@@ -361,13 +361,15 @@ impl ExecServerClient {
pub async fn write(
&self,
process_id: &ProcessId,
chunk: Vec<u8>,
chunk: Option<Vec<u8>>,
close_stdin: bool,
) -> Result<WriteResponse, ExecServerError> {
self.call(
EXEC_WRITE_METHOD,
&WriteParams {
process_id: process_id.clone(),
chunk: chunk.into(),
chunk: chunk.map(Into::into),
close_stdin,
},
)
.await
@@ -720,8 +722,14 @@ impl Session {
}
}
pub(crate) async fn write(&self, chunk: Vec<u8>) -> Result<WriteResponse, ExecServerError> {
self.client.write(&self.process_id, chunk).await
pub(crate) async fn write(
&self,
chunk: Option<Vec<u8>>,
close_stdin: bool,
) -> Result<WriteResponse, ExecServerError> {
self.client
.write(&self.process_id, chunk, close_stdin)
.await
}
pub(crate) async fn terminate(&self) -> Result<(), ExecServerError> {
+37 -10
View File
@@ -352,7 +352,11 @@ impl LocalProcess {
params: WriteParams,
) -> Result<WriteResponse, JSONRPCErrorError> {
let _process_id = params.process_id.clone();
let _input_bytes = params.chunk.0.len();
if params.chunk.is_none() && !params.close_stdin {
return Err(invalid_params(
"process/write requires chunk, closeStdin, or both".to_string(),
));
}
let writer_tx = {
let process_map = self.inner.processes.lock().await;
let Some(process) = process_map.get(&params.process_id) else {
@@ -370,13 +374,28 @@ impl LocalProcess {
status: WriteStatus::StdinClosed,
});
}
process.session.writer_sender()
params
.chunk
.as_ref()
.map(|_| process.session.writer_sender())
};
writer_tx
.send(params.chunk.into_inner())
.await
.map_err(|_| internal_error("failed to write to process stdin".to_string()))?;
if let Some(chunk) = params.chunk {
writer_tx
.ok_or_else(|| internal_error("missing process stdin writer".to_string()))?
.send(chunk.into_inner())
.await
.map_err(|_| internal_error("failed to write to process stdin".to_string()))?;
}
if params.close_stdin {
let process_map = self.inner.processes.lock().await;
let Some(ProcessEntry::Running(process)) = process_map.get(&params.process_id) else {
return Ok(WriteResponse {
status: WriteStatus::UnknownProcess,
});
};
process.session.close_stdin();
}
Ok(WriteResponse {
status: WriteStatus::Accepted,
@@ -479,8 +498,14 @@ impl ExecProcess for LocalExecProcess {
.await
}
async fn write(&self, chunk: Vec<u8>) -> Result<WriteResponse, ExecServerError> {
self.backend.write(&self.process_id, chunk).await
async fn write(
&self,
chunk: Option<Vec<u8>>,
close_stdin: bool,
) -> Result<WriteResponse, ExecServerError> {
self.backend
.write(&self.process_id, chunk, close_stdin)
.await
}
async fn terminate(&self) -> Result<(), ExecServerError> {
@@ -509,11 +534,13 @@ impl LocalProcess {
async fn write(
&self,
process_id: &ProcessId,
chunk: Vec<u8>,
chunk: Option<Vec<u8>>,
close_stdin: bool,
) -> Result<WriteResponse, ExecServerError> {
self.exec_write(WriteParams {
process_id: process_id.clone(),
chunk: chunk.into(),
chunk: chunk.map(Into::into),
close_stdin,
})
.await
.map_err(map_handler_error)
+5 -1
View File
@@ -176,7 +176,11 @@ pub trait ExecProcess: Send + Sync {
wait_ms: Option<u64>,
) -> Result<ReadResponse, ExecServerError>;
async fn write(&self, chunk: Vec<u8>) -> Result<WriteResponse, ExecServerError>;
async fn write(
&self,
chunk: Option<Vec<u8>>,
close_stdin: bool,
) -> Result<WriteResponse, ExecServerError>;
async fn terminate(&self) -> Result<(), ExecServerError>;
}
+3 -1
View File
@@ -127,7 +127,9 @@ pub struct ReadResponse {
#[serde(rename_all = "camelCase")]
pub struct WriteParams {
pub process_id: ProcessId,
pub chunk: ByteChunk,
pub chunk: Option<ByteChunk>,
#[serde(default)]
pub close_stdin: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
+6 -2
View File
@@ -71,9 +71,13 @@ impl ExecProcess for RemoteExecProcess {
self.session.read(after_seq, max_bytes, wait_ms).await
}
async fn write(&self, chunk: Vec<u8>) -> Result<WriteResponse, ExecServerError> {
async fn write(
&self,
chunk: Option<Vec<u8>>,
close_stdin: bool,
) -> Result<WriteResponse, ExecServerError> {
trace!("exec process write");
self.session.write(chunk).await
self.session.write(chunk, close_stdin).await
}
async fn terminate(&self) -> Result<(), ExecServerError> {