fix: agent usability improvements - unified schema casing, fixed silent handler failures, and made namespaces strictly optional
This commit is contained in:
1 parent
5dd413c397
commit
be85b58be4
3 files changed
+52
-15
No files matched your search
@@ -152,13 +152,25 @@ impl McpTool for CreateRelationsHandler {
|
||||
|
||||
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> Result<String, String> {
|
||||
let req: CreateRelationsTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
|
||||
let mut missing_nodes = std::collections::HashSet::new();
|
||||
state.modify_graph(|g| {
|
||||
for relation in req.relations {
|
||||
if !relation.from.is_empty() && !relation.to.is_empty() {
|
||||
g.relations.push(relation);
|
||||
let from_exists = g.entities.contains_key(&relation.from);
|
||||
let to_exists = g.entities.contains_key(&relation.to);
|
||||
if from_exists && to_exists {
|
||||
g.relations.push(relation);
|
||||
} else {
|
||||
if !from_exists { missing_nodes.insert(relation.from); }
|
||||
if !to_exists { missing_nodes.insert(relation.to); }
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
if !missing_nodes.is_empty() {
|
||||
let missing: Vec<_> = missing_nodes.into_iter().collect();
|
||||
return Ok(format!("Warning: Relations dropped due to missing entities: {}", missing.join(", ")));
|
||||
}
|
||||
Ok("Relations created".to_string())
|
||||
}
|
||||
}
|
||||
@@ -177,13 +189,19 @@ impl McpTool for AddObservationsHandler {
|
||||
|
||||
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> Result<String, String> {
|
||||
let req: AddObservationsTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
|
||||
let mut missing_entities = Vec::new();
|
||||
state.modify_graph(|g| {
|
||||
for o in req.observations {
|
||||
if let Some(e) = g.entities.get_mut(&o.entity_name) {
|
||||
e.observations.extend(o.contents);
|
||||
} else {
|
||||
missing_entities.push(o.entity_name);
|
||||
}
|
||||
}
|
||||
});
|
||||
if !missing_entities.is_empty() {
|
||||
return Ok(format!("Warning: Observations dropped for missing entities: {}", missing_entities.join(", ")));
|
||||
}
|
||||
Ok("Observations added".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ pub fn default_namespace() -> String {
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct Entity {
|
||||
pub name: String,
|
||||
#[serde(rename = "entityType")]
|
||||
#[serde(alias = "entityType")]
|
||||
pub entity_type: String,
|
||||
#[serde(default)]
|
||||
pub observations: Vec<String>,
|
||||
@@ -34,7 +34,7 @@ pub struct Entity {
|
||||
pub struct Relation {
|
||||
pub from: String,
|
||||
pub to: String,
|
||||
#[serde(rename = "relationType")]
|
||||
#[serde(alias = "relationType")]
|
||||
pub relation_type: String,
|
||||
#[serde(default = "default_namespace")]
|
||||
pub namespace: String,
|
||||
@@ -50,7 +50,7 @@ pub struct KnowledgeGraph {
|
||||
pub struct AcceptanceCriteria {
|
||||
pub id: String,
|
||||
pub description: String,
|
||||
#[serde(alias = "is_met", rename = "isMet")]
|
||||
#[serde(alias = "is_met")]
|
||||
pub is_met: bool,
|
||||
}
|
||||
|
||||
@@ -60,19 +60,19 @@ pub struct Task {
|
||||
pub title: String,
|
||||
pub status: String,
|
||||
pub description: String,
|
||||
#[serde(alias = "created_at", rename = "createdAt")]
|
||||
#[serde(alias = "created_at")]
|
||||
pub created_at: u64,
|
||||
#[serde(alias = "updated_at", rename = "updatedAt")]
|
||||
#[serde(alias = "updated_at")]
|
||||
pub updated_at: u64,
|
||||
#[serde(alias = "git_branch", rename = "gitBranch")]
|
||||
#[serde(alias = "git_branch")]
|
||||
pub git_branch: Option<String>,
|
||||
#[serde(default)]
|
||||
#[serde(alias = "parent_id", rename = "parentId")]
|
||||
#[serde(alias = "parent_id")]
|
||||
pub parent_id: Option<String>,
|
||||
#[serde(default)]
|
||||
pub dependencies: Vec<String>,
|
||||
#[serde(default)]
|
||||
#[serde(alias = "acceptance_criteria", rename = "acceptanceCriteria")]
|
||||
#[serde(alias = "acceptance_criteria")]
|
||||
pub acceptance_criteria: Vec<AcceptanceCriteria>,
|
||||
}
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||
|
||||
+25
-6
@@ -17,7 +17,7 @@ pub struct CreateRelationsTool {
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct ObservationInput {
|
||||
#[serde(rename = "entityName")]
|
||||
#[serde(alias = "entityName")]
|
||||
pub entity_name: String,
|
||||
pub contents: Vec<String>,
|
||||
}
|
||||
@@ -33,13 +33,13 @@ pub struct AddObservationsTool {
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct DeleteEntitiesTool {
|
||||
/// Array of entity names to delete.
|
||||
#[serde(rename = "entityNames")]
|
||||
#[serde(alias = "entityNames")]
|
||||
pub entity_names: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct DeleteObservationInput {
|
||||
#[serde(rename = "entityName")]
|
||||
#[serde(alias = "entityName")]
|
||||
pub entity_name: String,
|
||||
pub observations: Vec<String>,
|
||||
}
|
||||
@@ -134,7 +134,7 @@ pub struct ClearStickyNotesTool {}
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct CondenseEntityTool {
|
||||
/// The name of the entity to condense.
|
||||
#[serde(rename = "entityName")]
|
||||
#[serde(alias = "entityName")]
|
||||
pub entity_name: String,
|
||||
/// The condensed observations that will replace the existing ones.
|
||||
pub summarized_observations: Vec<String>,
|
||||
@@ -230,10 +230,10 @@ pub struct QueryDecisionsTool {
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct MergeEntitiesTool {
|
||||
/// The name of the entity to merge from (will be deleted).
|
||||
#[serde(rename = "sourceEntity")]
|
||||
#[serde(alias = "sourceEntity")]
|
||||
pub source_entity: String,
|
||||
/// The name of the entity to merge into.
|
||||
#[serde(rename = "targetEntity")]
|
||||
#[serde(alias = "targetEntity")]
|
||||
pub target_entity: String,
|
||||
}
|
||||
|
||||
@@ -278,6 +278,7 @@ pub struct SearchErrorFixesTool {
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct PinFileTool {
|
||||
/// The namespace to pin the file in.
|
||||
#[serde(default = "crate::models::default_namespace")]
|
||||
pub namespace: String,
|
||||
/// The absolute path of the file to pin.
|
||||
pub file_path: String,
|
||||
@@ -289,6 +290,7 @@ pub struct PinFileTool {
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct UnpinFileTool {
|
||||
/// The namespace the file is pinned in.
|
||||
#[serde(default = "crate::models::default_namespace")]
|
||||
pub namespace: String,
|
||||
/// The absolute path of the file to unpin.
|
||||
pub file_path: String,
|
||||
@@ -309,6 +311,7 @@ pub struct AddSessionSummaryTool {
|
||||
/// The summary content.
|
||||
pub summary: String,
|
||||
/// The namespace to add the summary to.
|
||||
#[serde(default = "crate::models::default_namespace")]
|
||||
pub namespace: String,
|
||||
}
|
||||
|
||||
@@ -326,6 +329,7 @@ pub struct LeaveHandoffMemoTool {
|
||||
/// The content of the memo.
|
||||
pub content: String,
|
||||
/// The namespace to leave the memo in.
|
||||
#[serde(default = "crate::models::default_namespace")]
|
||||
pub namespace: String,
|
||||
}
|
||||
|
||||
@@ -347,6 +351,7 @@ pub struct ClearHandoffMemosTool {
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct UpdateEnvFingerprintTool {
|
||||
/// The namespace to update the fingerprint for.
|
||||
#[serde(default = "crate::models::default_namespace")]
|
||||
pub namespace: String,
|
||||
/// A map of tool names to their versions.
|
||||
pub tool_versions: std::collections::HashMap<String, String>,
|
||||
@@ -356,6 +361,7 @@ pub struct UpdateEnvFingerprintTool {
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct ReadEnvFingerprintTool {
|
||||
/// The namespace to read the fingerprint for.
|
||||
#[serde(default = "crate::models::default_namespace")]
|
||||
pub namespace: String,
|
||||
}
|
||||
|
||||
@@ -363,6 +369,7 @@ pub struct ReadEnvFingerprintTool {
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct LogEnvRequirementTool {
|
||||
/// The namespace.
|
||||
#[serde(default = "crate::models::default_namespace")]
|
||||
pub namespace: String,
|
||||
/// The environment variable key (e.g., DATABASE_URL).
|
||||
pub key: String,
|
||||
@@ -378,6 +385,7 @@ pub struct AddMilestoneTool {
|
||||
/// The title of the milestone.
|
||||
pub title: String,
|
||||
/// The namespace for the milestone.
|
||||
#[serde(default = "crate::models::default_namespace")]
|
||||
pub namespace: String,
|
||||
}
|
||||
|
||||
@@ -401,6 +409,7 @@ pub struct ListMilestonesTool {
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct GenerateStandupReportTool {
|
||||
/// The namespace to generate the report for.
|
||||
#[serde(default = "crate::models::default_namespace")]
|
||||
pub namespace: String,
|
||||
/// The number of hours to look back for activity.
|
||||
pub hours_lookback: u64,
|
||||
@@ -410,6 +419,7 @@ pub struct GenerateStandupReportTool {
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct RegisterEnvironmentTool {
|
||||
/// The namespace.
|
||||
#[serde(default = "crate::models::default_namespace")]
|
||||
pub namespace: String,
|
||||
/// The name of the environment (e.g., 'staging', 'prod').
|
||||
pub name: String,
|
||||
@@ -425,6 +435,7 @@ pub struct RegisterEnvironmentTool {
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct GetEnvironmentDetailsTool {
|
||||
/// The namespace to retrieve details for.
|
||||
#[serde(default = "crate::models::default_namespace")]
|
||||
pub namespace: String,
|
||||
}
|
||||
|
||||
@@ -432,6 +443,7 @@ pub struct GetEnvironmentDetailsTool {
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct AddPrChecklistItemTool {
|
||||
/// The namespace.
|
||||
#[serde(default = "crate::models::default_namespace")]
|
||||
pub namespace: String,
|
||||
/// The description of the checklist item.
|
||||
pub description: String,
|
||||
@@ -441,6 +453,7 @@ pub struct AddPrChecklistItemTool {
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct GetPrChecklistTool {
|
||||
/// The namespace.
|
||||
#[serde(default = "crate::models::default_namespace")]
|
||||
pub namespace: String,
|
||||
}
|
||||
|
||||
@@ -448,6 +461,7 @@ pub struct GetPrChecklistTool {
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct ClearPrChecklistTool {
|
||||
/// The namespace.
|
||||
#[serde(default = "crate::models::default_namespace")]
|
||||
pub namespace: String,
|
||||
}
|
||||
|
||||
@@ -455,6 +469,7 @@ pub struct ClearPrChecklistTool {
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct LogTechDebtTool {
|
||||
/// The namespace.
|
||||
#[serde(default = "crate::models::default_namespace")]
|
||||
pub namespace: String,
|
||||
/// A description of the technical debt.
|
||||
pub description: String,
|
||||
@@ -477,6 +492,7 @@ pub struct ResolveTechDebtTool {
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct ListTechDebtTool {
|
||||
/// The namespace.
|
||||
#[serde(default = "crate::models::default_namespace")]
|
||||
pub namespace: String,
|
||||
/// Whether to include resolved technical debt in the results.
|
||||
pub include_resolved: bool,
|
||||
@@ -486,6 +502,7 @@ pub struct ListTechDebtTool {
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct SaveContextWorkspaceTool {
|
||||
/// The namespace for the workspace.
|
||||
#[serde(default = "crate::models::default_namespace")]
|
||||
pub namespace: String,
|
||||
/// The name to save the workspace as.
|
||||
pub name: String,
|
||||
@@ -499,6 +516,7 @@ pub struct SaveContextWorkspaceTool {
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct LoadContextWorkspaceTool {
|
||||
/// The namespace of the workspace.
|
||||
#[serde(default = "crate::models::default_namespace")]
|
||||
pub namespace: String,
|
||||
/// The name of the workspace to load.
|
||||
pub name: String,
|
||||
@@ -524,6 +542,7 @@ pub struct OmniSearchTool {
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct GetProjectHealthTool {
|
||||
/// The namespace to get health for.
|
||||
#[serde(default = "crate::models::default_namespace")]
|
||||
pub namespace: String,
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user