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> {
|
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 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| {
|
state.modify_graph(|g| {
|
||||||
for relation in req.relations {
|
for relation in req.relations {
|
||||||
if !relation.from.is_empty() && !relation.to.is_empty() {
|
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())
|
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> {
|
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 req: AddObservationsTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
|
||||||
|
let mut missing_entities = Vec::new();
|
||||||
state.modify_graph(|g| {
|
state.modify_graph(|g| {
|
||||||
for o in req.observations {
|
for o in req.observations {
|
||||||
if let Some(e) = g.entities.get_mut(&o.entity_name) {
|
if let Some(e) = g.entities.get_mut(&o.entity_name) {
|
||||||
e.observations.extend(o.contents);
|
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())
|
Ok("Observations added".to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ pub fn default_namespace() -> String {
|
|||||||
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
|
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
|
||||||
pub struct Entity {
|
pub struct Entity {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
#[serde(rename = "entityType")]
|
#[serde(alias = "entityType")]
|
||||||
pub entity_type: String,
|
pub entity_type: String,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub observations: Vec<String>,
|
pub observations: Vec<String>,
|
||||||
@@ -34,7 +34,7 @@ pub struct Entity {
|
|||||||
pub struct Relation {
|
pub struct Relation {
|
||||||
pub from: String,
|
pub from: String,
|
||||||
pub to: String,
|
pub to: String,
|
||||||
#[serde(rename = "relationType")]
|
#[serde(alias = "relationType")]
|
||||||
pub relation_type: String,
|
pub relation_type: String,
|
||||||
#[serde(default = "default_namespace")]
|
#[serde(default = "default_namespace")]
|
||||||
pub namespace: String,
|
pub namespace: String,
|
||||||
@@ -50,7 +50,7 @@ pub struct KnowledgeGraph {
|
|||||||
pub struct AcceptanceCriteria {
|
pub struct AcceptanceCriteria {
|
||||||
pub id: String,
|
pub id: String,
|
||||||
pub description: String,
|
pub description: String,
|
||||||
#[serde(alias = "is_met", rename = "isMet")]
|
#[serde(alias = "is_met")]
|
||||||
pub is_met: bool,
|
pub is_met: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,19 +60,19 @@ pub struct Task {
|
|||||||
pub title: String,
|
pub title: String,
|
||||||
pub status: String,
|
pub status: String,
|
||||||
pub description: String,
|
pub description: String,
|
||||||
#[serde(alias = "created_at", rename = "createdAt")]
|
#[serde(alias = "created_at")]
|
||||||
pub created_at: u64,
|
pub created_at: u64,
|
||||||
#[serde(alias = "updated_at", rename = "updatedAt")]
|
#[serde(alias = "updated_at")]
|
||||||
pub updated_at: u64,
|
pub updated_at: u64,
|
||||||
#[serde(alias = "git_branch", rename = "gitBranch")]
|
#[serde(alias = "git_branch")]
|
||||||
pub git_branch: Option<String>,
|
pub git_branch: Option<String>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
#[serde(alias = "parent_id", rename = "parentId")]
|
#[serde(alias = "parent_id")]
|
||||||
pub parent_id: Option<String>,
|
pub parent_id: Option<String>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub dependencies: Vec<String>,
|
pub dependencies: Vec<String>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
#[serde(alias = "acceptance_criteria", rename = "acceptanceCriteria")]
|
#[serde(alias = "acceptance_criteria")]
|
||||||
pub acceptance_criteria: Vec<AcceptanceCriteria>,
|
pub acceptance_criteria: Vec<AcceptanceCriteria>,
|
||||||
}
|
}
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||||
|
|||||||
+25
-6
@@ -17,7 +17,7 @@ pub struct CreateRelationsTool {
|
|||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||||
pub struct ObservationInput {
|
pub struct ObservationInput {
|
||||||
#[serde(rename = "entityName")]
|
#[serde(alias = "entityName")]
|
||||||
pub entity_name: String,
|
pub entity_name: String,
|
||||||
pub contents: Vec<String>,
|
pub contents: Vec<String>,
|
||||||
}
|
}
|
||||||
@@ -33,13 +33,13 @@ pub struct AddObservationsTool {
|
|||||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||||
pub struct DeleteEntitiesTool {
|
pub struct DeleteEntitiesTool {
|
||||||
/// Array of entity names to delete.
|
/// Array of entity names to delete.
|
||||||
#[serde(rename = "entityNames")]
|
#[serde(alias = "entityNames")]
|
||||||
pub entity_names: Vec<String>,
|
pub entity_names: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||||
pub struct DeleteObservationInput {
|
pub struct DeleteObservationInput {
|
||||||
#[serde(rename = "entityName")]
|
#[serde(alias = "entityName")]
|
||||||
pub entity_name: String,
|
pub entity_name: String,
|
||||||
pub observations: Vec<String>,
|
pub observations: Vec<String>,
|
||||||
}
|
}
|
||||||
@@ -134,7 +134,7 @@ pub struct ClearStickyNotesTool {}
|
|||||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||||
pub struct CondenseEntityTool {
|
pub struct CondenseEntityTool {
|
||||||
/// The name of the entity to condense.
|
/// The name of the entity to condense.
|
||||||
#[serde(rename = "entityName")]
|
#[serde(alias = "entityName")]
|
||||||
pub entity_name: String,
|
pub entity_name: String,
|
||||||
/// The condensed observations that will replace the existing ones.
|
/// The condensed observations that will replace the existing ones.
|
||||||
pub summarized_observations: Vec<String>,
|
pub summarized_observations: Vec<String>,
|
||||||
@@ -230,10 +230,10 @@ pub struct QueryDecisionsTool {
|
|||||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||||
pub struct MergeEntitiesTool {
|
pub struct MergeEntitiesTool {
|
||||||
/// The name of the entity to merge from (will be deleted).
|
/// The name of the entity to merge from (will be deleted).
|
||||||
#[serde(rename = "sourceEntity")]
|
#[serde(alias = "sourceEntity")]
|
||||||
pub source_entity: String,
|
pub source_entity: String,
|
||||||
/// The name of the entity to merge into.
|
/// The name of the entity to merge into.
|
||||||
#[serde(rename = "targetEntity")]
|
#[serde(alias = "targetEntity")]
|
||||||
pub target_entity: String,
|
pub target_entity: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -278,6 +278,7 @@ pub struct SearchErrorFixesTool {
|
|||||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||||
pub struct PinFileTool {
|
pub struct PinFileTool {
|
||||||
/// The namespace to pin the file in.
|
/// The namespace to pin the file in.
|
||||||
|
#[serde(default = "crate::models::default_namespace")]
|
||||||
pub namespace: String,
|
pub namespace: String,
|
||||||
/// The absolute path of the file to pin.
|
/// The absolute path of the file to pin.
|
||||||
pub file_path: String,
|
pub file_path: String,
|
||||||
@@ -289,6 +290,7 @@ pub struct PinFileTool {
|
|||||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||||
pub struct UnpinFileTool {
|
pub struct UnpinFileTool {
|
||||||
/// The namespace the file is pinned in.
|
/// The namespace the file is pinned in.
|
||||||
|
#[serde(default = "crate::models::default_namespace")]
|
||||||
pub namespace: String,
|
pub namespace: String,
|
||||||
/// The absolute path of the file to unpin.
|
/// The absolute path of the file to unpin.
|
||||||
pub file_path: String,
|
pub file_path: String,
|
||||||
@@ -309,6 +311,7 @@ pub struct AddSessionSummaryTool {
|
|||||||
/// The summary content.
|
/// The summary content.
|
||||||
pub summary: String,
|
pub summary: String,
|
||||||
/// The namespace to add the summary to.
|
/// The namespace to add the summary to.
|
||||||
|
#[serde(default = "crate::models::default_namespace")]
|
||||||
pub namespace: String,
|
pub namespace: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,6 +329,7 @@ pub struct LeaveHandoffMemoTool {
|
|||||||
/// The content of the memo.
|
/// The content of the memo.
|
||||||
pub content: String,
|
pub content: String,
|
||||||
/// The namespace to leave the memo in.
|
/// The namespace to leave the memo in.
|
||||||
|
#[serde(default = "crate::models::default_namespace")]
|
||||||
pub namespace: String,
|
pub namespace: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -347,6 +351,7 @@ pub struct ClearHandoffMemosTool {
|
|||||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||||
pub struct UpdateEnvFingerprintTool {
|
pub struct UpdateEnvFingerprintTool {
|
||||||
/// The namespace to update the fingerprint for.
|
/// The namespace to update the fingerprint for.
|
||||||
|
#[serde(default = "crate::models::default_namespace")]
|
||||||
pub namespace: String,
|
pub namespace: String,
|
||||||
/// A map of tool names to their versions.
|
/// A map of tool names to their versions.
|
||||||
pub tool_versions: std::collections::HashMap<String, String>,
|
pub tool_versions: std::collections::HashMap<String, String>,
|
||||||
@@ -356,6 +361,7 @@ pub struct UpdateEnvFingerprintTool {
|
|||||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||||
pub struct ReadEnvFingerprintTool {
|
pub struct ReadEnvFingerprintTool {
|
||||||
/// The namespace to read the fingerprint for.
|
/// The namespace to read the fingerprint for.
|
||||||
|
#[serde(default = "crate::models::default_namespace")]
|
||||||
pub namespace: String,
|
pub namespace: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -363,6 +369,7 @@ pub struct ReadEnvFingerprintTool {
|
|||||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||||
pub struct LogEnvRequirementTool {
|
pub struct LogEnvRequirementTool {
|
||||||
/// The namespace.
|
/// The namespace.
|
||||||
|
#[serde(default = "crate::models::default_namespace")]
|
||||||
pub namespace: String,
|
pub namespace: String,
|
||||||
/// The environment variable key (e.g., DATABASE_URL).
|
/// The environment variable key (e.g., DATABASE_URL).
|
||||||
pub key: String,
|
pub key: String,
|
||||||
@@ -378,6 +385,7 @@ pub struct AddMilestoneTool {
|
|||||||
/// The title of the milestone.
|
/// The title of the milestone.
|
||||||
pub title: String,
|
pub title: String,
|
||||||
/// The namespace for the milestone.
|
/// The namespace for the milestone.
|
||||||
|
#[serde(default = "crate::models::default_namespace")]
|
||||||
pub namespace: String,
|
pub namespace: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -401,6 +409,7 @@ pub struct ListMilestonesTool {
|
|||||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||||
pub struct GenerateStandupReportTool {
|
pub struct GenerateStandupReportTool {
|
||||||
/// The namespace to generate the report for.
|
/// The namespace to generate the report for.
|
||||||
|
#[serde(default = "crate::models::default_namespace")]
|
||||||
pub namespace: String,
|
pub namespace: String,
|
||||||
/// The number of hours to look back for activity.
|
/// The number of hours to look back for activity.
|
||||||
pub hours_lookback: u64,
|
pub hours_lookback: u64,
|
||||||
@@ -410,6 +419,7 @@ pub struct GenerateStandupReportTool {
|
|||||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||||
pub struct RegisterEnvironmentTool {
|
pub struct RegisterEnvironmentTool {
|
||||||
/// The namespace.
|
/// The namespace.
|
||||||
|
#[serde(default = "crate::models::default_namespace")]
|
||||||
pub namespace: String,
|
pub namespace: String,
|
||||||
/// The name of the environment (e.g., 'staging', 'prod').
|
/// The name of the environment (e.g., 'staging', 'prod').
|
||||||
pub name: String,
|
pub name: String,
|
||||||
@@ -425,6 +435,7 @@ pub struct RegisterEnvironmentTool {
|
|||||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||||
pub struct GetEnvironmentDetailsTool {
|
pub struct GetEnvironmentDetailsTool {
|
||||||
/// The namespace to retrieve details for.
|
/// The namespace to retrieve details for.
|
||||||
|
#[serde(default = "crate::models::default_namespace")]
|
||||||
pub namespace: String,
|
pub namespace: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -432,6 +443,7 @@ pub struct GetEnvironmentDetailsTool {
|
|||||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||||
pub struct AddPrChecklistItemTool {
|
pub struct AddPrChecklistItemTool {
|
||||||
/// The namespace.
|
/// The namespace.
|
||||||
|
#[serde(default = "crate::models::default_namespace")]
|
||||||
pub namespace: String,
|
pub namespace: String,
|
||||||
/// The description of the checklist item.
|
/// The description of the checklist item.
|
||||||
pub description: String,
|
pub description: String,
|
||||||
@@ -441,6 +453,7 @@ pub struct AddPrChecklistItemTool {
|
|||||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||||
pub struct GetPrChecklistTool {
|
pub struct GetPrChecklistTool {
|
||||||
/// The namespace.
|
/// The namespace.
|
||||||
|
#[serde(default = "crate::models::default_namespace")]
|
||||||
pub namespace: String,
|
pub namespace: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -448,6 +461,7 @@ pub struct GetPrChecklistTool {
|
|||||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||||
pub struct ClearPrChecklistTool {
|
pub struct ClearPrChecklistTool {
|
||||||
/// The namespace.
|
/// The namespace.
|
||||||
|
#[serde(default = "crate::models::default_namespace")]
|
||||||
pub namespace: String,
|
pub namespace: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -455,6 +469,7 @@ pub struct ClearPrChecklistTool {
|
|||||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||||
pub struct LogTechDebtTool {
|
pub struct LogTechDebtTool {
|
||||||
/// The namespace.
|
/// The namespace.
|
||||||
|
#[serde(default = "crate::models::default_namespace")]
|
||||||
pub namespace: String,
|
pub namespace: String,
|
||||||
/// A description of the technical debt.
|
/// A description of the technical debt.
|
||||||
pub description: String,
|
pub description: String,
|
||||||
@@ -477,6 +492,7 @@ pub struct ResolveTechDebtTool {
|
|||||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||||
pub struct ListTechDebtTool {
|
pub struct ListTechDebtTool {
|
||||||
/// The namespace.
|
/// The namespace.
|
||||||
|
#[serde(default = "crate::models::default_namespace")]
|
||||||
pub namespace: String,
|
pub namespace: String,
|
||||||
/// Whether to include resolved technical debt in the results.
|
/// Whether to include resolved technical debt in the results.
|
||||||
pub include_resolved: bool,
|
pub include_resolved: bool,
|
||||||
@@ -486,6 +502,7 @@ pub struct ListTechDebtTool {
|
|||||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||||
pub struct SaveContextWorkspaceTool {
|
pub struct SaveContextWorkspaceTool {
|
||||||
/// The namespace for the workspace.
|
/// The namespace for the workspace.
|
||||||
|
#[serde(default = "crate::models::default_namespace")]
|
||||||
pub namespace: String,
|
pub namespace: String,
|
||||||
/// The name to save the workspace as.
|
/// The name to save the workspace as.
|
||||||
pub name: String,
|
pub name: String,
|
||||||
@@ -499,6 +516,7 @@ pub struct SaveContextWorkspaceTool {
|
|||||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||||
pub struct LoadContextWorkspaceTool {
|
pub struct LoadContextWorkspaceTool {
|
||||||
/// The namespace of the workspace.
|
/// The namespace of the workspace.
|
||||||
|
#[serde(default = "crate::models::default_namespace")]
|
||||||
pub namespace: String,
|
pub namespace: String,
|
||||||
/// The name of the workspace to load.
|
/// The name of the workspace to load.
|
||||||
pub name: String,
|
pub name: String,
|
||||||
@@ -524,6 +542,7 @@ pub struct OmniSearchTool {
|
|||||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||||
pub struct GetProjectHealthTool {
|
pub struct GetProjectHealthTool {
|
||||||
/// The namespace to get health for.
|
/// The namespace to get health for.
|
||||||
|
#[serde(default = "crate::models::default_namespace")]
|
||||||
pub namespace: String,
|
pub namespace: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user