refactor!: remove redundant compatibility layers
Use native browser and Tauri behavior instead of custom selector, dialog, and window-state implementations. Remove obsolete bridge, relay, asset, and dependency paths to keep the supported surface small. BREAKING CHANGE: The Noctalia relay no longer accepts --agent, and the Tauri host no longer exposes the legacy load_agent command.
This commit is contained in:
+5
-152
@@ -1,7 +1,6 @@
|
||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||
use serde_json::{json, Value};
|
||||
use std::env;
|
||||
use std::path::Path;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use tauri::{AppHandle, Emitter};
|
||||
use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader};
|
||||
@@ -346,72 +345,11 @@ pub async fn new_session(socket_path: &str, agent_id: &str) -> Result<Value, Str
|
||||
request(socket_path, "new_session", Some(agent_id), None).await
|
||||
}
|
||||
|
||||
fn fallback_transcript(state: &Value) -> Value {
|
||||
let Some(path) = state.pointer("/data/sessionFile").and_then(Value::as_str) else {
|
||||
return json!({ "data": { "messages": [] } });
|
||||
};
|
||||
let path = Path::new(path);
|
||||
if !path.is_absolute()
|
||||
|| path.extension().and_then(|extension| extension.to_str()) != Some("jsonl")
|
||||
{
|
||||
return json!({ "data": { "messages": [] } });
|
||||
}
|
||||
let messages = std::fs::read_to_string(path)
|
||||
.ok()
|
||||
.map(|content| {
|
||||
content
|
||||
.lines()
|
||||
.filter_map(|line| serde_json::from_str::<Value>(line).ok())
|
||||
.filter(|entry| entry.get("type").and_then(Value::as_str) == Some("message"))
|
||||
.filter_map(|entry| entry.get("message").cloned())
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
.unwrap_or_default();
|
||||
json!({ "data": { "messages": messages } })
|
||||
}
|
||||
|
||||
fn compact_commands(value: Value) -> Value {
|
||||
let commands = value
|
||||
.pointer("/data/commands")
|
||||
.and_then(Value::as_array)
|
||||
.map(|commands| {
|
||||
commands
|
||||
.iter()
|
||||
.map(|command| {
|
||||
let mut compact = serde_json::Map::new();
|
||||
for field in ["name", "description"] {
|
||||
if let Some(value) = command.get(field) {
|
||||
compact.insert(field.to_owned(), value.clone());
|
||||
}
|
||||
}
|
||||
Value::Object(compact)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
.unwrap_or_default();
|
||||
json!({ "data": { "commands": commands } })
|
||||
}
|
||||
|
||||
pub async fn load_agent(socket_path: &str, agent_id: &str) -> Result<Value, String> {
|
||||
// Older bridge daemons can still serve the conversation while they await a restart.
|
||||
let stats = request(socket_path, "get_session_stats", Some(agent_id), None)
|
||||
.await
|
||||
.unwrap_or_else(|_| json!({ "data": {} }));
|
||||
let (state, commands, models) = tokio::try_join!(
|
||||
request(socket_path, "get_state", Some(agent_id), None),
|
||||
request(socket_path, "get_commands", Some(agent_id), None),
|
||||
request(socket_path, "get_available_models", Some(agent_id), None),
|
||||
)?;
|
||||
Ok(json!({
|
||||
"state": state,
|
||||
"stats": stats,
|
||||
"transcript": fallback_transcript(&state),
|
||||
"commands": compact_commands(commands),
|
||||
"models": models
|
||||
}))
|
||||
}
|
||||
|
||||
pub async fn submit_prompt(socket_path: &str, agent_id: &str, message: &str) -> Result<Value, String> {
|
||||
pub async fn submit_prompt(
|
||||
socket_path: &str,
|
||||
agent_id: &str,
|
||||
message: &str,
|
||||
) -> Result<Value, String> {
|
||||
request(
|
||||
socket_path,
|
||||
"submit_prompt",
|
||||
@@ -896,91 +834,6 @@ mod tests {
|
||||
std::fs::remove_file(path).expect("socket cleanup");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reads_messages_from_the_saved_session_file_when_transcript_rpc_is_unavailable() {
|
||||
let path = format!(
|
||||
"{}/pi-status-ui-history-{}.jsonl",
|
||||
env::temp_dir().display(),
|
||||
std::process::id()
|
||||
);
|
||||
std::fs::write(
|
||||
&path,
|
||||
concat!(
|
||||
"{\"type\":\"session\",\"id\":\"session-1\"}\n",
|
||||
"{\"type\":\"message\",\"message\":{\"role\":\"user\",\"content\":\"Hello\"}}\n",
|
||||
"{\"type\":\"message\",\"message\":{\"role\":\"assistant\",\"content\":\"Hi\"}}\n"
|
||||
),
|
||||
)
|
||||
.expect("session fixture");
|
||||
let transcript = fallback_transcript(&json!({
|
||||
"data": { "sessionFile": path }
|
||||
}));
|
||||
assert_eq!(
|
||||
transcript["data"]["messages"],
|
||||
json!([
|
||||
{ "role": "user", "content": "Hello" },
|
||||
{ "role": "assistant", "content": "Hi" }
|
||||
])
|
||||
);
|
||||
std::fs::remove_file(path).expect("session cleanup");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn loads_state_history_commands_and_models_as_one_snapshot() {
|
||||
let path = format!(
|
||||
"{}/pi-status-ui-load-{}.sock",
|
||||
env::temp_dir().display(),
|
||||
std::process::id()
|
||||
);
|
||||
let _ = std::fs::remove_file(&path);
|
||||
let listener = UnixListener::bind(&path).expect("listener");
|
||||
let server = tokio::spawn(async move {
|
||||
for _ in 0..4 {
|
||||
let (stream, _) = listener.accept().await.expect("connection");
|
||||
tokio::spawn(async move {
|
||||
let mut line = String::new();
|
||||
let mut reader = BufReader::new(stream);
|
||||
reader.read_line(&mut line).await.expect("request");
|
||||
let request: Value = serde_json::from_str(&line).expect("JSON request");
|
||||
assert_eq!(request["agentId"], "agent-1");
|
||||
let result = match request["op"].as_str() {
|
||||
Some("get_state") => json!({ "data": { "isStreaming": false } }),
|
||||
Some("get_session_stats") => json!({
|
||||
"data": { "contextUsage": { "tokens": 32000, "contextWindow": 200000 } }
|
||||
}),
|
||||
Some("get_commands") => json!({ "data": { "commands": [{
|
||||
"name": "resume",
|
||||
"description": "Resume a saved session",
|
||||
"sourceInfo": { "path": "/very/large/extension/metadata" }
|
||||
}] } }),
|
||||
Some("get_available_models") => json!({ "data": { "models": [] } }),
|
||||
other => panic!("unexpected operation: {other:?}"),
|
||||
};
|
||||
let mut response = serde_json::to_vec(&json!({
|
||||
"id": "tauri-ui", "ok": true, "result": result
|
||||
}))
|
||||
.expect("response JSON");
|
||||
response.push(b'\n');
|
||||
reader
|
||||
.get_mut()
|
||||
.write_all(&response)
|
||||
.await
|
||||
.expect("response");
|
||||
});
|
||||
}
|
||||
});
|
||||
let snapshot = load_agent(&path, "agent-1").await.expect("snapshot");
|
||||
assert_eq!(snapshot["state"]["data"]["isStreaming"], false);
|
||||
assert_eq!(snapshot["stats"]["data"]["contextUsage"]["tokens"], 32000);
|
||||
assert_eq!(snapshot["transcript"]["data"]["messages"], json!([]));
|
||||
assert_eq!(
|
||||
snapshot["commands"]["data"]["commands"],
|
||||
json!([{ "name": "resume", "description": "Resume a saved session" }])
|
||||
);
|
||||
server.await.expect("server succeeds");
|
||||
std::fs::remove_file(path).expect("socket cleanup");
|
||||
}
|
||||
|
||||
fn runtime(id: &str) -> Value {
|
||||
json!({
|
||||
"runtimeId": id,
|
||||
|
||||
Reference in New Issue
Block a user