feat(api): enhance statistics storage management with scope options

- Introduced a new type `StatisticsStorageScope` to specify the scope for clearing statistics.
- Updated the `clearStatisticsStorage` API method to accept a scope parameter, allowing for selective clearing of detailed records or all statistics.
- Modified the demo API to handle the new scope parameter appropriately.
- Updated the SettingsPage component to include a selection for clearing scope, enhancing user control over statistics management.
- Added new translations for the updated messages related to statistics clearing in both English and Chinese.
This commit is contained in:
leookun
2026-08-28 10:18:11 +08:00
parent 217f984112
commit 71ddf71ec1
15 changed files with 514 additions and 111 deletions
+40
View File
@@ -7,6 +7,7 @@ use std::{collections::HashMap, sync::Arc};
use cursor_server::{
cursor::{
bidi_append::{self, DecodedAppend},
connect,
prompting::{PromptAssets, PromptCompiler},
proto::agent::v1 as pb,
@@ -20,6 +21,45 @@ use prost::Message;
const FOLLOW_UP: &str = "Perform any necessary follow-up actions in response to the subagent completion above. If no follow-up work is needed, no further action is required. If you mention an agent or subagent in your response, link it with the `[Name](id)` Don't use generic label such as `[agent]`, `[worker]`, or `[subagent]`.";
const SHELL_FOLLOW_UP: &str = "Briefly inform the user about the task result and perform any follow-up actions (if needed). If there's no follow-ups needed, don't explicitly say that.";
#[tokio::test]
async fn cancelled_conversation_drops_late_background_completion() {
let (_directory, store) = fixtures::temp_store().await;
let provider = fake_provider::FakeProvider::default();
let assets = PromptAssets::load(
std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
.join("prompt/cursor")
.as_path(),
)
.unwrap();
let registry = CursorSessionRegistry::new(
store,
Arc::new(provider.clone()),
PromptCompiler::new(assets),
Default::default(),
);
let active = registry.get_or_create("cancelled-request").await.unwrap();
active.set_conversation_id("parent-conversation").unwrap();
active.mark_conversation_cancelled();
bidi_append::append(
&registry,
DecodedAppend {
request_id: "late-completion".into(),
seqno: 1,
message: completion_run(
"child-id",
"cancelled-parent-run",
pb::ConversationStateStructure::default(),
),
},
None,
)
.await
.unwrap();
assert!(provider.requests().is_empty());
}
#[tokio::test]
async fn background_subagent_completion_starts_a_simulated_parent_turn() {
let (_directory, store) = fixtures::temp_store().await;
+10
View File
@@ -672,7 +672,17 @@ async fn anthropic_raw_stream_uses_explicit_and_default_token_limits() {
server.abort();
assert_eq!(body["max_tokens"], 1234);
assert!(body.get("cache_control").is_none());
assert_eq!(
body["messages"][0]["content"][0]["cache_control"]["type"],
"ephemeral"
);
assert_eq!(default_body["max_tokens"], 65_000);
assert!(default_body.get("cache_control").is_none());
assert_eq!(
default_body["messages"][0]["content"][0]["cache_control"]["type"],
"ephemeral"
);
assert!(body.get("service_tier").is_none());
assert_eq!(body["messages"][0]["content"][1]["type"], "image");
assert_eq!(