mirror of
https://github.com/aiclientproxy/proxycast.git
synced 2026-09-24 23:10:56 +08:00
release: v1.4.0
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
//! 负责在工作区内生成稳定路径、落盘 JSON 快照,并给前端 workbench
|
||||
//! 提供可直接消费的 snapshot metadata。
|
||||
|
||||
use crate::commands::content_cmd::THEME_WORKBENCH_DOCUMENT_META_KEY;
|
||||
use crate::commands::content_cmd::GENERAL_WORKBENCH_DOCUMENT_META_KEY;
|
||||
use crate::content::{ContentManager, ContentUpdateRequest};
|
||||
use crate::database::DbConnection;
|
||||
use crate::services::artifact_document_validator::{
|
||||
@@ -29,7 +29,7 @@ pub struct PersistedArtifactDocument {
|
||||
pub absolute_path: PathBuf,
|
||||
pub serialized_document: String,
|
||||
pub snapshot_metadata: Map<String, Value>,
|
||||
pub theme_workbench_document_state: Map<String, Value>,
|
||||
pub general_workbench_document_state: Map<String, Value>,
|
||||
pub content_body: String,
|
||||
pub title: String,
|
||||
pub kind: String,
|
||||
@@ -274,8 +274,8 @@ pub fn persist_artifact_document_from_text(
|
||||
&source_links,
|
||||
version_diff.as_ref(),
|
||||
);
|
||||
let theme_workbench_document_state =
|
||||
build_theme_workbench_document_state(&version_history, current_version.id.as_str());
|
||||
let general_workbench_document_state =
|
||||
build_general_workbench_document_state(&version_history, current_version.id.as_str());
|
||||
let content_body = build_content_body_from_document(&enriched_document);
|
||||
|
||||
Ok(PersistedArtifactDocument {
|
||||
@@ -286,7 +286,7 @@ pub fn persist_artifact_document_from_text(
|
||||
absolute_path,
|
||||
serialized_document,
|
||||
snapshot_metadata,
|
||||
theme_workbench_document_state,
|
||||
general_workbench_document_state,
|
||||
content_body,
|
||||
title: outcome.title,
|
||||
kind: outcome.kind,
|
||||
@@ -423,7 +423,7 @@ fn resolve_topic_branch_status(status: &str) -> Option<&'static str> {
|
||||
}
|
||||
}
|
||||
|
||||
fn build_theme_workbench_document_state(
|
||||
fn build_general_workbench_document_state(
|
||||
version_history: &[ArtifactVersionSummary],
|
||||
current_version_id: &str,
|
||||
) -> Map<String, Value> {
|
||||
@@ -628,8 +628,8 @@ pub fn sync_persisted_artifact_document_to_content(
|
||||
}
|
||||
}
|
||||
next_metadata.insert(
|
||||
THEME_WORKBENCH_DOCUMENT_META_KEY.to_string(),
|
||||
Value::Object(persisted.theme_workbench_document_state.clone()),
|
||||
GENERAL_WORKBENCH_DOCUMENT_META_KEY.to_string(),
|
||||
Value::Object(persisted.general_workbench_document_state.clone()),
|
||||
);
|
||||
|
||||
manager.update(
|
||||
@@ -1426,7 +1426,7 @@ mod tests {
|
||||
.contains("\"currentVersionDiff\""));
|
||||
assert_eq!(
|
||||
persisted_second
|
||||
.theme_workbench_document_state
|
||||
.general_workbench_document_state
|
||||
.get("currentVersionId")
|
||||
.and_then(Value::as_str),
|
||||
Some("artifact-document:artifact:analysis:demo:v2")
|
||||
@@ -1512,7 +1512,7 @@ mod tests {
|
||||
let metadata = updated.metadata.expect("metadata should exist");
|
||||
assert_eq!(
|
||||
metadata
|
||||
.get(THEME_WORKBENCH_DOCUMENT_META_KEY)
|
||||
.get(GENERAL_WORKBENCH_DOCUMENT_META_KEY)
|
||||
.and_then(Value::as_object)
|
||||
.and_then(|value| value.get("currentVersionId"))
|
||||
.and_then(Value::as_str),
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
|
||||
use serde_json::{Map, Value};
|
||||
|
||||
const GENERAL_WORKBENCH_SESSION_MODE: &str = "general_workbench";
|
||||
const LEGACY_GENERAL_WORKBENCH_SESSION_MODE_ALIAS: &str = "theme_workbench";
|
||||
|
||||
const ARTIFACT_MEANINGFUL_KEYS: &[&str] = &[
|
||||
"artifact_mode",
|
||||
"artifactMode",
|
||||
@@ -31,6 +34,16 @@ fn normalize_text(value: Option<&str>) -> Option<String> {
|
||||
.map(str::to_string)
|
||||
}
|
||||
|
||||
fn normalize_session_mode_text(value: Option<&str>) -> Option<String> {
|
||||
match normalize_text(value)?.as_str() {
|
||||
GENERAL_WORKBENCH_SESSION_MODE | LEGACY_GENERAL_WORKBENCH_SESSION_MODE_ALIAS => {
|
||||
Some(GENERAL_WORKBENCH_SESSION_MODE.to_string())
|
||||
}
|
||||
"default" => Some("default".to_string()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn root_object(request_metadata: Option<&Value>) -> Option<&Map<String, Value>> {
|
||||
request_metadata?.as_object()
|
||||
}
|
||||
@@ -51,6 +64,40 @@ fn extract_harness_string(request_metadata: Option<&Value>, keys: &[&str]) -> Op
|
||||
.and_then(|value| normalize_text(Some(value)))
|
||||
}
|
||||
|
||||
fn extract_harness_session_mode(request_metadata: Option<&Value>) -> Option<String> {
|
||||
normalize_session_mode_text(
|
||||
extract_harness_string(request_metadata, &["session_mode", "sessionMode"]).as_deref(),
|
||||
)
|
||||
}
|
||||
|
||||
fn normalize_harness_session_mode_field(request_metadata: Value) -> Value {
|
||||
let Some(normalized_session_mode) = extract_harness_session_mode(Some(&request_metadata))
|
||||
else {
|
||||
return request_metadata;
|
||||
};
|
||||
|
||||
let mut request_metadata = request_metadata;
|
||||
let Some(root) = request_metadata.as_object_mut() else {
|
||||
return request_metadata;
|
||||
};
|
||||
|
||||
if let Some(harness) = root.get_mut("harness").and_then(Value::as_object_mut) {
|
||||
harness.insert(
|
||||
"session_mode".to_string(),
|
||||
Value::String(normalized_session_mode),
|
||||
);
|
||||
harness.remove("sessionMode");
|
||||
return request_metadata;
|
||||
}
|
||||
|
||||
root.insert(
|
||||
"session_mode".to_string(),
|
||||
Value::String(normalized_session_mode),
|
||||
);
|
||||
root.remove("sessionMode");
|
||||
request_metadata
|
||||
}
|
||||
|
||||
fn is_flat_artifact_metadata_key(key: &str) -> bool {
|
||||
matches!(
|
||||
key,
|
||||
@@ -117,8 +164,8 @@ fn infer_source_policy(kind: Option<&str>) -> Option<&'static str> {
|
||||
}
|
||||
|
||||
fn should_enable_artifact_draft(request_metadata: Option<&Value>) -> bool {
|
||||
if extract_harness_string(request_metadata, &["session_mode", "sessionMode"]).as_deref()
|
||||
!= Some("theme_workbench")
|
||||
if extract_harness_session_mode(request_metadata).as_deref()
|
||||
!= Some(GENERAL_WORKBENCH_SESSION_MODE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -183,6 +230,7 @@ pub fn normalize_request_metadata_with_artifact_defaults(
|
||||
content_id_fallback: Option<&str>,
|
||||
) -> Option<Value> {
|
||||
let request_metadata = request_metadata?;
|
||||
let request_metadata = normalize_harness_session_mode_field(request_metadata);
|
||||
let request_metadata = backfill_harness_string_if_missing(
|
||||
request_metadata,
|
||||
&["theme", "harness_theme", "harnessTheme"],
|
||||
@@ -294,11 +342,11 @@ mod tests {
|
||||
use serde_json::json;
|
||||
|
||||
#[test]
|
||||
fn should_infer_theme_workbench_artifact_defaults_from_harness() {
|
||||
fn should_infer_general_workbench_artifact_defaults_from_harness() {
|
||||
let metadata = json!({
|
||||
"harness": {
|
||||
"theme": "general",
|
||||
"session_mode": "theme_workbench",
|
||||
"session_mode": "general_workbench",
|
||||
"content_id": "content-1"
|
||||
}
|
||||
});
|
||||
@@ -356,7 +404,7 @@ mod tests {
|
||||
let metadata = json!({
|
||||
"harness": {
|
||||
"theme": "general",
|
||||
"session_mode": "theme_workbench",
|
||||
"session_mode": "general_workbench",
|
||||
"turn_purpose": "content_review",
|
||||
"content_id": "content-1"
|
||||
}
|
||||
@@ -422,7 +470,7 @@ mod tests {
|
||||
let metadata = json!({
|
||||
"harness": {
|
||||
"theme": "general",
|
||||
"session_mode": "theme_workbench"
|
||||
"session_mode": "general_workbench"
|
||||
}
|
||||
});
|
||||
|
||||
@@ -461,7 +509,7 @@ mod tests {
|
||||
let normalized = normalize_request_metadata_with_artifact_defaults(
|
||||
Some(metadata),
|
||||
Some("general"),
|
||||
Some("theme_workbench"),
|
||||
Some("general_workbench"),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
@@ -476,7 +524,7 @@ mod tests {
|
||||
normalized
|
||||
.pointer("/harness/session_mode")
|
||||
.and_then(Value::as_str),
|
||||
Some("theme_workbench")
|
||||
Some("general_workbench")
|
||||
);
|
||||
assert_eq!(
|
||||
normalized
|
||||
@@ -491,7 +539,7 @@ mod tests {
|
||||
let metadata = json!({
|
||||
"harness": {
|
||||
"theme": "general",
|
||||
"session_mode": "theme_workbench",
|
||||
"session_mode": "general_workbench",
|
||||
"content_id": "content-social-1"
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user